diff --git a/wrap/Argument.cpp b/wrap/Argument.cpp index d76556e4a..6e9ac5514 100644 --- a/wrap/Argument.cpp +++ b/wrap/Argument.cpp @@ -31,31 +31,31 @@ using namespace wrap; /* ************************************************************************* */ string Argument::matlabClass(const string& delim) const { string result; - BOOST_FOREACH(const string& ns, namespaces) + BOOST_FOREACH(const string& ns, type.namespaces) result += ns + delim; - if (type == "string" || type == "unsigned char" || type == "char") + if (type.name == "string" || type.name == "unsigned char" || type.name == "char") return result + "char"; - if (type == "Vector" || type == "Matrix") + if (type.name == "Vector" || type.name == "Matrix") return result + "double"; - if (type == "int" || type == "size_t") + if (type.name == "int" || type.name == "size_t") return result + "numeric"; - if (type == "bool") + if (type.name == "bool") return result + "logical"; - return result + type; + return result + type.name; } /* ************************************************************************* */ bool Argument::isScalar() const { - return (type == "bool" || type == "char" || type == "unsigned char" - || type == "int" || type == "size_t" || type == "double"); + return (type.name == "bool" || type.name == "char" || type.name == "unsigned char" + || type.name == "int" || type.name == "size_t" || type.name == "double"); } /* ************************************************************************* */ void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const { file.oss << " "; - string cppType = qualifiedType("::"); - string matlabUniqueType = qualifiedType(); + string cppType = type.qualifiedName("::"); + string matlabUniqueType = type.qualifiedName(); if (is_ptr) // A pointer: emit an "unwrap_shared_ptr" call which returns a pointer @@ -78,14 +78,6 @@ void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const { file.oss << ");" << endl; } -/* ************************************************************************* */ -string Argument::qualifiedType(const string& delim) const { - string result; - BOOST_FOREACH(const string& ns, namespaces) - result += ns + delim; - return result + type; -} - /* ************************************************************************* */ string ArgumentList::types() const { string str; @@ -93,7 +85,7 @@ string ArgumentList::types() const { BOOST_FOREACH(Argument arg, *this) { if (!first) str += ","; - str += arg.type; + str += arg.type.name; first = false; } return str; @@ -105,14 +97,14 @@ string ArgumentList::signature() const { bool cap = false; BOOST_FOREACH(Argument arg, *this) { - BOOST_FOREACH(char ch, arg.type) + BOOST_FOREACH(char ch, arg.type.name) if (isupper(ch)) { sig += ch; //If there is a capital letter, we don't want to read it below cap = true; } if (!cap) - sig += arg.type[0]; + sig += arg.type.name[0]; //Reset to default cap = false; } @@ -158,7 +150,7 @@ void ArgumentList::emit_prototype(FileWriter& file, const string& name) const { BOOST_FOREACH(Argument arg, *this) { if (!first) file.oss << ", "; - file.oss << arg.type << " " << arg.name; + file.oss << arg.type.name << " " << arg.name; first = false; } file.oss << ")"; @@ -180,7 +172,7 @@ void ArgumentList::emit_conditional_call(FileWriter& file, file.oss << "if length(varargin) == " << size(); if (size() > 0) file.oss << " && "; - // ...and their types + // ...and their type.names bool first = true; for (size_t i = 0; i < size(); i++) { if (!first) diff --git a/wrap/Argument.h b/wrap/Argument.h index 6f791978a..73bc66929 100644 --- a/wrap/Argument.h +++ b/wrap/Argument.h @@ -19,20 +19,17 @@ #pragma once +#include "Qualified.h" #include "FileWriter.h" #include "ReturnValue.h" -#include -#include - namespace wrap { /// Argument class struct Argument { + Qualified type; bool is_const, is_ref, is_ptr; - std::string type; std::string name; - std::vector namespaces; Argument() : is_const(false), is_ref(false), is_ptr(false) { @@ -44,9 +41,6 @@ struct Argument { /// Check if will be unwrapped using scalar login in wrap/matlab.h bool isScalar() const; - /// adds namespaces to type - std::string qualifiedType(const std::string& delim = "") const; - /// MATLAB code generation, MATLAB to C++ void matlab_unwrap(FileWriter& file, const std::string& matlabName) const; }; diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 8c95331c5..384037a92 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -41,17 +41,15 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, createNamespaceStructure(namespaces, toolboxPath); // open destination classFile - string classFile = toolboxPath; - if (!namespaces.empty()) - classFile += "/+" + wrap::qualifiedName("/+", namespaces); - classFile += "/" + name + ".m"; + string classFile = matlabName(toolboxPath); FileWriter proxyFile(classFile, verbose_, "%"); // get the name of actual matlab object - const string matlabQualName = qualifiedName("."), matlabUniqueName = - qualifiedName(), cppName = qualifiedName("::"); - const string matlabBaseName = wrap::qualifiedName(".", qualifiedParent); - const string cppBaseName = wrap::qualifiedName("::", qualifiedParent); + const string matlabQualName = qualifiedName("."); + const string matlabUniqueName = qualifiedName(); + const string cppName = qualifiedName("::"); + const string matlabBaseName = qualifiedParent.qualifiedName("."); + const string cppBaseName = qualifiedParent.qualifiedName("::"); // emit class proxy code // we want our class to inherit the handle class for memory purposes @@ -144,19 +142,14 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, proxyFile.emit(true); } -/* ************************************************************************* */ -string Class::qualifiedName(const string& delim) const { - return ::wrap::qualifiedName(delim, namespaces, name); -} - /* ************************************************************************* */ void Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const string& wrapperName, vector& functionNames) const { - const string matlabUniqueName = qualifiedName(), cppName = qualifiedName( - "::"); - const string baseCppName = wrap::qualifiedName("::", qualifiedParent); + const string matlabUniqueName = qualifiedName(); + const string cppName = qualifiedName("::"); + const string baseCppName = qualifiedParent.qualifiedName("::"); const int collectorInsertId = (int) functionNames.size(); const string collectorInsertFunctionName = matlabUniqueName @@ -247,23 +240,18 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile, } /* ************************************************************************* */ -vector expandArgumentListsTemplate( +static vector expandArgumentListsTemplate( const vector& argLists, const string& templateArg, - const vector& instName, - const vector& expandedClassNamespace, - const string& expandedClassName) { + const Qualified& qualifiedType, const Qualified& expandedClass) { vector result; BOOST_FOREACH(const ArgumentList& argList, argLists) { ArgumentList instArgList; BOOST_FOREACH(const Argument& arg, argList) { Argument instArg = arg; - if (arg.type == templateArg) { - instArg.namespaces.assign(instName.begin(), instName.end() - 1); - instArg.type = instName.back(); - } else if (arg.type == "This") { - instArg.namespaces.assign(expandedClassNamespace.begin(), - expandedClassNamespace.end()); - instArg.type = expandedClassName; + if (arg.type.name == templateArg) { + instArg.type = qualifiedType; + } else if (arg.type.name == "This") { + instArg.type = expandedClass; } instArgList.push_back(instArg); } @@ -275,34 +263,27 @@ vector expandArgumentListsTemplate( /* ************************************************************************* */ template map expandMethodTemplate(const map& methods, - const string& templateArg, const vector& instName, - const vector& expandedClassNamespace, - const string& expandedClassName) { + const string& templateArg, const Qualified& qualifiedType, + const Qualified& expandedClass) { map result; typedef pair Name_Method; BOOST_FOREACH(const Name_Method& name_method, methods) { const METHOD& method = name_method.second; METHOD instMethod = method; instMethod.argLists = expandArgumentListsTemplate(method.argLists, - templateArg, instName, expandedClassNamespace, expandedClassName); + templateArg, qualifiedType, expandedClass); instMethod.returnVals.clear(); BOOST_FOREACH(const ReturnValue& retVal, method.returnVals) { ReturnValue instRetVal = retVal; - if (retVal.type1 == templateArg) { - instRetVal.namespaces1.assign(instName.begin(), instName.end() - 1); - instRetVal.type1 = instName.back(); - } else if (retVal.type1 == "This") { - instRetVal.namespaces1.assign(expandedClassNamespace.begin(), - expandedClassNamespace.end()); - instRetVal.type1 = expandedClassName; + if (retVal.type1.name == templateArg) { + instRetVal.type1 = qualifiedType; + } else if (retVal.type1.name == "This") { + instRetVal.type1 = expandedClass; } - if (retVal.type2 == templateArg) { - instRetVal.namespaces2.assign(instName.begin(), instName.end() - 1); - instRetVal.type2 = instName.back(); - } else if (retVal.type1 == "This") { - instRetVal.namespaces2.assign(expandedClassNamespace.begin(), - expandedClassNamespace.end()); - instRetVal.type2 = expandedClassName; + if (retVal.type2.name == templateArg) { + instRetVal.type2 = qualifiedType; + } else if (retVal.type2.name == "This") { + instRetVal.type2 = expandedClass; } instMethod.returnVals.push_back(instRetVal); } @@ -313,17 +294,14 @@ map expandMethodTemplate(const map& methods, /* ************************************************************************* */ Class Class::expandTemplate(const string& templateArg, - const vector& instName, - const vector& expandedClassNamespace, - const string& expandedClassName) const { + const Qualified& instName, const Qualified& expandedClass) const { Class inst = *this; inst.methods = expandMethodTemplate(methods, templateArg, instName, - expandedClassNamespace, expandedClassName); + expandedClass); inst.static_methods = expandMethodTemplate(static_methods, templateArg, - instName, expandedClassNamespace, expandedClassName); + instName, expandedClass); inst.constructor.args_list = expandArgumentListsTemplate( - constructor.args_list, templateArg, instName, expandedClassNamespace, - expandedClassName); + constructor.args_list, templateArg, instName, expandedClass); inst.constructor.name = inst.name; inst.deconstructor.name = inst.name; return inst; @@ -331,16 +309,16 @@ Class Class::expandTemplate(const string& templateArg, /* ************************************************************************* */ vector Class::expandTemplate(const string& templateArg, - const vector >& instantiations) const { + const vector& instantiations) const { vector result; - BOOST_FOREACH(const vector& instName, instantiations) { - const string expandedName = name + instName.back(); - Class inst = expandTemplate(templateArg, instName, namespaces, - expandedName); - inst.name = expandedName; + BOOST_FOREACH(const Qualified& instName, instantiations) { + Qualified expandedClass = (Qualified)(*this); + expandedClass.name += instName.name; + Class inst = expandTemplate(templateArg, instName, expandedClass); + inst.name = expandedClass.name; inst.templateArgs.clear(); - inst.typedefName = qualifiedName("::") + "<" - + wrap::qualifiedName("::", instName) + ">"; + inst.typedefName = qualifiedName("::") + "<" + instName.qualifiedName("::") + + ">"; result.push_back(inst); } return result; @@ -425,8 +403,9 @@ void Class::serialization_fragments(FileWriter& proxyFile, //} int serialize_id = functionNames.size(); - const string matlabQualName = qualifiedName("."), matlabUniqueName = - qualifiedName(), cppClassName = qualifiedName("::"); + const string matlabQualName = qualifiedName("."); + const string matlabUniqueName = qualifiedName(); + const string cppClassName = qualifiedName("::"); const string wrapFunctionNameSerialize = matlabUniqueName + "_string_serialize_" + boost::lexical_cast(serialize_id); functionNames.push_back(wrapFunctionNameSerialize); @@ -515,8 +494,9 @@ void Class::deserialization_fragments(FileWriter& proxyFile, // out[0] = wrap_shared_ptr(output,"Point3", false); //} int deserialize_id = functionNames.size(); - const string matlabQualName = qualifiedName("."), matlabUniqueName = - qualifiedName(), cppClassName = qualifiedName("::"); + const string matlabQualName = qualifiedName("."); + const string matlabUniqueName = qualifiedName(); + const string cppClassName = qualifiedName("::"); const string wrapFunctionNameDeserialize = matlabUniqueName + "_string_deserialize_" + boost::lexical_cast(deserialize_id); functionNames.push_back(wrapFunctionNameDeserialize); diff --git a/wrap/Class.h b/wrap/Class.h index c3ef09814..78c733134 100644 --- a/wrap/Class.h +++ b/wrap/Class.h @@ -31,7 +31,7 @@ namespace wrap { /// Class has name, constructors, methods -struct Class { +struct Class : public Qualified { typedef std::map Methods; typedef std::map StaticMethods; @@ -39,16 +39,14 @@ struct Class { Class(bool verbose=true) : isVirtual(false), isSerializable(false), hasSerialization(false), verbose_(verbose) {} // Then the instance variables are set directly by the Module constructor - std::string name; ///< Class name std::vector templateArgs; ///< Template arguments std::string typedefName; ///< The name to typedef *from*, if this class is actually a typedef, i.e. typedef [typedefName] [name] 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 - std::vector qualifiedParent; ///< The *single* parent - the last string is the parent class name, preceededing elements are a namespace stack + Qualified qualifiedParent; ///< The *single* parent Methods methods; ///< Class methods StaticMethods static_methods; ///< Static methods - std::vector namespaces; ///< Stack of namespaces Constructor constructor; ///< Class constructors Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object bool verbose_; ///< verbose flag @@ -57,15 +55,12 @@ struct Class { void matlab_proxy(const std::string& toolboxPath, const std::string& wrapperName, const TypeAttributesTable& typeAttributes, FileWriter& wrapperFile, std::vector& functionNames) const; ///< emit proxy class - std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter - Class expandTemplate(const std::string& templateArg, - const std::vector& instantiation, - const std::vector& expandedClassNamespace, - const std::string& expandedClassName) const; + const Qualified& instantiation, + const Qualified& expandedClass) const; std::vector expandTemplate(const std::string& templateArg, - const std::vector >& instantiations) const; + const std::vector& instantiations) const; // The typedef line for this class, if this class is a typedef, otherwise returns an empty string. std::string getTypedef() const; diff --git a/wrap/GlobalFunction.cpp b/wrap/GlobalFunction.cpp index 25e1dcedb..afc099070 100644 --- a/wrap/GlobalFunction.cpp +++ b/wrap/GlobalFunction.cpp @@ -16,14 +16,18 @@ namespace wrap { using namespace std; /* ************************************************************************* */ -void GlobalFunction::addOverload(bool verbose, const std::string& name, - const ArgumentList& args, const ReturnValue& retVal, - const StrVec& ns_stack) { - this->verbose_ = verbose; - this->name = name; - this->argLists.push_back(args); - this->returnVals.push_back(retVal); - this->namespaces.push_back(ns_stack); +void GlobalFunction::addOverload(bool verbose, const Qualified& overload, + const ArgumentList& args, const ReturnValue& retVal) { + if (name.empty()) + name = overload.name; + else if (overload.name != name) + throw std::runtime_error( + "GlobalFunction::addOverload: tried to add overload with name " + + overload.name + " instead of expected " + name); + verbose_ = verbose; + argLists.push_back(args); + returnVals.push_back(retVal); + overloads.push_back(overload); } /* ************************************************************************* */ @@ -36,9 +40,10 @@ void GlobalFunction::matlab_proxy(const std::string& toolboxPath, // map of namespace to global function typedef map GlobalFunctionMap; GlobalFunctionMap grouped_functions; - for (size_t i = 0; i < namespaces.size(); ++i) { - StrVec ns = namespaces.at(i); - string str_ns = qualifiedName("", ns, ""); + for (size_t i = 0; i < overloads.size(); ++i) { + Qualified overload = overloads.at(i); + // use concatenated namespaces as key + string str_ns = qualifiedName("", overload.namespaces); ReturnValue ret = returnVals.at(i); ArgumentList args = argLists.at(i); @@ -47,7 +52,7 @@ void GlobalFunction::matlab_proxy(const std::string& toolboxPath, grouped_functions[str_ns].argLists.push_back(args); grouped_functions[str_ns].returnVals.push_back(ret); - grouped_functions[str_ns].namespaces.push_back(ns); + grouped_functions[str_ns].overloads.push_back(overload); } size_t lastcheck = grouped_functions.size(); @@ -65,19 +70,17 @@ void GlobalFunction::generateSingleFunction(const std::string& toolboxPath, FileWriter& file, std::vector& functionNames) const { // create the folder for the namespace - const StrVec& ns = namespaces.front(); - createNamespaceStructure(ns, toolboxPath); + const Qualified& overload1 = overloads.front(); + createNamespaceStructure(overload1.namespaces, toolboxPath); // open destination mfunctionFileName - string mfunctionFileName = toolboxPath; - if (!ns.empty()) - mfunctionFileName += "/+" + wrap::qualifiedName("/+", ns); - mfunctionFileName += "/" + name + ".m"; + string mfunctionFileName = overload1.matlabName(toolboxPath); FileWriter mfunctionFile(mfunctionFileName, verbose_, "%"); // get the name of actual matlab object - const string matlabQualName = qualifiedName(".", ns, name), matlabUniqueName = - qualifiedName("", ns, name), cppName = qualifiedName("::", ns, name); + const string matlabQualName = overload1.qualifiedName("."); + const string matlabUniqueName = overload1.qualifiedName(""); + const string cppName = overload1.qualifiedName("::"); mfunctionFile.oss << "function varargout = " << name << "(varargin)\n"; @@ -114,7 +117,7 @@ void GlobalFunction::generateSingleFunction(const std::string& toolboxPath, args.matlab_unwrap(file, 0); // We start at 0 because there is no self object // call method with default type and wrap result - if (returnVal.type1 != "void") + if (returnVal.type1.name != "void") returnVal.wrap_result(cppName + "(" + args.names() + ")", file, typeAttributes); else diff --git a/wrap/GlobalFunction.h b/wrap/GlobalFunction.h index 6c8ad0c86..b31bd313d 100644 --- a/wrap/GlobalFunction.h +++ b/wrap/GlobalFunction.h @@ -16,15 +16,13 @@ namespace wrap { struct GlobalFunction { - typedef std::vector StrVec; - bool verbose_; std::string name; // each overload, regardless of namespace - std::vector argLists; ///< arugments for each overload + std::vector argLists; ///< arugments for each overload std::vector returnVals; ///< returnVals for each overload - std::vector namespaces; ///< Stack of namespaces + std::vector overloads; ///< Stack of qualified names // Constructor only used in Module GlobalFunction(bool verbose = true) : @@ -37,9 +35,8 @@ struct GlobalFunction { } // adds an overloaded version of this function - void addOverload(bool verbose, const std::string& name, - const ArgumentList& args, const ReturnValue& retVal, - const StrVec& ns_stack); + void addOverload(bool verbose, const Qualified& overload, + const ArgumentList& args, const ReturnValue& retVal); // codegen function called from Module to build the cpp and matlab versions of the function void matlab_proxy(const std::string& toolboxPath, diff --git a/wrap/Method.cpp b/wrap/Method.cpp index 7b88b9cdc..6caef52e9 100644 --- a/wrap/Method.cpp +++ b/wrap/Method.cpp @@ -140,15 +140,15 @@ string Method::wrapper_fragment(FileWriter& file, const string& cppClassName, if (returnVal.isPair) { if (returnVal.category1 == ReturnValue::CLASS) file.oss << " typedef boost::shared_ptr<" - << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 + << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1.name << ";" << endl; if (returnVal.category2 == ReturnValue::CLASS) file.oss << " typedef boost::shared_ptr<" - << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 + << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2.name << ";" << endl; } else if (returnVal.category1 == ReturnValue::CLASS) file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") - << "> Shared" << returnVal.type1 << ";" << endl; + << "> Shared" << returnVal.type1.name << ";" << endl; file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl; @@ -168,7 +168,7 @@ string Method::wrapper_fragment(FileWriter& file, const string& cppClassName, // call method and wrap result // example: out[0]=wrap(self->return_field(t)); - if (returnVal.type1 != "void") + if (returnVal.type1.name != "void") returnVal.wrap_result("obj->" + name + "(" + args.names() + ")", file, typeAttributes); else diff --git a/wrap/Module.cpp b/wrap/Module.cpp index f53da6ede..0a3f95292 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -65,8 +65,7 @@ typedef rule Rule; // 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) { + const string& templateArgument, const vector& instantiations) { if (instantiations.empty()) { classes.push_back(cls); } else { @@ -100,8 +99,8 @@ Module::Module(const string& interfacePath, void Module::parseMarkup(const std::string& data) { // these variables will be imperatively updated to gradually build [cls] // The one with postfix 0 are used to reset the variables after parse. - string methodName, methodName0; - bool isConst, isConst0 = false; + string methodName; + bool isConst, isConst0 = false; ReturnValue retVal0, retVal; Argument arg0, arg; ArgumentList args0, args; @@ -144,38 +143,38 @@ void Module::parseMarkup(const std::string& data) { Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p; - Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::"); + Rule namespace_arg_p = namespace_name_p[push_back_a(arg.type.namespaces)] >> str_p("::"); Rule argEigenType_p = - eigenType_p[assign_a(arg.type)]; + eigenType_p[assign_a(arg.type.name)]; Rule eigenRef_p = !str_p("const") [assign_a(arg.is_const,true)] >> - eigenType_p [assign_a(arg.type)] >> + eigenType_p [assign_a(arg.type.name)] >> ch_p('&') [assign_a(arg.is_ref,true)]; Rule classArg_p = !str_p("const") [assign_a(arg.is_const,true)] >> *namespace_arg_p >> - className_p[assign_a(arg.type)] >> + className_p[assign_a(arg.type.name)] >> !ch_p('&')[assign_a(arg.is_ref,true)]; Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')]; Rule classParent_p = - *(namespace_name_p[push_back_a(cls.qualifiedParent)] >> str_p("::")) >> - className_p[push_back_a(cls.qualifiedParent)]; + *(namespace_name_p[push_back_a(cls.qualifiedParent.namespaces)] >> str_p("::")) >> + className_p[assign_a(cls.qualifiedParent.name)]; // TODO: get rid of copy/paste below? // parse "gtsam::Pose2" and add to templateInstantiations - vector templateArgumentValue; - vector > templateInstantiations; + Qualified argValue; + vector templateInstantiations; Rule templateInstantiation_p = - (*(namespace_name_p[push_back_a(templateArgumentValue)] >> str_p("::")) >> - className_p[push_back_a(templateArgumentValue)]) - [push_back_a(templateInstantiations, templateArgumentValue)] - [clear_a(templateArgumentValue)]; + (*(namespace_name_p[push_back_a(argValue.namespaces)] >> str_p("::")) >> + className_p[assign_a(argValue.name)]) + [push_back_a(templateInstantiations, argValue)] + [clear_a(argValue)]; // template string templateArgument; @@ -187,12 +186,12 @@ void Module::parseMarkup(const std::string& data) { [push_back_a(cls.templateArgs, templateArgument)]; // parse "gtsam::Pose2" and add to methodInstantiations - vector > 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)]; + (*(namespace_name_p[push_back_a(argValue.namespaces)] >> str_p("::")) >> + className_p[assign_a(argValue.name)]) + [push_back_a(methodInstantiations, argValue)] + [clear_a(argValue)]; // template string methodArgument; @@ -205,17 +204,17 @@ void Module::parseMarkup(const std::string& data) { // parse "gtsam::Pose2" and add to singleInstantiation.typeList TemplateInstantiationTypedef singleInstantiation; Rule templateSingleInstantiationArg_p = - (*(namespace_name_p[push_back_a(templateArgumentValue)] >> str_p("::")) >> - className_p[push_back_a(templateArgumentValue)]) - [push_back_a(singleInstantiation.typeList, templateArgumentValue)] - [clear_a(templateArgumentValue)]; + (*(namespace_name_p[push_back_a(argValue.namespaces)] >> str_p("::")) >> + className_p[assign_a(argValue.name)]) + [push_back_a(singleInstantiation.typeList, argValue)] + [clear_a(argValue)]; // typedef gtsam::RangeFactor RangeFactorPosePoint2; TemplateInstantiationTypedef singleInstantiation0; Rule templateSingleInstantiation_p = (str_p("typedef") >> - *(namespace_name_p[push_back_a(singleInstantiation.classNamespaces)] >> str_p("::")) >> - className_p[assign_a(singleInstantiation.className)] >> + *(namespace_name_p[push_back_a(singleInstantiation.class_.namespaces)] >> str_p("::")) >> + className_p[assign_a(singleInstantiation.class_.name)] >> '<' >> templateSingleInstantiationArg_p >> *(',' >> templateSingleInstantiationArg_p) >> '>' >> className_p[assign_a(singleInstantiation.name)] >> @@ -232,7 +231,7 @@ void Module::parseMarkup(const std::string& data) { // NOTE: allows for pointers to all types Rule argument_p = - ((basisType_p[assign_a(arg.type)] | argEigenType_p | eigenRef_p | classArg_p) + ((basisType_p[assign_a(arg.type.name)] | argEigenType_p | eigenRef_p | classArg_p) >> !ch_p('*')[assign_a(arg.is_ptr,true)] >> name_p[assign_a(arg.name)]) [push_back_a(args, arg)] @@ -258,24 +257,24 @@ void Module::parseMarkup(const std::string& data) { static const ReturnValue::return_category RETURN_VOID = ReturnValue::VOID; Rule returnType1_p = - (basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, RETURN_BASIS)]) | - ((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)] - >> (className_p[assign_a(retVal.type1)][assign_a(retVal.category1, RETURN_CLASS)]) >> + (basisType_p[assign_a(retVal.type1.name)][assign_a(retVal.category1, RETURN_BASIS)]) | + ((*namespace_ret_p)[assign_a(retVal.type1.namespaces, namespaces_return)][clear_a(namespaces_return)] + >> (className_p[assign_a(retVal.type1.name)][assign_a(retVal.category1, RETURN_CLASS)]) >> !ch_p('*')[assign_a(retVal.isPtr1,true)]) | - (eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, RETURN_EIGEN)]); + (eigenType_p[assign_a(retVal.type1.name)][assign_a(retVal.category1, RETURN_EIGEN)]); Rule returnType2_p = - (basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, RETURN_BASIS)]) | - ((*namespace_ret_p)[assign_a(retVal.namespaces2, namespaces_return)][clear_a(namespaces_return)] - >> (className_p[assign_a(retVal.type2)][assign_a(retVal.category2, RETURN_CLASS)]) >> + (basisType_p[assign_a(retVal.type2.name)][assign_a(retVal.category2, RETURN_BASIS)]) | + ((*namespace_ret_p)[assign_a(retVal.type2.namespaces, namespaces_return)][clear_a(namespaces_return)] + >> (className_p[assign_a(retVal.type2.name)][assign_a(retVal.category2, RETURN_CLASS)]) >> !ch_p('*') [assign_a(retVal.isPtr2,true)]) | - (eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, RETURN_EIGEN)]); + (eigenType_p[assign_a(retVal.type2.name)][assign_a(retVal.category2, RETURN_EIGEN)]); Rule pair_p = (str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>') [assign_a(retVal.isPair,true)]; - Rule void_p = str_p("void")[assign_a(retVal.type1)][assign_a(retVal.category1, RETURN_VOID)]; + Rule void_p = str_p("void")[assign_a(retVal.type1.name)][assign_a(retVal.category1, RETURN_VOID)]; Rule returnType_p = void_p | pair_p | returnType1_p; @@ -295,7 +294,7 @@ void Module::parseMarkup(const std::string& data) { bl::var(args), bl::var(retVal))] [assign_a(isConst,isConst0)] - [assign_a(methodName,methodName0)] + [clear_a(methodName)] [assign_a(args,args0)] [assign_a(retVal,retVal0)]; @@ -310,7 +309,7 @@ void Module::parseMarkup(const std::string& data) { bl::var(methodName), bl::var(args), bl::var(retVal))] - [assign_a(methodName,methodName0)] + [clear_a(methodName)] [assign_a(args,args0)] [assign_a(retVal,retVal0)]; @@ -337,17 +336,18 @@ void Module::parseMarkup(const std::string& data) { [clear_a(templateArgument)] [clear_a(templateInstantiations)]; + Qualified globalFunction; Rule global_function_p = - (returnType_p >> staticMethodName_p[assign_a(methodName)] >> + (returnType_p >> staticMethodName_p[assign_a(globalFunction.name)] >> '(' >> argumentList_p >> ')' >> ';' >> *comments_p) + [assign_a(globalFunction.namespaces,namespaces)] [bl::bind(&GlobalFunction::addOverload, - bl::var(global_functions)[bl::var(methodName)], + bl::var(global_functions)[bl::var(globalFunction.name)], verbose, - bl::var(methodName), + bl::var(globalFunction), bl::var(args), - bl::var(retVal), - bl::var(namespaces))] - [assign_a(methodName,methodName0)] + bl::var(retVal))] + [clear_a(globalFunction)] [assign_a(args,args0)] [assign_a(retVal,retVal0)]; @@ -457,7 +457,7 @@ void verifyArguments(const vector& validArgs, const map& vt) { const T& t = name_method.second; BOOST_FOREACH(const ArgumentList& argList, t.argLists) { BOOST_FOREACH(Argument arg, argList) { - string fullType = arg.qualifiedType("::"); + string fullType = arg.type.qualifiedName("::"); if(find(validArgs.begin(), validArgs.end(), fullType) == validArgs.end()) throw DependencyMissing(fullType, t.name); @@ -528,8 +528,9 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co verifyReturnTypes(validTypes, cls.methods); // verify parents - if(!cls.qualifiedParent.empty() && std::find(validTypes.begin(), validTypes.end(), wrap::qualifiedName("::", cls.qualifiedParent)) == validTypes.end()) - throw DependencyMissing(wrap::qualifiedName("::", cls.qualifiedParent), cls.qualifiedName("::")); + Qualified parent = cls.qualifiedParent; + if(!parent.empty() && std::find(validTypes.begin(), validTypes.end(), parent.qualifiedName("::")) == validTypes.end()) + throw DependencyMissing(parent.qualifiedName("::"), cls.qualifiedName("::")); } // Create type attributes table and check validity @@ -606,7 +607,7 @@ map Module::appendInheretedMethods(const Class& cls, const vecto //Find Class BOOST_FOREACH(const Class& parent, classes) { //We found the class for our parent - if(parent.name == cls.qualifiedParent.back()) + if(parent.name == cls.qualifiedParent.name) { Methods inhereted = appendInheretedMethods(parent, classes); methods.insert(inhereted.begin(), inhereted.end()); diff --git a/wrap/Qualified.h b/wrap/Qualified.h new file mode 100644 index 000000000..b92d6dace --- /dev/null +++ b/wrap/Qualified.h @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- + + * 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 Qualified.h + * @brief Qualified name + * @author Frank Dellaert + * @date Nov 11, 2014 + **/ + +#pragma once + +#include +#include + +namespace wrap { + +/** + * Class to encapuslate a qualified name, i.e., with (nested) namespaces + */ +struct Qualified { + + std::vector namespaces; ///< Stack of namespaces + std::string name; ///< type name + + bool empty() const { + return namespaces.empty() && name.empty(); + } + + void clear() { + namespaces.clear(); + name.clear(); + } + + /// Return a qualified string using given delimiter + std::string qualifiedName(const std::string& delimiter = "") const { + std::string result; + for (std::size_t i = 0; i < namespaces.size(); ++i) + result += (namespaces[i] + delimiter); + result += name; + return result; + } + + /// Return a matlab file name, i.e. "toolboxPath/+ns1/+ns2/name.m" + std::string matlabName(const std::string& toolboxPath) const { + std::string result = toolboxPath; + for (std::size_t i = 0; i < namespaces.size(); ++i) + result += ("/+" + namespaces[i]); + result += "/" + name + ".m"; + return result; + } + +}; + +} // \namespace wrap + diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index 78e36d4da..87d49de6a 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -17,13 +17,17 @@ using namespace wrap; /* ************************************************************************* */ string ReturnValue::return_type(bool add_ptr, pairing p) const { - if (p==pair && isPair) { - string str = "pair< " + - maybe_shared_ptr(add_ptr || isPtr1, qualifiedType1("::"), type1) + ", " + - maybe_shared_ptr(add_ptr || isPtr2, qualifiedType2("::"), type2) + " >"; + if (p == pair && isPair) { + string str = "pair< " + + maybe_shared_ptr(add_ptr || isPtr1, qualifiedType1("::"), type1.name) + + ", " + + maybe_shared_ptr(add_ptr || isPtr2, qualifiedType2("::"), type2.name) + + " >"; return str; } else - return maybe_shared_ptr(add_ptr && isPtr1, (p==arg2)? qualifiedType2("::") : qualifiedType1("::"), (p==arg2)? type2 : type1); + return maybe_shared_ptr(add_ptr && isPtr1, + (p == arg2) ? qualifiedType2("::") : qualifiedType1("::"), + (p == arg2) ? type2.name : type1.name); } /* ************************************************************************* */ @@ -33,16 +37,12 @@ string ReturnValue::matlab_returnType() const { /* ************************************************************************* */ string ReturnValue::qualifiedType1(const string& delim) const { - string result; - BOOST_FOREACH(const string& ns, namespaces1) result += ns + delim; - return result + type1; + return type1.qualifiedName(delim); } /* ************************************************************************* */ string ReturnValue::qualifiedType2(const string& delim) const { - string result; - BOOST_FOREACH(const string& ns, namespaces2) result += ns + delim; - return result + type2; + return type2.qualifiedName(delim); } /* ************************************************************************* */ @@ -58,7 +58,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type // first return value in pair if (category1 == ReturnValue::CLASS) { // if we are going to make one string objCopy, ptrType; - ptrType = "Shared" + type1; + ptrType = "Shared" + type1.name; const bool isVirtual = typeAttributes.at(cppType1).isVirtual; if(isVirtual) { if(isPtr1) @@ -73,7 +73,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type } file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n"; } else if(isPtr1) { - file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(pairResult.first);" << endl; + file.oss << " Shared" << type1.name <<"* ret = new Shared" << type1.name << "(pairResult.first);" << endl; file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\", false);\n"; } else // if basis type file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(pairResult.first);\n"; @@ -81,7 +81,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type // second return value in pair if (category2 == ReturnValue::CLASS) { // if we are going to make one string objCopy, ptrType; - ptrType = "Shared" + type2; + ptrType = "Shared" + type2.name; const bool isVirtual = typeAttributes.at(cppType2).isVirtual; if(isVirtual) { if(isPtr2) @@ -96,7 +96,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type } file.oss << " out[1] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType2 << "\", " << (isVirtual ? "true" : "false") << ");\n"; } else if(isPtr2) { - file.oss << " Shared" << type2 <<"* ret = new Shared" << type2 << "(pairResult.second);" << endl; + file.oss << " Shared" << type2.name <<"* ret = new Shared" << type2.name << "(pairResult.second);" << endl; file.oss << " out[1] = wrap_shared_ptr(ret,\"" << matlabType2 << "\");\n"; } else file.oss << " out[1] = wrap< " << return_type(true,arg2) << " >(pairResult.second);\n"; @@ -104,7 +104,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type if (category1 == ReturnValue::CLASS) { string objCopy, ptrType; - ptrType = "Shared" + type1; + ptrType = "Shared" + type1.name; const bool isVirtual = typeAttributes.at(cppType1).isVirtual; if(isVirtual) { if(isPtr1) @@ -119,7 +119,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type } file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n"; } else if(isPtr1) { - file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(" << result << ");" << endl; + file.oss << " Shared" << type1.name <<"* ret = new Shared" << type1.name << "(" << result << ");" << endl; file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\");\n"; } else if (matlabType1!="void") file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ");\n"; @@ -131,13 +131,13 @@ void ReturnValue::wrapTypeUnwrap(FileWriter& wrapperFile) const { if(isPair) { if(category1 == ReturnValue::CLASS) - wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType1("::") << "> Shared" << type1 << ";"<< endl; + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType1("::") << "> Shared" << type1.name << ";"<< endl; if(category2 == ReturnValue::CLASS) - wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType2("::") << "> Shared" << type2 << ";"<< endl; + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType2("::") << "> Shared" << type2.name << ";"<< endl; } else { if (category1 == ReturnValue::CLASS) - wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType1("::") << "> Shared" << type1 << ";"<< endl; + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType1("::") << "> Shared" << type1.name << ";"<< endl; } } /* ************************************************************************* */ diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index 989f81109..838946d49 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -10,8 +10,7 @@ #include "FileWriter.h" #include "TypeAttributesTable.h" - -#include +#include "Qualified.h" #pragma once @@ -29,8 +28,7 @@ struct ReturnValue { bool isPtr1, isPtr2, isPair; return_category category1, category2; - std::string type1, type2; - std::vector namespaces1, namespaces2; + Qualified type1, type2; /// Constructor ReturnValue() : diff --git a/wrap/StaticMethod.cpp b/wrap/StaticMethod.cpp index 0c4cc7d75..5b88034d2 100644 --- a/wrap/StaticMethod.cpp +++ b/wrap/StaticMethod.cpp @@ -131,7 +131,7 @@ string StaticMethod::wrapper_fragment(FileWriter& file, args.matlab_unwrap(file, 0); // We start at 0 because there is no self object // call method with default type and wrap result - if (returnVal.type1 != "void") + if (returnVal.type1.name != "void") returnVal.wrap_result(cppClassName + "::" + name + "(" + args.names() + ")", file, typeAttributes); else diff --git a/wrap/TemplateInstantiationTypedef.cpp b/wrap/TemplateInstantiationTypedef.cpp index 85615cef4..b93a05a54 100644 --- a/wrap/TemplateInstantiationTypedef.cpp +++ b/wrap/TemplateInstantiationTypedef.cpp @@ -19,43 +19,48 @@ #include "TemplateInstantiationTypedef.h" #include "utilities.h" +#include +#include +#include using namespace std; namespace wrap { - Class TemplateInstantiationTypedef::findAndExpand(const vector& classes) const { - // Find matching class - std::vector::const_iterator clsIt = classes.end(); - for(std::vector::const_iterator it = classes.begin(); it != classes.end(); ++it) { - if(it->name == className && it->namespaces == classNamespaces && it->templateArgs.size() == typeList.size()) { - clsIt = it; - break; - } +Class TemplateInstantiationTypedef::findAndExpand( + const vector& classes) const { + // Find matching class + boost::optional matchedClass; + BOOST_FOREACH(const Class& cls, classes) { + if (cls.name == class_.name && cls.namespaces == class_.namespaces + && cls.templateArgs.size() == typeList.size()) { + matchedClass.reset(cls); + break; } - - if(clsIt == classes.end()) - throw DependencyMissing(wrap::qualifiedName("::", classNamespaces, className), - "instantiation into typedef name " + wrap::qualifiedName("::", namespaces, name) + - ". Ensure that the typedef provides the correct number of template arguments."); - - // Instantiate it - Class classInst = *clsIt; - for(size_t i = 0; i < typeList.size(); ++i) - classInst = classInst.expandTemplate(classInst.templateArgs[i], typeList[i], namespaces, name); - - // Fix class properties - classInst.name = name; - classInst.templateArgs.clear(); - classInst.typedefName = clsIt->qualifiedName("::") + "<"; - if(typeList.size() > 0) - classInst.typedefName += wrap::qualifiedName("::", typeList[0]); - for(size_t i = 1; i < typeList.size(); ++i) - classInst.typedefName += (", " + wrap::qualifiedName("::", typeList[i])); - classInst.typedefName += ">"; - classInst.namespaces = namespaces; - - return classInst; } -} \ No newline at end of file + if (!matchedClass) + throw DependencyMissing(class_.qualifiedName("::"), + "instantiation into typedef name " + qualifiedName("::") + + ". Ensure that the typedef provides the correct number of template arguments."); + + // Instantiate it + Class classInst = *matchedClass; + for (size_t i = 0; i < typeList.size(); ++i) + classInst = classInst.expandTemplate(classInst.templateArgs[i], typeList[i], *this); + + // Fix class properties + classInst.name = name; + classInst.templateArgs.clear(); + classInst.typedefName = matchedClass->qualifiedName("::") + "<"; + if (typeList.size() > 0) + classInst.typedefName += typeList[0].qualifiedName("::"); + for (size_t i = 1; i < typeList.size(); ++i) + classInst.typedefName += (", " + typeList[i].qualifiedName("::")); + classInst.typedefName += ">"; + classInst.namespaces = namespaces; + + return classInst; +} + +} diff --git a/wrap/TemplateInstantiationTypedef.h b/wrap/TemplateInstantiationTypedef.h index 2292f16ee..2a08d7a94 100644 --- a/wrap/TemplateInstantiationTypedef.h +++ b/wrap/TemplateInstantiationTypedef.h @@ -26,14 +26,11 @@ namespace wrap { -struct TemplateInstantiationTypedef { - std::vector classNamespaces; - std::string className; - std::vector namespaces; - std::string name; - std::vector > typeList; +struct TemplateInstantiationTypedef : public Qualified { + Qualified class_; + std::vector typeList; Class findAndExpand(const std::vector& classes) const; }; -} \ No newline at end of file +} diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index 8edb75767..a534bd1a8 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -48,9 +48,9 @@ static const std::string headerPath = "/not_really_a_real_path/borg/gtsam/wrap"; /* ************************************************************************* */ TEST( wrap, ArgumentList ) { ArgumentList args; - Argument arg1; arg1.type = "double"; arg1.name = "x"; - Argument arg2; arg2.type = "double"; arg2.name = "y"; - Argument arg3; arg3.type = "double"; arg3.name = "z"; + Argument arg1; arg1.type.name = "double"; arg1.name = "x"; + Argument arg2; arg2.type.name = "double"; arg2.name = "y"; + Argument arg3; arg3.type.name = "double"; arg3.name = "z"; args.push_back(arg1); args.push_back(arg2); args.push_back(arg3); @@ -105,7 +105,7 @@ TEST( wrap, small_parse ) { ReturnValue rv1 = m1.returnVals.front(); EXPECT(!rv1.isPair); EXPECT(!rv1.isPtr1); - EXPECT(assert_equal("double", rv1.type1)); + EXPECT(assert_equal("double", rv1.type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::BASIS, rv1.category1); // Method 2 @@ -118,7 +118,7 @@ TEST( wrap, small_parse ) { ReturnValue rv2 = m2.returnVals.front(); EXPECT(!rv2.isPair); EXPECT(!rv2.isPtr1); - EXPECT(assert_equal("Matrix", rv2.type1)); + EXPECT(assert_equal("Matrix", rv2.type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv2.category1); // Method 3 @@ -131,7 +131,7 @@ TEST( wrap, small_parse ) { ReturnValue rv3 = m3.returnVals.front(); EXPECT(!rv3.isPair); EXPECT(!rv3.isPtr1); - EXPECT(assert_equal("Point2", rv3.type1)); + EXPECT(assert_equal("Point2", rv3.type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::CLASS, rv3.category1); // Static Method 1 @@ -144,7 +144,7 @@ TEST( wrap, small_parse ) { ReturnValue rv4 = sm1.returnVals.front(); EXPECT(!rv4.isPair); EXPECT(!rv4.isPtr1); - EXPECT(assert_equal("Vector", rv4.type1)); + EXPECT(assert_equal("Vector", rv4.type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv4.category1); } @@ -196,7 +196,7 @@ TEST( wrap, parse_geometry ) { CHECK(cls.methods.find("returnChar") != cls.methods.end()); Method m1 = cls.methods.find("returnChar")->second; LONGS_EQUAL(1, m1.returnVals.size()); - EXPECT(assert_equal("char", m1.returnVals.front().type1)); + EXPECT(assert_equal("char", m1.returnVals.front().type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::BASIS, m1.returnVals.front().category1); EXPECT(!m1.returnVals.front().isPair); EXPECT(assert_equal("returnChar", m1.name)); @@ -210,7 +210,7 @@ TEST( wrap, parse_geometry ) { CHECK(cls.methods.find("vectorConfusion") != cls.methods.end()); Method m1 = cls.methods.find("vectorConfusion")->second; LONGS_EQUAL(1, m1.returnVals.size()); - EXPECT(assert_equal("VectorNotEigen", m1.returnVals.front().type1)); + EXPECT(assert_equal("VectorNotEigen", m1.returnVals.front().type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::CLASS, m1.returnVals.front().category1); EXPECT(!m1.returnVals.front().isPair); EXPECT(assert_equal("vectorConfusion", m1.name)); @@ -245,7 +245,7 @@ TEST( wrap, parse_geometry ) { // check first double argument Argument a1 = c1.front(); EXPECT(!a1.is_const); - EXPECT(assert_equal("double", a1.type)); + EXPECT(assert_equal("double", a1.type.name)); EXPECT(!a1.is_ref); EXPECT(assert_equal("x", a1.name)); @@ -253,7 +253,7 @@ TEST( wrap, parse_geometry ) { CHECK(cls.methods.find("norm") != cls.methods.end()); Method m1 = cls.methods.find("norm")->second; LONGS_EQUAL(1, m1.returnVals.size()); - EXPECT(assert_equal("double", m1.returnVals.front().type1)); + EXPECT(assert_equal("double", m1.returnVals.front().type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::BASIS, m1.returnVals.front().category1); EXPECT(assert_equal("norm", m1.name)); LONGS_EQUAL(1, m1.argLists.size()); @@ -281,9 +281,9 @@ TEST( wrap, parse_geometry ) { LONGS_EQUAL(1, m2.returnVals.size()); EXPECT(m2.returnVals.front().isPair); EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, m2.returnVals.front().category1); - EXPECT(assert_equal("Vector", m2.returnVals.front().type1)); + EXPECT(assert_equal("Vector", m2.returnVals.front().type1.name)); EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, m2.returnVals.front().category2); - EXPECT(assert_equal("Matrix", m2.returnVals.front().type2)); + EXPECT(assert_equal("Matrix", m2.returnVals.front().type2.name)); // checking pointer args and return values // pair return_ptrs (Test* p1, Test* p2) const; @@ -297,17 +297,17 @@ TEST( wrap, parse_geometry ) { EXPECT(arg1.is_ptr); EXPECT(!arg1.is_const); EXPECT(!arg1.is_ref); - EXPECT(assert_equal("Test", arg1.type)); + EXPECT(assert_equal("Test", arg1.type.name)); EXPECT(assert_equal("p1", arg1.name)); - EXPECT(arg1.namespaces.empty()); + EXPECT(arg1.type.namespaces.empty()); Argument arg2 = args.at(1); EXPECT(arg2.is_ptr); EXPECT(!arg2.is_const); EXPECT(!arg2.is_ref); - EXPECT(assert_equal("Test", arg2.type)); + EXPECT(assert_equal("Test", arg2.type.name)); EXPECT(assert_equal("p2", arg2.name)); - EXPECT(arg2.namespaces.empty()); + EXPECT(arg2.type.namespaces.empty()); } // evaluate global functions @@ -318,10 +318,10 @@ TEST( wrap, parse_geometry ) { GlobalFunction gfunc = module.global_functions.at("aGlobalFunction"); EXPECT(assert_equal("aGlobalFunction", gfunc.name)); LONGS_EQUAL(1, gfunc.returnVals.size()); - EXPECT(assert_equal("Vector", gfunc.returnVals.front().type1)); + EXPECT(assert_equal("Vector", gfunc.returnVals.front().type1.name)); EXPECT_LONGS_EQUAL(1, gfunc.argLists.size()); - LONGS_EQUAL(1, gfunc.namespaces.size()); - EXPECT(gfunc.namespaces.front().empty()); + LONGS_EQUAL(1, gfunc.overloads.size()); + EXPECT(gfunc.overloads.front().namespaces.empty()); } } @@ -392,16 +392,16 @@ TEST( wrap, parse_namespaces ) { GlobalFunction gfunc = module.global_functions.at("aGlobalFunction"); EXPECT(assert_equal("aGlobalFunction", gfunc.name)); LONGS_EQUAL(2, gfunc.returnVals.size()); - EXPECT(assert_equal("Vector", gfunc.returnVals.front().type1)); + EXPECT(assert_equal("Vector", gfunc.returnVals.front().type1.name)); EXPECT_LONGS_EQUAL(2, gfunc.argLists.size()); // check namespaces - LONGS_EQUAL(2, gfunc.namespaces.size()); + LONGS_EQUAL(2, gfunc.overloads.size()); strvec exp_namespaces1; exp_namespaces1 += "ns1"; - EXPECT(assert_equal(exp_namespaces1, gfunc.namespaces.at(0))); + EXPECT(assert_equal(exp_namespaces1, gfunc.overloads.at(0).namespaces)); strvec exp_namespaces2; exp_namespaces2 += "ns2"; - EXPECT(assert_equal(exp_namespaces2, gfunc.namespaces.at(1))); + EXPECT(assert_equal(exp_namespaces2, gfunc.overloads.at(1).namespaces)); } } diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index 47f7d10a6..4bd757d15 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -118,23 +118,19 @@ string maybe_shared_ptr(bool add, const string& qtype, const string& type) { } /* ************************************************************************* */ -string qualifiedName(const string& separator, const vector& names, const string& finalName) { +string qualifiedName(const string& separator, const vector& names) { string result; - if(!names.empty()) { - for(size_t i = 0; i < names.size() - 1; ++i) + if (!names.empty()) { + for (size_t i = 0; i < names.size() - 1; ++i) result += (names[i] + separator); - if(finalName.empty()) - result += names.back(); - else - result += (names.back() + separator + finalName); - } else if(!finalName.empty()) { - result = finalName; + result += names.back(); } return result; } /* ************************************************************************* */ -void createNamespaceStructure(const std::vector& namespaces, const std::string& toolboxPath) { +void createNamespaceStructure(const std::vector& namespaces, + const std::string& toolboxPath) { using namespace boost::filesystem; path curPath = toolboxPath; BOOST_FOREACH(const string& subdir, namespaces) { diff --git a/wrap/utilities.h b/wrap/utilities.h index 7280dd297..fe146dd04 100644 --- a/wrap/utilities.h +++ b/wrap/utilities.h @@ -123,12 +123,12 @@ bool assert_equal(const std::vector& expected, const std::vector& names, const std::string& finalName = ""); +std::string qualifiedName(const std::string& separator, const std::vector& names); /** creates the necessary folders for namespaces, as specified by a namespace stack */ -void createNamespaceStructure(const std::vector& namespaces, const std::string& toolboxPath); +void createNamespaceStructure(const std::vector& namespaces, + const std::string& toolboxPath); } // \namespace wrap