2012-08-26 23:46:19 +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
2014-05-26 00:43:19 +08:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2012-08-26 23:46:19 +08:00
/**
* @ file Class . cpp
* @ author Frank Dellaert
* @ author Andrew Melim
2012-07-13 06:28:28 +08:00
* @ author Richard Roberts
2014-05-26 00:43:19 +08:00
* */
2014-05-26 01:02:29 +08:00
# include "Class.h"
# include "utilities.h"
# include "Argument.h"
# include <boost/foreach.hpp>
# include <boost/lexical_cast.hpp>
2014-11-29 23:13:23 +08:00
# include <boost/range/adaptor/map.hpp>
# include <boost/range/algorithm/copy.hpp>
2014-05-26 01:02:29 +08:00
2012-08-26 23:46:19 +08:00
# include <vector>
# include <iostream>
# include <fstream>
2014-11-29 23:13:23 +08:00
# include <iterator> // std::ostream_iterator
2012-08-26 23:46:19 +08:00
//#include <cstdint> // on Linux GCC: fails with error regarding needing C++0x std flags
//#include <cinttypes> // same failure as above
# include <stdint.h> // works on Linux GCC
2014-05-26 00:43:19 +08:00
using namespace std ;
using namespace wrap ;
2014-11-29 23:13:23 +08:00
/* ************************************************************************* */
2014-12-01 16:48:56 +08:00
void Class : : assignParent ( const Qualified & parent ) {
parentClass . reset ( parent ) ;
}
/* ************************************************************************* */
boost : : optional < string > Class : : qualifiedParent ( ) const {
boost : : optional < string > result = boost : : none ;
2014-12-01 21:35:02 +08:00
if ( parentClass )
result = parentClass - > qualifiedName ( " :: " ) ;
2014-12-01 16:48:56 +08:00
return result ;
}
/* ************************************************************************* */
static void handleException ( const out_of_range & oor ,
const Class : : Methods & methods ) {
cerr < < " Class::method: key not found: " < < oor . what ( ) < < " , methods are: \n " ;
using boost : : adaptors : : map_keys ;
ostream_iterator < string > out_it ( cerr , " \n " ) ;
boost : : copy ( methods | map_keys , out_it ) ;
}
/* ************************************************************************* */
Method & Class : : mutableMethod ( Str key ) {
2014-11-29 23:13:23 +08:00
try {
return methods_ . at ( key ) ;
} catch ( const out_of_range & oor ) {
2014-12-01 21:35:02 +08:00
handleException ( oor , methods_ ) ;
2014-12-01 16:48:56 +08:00
throw runtime_error ( " Internal error in wrap " ) ;
}
}
/* ************************************************************************* */
const Method & Class : : method ( Str key ) const {
2014-11-29 23:13:23 +08:00
try {
return methods_ . at ( key ) ;
} catch ( const out_of_range & oor ) {
2014-12-01 21:35:02 +08:00
handleException ( oor , methods_ ) ;
2014-11-29 23:13:23 +08:00
throw runtime_error ( " Internal error in wrap " ) ;
}
}
2014-05-26 00:43:19 +08:00
/* ************************************************************************* */
2014-11-14 00:34:33 +08:00
void Class : : matlab_proxy ( Str toolboxPath , Str wrapperName ,
2014-05-26 00:43:19 +08:00
const TypeAttributesTable & typeAttributes , FileWriter & wrapperFile ,
vector < string > & functionNames ) const {
2012-10-02 22:40:07 +08:00
// Create namespace folders
2014-12-01 03:12:03 +08:00
createNamespaceStructure ( namespaces ( ) , toolboxPath ) ;
2014-05-26 00:43:19 +08:00
2012-10-02 22:40:07 +08:00
// open destination classFile
2014-11-12 09:49:23 +08:00
string classFile = matlabName ( toolboxPath ) ;
2014-05-26 00:43:19 +08:00
FileWriter proxyFile ( classFile , verbose_ , " % " ) ;
2012-08-26 23:46:19 +08:00
// get the name of actual matlab object
2014-11-12 09:49:23 +08:00
const string matlabQualName = qualifiedName ( " . " ) ;
const string matlabUniqueName = qualifiedName ( ) ;
const string cppName = qualifiedName ( " :: " ) ;
2014-05-26 00:43:19 +08:00
2012-08-26 23:46:19 +08:00
// emit class proxy code
// we want our class to inherit the handle class for memory purposes
2014-11-30 17:38:24 +08:00
const string parent =
2014-12-01 16:48:56 +08:00
parentClass ? parentClass - > qualifiedName ( " . " ) : " handle " ;
2012-10-02 22:40:07 +08:00
comment_fragment ( proxyFile ) ;
2014-12-01 03:12:03 +08:00
proxyFile . oss < < " classdef " < < name ( ) < < " < " < < parent < < endl ;
2012-09-08 13:44:26 +08:00
proxyFile . oss < < " properties \n " ;
proxyFile . oss < < " ptr_ " < < matlabUniqueName < < " = 0 \n " ;
proxyFile . oss < < " end \n " ;
proxyFile . oss < < " methods \n " ;
2014-05-26 00:43:19 +08:00
2012-08-26 23:46:19 +08:00
// Constructor
2014-12-01 03:12:03 +08:00
proxyFile . oss < < " function obj = " < < name ( ) < < " (varargin) \n " ;
2012-08-26 23:46:19 +08:00
// Special pointer constructors - one in MATLAB to create an object and
2012-10-02 22:40:07 +08:00
// assign a pointer returned from a C++ function. In turn this MATLAB
// constructor calls a special C++ function that just adds the object to
// its collector. This allows wrapped functions to return objects in
// other wrap modules - to add these to their collectors the pointer is
// passed from one C++ module into matlab then back into the other C++
// module.
2014-05-26 00:43:19 +08:00
pointer_constructor_fragments ( proxyFile , wrapperFile , wrapperName ,
functionNames ) ;
wrapperFile . oss < < " \n " ;
2014-11-14 04:34:59 +08:00
2012-10-02 22:40:07 +08:00
// Regular constructors
2014-12-01 16:48:56 +08:00
boost : : optional < string > cppBaseName = qualifiedParent ( ) ;
2014-11-14 04:34:59 +08:00
for ( size_t i = 0 ; i < constructor . nrOverloads ( ) ; i + + ) {
ArgumentList args = constructor . argumentList ( i ) ;
2014-05-26 00:43:19 +08:00
const int id = ( int ) functionNames . size ( ) ;
2014-11-30 17:38:24 +08:00
constructor . proxy_fragment ( proxyFile , wrapperName , ( bool ) parentClass , id ,
args ) ;
2014-05-26 00:43:19 +08:00
const string wrapFunctionName = constructor . wrapper_fragment ( wrapperFile ,
2014-11-14 04:34:59 +08:00
cppName , matlabUniqueName , cppBaseName , id , args ) ;
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " \n " ;
functionNames . push_back ( wrapFunctionName ) ;
}
proxyFile . oss < < " else \n " ;
proxyFile . oss < < " error('Arguments do not match any overload of "
< < matlabQualName < < " constructor'); \n " ;
proxyFile . oss < < " end \n " ;
2014-11-30 17:38:24 +08:00
if ( parentClass )
proxyFile . oss < < " obj = obj@ " < < parentClass - > qualifiedName ( " . " )
< < " (uint64( " < < ptr_constructor_key < < " ), base_ptr); \n " ;
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " obj.ptr_ " < < matlabUniqueName < < " = my_ptr; \n " ;
proxyFile . oss < < " end \n \n " ;
2012-10-02 22:40:07 +08:00
// Deconstructor
2014-05-26 00:43:19 +08:00
{
const int id = ( int ) functionNames . size ( ) ;
deconstructor . proxy_fragment ( proxyFile , wrapperName , matlabUniqueName , id ) ;
proxyFile . oss < < " \n " ;
const string functionName = deconstructor . wrapper_fragment ( wrapperFile ,
cppName , matlabUniqueName , id ) ;
wrapperFile . oss < < " \n " ;
functionNames . push_back ( functionName ) ;
}
proxyFile . oss
< < " function display(obj), obj.print(''); end \n %DISPLAY Calls print on the object \n " ;
proxyFile . oss
< < " function disp(obj), obj.display; end \n %DISP Calls print on the object \n " ;
2012-10-02 22:40:07 +08:00
// Methods
2014-11-29 23:13:23 +08:00
BOOST_FOREACH ( const Methods : : value_type & name_m , methods_ ) {
2014-05-26 00:43:19 +08:00
const Method & m = name_m . second ;
m . proxy_wrapper_fragments ( proxyFile , wrapperFile , cppName , matlabQualName ,
matlabUniqueName , wrapperName , typeAttributes , functionNames ) ;
proxyFile . oss < < " \n " ;
wrapperFile . oss < < " \n " ;
}
2013-06-20 01:50:05 +08:00
if ( hasSerialization )
2013-06-20 01:50:00 +08:00
serialization_fragments ( proxyFile , wrapperFile , wrapperName , functionNames ) ;
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " end \n " ;
proxyFile . oss < < " \n " ;
proxyFile . oss < < " methods(Static = true) \n " ;
2012-10-02 22:40:07 +08:00
// Static methods
2014-05-26 00:43:19 +08:00
BOOST_FOREACH ( const StaticMethods : : value_type & name_m , static_methods ) {
const StaticMethod & m = name_m . second ;
m . proxy_wrapper_fragments ( proxyFile , wrapperFile , cppName , matlabQualName ,
matlabUniqueName , wrapperName , typeAttributes , functionNames ) ;
proxyFile . oss < < " \n " ;
wrapperFile . oss < < " \n " ;
}
2013-06-20 01:50:05 +08:00
if ( hasSerialization )
2014-05-26 00:43:19 +08:00
deserialization_fragments ( proxyFile , wrapperFile , wrapperName ,
functionNames ) ;
2013-06-20 01:49:57 +08:00
2012-10-02 22:40:07 +08:00
proxyFile . oss < < " end \n " ;
proxyFile . oss < < " end \n " ;
2014-05-26 00:43:19 +08:00
2012-08-26 23:46:19 +08:00
// Close file
2014-05-26 00:43:19 +08:00
proxyFile . emit ( true ) ;
}
/* ************************************************************************* */
void Class : : pointer_constructor_fragments ( FileWriter & proxyFile ,
2014-11-14 00:34:33 +08:00
FileWriter & wrapperFile , Str wrapperName ,
2014-05-26 00:43:19 +08:00
vector < string > & functionNames ) const {
2014-11-12 09:49:23 +08:00
const string matlabUniqueName = qualifiedName ( ) ;
const string cppName = qualifiedName ( " :: " ) ;
2014-05-26 00:43:19 +08:00
const int collectorInsertId = ( int ) functionNames . size ( ) ;
const string collectorInsertFunctionName = matlabUniqueName
+ " _collectorInsertAndMakeBase_ "
+ boost : : lexical_cast < string > ( collectorInsertId ) ;
functionNames . push_back ( collectorInsertFunctionName ) ;
int upcastFromVoidId ;
string upcastFromVoidFunctionName ;
if ( isVirtual ) {
upcastFromVoidId = ( int ) functionNames . size ( ) ;
upcastFromVoidFunctionName = matlabUniqueName + " _upcastFromVoid_ "
+ boost : : lexical_cast < string > ( upcastFromVoidId ) ;
functionNames . push_back ( upcastFromVoidFunctionName ) ;
}
2012-10-02 22:40:07 +08:00
// MATLAB constructor that assigns pointer to matlab object then calls c++
// function to add the object to the collector.
2014-05-26 00:43:19 +08:00
if ( isVirtual ) {
proxyFile . oss
< < " if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void'))) " ;
} else {
proxyFile . oss < < " if nargin == 2 " ;
}
proxyFile . oss < < " && isa(varargin{1}, 'uint64') && varargin{1} == uint64( "
< < ptr_constructor_key < < " ) \n " ;
if ( isVirtual ) {
proxyFile . oss < < " if nargin == 2 \n " ;
proxyFile . oss < < " my_ptr = varargin{2}; \n " ;
proxyFile . oss < < " else \n " ;
proxyFile . oss < < " my_ptr = " < < wrapperName < < " ( "
< < upcastFromVoidId < < " , varargin{2}); \n " ;
proxyFile . oss < < " end \n " ;
} else {
proxyFile . oss < < " my_ptr = varargin{2}; \n " ;
}
2014-11-30 17:38:24 +08:00
if ( ! parentClass ) // If this class has a base class, we'll get a base class pointer back
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " " ;
else
proxyFile . oss < < " base_ptr = " ;
2012-10-02 22:40:07 +08:00
proxyFile . oss < < wrapperName < < " ( " < < collectorInsertId < < " , my_ptr); \n " ; // Call collector insert and get base class ptr
2014-05-26 00:43:19 +08:00
2012-10-02 22:40:07 +08:00
// C++ function to add pointer from MATLAB to collector. The pointer always
// comes from a C++ return value; this mechanism allows the object to be added
// to a collector in a different wrap module. If this class has a base class,
// a new pointer to the base class is allocated and returned.
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " void " < < collectorInsertFunctionName
< < " (int nargout, mxArray *out[], int nargin, const mxArray *in[]) \n " ;
wrapperFile . oss < < " { \n " ;
wrapperFile . oss < < " mexAtExit(&_deleteAllObjects); \n " ;
2012-08-26 23:46:19 +08:00
// Typedef boost::shared_ptr
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " typedef boost::shared_ptr< " < < cppName < < " > Shared; \n " ;
wrapperFile . oss < < " \n " ;
2012-10-02 22:40:07 +08:00
// Get self pointer passed in
2014-05-26 00:43:19 +08:00
wrapperFile . oss
< < " Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0])); \n " ;
2012-10-02 22:40:07 +08:00
// Add to collector
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " collector_ " < < matlabUniqueName < < " .insert(self); \n " ;
2012-10-02 22:40:07 +08:00
// If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy)
2014-12-01 16:48:56 +08:00
boost : : optional < string > cppBaseName = qualifiedParent ( ) ;
if ( cppBaseName ) {
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " \n " ;
2014-12-01 16:48:56 +08:00
wrapperFile . oss < < " typedef boost::shared_ptr< " < < * cppBaseName
2014-05-26 00:43:19 +08:00
< < " > SharedBase; \n " ;
wrapperFile . oss
< < " out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL); \n " ;
wrapperFile . oss
< < " *reinterpret_cast<SharedBase**>(mxGetData(out[0])) = new SharedBase(*self); \n " ;
}
wrapperFile . oss < < " } \n " ;
2012-10-02 22:40:07 +08:00
// If this is a virtual function, C++ function to dynamic upcast it from a
// shared_ptr<void>. This mechanism allows automatic dynamic creation of the
// real underlying derived-most class when a C++ method returns a virtual
// base class.
2014-05-26 00:43:19 +08:00
if ( isVirtual )
wrapperFile . oss < < " \n "
" void " < < upcastFromVoidFunctionName
< < " (int nargout, mxArray *out[], int nargin, const mxArray *in[]) { \n "
" mexAtExit(&_deleteAllObjects); \n "
" typedef boost::shared_ptr< " < < cppName
< < " > Shared; \n "
" boost::shared_ptr<void> *asVoid = *reinterpret_cast<boost::shared_ptr<void>**> (mxGetData(in[0])); \n "
" out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL); \n "
" Shared *self = new Shared(boost::static_pointer_cast< " < < cppName
< < " >(*asVoid)); \n "
" *reinterpret_cast<Shared**>(mxGetData(out[0])) = self; \n "
" } \n " ;
}
/* ************************************************************************* */
2014-11-14 00:28:05 +08:00
Class Class : : expandTemplate ( const TemplateSubstitution & ts ) const {
2014-11-12 05:55:36 +08:00
Class inst = * this ;
2014-11-29 23:13:23 +08:00
inst . methods_ = expandMethodTemplate ( methods_ , ts ) ;
2014-11-14 00:28:05 +08:00
inst . static_methods = expandMethodTemplate ( static_methods , ts ) ;
2014-11-14 04:34:59 +08:00
inst . constructor = constructor . expandTemplate ( ts ) ;
2014-12-01 03:12:03 +08:00
inst . deconstructor . name = inst . name ( ) ;
2014-05-26 00:43:19 +08:00
return inst ;
}
/* ************************************************************************* */
2014-11-14 00:34:33 +08:00
vector < Class > Class : : expandTemplate ( Str templateArg ,
2014-11-13 03:52:07 +08:00
const vector < Qualified > & instantiations ) const {
2014-05-26 00:43:19 +08:00
vector < Class > result ;
2014-11-12 09:49:23 +08:00
BOOST_FOREACH ( const Qualified & instName , instantiations ) {
2014-11-13 03:52:07 +08:00
Qualified expandedClass = ( Qualified ) ( * this ) ;
2014-12-01 03:12:03 +08:00
expandedClass . expand ( instName . name ( ) ) ;
2014-11-14 00:28:05 +08:00
const TemplateSubstitution ts ( templateArg , instName , expandedClass ) ;
Class inst = expandTemplate ( ts ) ;
2014-12-01 03:12:03 +08:00
inst . name_ = expandedClass . name ( ) ;
2014-05-26 00:43:19 +08:00
inst . templateArgs . clear ( ) ;
2014-11-12 09:49:23 +08:00
inst . typedefName = qualifiedName ( " :: " ) + " < " + instName . qualifiedName ( " :: " )
+ " > " ;
2014-05-26 00:43:19 +08:00
result . push_back ( inst ) ;
}
return result ;
}
2014-11-13 06:22:59 +08:00
/* ************************************************************************* */
2014-11-14 00:34:33 +08:00
void Class : : 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 07:39:15 +08:00
// Check if templated
2014-12-02 03:29:35 +08:00
if ( tmplate . valid ( ) ) {
2014-11-13 07:39:15 +08:00
// Create method to expand
// For all values of the template argument, create a new method
2014-12-02 03:29:35 +08:00
BOOST_FOREACH ( const Qualified & instName , tmplate . argValues ( ) ) {
const TemplateSubstitution ts ( tmplate . argName ( ) , instName , * this ) ;
2014-11-13 19:52:41 +08:00
// substitute template in arguments
2014-11-14 00:34:33 +08:00
ArgumentList expandedArgs = argumentList . expandTemplate ( ts ) ;
2014-11-14 02:34:15 +08:00
// do the same for return type
2014-11-14 00:34:33 +08:00
ReturnValue expandedRetVal = returnValue . expandTemplate ( ts ) ;
// Now stick in new overload stack with expandedMethodName key
// but note we use the same, unexpanded methodName in overload
2014-12-01 03:12:03 +08:00
string expandedMethodName = methodName + instName . name ( ) ;
2014-11-29 23:13:23 +08:00
methods_ [ expandedMethodName ] . addOverload ( methodName , expandedArgs ,
2014-11-14 23:43:53 +08:00
expandedRetVal , is_const , instName , verbose ) ;
2014-11-13 07:39:15 +08:00
}
} else
// just add overload
2014-11-29 23:13:23 +08:00
methods_ [ methodName ] . addOverload ( methodName , argumentList , returnValue ,
2014-12-01 16:48:56 +08:00
is_const , boost : : none , verbose ) ;
2014-11-13 06:22:59 +08:00
}
/* ************************************************************************* */
void Class : : erase_serialization ( ) {
2014-11-29 23:13:23 +08:00
Methods : : iterator it = methods_ . find ( " serializable " ) ;
if ( it ! = methods_ . end ( ) ) {
2014-11-13 06:22:59 +08:00
# ifndef WRAP_DISABLE_SERIALIZE
isSerializable = true ;
# else
// cout << "Ignoring serializable() flag in class " << name << endl;
# endif
2014-11-29 23:13:23 +08:00
methods_ . erase ( it ) ;
2014-11-13 06:22:59 +08:00
}
2014-11-29 23:13:23 +08:00
it = methods_ . find ( " serialize " ) ;
if ( it ! = methods_ . end ( ) ) {
2014-11-13 06:22:59 +08:00
# ifndef WRAP_DISABLE_SERIALIZE
isSerializable = true ;
hasSerialization = true ;
# else
// cout << "Ignoring serialize() flag in class " << name << endl;
# endif
2014-11-29 23:13:23 +08:00
methods_ . erase ( it ) ;
2014-11-13 06:22:59 +08:00
}
}
/* ************************************************************************* */
void Class : : verifyAll ( vector < string > & validTypes , bool & hasSerialiable ) const {
hasSerialiable | = isSerializable ;
// verify all of the function arguments
//TODO:verifyArguments<ArgumentList>(validTypes, constructor.args_list);
verifyArguments < StaticMethod > ( validTypes , static_methods ) ;
2014-11-29 23:13:23 +08:00
verifyArguments < Method > ( validTypes , methods_ ) ;
2014-11-13 06:22:59 +08:00
// verify function return types
verifyReturnTypes < StaticMethod > ( validTypes , static_methods ) ;
2014-11-29 23:13:23 +08:00
verifyReturnTypes < Method > ( validTypes , methods_ ) ;
2014-11-13 06:22:59 +08:00
// verify parents
2014-12-01 16:48:56 +08:00
boost : : optional < string > parent = qualifiedParent ( ) ;
if ( parent
& & find ( validTypes . begin ( ) , validTypes . end ( ) , * parent )
= = validTypes . end ( ) )
throw DependencyMissing ( * parent , qualifiedName ( " :: " ) ) ;
2014-11-13 06:22:59 +08:00
}
/* ************************************************************************* */
void Class : : appendInheritedMethods ( const Class & cls ,
const vector < Class > & classes ) {
2014-11-30 17:38:24 +08:00
if ( cls . parentClass ) {
2014-11-13 06:22:59 +08:00
// Find parent
BOOST_FOREACH ( const Class & parent , classes ) {
// We found a parent class for our parent, TODO improve !
2014-12-01 16:48:56 +08:00
if ( parent . name ( ) = = cls . parentClass - > name ( ) ) {
2014-11-29 23:13:23 +08:00
methods_ . insert ( parent . methods_ . begin ( ) , parent . methods_ . end ( ) ) ;
2014-11-13 06:22:59 +08:00
appendInheritedMethods ( parent , classes ) ;
}
}
}
}
2014-05-26 00:43:19 +08:00
/* ************************************************************************* */
2014-11-12 05:55:36 +08:00
string Class : : getTypedef ( ) const {
2014-05-26 00:43:19 +08:00
string result ;
2014-12-01 03:12:03 +08:00
BOOST_FOREACH ( Str namesp , namespaces ( ) ) {
2014-05-26 00:43:19 +08:00
result + = ( " namespace " + namesp + " { " ) ;
}
2014-12-01 03:12:03 +08:00
result + = ( " typedef " + typedefName + " " + name ( ) + " ; " ) ;
for ( size_t i = 0 ; i < namespaces ( ) . size ( ) ; + + i ) {
2014-05-26 00:43:19 +08:00
result + = " } " ;
}
return result ;
}
/* ************************************************************************* */
2012-09-08 13:44:26 +08:00
void Class : : comment_fragment ( FileWriter & proxyFile ) const {
2014-12-01 03:12:03 +08:00
proxyFile . oss < < " %class " < < name ( ) < < " , see Doxygen page for details \n " ;
2012-09-08 13:44:26 +08:00
proxyFile . oss
< < " %at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html \n " ;
2012-08-29 05:44:45 +08:00
2014-11-14 04:34:59 +08:00
constructor . comment_fragment ( proxyFile ) ;
2012-08-27 05:58:18 +08:00
2014-11-29 23:13:23 +08:00
if ( ! methods_ . empty ( ) )
2012-09-08 13:44:26 +08:00
proxyFile . oss < < " % \n %-------Methods------- \n " ;
2014-11-29 23:13:23 +08:00
BOOST_FOREACH ( const Methods : : value_type & name_m , methods_ )
2014-11-14 05:43:29 +08:00
name_m . second . comment_fragment ( proxyFile ) ;
2012-08-27 23:19:55 +08:00
2012-09-08 13:44:26 +08:00
if ( ! static_methods . empty ( ) )
proxyFile . oss < < " % \n %-------Static Methods------- \n " ;
2014-11-14 05:43:29 +08:00
BOOST_FOREACH ( const StaticMethods : : value_type & name_m , static_methods )
name_m . second . comment_fragment ( proxyFile ) ;
2012-08-27 23:30:47 +08:00
2013-06-20 01:50:05 +08:00
if ( hasSerialization ) {
2013-06-20 01:49:57 +08:00
proxyFile . oss < < " % \n %-------Serialization Interface------- \n " ;
proxyFile . oss < < " %string_serialize() : returns string \n " ;
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " %string_deserialize(string serialized) : returns "
2014-12-01 03:12:03 +08:00
< < name ( ) < < " \n " ;
2013-06-20 01:49:57 +08:00
}
2012-09-08 13:44:26 +08:00
proxyFile . oss < < " % \n " ;
2012-08-26 23:46:19 +08:00
}
2013-06-20 01:49:57 +08:00
2014-05-26 00:43:19 +08:00
/* ************************************************************************* */
void Class : : serialization_fragments ( FileWriter & proxyFile ,
2014-11-14 00:34:33 +08:00
FileWriter & wrapperFile , Str wrapperName ,
2014-11-12 05:55:36 +08:00
vector < string > & functionNames ) const {
2013-06-20 01:49:58 +08:00
2013-06-20 01:49:57 +08:00
//void Point3_string_serialize_17(int nargout, mxArray *out[], int nargin, const mxArray *in[])
//{
// typedef boost::shared_ptr<Point3> Shared;
// checkArguments("string_serialize",nargout,nargin-1,0);
// Shared obj = unwrap_shared_ptr<Point3>(in[0], "ptr_Point3");
2014-11-12 05:55:36 +08:00
// ostringstream out_archive_stream;
2013-06-20 01:49:57 +08:00
// boost::archive::text_oarchive out_archive(out_archive_stream);
// out_archive << *obj;
// out[0] = wrap< string >(out_archive_stream.str());
//}
2013-06-20 01:49:58 +08:00
int serialize_id = functionNames . size ( ) ;
2014-11-12 09:49:23 +08:00
const string matlabQualName = qualifiedName ( " . " ) ;
const string matlabUniqueName = qualifiedName ( ) ;
const string cppClassName = qualifiedName ( " :: " ) ;
2014-05-26 00:43:19 +08:00
const string wrapFunctionNameSerialize = matlabUniqueName
+ " _string_serialize_ " + boost : : lexical_cast < string > ( serialize_id ) ;
2013-06-20 01:49:58 +08:00
functionNames . push_back ( wrapFunctionNameSerialize ) ;
// call
//void Point3_string_serialize_17(int nargout, mxArray *out[], int nargin, const mxArray *in[])
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " void " < < wrapFunctionNameSerialize
< < " (int nargout, mxArray *out[], int nargin, const mxArray *in[]) \n " ;
2013-06-20 01:49:59 +08:00
wrapperFile . oss < < " { \n " ;
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " typedef boost::shared_ptr< " < < cppClassName
< < " > Shared; " < < endl ;
2013-06-20 01:49:58 +08:00
// check arguments - for serialize, no arguments
// example: checkArguments("string_serialize",nargout,nargin-1,0);
2014-05-26 00:43:19 +08:00
wrapperFile . oss
< < " checkArguments( \" string_serialize \" ,nargout,nargin-1,0); \n " ;
2013-06-20 01:49:58 +08:00
// get class pointer
// example: Shared obj = unwrap_shared_ptr<Point3>(in[0], "ptr_Point3");
2014-05-26 00:43:19 +08:00
wrapperFile . oss < < " Shared obj = unwrap_shared_ptr< " < < cppClassName
< < " >(in[0], \" ptr_ " < < matlabUniqueName < < " \" ); " < < endl ;
2013-06-20 01:49:58 +08:00
// Serialization boilerplate
2014-11-12 05:55:36 +08:00
wrapperFile . oss < < " ostringstream out_archive_stream; \n " ;
2014-05-26 00:43:19 +08:00
wrapperFile . oss
< < " boost::archive::text_oarchive out_archive(out_archive_stream); \n " ;
2013-06-20 01:49:59 +08:00
wrapperFile . oss < < " out_archive << *obj; \n " ;
wrapperFile . oss < < " out[0] = wrap< string >(out_archive_stream.str()); \n " ;
2013-06-20 01:49:58 +08:00
// finish
2013-06-20 01:49:59 +08:00
wrapperFile . oss < < " } \n " ;
2013-06-20 01:49:58 +08:00
2013-06-20 01:49:59 +08:00
// Generate code for matlab function
// function varargout string_serialize(this, varargin)
// % STRING_SERIALIZE usage: string_serialize() : returns string
// % Doxygen can be found at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html
// if length(varargin) == 0
// varargout{1} = geometry_wrapper(15, this, varargin{:});
// else
// error('Arguments do not match any overload of function Point3.string_serialize');
// end
// end
2013-06-20 01:49:58 +08:00
2014-05-26 00:43:19 +08:00
proxyFile . oss
< < " function varargout = string_serialize(this, varargin) \n " ;
proxyFile . oss
< < " % STRING_SERIALIZE usage: string_serialize() : returns string \n " ;
proxyFile . oss
< < " % Doxygen can be found at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html \n " ;
2013-06-20 01:49:59 +08:00
proxyFile . oss < < " if length(varargin) == 0 \n " ;
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " varargout{1} = " < < wrapperName < < " ( "
< < boost : : lexical_cast < string > ( serialize_id ) < < " , this, varargin{:}); \n " ;
2013-06-20 01:49:59 +08:00
proxyFile . oss < < " else \n " ;
2014-05-26 00:43:19 +08:00
proxyFile . oss
< < " error('Arguments do not match any overload of function "
< < matlabQualName < < " .string_serialize'); \n " ;
2013-06-20 01:49:59 +08:00
proxyFile . oss < < " end \n " ;
2013-06-23 07:16:53 +08:00
proxyFile . oss < < " end \n \n " ;
// Generate code for matlab save function
// function sobj = saveobj(obj)
// % SAVEOBJ Saves the object to a matlab-readable format
// sobj = obj.string_serialize();
// end
proxyFile . oss < < " function sobj = saveobj(obj) \n " ;
2014-05-26 00:43:19 +08:00
proxyFile . oss
< < " % SAVEOBJ Saves the object to a matlab-readable format \n " ;
2013-06-23 07:16:53 +08:00
proxyFile . oss < < " sobj = obj.string_serialize(); \n " ;
2013-06-26 02:30:59 +08:00
proxyFile . oss < < " end \n " ;
2013-06-20 01:49:59 +08:00
}
2013-06-20 01:49:58 +08:00
2013-06-20 01:50:00 +08:00
/* ************************************************************************* */
2014-05-26 00:43:19 +08:00
void Class : : deserialization_fragments ( FileWriter & proxyFile ,
2014-11-14 00:34:33 +08:00
FileWriter & wrapperFile , Str wrapperName ,
2014-11-12 05:55:36 +08:00
vector < string > & functionNames ) const {
2013-06-20 01:49:59 +08:00
//void Point3_string_deserialize_18(int nargout, mxArray *out[], int nargin, const mxArray *in[])
//{
// typedef boost::shared_ptr<Point3> Shared;
// checkArguments("Point3.string_deserialize",nargout,nargin,1);
// string serialized = unwrap< string >(in[0]);
2014-11-12 05:55:36 +08:00
// istringstream in_archive_stream(serialized);
2013-06-20 01:49:59 +08:00
// boost::archive::text_iarchive in_archive(in_archive_stream);
// Shared output(new Point3());
// in_archive >> *output;
// out[0] = wrap_shared_ptr(output,"Point3", false);
//}
2014-05-26 00:43:19 +08:00
int deserialize_id = functionNames . size ( ) ;
2014-11-12 09:49:23 +08:00
const string matlabQualName = qualifiedName ( " . " ) ;
const string matlabUniqueName = qualifiedName ( ) ;
const string cppClassName = qualifiedName ( " :: " ) ;
2014-05-26 00:43:19 +08:00
const string wrapFunctionNameDeserialize = matlabUniqueName
+ " _string_deserialize_ " + boost : : lexical_cast < string > ( deserialize_id ) ;
functionNames . push_back ( wrapFunctionNameDeserialize ) ;
// call
wrapperFile . oss < < " void " < < wrapFunctionNameDeserialize
< < " (int nargout, mxArray *out[], int nargin, const mxArray *in[]) \n " ;
wrapperFile . oss < < " { \n " ;
wrapperFile . oss < < " typedef boost::shared_ptr< " < < cppClassName
< < " > Shared; " < < endl ;
// check arguments - for deserialize, 1 string argument
wrapperFile . oss < < " checkArguments( \" " < < matlabUniqueName
< < " .string_deserialize \" ,nargout,nargin,1); \n " ;
// string argument with deserialization boilerplate
wrapperFile . oss < < " string serialized = unwrap< string >(in[0]); \n " ;
2014-11-12 05:55:36 +08:00
wrapperFile . oss < < " istringstream in_archive_stream(serialized); \n " ;
2014-05-26 00:43:19 +08:00
wrapperFile . oss
< < " boost::archive::text_iarchive in_archive(in_archive_stream); \n " ;
wrapperFile . oss < < " Shared output(new " < < cppClassName < < " ()); \n " ;
wrapperFile . oss < < " in_archive >> *output; \n " ;
wrapperFile . oss < < " out[0] = wrap_shared_ptr(output, \" " < < matlabQualName
< < " \" , false); \n " ;
wrapperFile . oss < < " } \n " ;
// Generate matlab function
2013-06-20 01:49:59 +08:00
// function varargout = string_deserialize(varargin)
// % STRING_DESERIALIZE usage: string_deserialize() : returns Point3
// % Doxygen can be found at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html
2013-06-20 01:50:00 +08:00
// if length(varargin) == 1
2013-06-20 01:49:59 +08:00
// varargout{1} = geometry_wrapper(18, varargin{:});
// else
// error('Arguments do not match any overload of function Point3.string_deserialize');
// end
// end
2013-06-20 01:49:57 +08:00
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " function varargout = string_deserialize(varargin) \n " ;
proxyFile . oss
< < " % STRING_DESERIALIZE usage: string_deserialize() : returns "
< < matlabQualName < < " \n " ;
proxyFile . oss
< < " % Doxygen can be found at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html \n " ;
proxyFile . oss < < " if length(varargin) == 1 \n " ;
proxyFile . oss < < " varargout{1} = " < < wrapperName < < " ( "
< < boost : : lexical_cast < string > ( deserialize_id ) < < " , varargin{:}); \n " ;
proxyFile . oss < < " else \n " ;
proxyFile . oss
< < " error('Arguments do not match any overload of function "
< < matlabQualName < < " .string_deserialize'); \n " ;
proxyFile . oss < < " end \n " ;
proxyFile . oss < < " end \n \n " ;
2013-06-23 07:16:53 +08:00
2014-05-26 00:43:19 +08:00
// Generate matlab load function
2013-06-23 07:16:53 +08:00
// function obj = loadobj(sobj)
// % LOADOBJ Saves the object to a matlab-readable format
// obj = Point3.string_deserialize(sobj);
// end
2014-05-26 00:43:19 +08:00
proxyFile . oss < < " function obj = loadobj(sobj) \n " ;
proxyFile . oss
< < " % LOADOBJ Saves the object to a matlab-readable format \n " ;
proxyFile . oss < < " obj = " < < matlabQualName
< < " .string_deserialize(sobj); \n " ;
proxyFile . oss < < " end " < < endl ;
2013-06-20 01:49:57 +08:00
}
2013-06-20 01:50:03 +08:00
/* ************************************************************************* */
2014-11-12 05:55:36 +08:00
string Class : : getSerializationExport ( ) const {
2013-06-20 01:50:03 +08:00
//BOOST_CLASS_EXPORT_GUID(gtsam::SharedDiagonal, "gtsamSharedDiagonal");
2014-05-26 00:43:19 +08:00
return " BOOST_CLASS_EXPORT_GUID( " + qualifiedName ( " :: " ) + " , \" "
+ qualifiedName ( ) + " \" ); " ;
2013-06-20 01:50:03 +08:00
}
2014-11-15 00:47:25 +08:00
/* ************************************************************************* */
void Class : : python_wrapper ( FileWriter & wrapperFile ) const {
2014-12-01 03:12:03 +08:00
wrapperFile . oss < < " class_< " < < name ( ) < < " >( \" " < < name ( ) < < " \" ) \n " ;
constructor . python_wrapper ( wrapperFile , name ( ) ) ;
2014-11-15 00:47:25 +08:00
BOOST_FOREACH ( const StaticMethod & m , static_methods | boost : : adaptors : : map_values )
2014-12-01 03:12:03 +08:00
m . python_wrapper ( wrapperFile , name ( ) ) ;
2014-11-29 23:13:23 +08:00
BOOST_FOREACH ( const Method & m , methods_ | boost : : adaptors : : map_values )
2014-12-01 03:12:03 +08:00
m . python_wrapper ( wrapperFile , name ( ) ) ;
2014-11-15 00:47:25 +08:00
wrapperFile . oss < < " ; \n \n " ;
}
2013-06-20 01:50:00 +08:00
/* ************************************************************************* */