diff --git a/.cproject b/.cproject index 241afea81..bcf690995 100644 --- a/.cproject +++ b/.cproject @@ -592,6 +592,7 @@ make + tests/testBayesTree.run true false @@ -599,6 +600,7 @@ make + testBinaryBayesNet.run true false @@ -646,6 +648,7 @@ make + testSymbolicBayesNet.run true false @@ -653,6 +656,7 @@ make + tests/testSymbolicFactor.run true false @@ -660,6 +664,7 @@ make + testSymbolicFactorGraph.run true false @@ -675,6 +680,7 @@ make + tests/testBayesTree true false @@ -1122,6 +1128,7 @@ make + testErrors.run true false @@ -1351,6 +1358,46 @@ true true + + make + -j5 + testBTree.run + true + true + true + + + make + -j5 + testDSF.run + true + true + true + + + make + -j5 + testDSFMap.run + true + true + true + + + make + -j5 + testDSFVector.run + true + true + true + + + make + -j5 + testFixedVector.run + true + true + true + make -j2 @@ -1433,7 +1480,6 @@ make - testSimulated2DOriented.run true false @@ -1473,7 +1519,6 @@ make - testSimulated2D.run true false @@ -1481,7 +1526,6 @@ make - testSimulated3D.run true false @@ -1495,46 +1539,6 @@ true true - - make - -j5 - testBTree.run - true - true - true - - - make - -j5 - testDSF.run - true - true - true - - - make - -j5 - testDSFMap.run - true - true - true - - - make - -j5 - testDSFVector.run - true - true - true - - - make - -j5 - testFixedVector.run - true - true - true - make -j5 @@ -1792,6 +1796,7 @@ cpack + -G DEB true false @@ -1799,6 +1804,7 @@ cpack + -G RPM true false @@ -1806,6 +1812,7 @@ cpack + -G TGZ true false @@ -1813,6 +1820,7 @@ cpack + --config CPackSourceConfig.cmake true false @@ -2425,6 +2433,14 @@ true true + + make + -j4 + testGlobalFunction.run + true + true + true + make -j5 @@ -2659,6 +2675,7 @@ make + testGraph.run true false @@ -2666,6 +2683,7 @@ make + testJunctionTree.run true false @@ -2673,6 +2691,7 @@ make + testSymbolicBayesNetB.run true false @@ -3216,7 +3235,6 @@ make - tests/testGaussianISAM2 true false diff --git a/wrap/Argument.h b/wrap/Argument.h index 3b7a13ee3..fd7e82061 100644 --- a/wrap/Argument.h +++ b/wrap/Argument.h @@ -171,27 +171,28 @@ struct ArgumentListGrammar: public classic::grammar { wrap::ArgumentList& result_; ///< successful parse will be placed in here - const Argument arg0; ///< used to reset arg - mutable Argument arg; ///< temporary argument for use during parsing - ArgumentGrammar argument_g; ///< single Argument parser - /// Construct type grammar and specify where result is placed ArgumentListGrammar(wrap::ArgumentList& result) : - result_(result), argument_g(arg) { + result_(result) { } /// Definition of type grammar template struct definition { + const Argument arg0; ///< used to reset arg + Argument arg; ///< temporary argument for use during parsing + ArgumentGrammar argument_g; ///< single Argument parser + classic::rule argument_p, argumentList_p; - definition(ArgumentListGrammar const& self) { + definition(ArgumentListGrammar const& self) : + argument_g(arg) { using namespace classic; - argument_p = self.argument_g // - [classic::push_back_a(self.result_, self.arg)] // - [assign_a(self.arg, self.arg0)]; + argument_p = argument_g // + [classic::push_back_a(self.result_, arg)] // + [assign_a(arg, arg0)]; argumentList_p = '(' >> !argument_p >> *(',' >> argument_p) >> ')'; } diff --git a/wrap/Class.h b/wrap/Class.h index 8faf7ab77..f4c687eca 100644 --- a/wrap/Class.h +++ b/wrap/Class.h @@ -19,6 +19,7 @@ #pragma once +#include "spirit.h" #include "Template.h" #include "Constructor.h" #include "Deconstructor.h" @@ -26,6 +27,18 @@ #include "StaticMethod.h" #include "TypeAttributesTable.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif +#include +#include +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +namespace bl = boost::lambda; + #include #include #include @@ -145,5 +158,122 @@ private: void comment_fragment(FileWriter& proxyFile) const; }; -} // \namespace wrap +/* ************************************************************************* */ +// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html +struct ClassGrammar: public classic::grammar { + + Class& cls_; ///< successful parse will be placed in here + Template& template_; ///< result needs to be visible outside + + /// Construct type grammar and specify where result is placed + ClassGrammar(Class& cls, Template& t) : + cls_(cls), template_(t) { + } + + /// Definition of type grammar + template + struct definition: BasicRules { + + using BasicRules::name_p; + using BasicRules::className_p; + using BasicRules::comments_p; + + // NOTE: allows for pointers to all types + ArgumentList args; + ArgumentListGrammar argumentList_g; + + Constructor constructor0, constructor; + + ReturnValue retVal0, retVal; + ReturnValueGrammar returnValue_g; + + Template methodTemplate; + TemplateGrammar methodTemplate_g, classTemplate_g; + + std::string methodName; + bool isConst, T, F; + + // Parent class + Qualified possibleParent; + TypeGrammar classParent_g; + + classic::rule constructor_p, methodName_p, method_p, + staticMethodName_p, static_method_p, templateList_p, classParent_p, + functions_p, class_p; + + definition(ClassGrammar const& self) : + argumentList_g(args), returnValue_g(retVal), // + methodTemplate_g(methodTemplate), classTemplate_g(self.template_), // + T(true), F(false), classParent_g(possibleParent) { + + using namespace classic; + bool verbose = false; // TODO + + // ConstructorGrammar + constructor_p = (className_p >> argumentList_g >> ';' >> !comments_p) // + [bl::bind(&Constructor::push_back, bl::var(constructor), + bl::var(args))] // + [clear_a(args)]; + + // MethodGrammar + 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) // + [bl::bind(&Class::addMethod, bl::var(self.cls_), verbose, + bl::var(isConst), bl::var(methodName), bl::var(args), + bl::var(retVal), bl::var(methodTemplate))] // + [assign_a(retVal, retVal0)][clear_a(args)] // + [clear_a(methodTemplate)][assign_a(isConst, F)]; + + // StaticMethodGrammar + 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, + bl::var(self.cls_.static_methods)[bl::var(methodName)], + bl::var(methodName), bl::var(args), bl::var(retVal), boost::none, + verbose)] // + [assign_a(retVal, retVal0)][clear_a(args)]; + + // template + 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)]; + + functions_p = constructor_p | method_p | static_method_p; + + // parse a full class + class_p = (!(classTemplate_g[push_back_a(self.cls_.templateArgs, + self.template_.argName())] | templateList_p) + >> !(str_p("virtual")[assign_a(self.cls_.isVirtual, T)]) + >> str_p("class") >> className_p[assign_a(self.cls_.name_)] + >> (classParent_p | '{') >> // + *(functions_p | comments_p) >> str_p("};")) // + [bl::bind(&Constructor::initializeOrCheck, bl::var(constructor), + bl::var(self.cls_.name_), boost::none, verbose)][assign_a( + self.cls_.constructor, constructor)] // + [assign_a(self.cls_.deconstructor.name, self.cls_.name_)] // + [assign_a(constructor, constructor0)]; + } + + classic::rule const& start() const { + return class_p; + } + + }; +}; +// ClassGrammar + +}// \namespace wrap diff --git a/wrap/GlobalFunction.h b/wrap/GlobalFunction.h index 4805231fb..b2a582654 100644 --- a/wrap/GlobalFunction.h +++ b/wrap/GlobalFunction.h @@ -11,6 +11,18 @@ #include "FullyOverloadedFunction.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif +#include +#include +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +namespace bl = boost::lambda; + namespace wrap { struct GlobalFunction: public FullyOverloadedFunction { @@ -47,5 +59,67 @@ private: }; -} // \namespace wrap +typedef std::map GlobalFunctions; + +/* ************************************************************************* */ +// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html +struct GlobalFunctionGrammar: public classic::grammar { + + GlobalFunctions& global_functions_; ///< successful parse will be placed in here + std::vector& namespaces_; + + /// Construct type grammar and specify where result is placed + GlobalFunctionGrammar(GlobalFunctions& global_functions, + std::vector& namespaces) : + global_functions_(global_functions), namespaces_(namespaces) { + } + + /// Definition of type grammar + template + struct definition: BasicRules { + +// using BasicRules::name_p; +// using BasicRules::className_p; + using BasicRules::comments_p; + + ArgumentList args; + ArgumentListGrammar argumentList_g; + + ReturnValue retVal0, retVal; + ReturnValueGrammar returnValue_g; + + Qualified globalFunction; + + classic::rule globalFunctionName_p, global_function_p; + + definition(GlobalFunctionGrammar const& self) : + argumentList_g(args), returnValue_g(retVal) { + + using namespace classic; + bool verbose = false; // TODO + + globalFunctionName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')]; + + // parse a global function + global_function_p = (returnValue_g + >> globalFunctionName_p[assign_a(globalFunction.name_)] + >> argumentList_g >> ';' >> *comments_p) // + [assign_a(globalFunction.namespaces_, self.namespaces_)][bl::bind( + &GlobalFunction::addOverload, + bl::var(self.global_functions_)[bl::var(globalFunction.name_)], + bl::var(globalFunction), bl::var(args), bl::var(retVal), + boost::none, verbose)] // + [assign_a(retVal, retVal0)][clear_a(globalFunction)][clear_a(args)]; + + } + + classic::rule const& start() const { + return global_function_p; + } + + }; +}; +// GlobalFunctionGrammar + +}// \namespace wrap diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 917130f5c..55fd13715 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -22,19 +22,6 @@ #include "TypeAttributesTable.h" #include "utilities.h" -//#define BOOST_SPIRIT_DEBUG -#include "spirit.h" - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif -#include -#include -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif -#include #include #include #include @@ -111,15 +98,24 @@ void Module::parseMarkup(const std::string& data) { typedef rule Rule; BasicRules basic; - // TODO, do we really need cls here? Non-local + vector namespaces; // current namespace tag + + // parse a full class Class cls0(verbose),cls(verbose); - + Template classTemplate; + ClassGrammar class_g(cls,classTemplate); + Rule class_p = class_g // + [assign_a(cls.namespaces_, namespaces)] + [bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls), + bl::var(classTemplate.argValues()))] + [clear_a(classTemplate)] // + [assign_a(cls,cls0)]; + // parse "gtsam::Pose2" and add to singleInstantiation.typeList TemplateInstantiationTypedef singleInstantiation, singleInstantiation0; TypeListGrammar<'<','>'> typelist_g(singleInstantiation.typeList); // typedef gtsam::RangeFactor RangeFactorPosePoint2; - vector namespaces; // current namespace tag TypeGrammar instantiationClass_g(singleInstantiation.class_); Rule templateSingleInstantiation_p = (str_p("typedef") >> instantiationClass_g >> @@ -130,109 +126,8 @@ void Module::parseMarkup(const std::string& data) { [push_back_a(templateInstantiationTypedefs, singleInstantiation)] [assign_a(singleInstantiation, singleInstantiation0)]; - // template - Rule templateList_p = - (str_p("template") >> - '<' >> basic.name_p[push_back_a(cls.templateArgs)] >> *(',' >> basic.name_p[push_back_a(cls.templateArgs)]) >> - '>'); - - // NOTE: allows for pointers to all types - ArgumentList args; - ArgumentListGrammar argumentList_g(args); - - // parse class constructor - Constructor constructor0(verbose), constructor(verbose); - Rule constructor_p = - (basic.className_p >> argumentList_g >> ';' >> !basic.comments_p) - [bl::bind(&Constructor::push_back, bl::var(constructor), bl::var(args))] - [clear_a(args)]; - - vector namespaces_return; /// namespace for current return type - Rule namespace_ret_p = basic.namespace_p[push_back_a(namespaces_return)] >> str_p("::"); - - ReturnValue retVal0, retVal; - ReturnValueGrammar returnValue_g(retVal); - - Rule methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')]; - - // template - Template methodTemplate; - TemplateGrammar methodTemplate_g(methodTemplate); - - // gtsam::Values retract(const gtsam::VectorValues& delta) const; - string methodName; - bool isConst, isConst0 = false; - Rule method_p = - !methodTemplate_g >> - (returnValue_g >> methodName_p[assign_a(methodName)] >> - argumentList_g >> - !str_p("const")[assign_a(isConst,true)] >> ';' >> *basic.comments_p) - [bl::bind(&Class::addMethod, bl::var(cls), verbose, bl::var(isConst), - bl::var(methodName), bl::var(args), bl::var(retVal), - bl::var(methodTemplate))] - [assign_a(retVal,retVal0)] - [clear_a(args)] - [clear_a(methodTemplate)] - [assign_a(isConst,isConst0)]; - - Rule staticMethodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')]; - - Rule static_method_p = - (str_p("static") >> returnValue_g >> staticMethodName_p[assign_a(methodName)] >> - argumentList_g >> ';' >> *basic.comments_p) - [bl::bind(&StaticMethod::addOverload, - bl::var(cls.static_methods)[bl::var(methodName)], - bl::var(methodName), bl::var(args), bl::var(retVal), boost::none,verbose)] - [assign_a(retVal,retVal0)] - [clear_a(args)]; - - Rule functions_p = constructor_p | method_p | static_method_p; - - // template - Template classTemplate; - TemplateGrammar classTemplate_g(classTemplate); - - // Parent class - Qualified possibleParent; - TypeGrammar classParent_p(possibleParent); - - // parse a full class - Rule class_p = - eps_p[assign_a(cls,cls0)] - >> (!(classTemplate_g - [push_back_a(cls.templateArgs, classTemplate.argName())] - | templateList_p) - >> !(str_p("virtual")[assign_a(cls.isVirtual, true)]) - >> str_p("class") - >> basic.className_p[assign_a(cls.name_)] - >> ((':' >> classParent_p >> '{') - [bl::bind(&Class::assignParent, bl::var(cls), bl::var(possibleParent))] - [clear_a(possibleParent)] | '{') - >> *(functions_p | basic.comments_p) - >> str_p("};")) - [bl::bind(&Constructor::initializeOrCheck, bl::var(constructor), - bl::var(cls.name_), boost::none, verbose)] - [assign_a(cls.constructor, constructor)] - [assign_a(cls.namespaces_, namespaces)] - [assign_a(cls.deconstructor.name,cls.name_)] - [bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls), - bl::var(classTemplate.argValues()))] - [clear_a(classTemplate)] - [assign_a(constructor, constructor0)] - [assign_a(cls,cls0)]; - - // parse a global function - Qualified globalFunction; - Rule global_function_p = - (returnValue_g >> staticMethodName_p[assign_a(globalFunction.name_)] >> - argumentList_g >> ';' >> *basic.comments_p) - [assign_a(globalFunction.namespaces_,namespaces)] - [bl::bind(&GlobalFunction::addOverload, - bl::var(global_functions)[bl::var(globalFunction.name_)], - bl::var(globalFunction), bl::var(args), bl::var(retVal), boost::none,verbose)] - [assign_a(retVal,retVal0)] - [clear_a(globalFunction)] - [clear_a(args)]; + // Create grammar for global functions + GlobalFunctionGrammar global_function_g(global_functions,namespaces); Rule include_p = str_p("#include") >> ch_p('<') >> (*(anychar_p - '>'))[push_back_a(includes)] >> ch_p('>'); @@ -245,7 +140,7 @@ void Module::parseMarkup(const std::string& data) { (str_p("namespace") >> basic.namespace_p[push_back_a(namespaces)] >> ch_p('{') - >> *(include_p | class_p | templateSingleInstantiation_p | global_function_p | namespace_def_p | basic.comments_p) + >> *(include_p | class_p | templateSingleInstantiation_p | global_function_g | namespace_def_p | basic.comments_p) >> ch_p('}')) [pop_a(namespaces)]; @@ -265,41 +160,16 @@ void Module::parseMarkup(const std::string& data) { Rule module_content_p = basic.comments_p | include_p | class_p | templateSingleInstantiation_p | forward_declaration_p - | global_function_p | namespace_def_p; + | global_function_g | namespace_def_p; Rule module_p = *module_content_p >> !end_p; - //---------------------------------------------------------------------------- - // for debugging, define BOOST_SPIRIT_DEBUG -# ifdef BOOST_SPIRIT_DEBUG - BOOST_SPIRIT_DEBUG_NODE(className_p); - BOOST_SPIRIT_DEBUG_NODE(classPtr_p); - BOOST_SPIRIT_DEBUG_NODE(classRef_p); - BOOST_SPIRIT_DEBUG_NODE(basisType_p); - BOOST_SPIRIT_DEBUG_NODE(name_p); - BOOST_SPIRIT_DEBUG_NODE(argument_p); - BOOST_SPIRIT_DEBUG_NODE(argumentList_g); - BOOST_SPIRIT_DEBUG_NODE(constructor_p); - BOOST_SPIRIT_DEBUG_NODE(returnType1_p); - BOOST_SPIRIT_DEBUG_NODE(returnType2_p); - BOOST_SPIRIT_DEBUG_NODE(pair_p); - BOOST_SPIRIT_DEBUG_NODE(void_p); - BOOST_SPIRIT_DEBUG_NODE(returnValue_g); - BOOST_SPIRIT_DEBUG_NODE(methodName_p); - BOOST_SPIRIT_DEBUG_NODE(method_p); - BOOST_SPIRIT_DEBUG_NODE(class_p); - BOOST_SPIRIT_DEBUG_NODE(namespace_def_p); - BOOST_SPIRIT_DEBUG_NODE(module_p); -# endif - //---------------------------------------------------------------------------- - // and parse contents parse_info info = parse(data.c_str(), module_p, space_p); if(!info.full) { printf("parsing stopped at \n%.20s\n",info.stop); - cout << "Stopped near:\n" - "class '" << cls.name_ << "'\n" - "method '" << methodName << "'" << endl; + cout << "Stopped in:\n" + "class '" << cls.name_ << "'" << endl; throw ParseFailed((int)info.length); } diff --git a/wrap/Module.h b/wrap/Module.h index e99e77bc9..e0c1b3f31 100644 --- a/wrap/Module.h +++ b/wrap/Module.h @@ -34,8 +34,6 @@ namespace wrap { */ struct Module { - typedef std::map GlobalFunctions; - // Filled during parsing: std::string name; ///< module name bool verbose; ///< verbose flag diff --git a/wrap/Qualified.h b/wrap/Qualified.h index 000d749ec..bcc4c0829 100644 --- a/wrap/Qualified.h +++ b/wrap/Qualified.h @@ -222,25 +222,26 @@ struct TypeListGrammar: public classic::grammar > { typedef std::vector TypeList; TypeList& result_; ///< successful parse will be placed in here - mutable wrap::Qualified type; // temporary type for use during parsing - TypeGrammar type_g; - /// Construct type grammar and specify where result is placed TypeListGrammar(TypeList& result) : - result_(result), type_g(type) { + result_(result) { } /// Definition of type grammar template struct definition { + wrap::Qualified type; ///< temporary for use during parsing + TypeGrammar type_g; ///< Individual Type grammars + classic::rule type_p, typeList_p; - definition(TypeListGrammar const& self) { + definition(TypeListGrammar const& self) : + type_g(type) { using namespace classic; - type_p = self.type_g // - [push_back_a(self.result_, self.type)] // - [clear_a(self.type)]; + + type_p = type_g[push_back_a(self.result_, type)][clear_a(type)]; + typeList_p = OPEN >> !type_p >> *(',' >> type_p) >> CLOSE; } diff --git a/wrap/tests/testClass.cpp b/wrap/tests/testClass.cpp index 0ceff500b..756b6668d 100644 --- a/wrap/tests/testClass.cpp +++ b/wrap/tests/testClass.cpp @@ -46,7 +46,7 @@ TEST( Class, OverloadingMethod ) { EXPECT_LONGS_EQUAL(1, cls.method(name).nrOverloads()); // add an overload w different argument list - args.push_back(Argument(Qualified("Vector",Qualified::EIGEN),"v")); + args.push_back(Argument(Qualified("Vector", Qualified::EIGEN), "v")); cls.addMethod(verbose, is_const, name, args, retVal, tmplate); EXPECT_LONGS_EQUAL(1, cls.nrMethods()); EXPECT_LONGS_EQUAL(2, cls.method(name).nrOverloads()); @@ -82,6 +82,84 @@ TEST( Class, TemplatedMethods ) { EXPECT(cls.exists(name+"Point3")); } +//****************************************************************************** +TEST( Class, Grammar ) { + + using classic::space_p; + + // Create type grammar that will place result in cls + Class cls; + Template t; + ClassGrammar g(cls, t); + + EXPECT(parse("class Point2 {\n};", g, space_p).full); + + string markup( + string("class Point2 { \n") + + string(" double x() const; \n") // Method 1 + + string(" Matrix returnMatrix() const; \n") // Method 2 + + string(" Point2 returnPoint2() const; \n") // Method 3 + + string(" static Vector returnVector(); \n") // Static Method 1 + + string("};")); + + EXPECT(parse(markup.c_str(), g, space_p).full); + + // check return types + EXPECT(assert_equal("Point2", cls.name())); + EXPECT(!cls.isVirtual); + EXPECT(cls.namespaces().empty()); + LONGS_EQUAL(3, cls.nrMethods()); + LONGS_EQUAL(1, cls.static_methods.size()); + + // Method 1 + Method m1 = cls.method("x"); + EXPECT(assert_equal("x", m1.name())); + EXPECT(m1.isConst()); + LONGS_EQUAL(1, m1.nrOverloads()); + + ReturnValue rv1 = m1.returnValue(0); + EXPECT(!rv1.isPair); + EXPECT(!rv1.type1.isPtr); + EXPECT(assert_equal("double", rv1.type1.name())); + EXPECT_LONGS_EQUAL(ReturnType::BASIS, rv1.type1.category); + + // Method 2 + Method m2 = cls.method("returnMatrix"); + EXPECT(assert_equal("returnMatrix", m2.name())); + EXPECT(m2.isConst()); + LONGS_EQUAL(1, m2.nrOverloads()); + + ReturnValue rv2 = m2.returnValue(0); + EXPECT(!rv2.isPair); + EXPECT(!rv2.type1.isPtr); + EXPECT(assert_equal("Matrix", rv2.type1.name())); + EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv2.type1.category); + + // Method 3 + Method m3 = cls.method("returnPoint2"); + EXPECT(assert_equal("returnPoint2", m3.name())); + EXPECT(m3.isConst()); + LONGS_EQUAL(1, m3.nrOverloads()); + + ReturnValue rv3 = m3.returnValue(0); + EXPECT(!rv3.isPair); + EXPECT(!rv3.type1.isPtr); + EXPECT(assert_equal("Point2", rv3.type1.name())); + EXPECT_LONGS_EQUAL(ReturnType::CLASS, rv3.type1.category); + + // Static Method 1 + // static Vector returnVector(); + StaticMethod sm1 = cls.static_methods.at("returnVector"); + EXPECT(assert_equal("returnVector", sm1.name())); + LONGS_EQUAL(1, sm1.nrOverloads()); + + ReturnValue rv4 = sm1.returnValue(0); + EXPECT(!rv4.isPair); + EXPECT(!rv4.type1.isPtr); + EXPECT(assert_equal("Vector", rv4.type1.name())); + EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv4.type1.category); +} + /* ************************************************************************* */ int main() { TestResult tr; diff --git a/wrap/tests/testGlobalFunction.cpp b/wrap/tests/testGlobalFunction.cpp new file mode 100644 index 000000000..32ab5dafb --- /dev/null +++ b/wrap/tests/testGlobalFunction.cpp @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + + * 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 + + * -------------------------------------------------------------------------- */ + +/** + * @file testMethod.cpp + * @brief Unit test for GlobalFunction class + * @author Frank Dellaert + * @date Nov 12, 2014 + **/ + +#include +#include +#include + +using namespace std; +using namespace wrap; + +//****************************************************************************** +// Constructor +TEST( GlobalFunction, Constructor ) { + GlobalFunction f; +} + +//****************************************************************************** +TEST( GlobalFunction, Grammar ) { + + using classic::space_p; + + // Create type grammar that will place result in actual + GlobalFunctions actual; + vector namespaces; + GlobalFunctionGrammar g(actual,namespaces); + + // a class type with namespaces + EXPECT(parse("Vector aGlobalFunction();", g, space_p).full); + EXPECT(parse("Vector overloadedGlobalFunction(int a);", g, space_p).full); + EXPECT(parse("Vector overloadedGlobalFunction(int a, double b);", g, space_p).full); + LONGS_EQUAL(2,actual.size()); +} + +//****************************************************************************** +int main() { + TestResult tr; + return TestRegistry::runAllTests(tr); +} +//****************************************************************************** diff --git a/wrap/tests/testMethod.cpp b/wrap/tests/testMethod.cpp index 5b58fa31e..d823e9099 100644 --- a/wrap/tests/testMethod.cpp +++ b/wrap/tests/testMethod.cpp @@ -42,83 +42,6 @@ TEST( Method, addOverload ) { EXPECT_LONGS_EQUAL(2, method.nrOverloads()); } -//// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html -//struct method_grammar: public classic::grammar { -// -// wrap::Method& result_; ///< successful parse will be placed in here -// -// ArgumentList args; -// Argument arg0, arg; -// TypeGrammar argument_type_g; -// -// ReturnType retType0, retType; -// TypeGrammar returntype_g; -// -// ReturnValue retVal0, retVal; -// -// /// Construct type grammar and specify where result is placed -// method_grammar(wrap::Method& result) : -// result_(result), argument_type_g(arg.type), returntype_g(retType) { -// } -// -// /// Definition of type grammar -// template -// struct definition: basic_rules { -// -// Rule templateArgValue_p, templateArgValues_p, argument_p, argumentList_p, -// returnType1_p, returnType2_p, pair_p, returnValue_p, methodName_p, -// method_p; -// -// definition(method_grammar const& self) { -// -// using namespace wrap; -// using namespace classic; -// -//// Rule templateArgValue_p = type_grammar(self.templateArgValue); -//// -//// // template -//// Rule templateArgValues_p = (str_p("template") >> '<' >> name_p >> '=' -//// >> '{' >> !(templateArgValue_p >> *(',' >> templateArgValue_p)) >> '}' -//// >> '>'); -//// -// // Create type grammar that will place result in actual -// ArgumentList actual; -// ArgumentListGrammar g(actual); -// -// EXPECT(parse("(const gtsam::Point2& p4)", g, space_p).full); -// EXPECT_LONGS_EQUAL(1, actual.size()); -// actual.clear(); -// -// returnType1_p = self.returntype_g // -// [assign_a(self.retVal.type1, retType)] // -// [assign_a(self.retType, self.retType0)]; -// -// returnType2_p = self.returntype_g // -// [assign_a(self.retVal.type2, retType)] // -// [assign_a(self.retType, self.retType0)]; -// -// pair_p = (str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p -// >> '>')[assign_a(self.retVal.isPair, true)]; -// -// returnValue_p = pair_p | returnType1_p; -// -// methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')]; -// -// // gtsam::Values retract(const gtsam::VectorValues& delta) const; -// method_p = -//// !templateArgValues_p >> -// (returnValue_p >> methodName_p >> '(' >> argumentList_p >> ')' -// >> !str_p("const") >> ';' >> *basic_rules::comments_p); -// } -// -// Rule const& start() const { -// return method_p; -// } -// -// }; -//}; -//// method_grammar -// ////****************************************************************************** //TEST( Method, grammar ) { //