2011-10-14 02:41:56 +08:00
/* ----------------------------------------------------------------------------
* GTSAM Copyright 2010 , Georgia Tech Research Corporation ,
* Atlanta , Georgia 30332 - 0415
* All Rights Reserved
* Authors : Frank Dellaert , et al . ( see THANKS for the full author list )
* See LICENSE for the license information
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
2011-10-14 11:23:14 +08:00
* @ file Class . h
* @ brief describe the C + + class that is being wrapped
* @ author Frank Dellaert
2012-06-27 02:52:27 +08:00
* @ author Andrew Melim
2012-07-13 06:28:28 +08:00
* @ author Richard Roberts
2011-10-14 02:41:56 +08:00
* */
# pragma once
2014-12-02 19:41:35 +08:00
# include "spirit.h"
2014-12-01 21:35:02 +08:00
# include "Template.h"
2011-10-14 02:41:56 +08:00
# include "Constructor.h"
2012-03-30 13:34:23 +08:00
# include "Deconstructor.h"
2011-10-14 02:41:56 +08:00
# include "Method.h"
2011-12-02 10:32:18 +08:00
# include "StaticMethod.h"
2016-09-09 19:26:11 +08:00
# include "TemplateMethod.h"
2012-07-13 06:28:28 +08:00
# include "TypeAttributesTable.h"
2011-10-14 02:41:56 +08:00
2014-12-02 19:41:35 +08:00
# ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-variable"
# endif
# include <boost/lambda/bind.hpp>
# include <boost/lambda/lambda.hpp>
# ifdef __GNUC__
# pragma GCC diagnostic pop
# endif
namespace bl = boost : : lambda ;
2014-11-14 04:11:29 +08:00
# include <boost/range/adaptor/map.hpp>
2014-11-30 17:38:24 +08:00
# include <boost/optional.hpp>
2014-11-14 04:11:29 +08:00
# include <string>
# include <map>
2011-12-03 00:43:15 +08:00
namespace wrap {
2011-10-14 12:43:06 +08:00
/// Class has name, constructors, methods
2014-11-13 06:22:59 +08:00
class Class : public Qualified {
2014-12-01 16:48:56 +08:00
public :
2014-11-29 23:13:23 +08:00
typedef const std : : string & Str ;
2012-10-02 22:40:07 +08:00
typedef std : : map < std : : string , Method > Methods ;
2014-12-01 16:48:56 +08:00
typedef std : : map < std : : string , StaticMethod > StaticMethods ;
2016-09-09 19:26:11 +08:00
typedef std : : map < std : : string , TemplateMethod > TemplateMethods ;
2014-12-01 16:48:56 +08:00
private :
boost : : optional < Qualified > parentClass ; ///< The *single* parent
2016-09-13 00:38:04 +08:00
Methods methods_ ; ///< Class methods, including all expanded/instantiated template methods -- to be serialized to matlab and Python classes in Cython pyx
Methods nontemplateMethods_ ; ///< only nontemplate methods -- to be serialized into Cython pxd
TemplateMethods templateMethods_ ; ///< only template methods -- to be serialized into Cython pxd
2016-09-09 19:18:00 +08:00
// Method& mutableMethod(Str key);
2014-11-13 06:22:59 +08:00
public :
2014-11-29 23:13:23 +08:00
StaticMethods static_methods ; ///< Static methods
2012-07-05 22:05:00 +08:00
2014-11-13 06:22:59 +08:00
// Then the instance variables are set directly by the Module constructor
std : : vector < std : : string > templateArgs ; ///< Template arguments
std : : string typedefName ; ///< The name to typedef *from*, if this class is actually a typedef, i.e. typedef [typedefName] [name]
2016-09-10 09:50:55 +08:00
std : : vector < Qualified > templateInstTypeList ; ///< the original typelist used to instantiate this class from a template.
2016-09-13 00:38:04 +08:00
///< Empty if it's not an instantiation. Needed for template classes in Cython pxd.
2016-09-10 09:50:55 +08:00
boost : : optional < Qualified > templateClass = boost : : none ; ///< qualified name of the original template class from which this class was instantiated.
2016-09-13 00:38:04 +08:00
///< boost::none if not an instantiation. Needed for template classes in Cython pxd.
2014-11-13 06:22:59 +08:00
bool isVirtual ; ///< Whether the class is part of a virtual inheritance chain
bool isSerializable ; ///< Whether we can use boost.serialization to serialize the class - creates exports
bool hasSerialization ; ///< Whether we should create the serialization functions
Constructor constructor ; ///< Class constructors
Deconstructor deconstructor ; ///< Deconstructor to deallocate C++ object
bool verbose_ ; ///< verbose flag
2016-09-09 01:33:32 +08:00
std : : string includeFile ;
2014-11-13 06:22:59 +08:00
2011-10-14 12:43:06 +08:00
/// Constructor creates an empty class
2014-11-13 01:04:38 +08:00
Class ( bool verbose = true ) :
2014-12-01 16:48:56 +08:00
parentClass ( boost : : none ) , isVirtual ( false ) , isSerializable ( false ) , hasSerialization (
false ) , deconstructor ( verbose ) , verbose_ ( verbose ) {
2014-11-13 01:04:38 +08:00
}
2011-10-14 02:41:56 +08:00
2016-12-20 06:47:30 +08:00
Class ( const std : : string & name , bool verbose = true )
: Qualified ( name , Qualified : : Category : : CLASS ) ,
parentClass ( boost : : none ) ,
isVirtual ( false ) ,
isSerializable ( false ) ,
hasSerialization ( false ) ,
deconstructor ( verbose ) ,
verbose_ ( verbose ) { }
2014-12-01 16:48:56 +08:00
void assignParent ( const Qualified & parent ) ;
boost : : optional < std : : string > qualifiedParent ( ) const ;
2016-12-16 13:23:45 +08:00
boost : : optional < Qualified > getParent ( ) const { return parentClass ; }
2014-12-01 16:48:56 +08:00
2014-11-14 00:34:33 +08:00
size_t nrMethods ( ) const {
2016-09-09 19:49:42 +08:00
return methods_ . size ( ) ;
2014-11-14 00:34:33 +08:00
}
2014-11-29 23:13:23 +08:00
2014-12-01 16:48:56 +08:00
const Method & method ( Str key ) const ;
2014-11-29 23:13:23 +08:00
2014-11-14 00:34:33 +08:00
bool exists ( Str name ) const {
2016-09-09 19:49:42 +08:00
return methods_ . find ( name ) ! = methods_ . end ( ) ;
2014-11-14 00:34:33 +08:00
}
2011-10-14 12:43:06 +08:00
// And finally MATLAB code is emitted, methods below called by Module::matlab_code
2014-11-14 00:34:33 +08:00
void matlab_proxy ( Str toolboxPath , Str wrapperName ,
const TypeAttributesTable & typeAttributes , FileWriter & wrapperFile ,
std : : vector < std : : string > & functionNames ) const ; ///< emit proxy class
2013-06-20 01:49:57 +08:00
2014-11-14 00:28:05 +08:00
Class expandTemplate ( const TemplateSubstitution & ts ) const ;
2013-06-20 01:49:57 +08:00
2014-11-14 00:34:33 +08:00
std : : vector < Class > expandTemplate ( Str templateArg ,
2014-11-13 06:22:59 +08:00
const std : : vector < Qualified > & instantiations ) const ;
2012-07-12 05:43:16 +08:00
2016-02-08 12:33:48 +08:00
// Create new classes with integer template arguments
std : : vector < Class > expandTemplate ( Str templateArg ,
const std : : vector < int > & integers ) const ;
2014-11-13 06:22:59 +08:00
/// Add potentially overloaded, potentially templated method
2014-11-14 00:34:33 +08:00
void addMethod ( bool verbose , bool is_const , Str methodName ,
const ArgumentList & argumentList , const ReturnValue & returnValue ,
2014-12-01 21:35:02 +08:00
const Template & tmplate ) ;
2014-11-13 06:22:59 +08:00
/// Post-process classes for serialization markers
void erase_serialization ( ) ; // non-const !
2016-09-09 19:49:42 +08:00
void erase_serialization ( Methods & methods ) ; // non-const !
2014-11-13 06:22:59 +08:00
/// verify all of the function arguments
void verifyAll ( std : : vector < std : : string > & functionNames ,
bool & hasSerialiable ) const ;
void appendInheritedMethods ( const Class & cls ,
const std : : vector < Class > & classes ) ;
2016-09-13 00:38:04 +08:00
void removeInheritedNontemplateMethods ( std : : vector < Class > & classes ) ;
2016-09-12 23:05:10 +08:00
2014-11-13 06:22:59 +08:00
/// The typedef line for this class, if this class is a typedef, otherwise returns an empty string.
2012-10-02 22:40:07 +08:00
std : : string getTypedef ( ) const ;
2012-07-12 05:43:16 +08:00
2014-11-13 06:22:59 +08:00
/// Returns the string for an export flag
2013-06-20 01:50:03 +08:00
std : : string getSerializationExport ( ) const ;
2014-11-13 06:22:59 +08:00
/// Creates a member function that performs serialization
2013-06-20 01:50:00 +08:00
void serialization_fragments ( FileWriter & proxyFile , FileWriter & wrapperFile ,
2014-11-14 00:34:33 +08:00
Str wrapperName , std : : vector < std : : string > & functionNames ) const ;
2012-08-26 23:46:19 +08:00
2014-11-13 06:22:59 +08:00
/// Creates a static member function that performs deserialization
2013-06-20 01:50:00 +08:00
void deserialization_fragments ( FileWriter & proxyFile , FileWriter & wrapperFile ,
2014-11-14 00:34:33 +08:00
Str wrapperName , std : : vector < std : : string > & functionNames ) const ;
2013-06-20 01:49:59 +08:00
2014-11-15 00:47:25 +08:00
// emit python wrapper
void python_wrapper ( FileWriter & wrapperFile ) const ;
2016-09-09 01:33:32 +08:00
// emit cython wrapper
2016-12-17 08:24:49 +08:00
void emit_cython_pxd ( FileWriter & pxdFile ) const ;
2016-09-10 03:52:44 +08:00
void emit_cython_pyx ( FileWriter & pyxFile ,
const std : : vector < Class > & allClasses ) const ;
void pyxInitParentObj ( FileWriter & pyxFile , const std : : string & pyObj ,
const std : : string & cySharedObj ,
const std : : vector < Class > & allClasses ) const ;
2016-11-19 00:00:15 +08:00
void pyxDynamicCast ( FileWriter & pyxFile , const Class & curLevel ,
const std : : vector < Class > & allClasses ) const ;
2016-09-09 01:33:32 +08:00
2014-11-14 04:11:29 +08:00
friend std : : ostream & operator < < ( std : : ostream & os , const Class & cls ) {
2014-12-01 03:12:03 +08:00
os < < " class " < < cls . name ( ) < < " { \n " ;
2014-11-14 04:34:59 +08:00
os < < cls . constructor < < " ; \n " ;
2016-05-21 09:41:18 +08:00
for ( const StaticMethod & m : cls . static_methods | boost : : adaptors : : map_values )
2014-11-14 04:34:59 +08:00
os < < m < < " ; \n " ;
2016-05-21 09:41:18 +08:00
for ( const Method & m : cls . methods_ | boost : : adaptors : : map_values )
2014-11-14 04:11:29 +08:00
os < < m < < " ; \n " ;
os < < " }; " < < std : : endl ;
return os ;
}
2012-07-05 22:04:57 +08:00
private :
2014-11-13 06:22:59 +08:00
void pointer_constructor_fragments ( FileWriter & proxyFile ,
2014-11-14 00:34:33 +08:00
FileWriter & wrapperFile , Str wrapperName ,
2014-11-13 06:22:59 +08:00
std : : vector < std : : string > & functionNames ) const ;
void comment_fragment ( FileWriter & proxyFile ) const ;
2011-10-14 02:41:56 +08:00
} ;
2014-12-02 19:41:35 +08:00
/* ************************************************************************* */
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
struct ClassGrammar : public classic : : grammar < ClassGrammar > {
2014-12-02 20:12:21 +08:00
Class & cls_ ; ///< successful parse will be placed in here
Template & template_ ; ///< result needs to be visible outside
2014-12-02 19:41:35 +08:00
/// Construct type grammar and specify where result is placed
2014-12-02 20:12:21 +08:00
ClassGrammar ( Class & cls , Template & t ) :
cls_ ( cls ) , template_ ( t ) {
2014-12-02 19:41:35 +08:00
}
/// Definition of type grammar
template < typename ScannerT >
struct definition : BasicRules < ScannerT > {
using BasicRules < ScannerT > : : name_p ;
using BasicRules < ScannerT > : : className_p ;
using BasicRules < ScannerT > : : comments_p ;
// NOTE: allows for pointers to all types
ArgumentList args ;
ArgumentListGrammar argumentList_g ;
Constructor constructor0 , constructor ;
ReturnValue retVal0 , retVal ;
ReturnValueGrammar returnValue_g ;
2014-12-02 20:12:21 +08:00
Template methodTemplate ;
2014-12-02 19:41:35 +08:00
TemplateGrammar methodTemplate_g , classTemplate_g ;
std : : string methodName ;
bool isConst , T , F ;
// Parent class
Qualified possibleParent ;
2014-12-02 20:12:21 +08:00
TypeGrammar classParent_g ;
2014-12-02 19:41:35 +08:00
2014-12-02 20:12:21 +08:00
classic : : rule < ScannerT > constructor_p , methodName_p , method_p ,
staticMethodName_p , static_method_p , templateList_p , classParent_p ,
functions_p , class_p ;
2014-12-02 19:41:35 +08:00
definition ( ClassGrammar const & self ) :
argumentList_g ( args ) , returnValue_g ( retVal ) , //
2014-12-02 20:12:21 +08:00
methodTemplate_g ( methodTemplate ) , classTemplate_g ( self . template_ ) , //
T ( true ) , F ( false ) , classParent_g ( possibleParent ) {
2014-12-02 19:41:35 +08:00
using namespace classic ;
bool verbose = false ; // TODO
2014-12-02 20:12:21 +08:00
// ConstructorGrammar
constructor_p = ( className_p > > argumentList_g > > ' ; ' > > ! comments_p ) //
[ bl : : bind ( & Constructor : : push_back , bl : : var ( constructor ) ,
bl : : var ( args ) ) ] //
[ clear_a ( args ) ] ;
2014-12-02 19:41:35 +08:00
2014-12-02 20:12:21 +08:00
// MethodGrammar
2014-12-02 19:41:35 +08:00
methodName_p = lexeme_d [ ( upper_p | lower_p ) > > * ( alnum_p | ' _ ' ) ] ;
// gtsam::Values retract(const gtsam::VectorValues& delta) const;
method_p = ! methodTemplate_g
> > ( returnValue_g > > methodName_p [ assign_a ( methodName ) ]
> > argumentList_g > > ! str_p ( " const " ) [ assign_a ( isConst , T ) ] > > ' ; '
> > * comments_p ) //
2014-12-02 20:12:21 +08:00
[ bl : : bind ( & Class : : addMethod , bl : : var ( self . cls_ ) , verbose ,
2014-12-02 19:41:35 +08:00
bl : : var ( isConst ) , bl : : var ( methodName ) , bl : : var ( args ) ,
bl : : var ( retVal ) , bl : : var ( methodTemplate ) ) ] //
2014-12-02 20:12:21 +08:00
[ assign_a ( retVal , retVal0 ) ] [ clear_a ( args ) ] //
[ clear_a ( methodTemplate ) ] [ assign_a ( isConst , F ) ] ;
2014-12-02 19:41:35 +08:00
2014-12-02 20:12:21 +08:00
// StaticMethodGrammar
2014-12-02 19:41:35 +08:00
staticMethodName_p = lexeme_d [ ( upper_p | lower_p ) > > * ( alnum_p | ' _ ' ) ] ;
static_method_p = ( str_p ( " static " ) > > returnValue_g
> > staticMethodName_p [ assign_a ( methodName ) ] > > argumentList_g > > ' ; '
> > * comments_p ) //
[ bl : : bind ( & StaticMethod : : addOverload ,
2014-12-02 20:12:21 +08:00
bl : : var ( self . cls_ . static_methods ) [ bl : : var ( methodName ) ] ,
2014-12-02 19:41:35 +08:00
bl : : var ( methodName ) , bl : : var ( args ) , bl : : var ( retVal ) , boost : : none ,
verbose ) ] //
[ assign_a ( retVal , retVal0 ) ] [ clear_a ( args ) ] ;
2014-12-02 20:12:21 +08:00
// template<POSE, POINT>
templateList_p = ( str_p ( " template " ) > > ' < '
> > name_p [ push_back_a ( self . cls_ . templateArgs ) ]
> > * ( ' , ' > > name_p [ push_back_a ( self . cls_ . templateArgs ) ] ) > > ' > ' ) ;
// parse a full class
classParent_p = ( ' : ' > > classParent_g > > ' { ' ) //
[ bl : : bind ( & Class : : assignParent , bl : : var ( self . cls_ ) ,
bl : : var ( possibleParent ) ) ] [ clear_a ( possibleParent ) ] ;
2014-12-02 19:41:35 +08:00
functions_p = constructor_p | method_p | static_method_p ;
// parse a full class
2014-12-02 20:12:21 +08:00
class_p = ( ! ( classTemplate_g [ push_back_a ( self . cls_ . templateArgs ,
self . template_ . argName ( ) ) ] | templateList_p )
2014-12-02 21:12:22 +08:00
> > ! ( str_p ( " virtual " ) [ assign_a ( self . cls_ . isVirtual , T ) ] )
2014-12-02 20:12:21 +08:00
> > str_p ( " class " ) > > className_p [ assign_a ( self . cls_ . name_ ) ]
> > ( classParent_p | ' { ' ) > > //
* ( functions_p | comments_p ) > > str_p ( " }; " ) ) //
2014-12-02 19:41:35 +08:00
[ bl : : bind ( & Constructor : : initializeOrCheck , bl : : var ( constructor ) ,
2014-12-02 20:12:21 +08:00
bl : : var ( self . cls_ . name_ ) , boost : : none , verbose ) ] [ assign_a (
self . cls_ . constructor , constructor ) ] //
[ assign_a ( self . cls_ . deconstructor . name , self . cls_ . name_ ) ] //
2014-12-02 19:41:35 +08:00
[ assign_a ( constructor , constructor0 ) ] ;
}
classic : : rule < ScannerT > const & start ( ) const {
return class_p ;
}
} ;
} ;
// ClassGrammar
2014-12-02 20:12:21 +08:00
} // \namespace wrap
2011-12-03 00:43:15 +08:00