diff --git a/wrap/Module.cpp b/wrap/Module.cpp index dc1ce4684..f53da6ede 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -62,17 +62,21 @@ typedef rule Rule; /* ************************************************************************* */ /* ************************************************************************* */ -void handle_possible_template(vector& classes, const Class& cls, const string& templateArgument, const vector >& instantiations) { - if(instantiations.empty()) { - classes.push_back(cls); - } else { - vector classInstantiations = cls.expandTemplate(templateArgument, instantiations); - BOOST_FOREACH(const Class& c, classInstantiations) { - classes.push_back(c); - } - } -} - +// If a number of template arguments were given, generate a number of expanded +// class names, e.g., PriorFactor -> PriorFactorPose2, and add those classes +static void handle_possible_template(vector& classes, const Class& cls, + const string& templateArgument, + const vector >& instantiations) { + if (instantiations.empty()) { + classes.push_back(cls); + } else { + vector classInstantiations = // + cls.expandTemplate(templateArgument, instantiations); + BOOST_FOREACH(const Class& c, classInstantiations) + classes.push_back(c); + } +} + /* ************************************************************************* */ Module::Module(const std::string& moduleName, bool enable_verbose) : name(moduleName), verbose(enable_verbose) @@ -162,6 +166,8 @@ void Module::parseMarkup(const std::string& data) { *(namespace_name_p[push_back_a(cls.qualifiedParent)] >> str_p("::")) >> className_p[push_back_a(cls.qualifiedParent)]; + // TODO: get rid of copy/paste below? + // parse "gtsam::Pose2" and add to templateInstantiations vector templateArgumentValue; vector > templateInstantiations; @@ -180,6 +186,22 @@ void Module::parseMarkup(const std::string& data) { '}' >> '>') [push_back_a(cls.templateArgs, templateArgument)]; + // parse "gtsam::Pose2" and add to methodInstantiations + vector > methodInstantiations; + Rule methodInstantiation_p = + (*(namespace_name_p[push_back_a(templateArgumentValue)] >> str_p("::")) >> + className_p[push_back_a(templateArgumentValue)]) + [push_back_a(methodInstantiations, templateArgumentValue)] + [clear_a(templateArgumentValue)]; + + // template + string methodArgument; + Rule methodInstantiations_p = + (str_p("template") >> + '<' >> name_p[assign_a(methodArgument)] >> '=' >> '{' >> + !(methodInstantiation_p >> *(',' >> methodInstantiation_p)) >> + '}' >> '>'); + // parse "gtsam::Pose2" and add to singleInstantiation.typeList TemplateInstantiationTypedef singleInstantiation; Rule templateSingleInstantiationArg_p = @@ -261,6 +283,7 @@ void Module::parseMarkup(const std::string& data) { // gtsam::Values retract(const gtsam::VectorValues& delta) const; Rule method_p = + !methodInstantiations_p >> (returnType_p >> methodName_p[assign_a(methodName)] >> '(' >> argumentList_p >> ')' >> !str_p("const")[assign_a(isConst,true)] >> ';' >> *comments_p) diff --git a/wrap/tests/expected2/MyBase.m b/wrap/tests/expected2/MyBase.m new file mode 100644 index 000000000..d7bfe7e81 --- /dev/null +++ b/wrap/tests/expected2/MyBase.m @@ -0,0 +1,35 @@ +%class MyBase, see Doxygen page for details +%at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html +% +classdef MyBase < handle + properties + ptr_MyBase = 0 + end + methods + function obj = MyBase(varargin) + if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void'))) && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682) + if nargin == 2 + my_ptr = varargin{2}; + else + my_ptr = geometry_wrapper(41, varargin{2}); + end + geometry_wrapper(40, my_ptr); + else + error('Arguments do not match any overload of MyBase constructor'); + end + obj.ptr_MyBase = my_ptr; + end + + function delete(obj) + geometry_wrapper(42, obj.ptr_MyBase); + end + + function display(obj), obj.print(''); end + %DISPLAY Calls print on the object + function disp(obj), obj.display; end + %DISP Calls print on the object + end + + methods(Static = true) + end +end diff --git a/wrap/tests/expected2/MyTemplatePoint2.m b/wrap/tests/expected2/MyTemplatePoint2.m new file mode 100644 index 000000000..bb3d20449 --- /dev/null +++ b/wrap/tests/expected2/MyTemplatePoint2.m @@ -0,0 +1,54 @@ +%class MyTemplatePoint2, see Doxygen page for details +%at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html +% +%-------Constructors------- +%MyTemplatePoint2() +% +%-------Methods------- +%templatedMethod(Test t) : returns void +% +classdef MyTemplatePoint2 < MyBase + properties + ptr_MyTemplatePoint2 = 0 + end + methods + function obj = MyTemplatePoint2(varargin) + if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void'))) && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682) + if nargin == 2 + my_ptr = varargin{2}; + else + my_ptr = geometry_wrapper(44, varargin{2}); + end + base_ptr = geometry_wrapper(43, my_ptr); + elseif nargin == 0 + [ my_ptr, base_ptr ] = geometry_wrapper(45); + else + error('Arguments do not match any overload of MyTemplatePoint2 constructor'); + end + obj = obj@MyBase(uint64(5139824614673773682), base_ptr); + obj.ptr_MyTemplatePoint2 = my_ptr; + end + + function delete(obj) + geometry_wrapper(46, obj.ptr_MyTemplatePoint2); + end + + function display(obj), obj.print(''); end + %DISPLAY Calls print on the object + function disp(obj), obj.display; end + %DISP Calls print on the object + function varargout = templatedMethod(this, varargin) + % TEMPLATEDMETHOD usage: templatedMethod(Test t) : returns void + % Doxygen can be found at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html + if length(varargin) == 1 && isa(varargin{1},'Test') + geometry_wrapper(47, this, varargin{:}); + else + error('Arguments do not match any overload of function MyTemplatePoint2.templatedMethod'); + end + end + + end + + methods(Static = true) + end +end diff --git a/wrap/tests/expected2/MyTemplatePoint3.m b/wrap/tests/expected2/MyTemplatePoint3.m new file mode 100644 index 000000000..fd9104328 --- /dev/null +++ b/wrap/tests/expected2/MyTemplatePoint3.m @@ -0,0 +1,54 @@ +%class MyTemplatePoint3, see Doxygen page for details +%at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html +% +%-------Constructors------- +%MyTemplatePoint3() +% +%-------Methods------- +%templatedMethod(Test t) : returns void +% +classdef MyTemplatePoint3 < MyBase + properties + ptr_MyTemplatePoint3 = 0 + end + methods + function obj = MyTemplatePoint3(varargin) + if (nargin == 2 || (nargin == 3 && strcmp(varargin{3}, 'void'))) && isa(varargin{1}, 'uint64') && varargin{1} == uint64(5139824614673773682) + if nargin == 2 + my_ptr = varargin{2}; + else + my_ptr = geometry_wrapper(49, varargin{2}); + end + base_ptr = geometry_wrapper(48, my_ptr); + elseif nargin == 0 + [ my_ptr, base_ptr ] = geometry_wrapper(50); + else + error('Arguments do not match any overload of MyTemplatePoint3 constructor'); + end + obj = obj@MyBase(uint64(5139824614673773682), base_ptr); + obj.ptr_MyTemplatePoint3 = my_ptr; + end + + function delete(obj) + geometry_wrapper(51, obj.ptr_MyTemplatePoint3); + end + + function display(obj), obj.print(''); end + %DISPLAY Calls print on the object + function disp(obj), obj.display; end + %DISP Calls print on the object + function varargout = templatedMethod(this, varargin) + % TEMPLATEDMETHOD usage: templatedMethod(Test t) : returns void + % Doxygen can be found at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html + if length(varargin) == 1 && isa(varargin{1},'Test') + geometry_wrapper(52, this, varargin{:}); + else + error('Arguments do not match any overload of function MyTemplatePoint3.templatedMethod'); + end + end + + end + + methods(Static = true) + end +end diff --git a/wrap/tests/expected2/aGlobalFunction.m b/wrap/tests/expected2/aGlobalFunction.m index a7450e591..990acdac5 100644 --- a/wrap/tests/expected2/aGlobalFunction.m +++ b/wrap/tests/expected2/aGlobalFunction.m @@ -1,6 +1,6 @@ function varargout = aGlobalFunction(varargin) if length(varargin) == 0 - varargout{1} = geometry_wrapper(51, varargin{:}); + varargout{1} = geometry_wrapper(53, varargin{:}); else error('Arguments do not match any overload of function aGlobalFunction'); end diff --git a/wrap/tests/expected2/geometry_wrapper.cpp b/wrap/tests/expected2/geometry_wrapper.cpp index 132c03674..ff603350d 100644 --- a/wrap/tests/expected2/geometry_wrapper.cpp +++ b/wrap/tests/expected2/geometry_wrapper.cpp @@ -579,7 +579,16 @@ void MyTemplatePoint2_deconstructor_46(int nargout, mxArray *out[], int nargin, } } -void MyTemplatePoint3_collectorInsertAndMakeBase_47(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void MyTemplatePoint2_templatedMethod_47(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + typedef boost::shared_ptr Shared; + checkArguments("templatedMethod",nargout,nargin-1,1); + Shared obj = unwrap_shared_ptr(in[0], "ptr_MyTemplatePoint2"); + Test& t = *unwrap_shared_ptr< Test >(in[1], "ptr_Test"); + obj->templatedMethod(t); +} + +void MyTemplatePoint3_collectorInsertAndMakeBase_48(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); typedef boost::shared_ptr Shared; @@ -592,7 +601,7 @@ void MyTemplatePoint3_collectorInsertAndMakeBase_47(int nargout, mxArray *out[], *reinterpret_cast(mxGetData(out[0])) = new SharedBase(*self); } -void MyTemplatePoint3_upcastFromVoid_48(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { +void MyTemplatePoint3_upcastFromVoid_49(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); typedef boost::shared_ptr Shared; boost::shared_ptr *asVoid = *reinterpret_cast**> (mxGetData(in[0])); @@ -601,7 +610,7 @@ void MyTemplatePoint3_upcastFromVoid_48(int nargout, mxArray *out[], int nargin, *reinterpret_cast(mxGetData(out[0])) = self; } -void MyTemplatePoint3_constructor_49(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void MyTemplatePoint3_constructor_50(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); typedef boost::shared_ptr Shared; @@ -616,7 +625,7 @@ void MyTemplatePoint3_constructor_49(int nargout, mxArray *out[], int nargin, co *reinterpret_cast(mxGetData(out[1])) = new SharedBase(*self); } -void MyTemplatePoint3_deconstructor_50(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void MyTemplatePoint3_deconstructor_51(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { typedef boost::shared_ptr Shared; checkArguments("delete_MyTemplatePoint3",nargout,nargin,1); @@ -629,18 +638,27 @@ void MyTemplatePoint3_deconstructor_50(int nargout, mxArray *out[], int nargin, } } -void aGlobalFunction_51(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void MyTemplatePoint3_templatedMethod_52(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + typedef boost::shared_ptr Shared; + checkArguments("templatedMethod",nargout,nargin-1,1); + Shared obj = unwrap_shared_ptr(in[0], "ptr_MyTemplatePoint3"); + Test& t = *unwrap_shared_ptr< Test >(in[1], "ptr_Test"); + obj->templatedMethod(t); +} + +void aGlobalFunction_53(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("aGlobalFunction",nargout,nargin,0); out[0] = wrap< Vector >(aGlobalFunction()); } -void overloadedGlobalFunction_52(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void overloadedGlobalFunction_54(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("overloadedGlobalFunction",nargout,nargin,1); int a = unwrap< int >(in[0]); out[0] = wrap< Vector >(overloadedGlobalFunction(a)); } -void overloadedGlobalFunction_53(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +void overloadedGlobalFunction_55(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { checkArguments("overloadedGlobalFunction",nargout,nargin,2); int a = unwrap< int >(in[0]); @@ -801,25 +819,31 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) MyTemplatePoint2_deconstructor_46(nargout, out, nargin-1, in+1); break; case 47: - MyTemplatePoint3_collectorInsertAndMakeBase_47(nargout, out, nargin-1, in+1); + MyTemplatePoint2_templatedMethod_47(nargout, out, nargin-1, in+1); break; case 48: - MyTemplatePoint3_upcastFromVoid_48(nargout, out, nargin-1, in+1); + MyTemplatePoint3_collectorInsertAndMakeBase_48(nargout, out, nargin-1, in+1); break; case 49: - MyTemplatePoint3_constructor_49(nargout, out, nargin-1, in+1); + MyTemplatePoint3_upcastFromVoid_49(nargout, out, nargin-1, in+1); break; case 50: - MyTemplatePoint3_deconstructor_50(nargout, out, nargin-1, in+1); + MyTemplatePoint3_constructor_50(nargout, out, nargin-1, in+1); break; case 51: - aGlobalFunction_51(nargout, out, nargin-1, in+1); + MyTemplatePoint3_deconstructor_51(nargout, out, nargin-1, in+1); break; case 52: - overloadedGlobalFunction_52(nargout, out, nargin-1, in+1); + MyTemplatePoint3_templatedMethod_52(nargout, out, nargin-1, in+1); break; case 53: - overloadedGlobalFunction_53(nargout, out, nargin-1, in+1); + aGlobalFunction_53(nargout, out, nargin-1, in+1); + break; + case 54: + overloadedGlobalFunction_54(nargout, out, nargin-1, in+1); + break; + case 55: + overloadedGlobalFunction_55(nargout, out, nargin-1, in+1); break; } } catch(const std::exception& e) { diff --git a/wrap/tests/expected2/overloadedGlobalFunction.m b/wrap/tests/expected2/overloadedGlobalFunction.m index e080a038a..bc6efe822 100644 --- a/wrap/tests/expected2/overloadedGlobalFunction.m +++ b/wrap/tests/expected2/overloadedGlobalFunction.m @@ -1,8 +1,8 @@ function varargout = overloadedGlobalFunction(varargin) if length(varargin) == 1 && isa(varargin{1},'numeric') - varargout{1} = geometry_wrapper(52, varargin{:}); + varargout{1} = geometry_wrapper(54, varargin{:}); elseif length(varargin) == 2 && isa(varargin{1},'numeric') && isa(varargin{2},'double') - varargout{1} = geometry_wrapper(53, varargin{:}); + varargout{1} = geometry_wrapper(55, varargin{:}); else error('Arguments do not match any overload of function overloadedGlobalFunction'); end diff --git a/wrap/tests/geometry.h b/wrap/tests/geometry.h index 238a25d72..1cc45fce8 100644 --- a/wrap/tests/geometry.h +++ b/wrap/tests/geometry.h @@ -100,6 +100,9 @@ virtual class MyBase { template virtual class MyTemplate : MyBase { MyTemplate(); + + template + void templatedMethod(const Test& t); }; diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index 399fa61aa..28022de80 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -458,6 +458,9 @@ TEST( wrap, matlab_code_geometry ) { EXPECT(files_equal(epath + "Point2.m" , apath + "Point2.m" )); EXPECT(files_equal(epath + "Point3.m" , apath + "Point3.m" )); EXPECT(files_equal(epath + "Test.m" , apath + "Test.m" )); + EXPECT(files_equal(epath + "MyBase.m" , apath + "MyBase.m" )); + EXPECT(files_equal(epath + "MyTemplatePoint2.m" , apath + "MyTemplatePoint2.m" )); + EXPECT(files_equal(epath + "MyTemplatePoint3.m" , apath + "MyTemplatePoint3.m" )); EXPECT(files_equal(epath + "aGlobalFunction.m" , apath + "aGlobalFunction.m" )); EXPECT(files_equal(epath + "overloadedGlobalFunction.m" , apath + "overloadedGlobalFunction.m" )); }