Added 'This' keyword in wrap templates to substitute instantiated class

release/4.3a0
Richard Roberts 2012-07-23 21:27:36 +00:00
parent 415881e0e6
commit 87d1e0a488
4 changed files with 26 additions and 13 deletions

View File

@ -66,6 +66,9 @@
* or with typedefs, e.g. * or with typedefs, e.g.
* template<T, U> class Class2 { ... }; * template<T, U> class Class2 { ... };
* typedef Class2<Type1, Type2> MyInstantiatedClass; * typedef Class2<Type1, Type2> 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 * - 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. * into the new module, but use only your new instantiation types.
* - When forward-declaring template instantiations, use the generated/typedefed name, e.g. * - When forward-declaring template instantiations, use the generated/typedefed name, e.g.

View File

@ -217,7 +217,7 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& wra
} }
/* ************************************************************************* */ /* ************************************************************************* */
vector<ArgumentList> expandArgumentListsTemplate(const vector<ArgumentList>& argLists, const string& templateArg, const vector<string>& instName) { vector<ArgumentList> expandArgumentListsTemplate(const vector<ArgumentList>& argLists, const string& templateArg, const vector<string>& instName, const std::vector<string>& expandedClassNamespace, const string& expandedClassName) {
vector<ArgumentList> result; vector<ArgumentList> result;
BOOST_FOREACH(const ArgumentList& argList, argLists) { BOOST_FOREACH(const ArgumentList& argList, argLists) {
ArgumentList instArgList; ArgumentList instArgList;
@ -226,6 +226,9 @@ vector<ArgumentList> expandArgumentListsTemplate(const vector<ArgumentList>& arg
if(arg.type == templateArg) { if(arg.type == templateArg) {
instArg.namespaces.assign(instName.begin(), instName.end()-1); instArg.namespaces.assign(instName.begin(), instName.end()-1);
instArg.type = instName.back(); instArg.type = instName.back();
} else if(arg.type == "This") {
instArg.namespaces.assign(expandedClassNamespace.begin(), expandedClassNamespace.end());
instArg.type = expandedClassName;
} }
instArgList.push_back(instArg); instArgList.push_back(instArg);
} }
@ -236,23 +239,29 @@ vector<ArgumentList> expandArgumentListsTemplate(const vector<ArgumentList>& arg
/* ************************************************************************* */ /* ************************************************************************* */
template<class METHOD> template<class METHOD>
map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods, const string& templateArg, const vector<string>& instName) { map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods, const string& templateArg, const vector<string>& instName, const std::vector<string>& expandedClassNamespace, const string& expandedClassName) {
map<string, METHOD> result; map<string, METHOD> result;
typedef pair<const string, METHOD> Name_Method; typedef pair<const string, METHOD> Name_Method;
BOOST_FOREACH(const Name_Method& name_method, methods) { BOOST_FOREACH(const Name_Method& name_method, methods) {
const METHOD& method = name_method.second; const METHOD& method = name_method.second;
METHOD instMethod = method; METHOD instMethod = method;
instMethod.argLists = expandArgumentListsTemplate(method.argLists, templateArg, instName); instMethod.argLists = expandArgumentListsTemplate(method.argLists, templateArg, instName, expandedClassNamespace, expandedClassName);
instMethod.returnVals.clear(); instMethod.returnVals.clear();
BOOST_FOREACH(const ReturnValue& retVal, method.returnVals) { BOOST_FOREACH(const ReturnValue& retVal, method.returnVals) {
ReturnValue instRetVal = retVal; ReturnValue instRetVal = retVal;
if(retVal.type1 == templateArg) { if(retVal.type1 == templateArg) {
instRetVal.namespaces1.assign(instName.begin(), instName.end()-1); instRetVal.namespaces1.assign(instName.begin(), instName.end()-1);
instRetVal.type1 = instName.back(); instRetVal.type1 = instName.back();
} else if(retVal.type1 == "This") {
instRetVal.namespaces1.assign(expandedClassNamespace.begin(), expandedClassNamespace.end());
instRetVal.type1 = expandedClassName;
} }
if(retVal.type2 == templateArg) { if(retVal.type2 == templateArg) {
instRetVal.namespaces2.assign(instName.begin(), instName.end()-1); instRetVal.namespaces2.assign(instName.begin(), instName.end()-1);
instRetVal.type2 = instName.back(); instRetVal.type2 = instName.back();
} else if(retVal.type1 == "This") {
instRetVal.namespaces2.assign(expandedClassNamespace.begin(), expandedClassNamespace.end());
instRetVal.type2 = expandedClassName;
} }
instMethod.returnVals.push_back(instRetVal); instMethod.returnVals.push_back(instRetVal);
} }
@ -262,18 +271,18 @@ map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods, con
} }
/* ************************************************************************* */ /* ************************************************************************* */
Class expandClassTemplate(const Class& cls, const string& templateArg, const vector<string>& instName) { Class expandClassTemplate(const Class& cls, const string& templateArg, const vector<string>& instName, const std::vector<string>& expandedClassNamespace, const string& expandedClassName) {
Class inst; Class inst;
inst.name = cls.name; inst.name = cls.name;
inst.templateArgs = cls.templateArgs; inst.templateArgs = cls.templateArgs;
inst.typedefName = cls.typedefName; inst.typedefName = cls.typedefName;
inst.isVirtual = cls.isVirtual; inst.isVirtual = cls.isVirtual;
inst.qualifiedParent = cls.qualifiedParent; inst.qualifiedParent = cls.qualifiedParent;
inst.methods = expandMethodTemplate(cls.methods, templateArg, instName); inst.methods = expandMethodTemplate(cls.methods, templateArg, instName, expandedClassNamespace, expandedClassName);
inst.static_methods = expandMethodTemplate(cls.static_methods, templateArg, instName); inst.static_methods = expandMethodTemplate(cls.static_methods, templateArg, instName, expandedClassNamespace, expandedClassName);
inst.namespaces = cls.namespaces; inst.namespaces = cls.namespaces;
inst.constructor = cls.constructor; 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.constructor.name = inst.name;
inst.deconstructor = cls.deconstructor; inst.deconstructor = cls.deconstructor;
inst.deconstructor.name = inst.name; inst.deconstructor.name = inst.name;
@ -285,8 +294,9 @@ Class expandClassTemplate(const Class& cls, const string& templateArg, const vec
vector<Class> Class::expandTemplate(const string& templateArg, const vector<vector<string> >& instantiations) const { vector<Class> Class::expandTemplate(const string& templateArg, const vector<vector<string> >& instantiations) const {
vector<Class> result; vector<Class> result;
BOOST_FOREACH(const vector<string>& instName, instantiations) { BOOST_FOREACH(const vector<string>& instName, instantiations) {
Class inst = expandClassTemplate(*this, templateArg, instName); const string expandedName = name + instName.back();
inst.name = name + instName.back(); Class inst = expandClassTemplate(*this, templateArg, instName, this->namespaces, expandedName);
inst.name = expandedName;
inst.templateArgs.clear(); inst.templateArgs.clear();
inst.typedefName = qualifiedName("::") + "<" + wrap::qualifiedName("::", instName) + ">"; inst.typedefName = qualifiedName("::") + "<" + wrap::qualifiedName("::", instName) + ">";
result.push_back(inst); result.push_back(inst);
@ -295,8 +305,8 @@ vector<Class> Class::expandTemplate(const string& templateArg, const vector<vect
} }
/* ************************************************************************* */ /* ************************************************************************* */
Class Class::expandTemplate(const string& templateArg, const vector<string>& instantiation) const { Class Class::expandTemplate(const string& templateArg, const vector<string>& instantiation, const std::vector<string>& expandedClassNamespace, const string& expandedClassName) const {
return expandClassTemplate(*this, templateArg, instantiation); return expandClassTemplate(*this, templateArg, instantiation, expandedClassNamespace, expandedClassName);
} }
/* ************************************************************************* */ /* ************************************************************************* */

View File

@ -57,7 +57,7 @@ struct Class {
std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter
std::vector<Class> expandTemplate(const std::string& templateArg, const std::vector<std::vector<std::string> >& instantiations) const; std::vector<Class> expandTemplate(const std::string& templateArg, const std::vector<std::vector<std::string> >& instantiations) const;
Class expandTemplate(const std::string& templateArg, const std::vector<std::string>& instantiation) const; Class expandTemplate(const std::string& templateArg, const std::vector<std::string>& instantiation, const std::vector<std::string>& expandedClassNamespace, const std::string& expandedClassName) const;
// The typedef line for this class, if this class is a typedef, otherwise returns an empty string. // The typedef line for this class, if this class is a typedef, otherwise returns an empty string.
std::string getTypedef() const; std::string getTypedef() const;

View File

@ -42,7 +42,7 @@ namespace wrap {
// Instantiate it // Instantiate it
Class classInst = *clsIt; Class classInst = *clsIt;
for(size_t i = 0; i < typeList.size(); ++i) 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 // Fix class properties
classInst.name = name; classInst.name = name;