From 87d1e0a488603d8b1d87965fd63991c8222f5afc Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Mon, 23 Jul 2012 21:27:36 +0000 Subject: [PATCH] Added 'This' keyword in wrap templates to substitute instantiated class --- gtsam.h | 3 +++ wrap/Class.cpp | 32 ++++++++++++++++++--------- wrap/Class.h | 2 +- wrap/TemplateInstantiationTypedef.cpp | 2 +- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/gtsam.h b/gtsam.h index b13bcb092..4e1437f06 100644 --- a/gtsam.h +++ b/gtsam.h @@ -66,6 +66,9 @@ * or with typedefs, e.g. * template class Class2 { ... }; * typedef Class2 MyInstantiatedClass; + * - In the class definition, appearances of the template argument(s) will be replaced with their + * instantiated types, e.g. 'void setValue(const T& value);'. + * - To refer to the instantiation of the template class itself, use 'This', i.e. 'static This Create();' * - To create new instantiations in other modules, you must copy-and-paste the whole class definition * into the new module, but use only your new instantiation types. * - When forward-declaring template instantiations, use the generated/typedefed name, e.g. diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 00fdba011..c1fac2c0b 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -217,7 +217,7 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& wra } /* ************************************************************************* */ -vector expandArgumentListsTemplate(const vector& argLists, const string& templateArg, const vector& instName) { +vector expandArgumentListsTemplate(const vector& argLists, const string& templateArg, const vector& instName, const std::vector& expandedClassNamespace, const string& expandedClassName) { vector result; BOOST_FOREACH(const ArgumentList& argList, argLists) { ArgumentList instArgList; @@ -226,6 +226,9 @@ vector expandArgumentListsTemplate(const vector& 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; } instArgList.push_back(instArg); } @@ -236,23 +239,29 @@ vector expandArgumentListsTemplate(const vector& arg /* ************************************************************************* */ template -map expandMethodTemplate(const map& methods, const string& templateArg, const vector& instName) { +map expandMethodTemplate(const map& methods, const string& templateArg, const vector& instName, const std::vector& expandedClassNamespace, const string& expandedClassName) { 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); + instMethod.argLists = expandArgumentListsTemplate(method.argLists, templateArg, instName, expandedClassNamespace, expandedClassName); 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.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; } instMethod.returnVals.push_back(instRetVal); } @@ -262,18 +271,18 @@ map expandMethodTemplate(const map& methods, con } /* ************************************************************************* */ -Class expandClassTemplate(const Class& cls, const string& templateArg, const vector& instName) { +Class expandClassTemplate(const Class& cls, const string& templateArg, const vector& instName, const std::vector& expandedClassNamespace, const string& expandedClassName) { Class inst; inst.name = cls.name; inst.templateArgs = cls.templateArgs; inst.typedefName = cls.typedefName; inst.isVirtual = cls.isVirtual; inst.qualifiedParent = cls.qualifiedParent; - inst.methods = expandMethodTemplate(cls.methods, templateArg, instName); - inst.static_methods = expandMethodTemplate(cls.static_methods, templateArg, instName); + inst.methods = expandMethodTemplate(cls.methods, templateArg, instName, expandedClassNamespace, expandedClassName); + inst.static_methods = expandMethodTemplate(cls.static_methods, templateArg, instName, expandedClassNamespace, expandedClassName); inst.namespaces = cls.namespaces; inst.constructor = cls.constructor; - inst.constructor.args_list = expandArgumentListsTemplate(cls.constructor.args_list, templateArg, instName); + inst.constructor.args_list = expandArgumentListsTemplate(cls.constructor.args_list, templateArg, instName, expandedClassNamespace, expandedClassName); inst.constructor.name = inst.name; inst.deconstructor = cls.deconstructor; inst.deconstructor.name = inst.name; @@ -285,8 +294,9 @@ Class expandClassTemplate(const Class& cls, const string& templateArg, const vec vector Class::expandTemplate(const string& templateArg, const vector >& instantiations) const { vector result; BOOST_FOREACH(const vector& instName, instantiations) { - Class inst = expandClassTemplate(*this, templateArg, instName); - inst.name = name + instName.back(); + const string expandedName = name + instName.back(); + Class inst = expandClassTemplate(*this, templateArg, instName, this->namespaces, expandedName); + inst.name = expandedName; inst.templateArgs.clear(); inst.typedefName = qualifiedName("::") + "<" + wrap::qualifiedName("::", instName) + ">"; result.push_back(inst); @@ -295,8 +305,8 @@ vector Class::expandTemplate(const string& templateArg, const vector& instantiation) const { - return expandClassTemplate(*this, templateArg, instantiation); +Class Class::expandTemplate(const string& templateArg, const vector& instantiation, const std::vector& expandedClassNamespace, const string& expandedClassName) const { + return expandClassTemplate(*this, templateArg, instantiation, expandedClassNamespace, expandedClassName); } /* ************************************************************************* */ diff --git a/wrap/Class.h b/wrap/Class.h index 2d10d691a..6b60f8219 100644 --- a/wrap/Class.h +++ b/wrap/Class.h @@ -57,7 +57,7 @@ struct Class { std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter std::vector expandTemplate(const std::string& templateArg, const std::vector >& instantiations) const; - Class expandTemplate(const std::string& templateArg, const std::vector& instantiation) const; + Class expandTemplate(const std::string& templateArg, const std::vector& instantiation, const std::vector& expandedClassNamespace, const std::string& expandedClassName) 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/TemplateInstantiationTypedef.cpp b/wrap/TemplateInstantiationTypedef.cpp index da1e8f616..b822f732b 100644 --- a/wrap/TemplateInstantiationTypedef.cpp +++ b/wrap/TemplateInstantiationTypedef.cpp @@ -42,7 +42,7 @@ namespace wrap { // Instantiate it Class classInst = *clsIt; for(size_t i = 0; i < typeList.size(); ++i) - classInst = classInst.expandTemplate(classInst.templateArgs[i], typeList[i]); + classInst = classInst.expandTemplate(classInst.templateArgs[i], typeList[i], namespaces, name); // Fix class properties classInst.name = name;