From 482dbd9226fd3638bda15329d0e85dc1432104a8 Mon Sep 17 00:00:00 2001 From: dellaert Date: Thu, 13 Nov 2014 19:34:15 +0100 Subject: [PATCH] Made TemplateSubstitution into an operator, and added stream operator --- wrap/Argument.cpp | 6 +--- wrap/Class.cpp | 4 ++- wrap/Function.h | 6 ++-- wrap/ReturnType.cpp | 61 +++++++++++++++++++++++++++++++++ wrap/ReturnType.h | 67 +++++++++++++++++++++++++++++++++++++ wrap/ReturnValue.cpp | 56 ++----------------------------- wrap/ReturnValue.h | 54 ++---------------------------- wrap/TemplateSubstitution.h | 45 +++++++++++++++++++++---- 8 files changed, 178 insertions(+), 121 deletions(-) create mode 100644 wrap/ReturnType.cpp create mode 100644 wrap/ReturnType.h diff --git a/wrap/Argument.cpp b/wrap/Argument.cpp index 19e46fd85..4989afb0d 100644 --- a/wrap/Argument.cpp +++ b/wrap/Argument.cpp @@ -31,11 +31,7 @@ using namespace wrap; /* ************************************************************************* */ Argument Argument::expandTemplate(const TemplateSubstitution& ts) const { Argument instArg = *this; - if (type.name == ts.templateArg) { - instArg.type = ts.qualifiedType; - } else if (type.name == "This") { - instArg.type = ts.expandedClass; - } + instArg.type = ts(type); return instArg; } diff --git a/wrap/Class.cpp b/wrap/Class.cpp index fab977802..5da9d8bd0 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -274,13 +274,15 @@ void Class::addMethod(bool verbose, bool is_const, Str methodName, Str templateArgName, const vector& templateArgValues) { // Check if templated if (!templateArgName.empty() && templateArgValues.size() > 0) { + cout << methodName << endl; // Create method to expand // For all values of the template argument, create a new method BOOST_FOREACH(const Qualified& instName, templateArgValues) { const TemplateSubstitution ts(templateArgName, instName, this->name); + cout << ts << endl; // substitute template in arguments ArgumentList expandedArgs = argumentList.expandTemplate(ts); - // do the same for return types + // do the same for return type ReturnValue expandedRetVal = returnValue.expandTemplate(ts); // Now stick in new overload stack with expandedMethodName key // but note we use the same, unexpanded methodName in overload diff --git a/wrap/Function.h b/wrap/Function.h index dd6d2158c..d175fe145 100644 --- a/wrap/Function.h +++ b/wrap/Function.h @@ -88,7 +88,7 @@ public: std::string fullType = arg.type.qualifiedName("::"); if (find(validArgs.begin(), validArgs.end(), fullType) == validArgs.end()) - throw DependencyMissing(fullType, s); + throw DependencyMissing(fullType, "checking argument of " + s); } } } @@ -125,7 +125,7 @@ public: } // TODO use transform ? - std::vector ExpandReturnValuesTemplate( + std::vector expandReturnValuesTemplate( const TemplateSubstitution& ts) const { std::vector result; BOOST_FOREACH(const ReturnValue& retVal, returnVals_) { @@ -140,7 +140,7 @@ public: // substitute template in arguments argLists_ = expandArgumentListsTemplate(ts); // do the same for return types - returnVals_ = ExpandReturnValuesTemplate(ts); + returnVals_ = expandReturnValuesTemplate(ts); } // emit a list of comments, one for each overload diff --git a/wrap/ReturnType.cpp b/wrap/ReturnType.cpp new file mode 100644 index 000000000..a317a5420 --- /dev/null +++ b/wrap/ReturnType.cpp @@ -0,0 +1,61 @@ +/** + * @file ReturnType.cpp + * @date Nov 13, 2014 + * @author Frank Dellaert + */ + +#include "ReturnType.h" +#include "utilities.h" +#include +#include + +using namespace std; +using namespace wrap; + +/* ************************************************************************* */ +string ReturnType::str(bool add_ptr) const { + return maybe_shared_ptr(add_ptr && isPtr, qualifiedName("::"), name); +} + +/* ************************************************************************* */ +void ReturnType::wrap_result(const string& out, const string& result, + FileWriter& wrapperFile, const TypeAttributesTable& typeAttributes) const { + + string cppType = qualifiedName("::"), matlabType = qualifiedName("."); + + if (category == CLASS) { + string objCopy, ptrType; + ptrType = "Shared" + name; + const bool isVirtual = typeAttributes.at(cppType).isVirtual; + if (isVirtual) { + if (isPtr) + objCopy = result; + else + objCopy = result + ".clone()"; + } else { + if (isPtr) + objCopy = result; + else + objCopy = ptrType + "(new " + cppType + "(" + result + "))"; + } + wrapperFile.oss << out << " = wrap_shared_ptr(" << objCopy << ",\"" + << matlabType << "\", " << (isVirtual ? "true" : "false") << ");\n"; + } else if (isPtr) { + wrapperFile.oss << " Shared" << name << "* ret = new Shared" << name << "(" + << result << ");" << endl; + wrapperFile.oss << out << " = wrap_shared_ptr(ret,\"" << matlabType + << "\");\n"; + } else if (matlabType != "void") + wrapperFile.oss << out << " = wrap< " << str(false) << " >(" << result + << ");\n"; +} + +/* ************************************************************************* */ +void ReturnType::wrapTypeUnwrap(FileWriter& wrapperFile) const { + if (category == CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedName("::") + << "> Shared" << name << ";" << endl; +} + +/* ************************************************************************* */ + diff --git a/wrap/ReturnType.h b/wrap/ReturnType.h new file mode 100644 index 000000000..1829fbc81 --- /dev/null +++ b/wrap/ReturnType.h @@ -0,0 +1,67 @@ +/** + * @file ReturnValue.h + * @brief Encapsulates a return type of a method + * @date Nov 13, 2014 + * @author Frank Dellaert + */ + +#include "Qualified.h" +#include "FileWriter.h" +#include "TypeAttributesTable.h" +#include "utilities.h" + +#pragma once + +namespace wrap { + +/** + * Encapsulates return value of a method or function + */ +struct ReturnType: Qualified { + + /// the different supported return value categories + typedef enum { + CLASS = 1, EIGEN = 2, BASIS = 3, VOID = 4 + } return_category; + + bool isPtr; + return_category category; + + ReturnType() : + isPtr(false), category(CLASS) { + } + + ReturnType(const std::string& name) : + isPtr(false), category(CLASS) { + Qualified::name = name; + } + + void rename(const Qualified& q) { + name = q.name; + namespaces = q.namespaces; + } + + /// Check if this type is in a set of valid types + template + void verify(TYPES validtypes, const std::string& s) const { + std::string key = qualifiedName("::"); + if (find(validtypes.begin(), validtypes.end(), key) == validtypes.end()) + throw DependencyMissing(key, "checking return type of " + s); + } + +private: + + friend struct ReturnValue; + + std::string str(bool add_ptr) const; + + /// Example: out[1] = wrap_shared_ptr(pairResult.second,"Test", false); + void wrap_result(const std::string& out, const std::string& result, + FileWriter& wrapperFile, const TypeAttributesTable& typeAttributes) const; + + /// Creates typedef + void wrapTypeUnwrap(FileWriter& wrapperFile) const; + +}; + +} // \namespace wrap diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index a511652e8..993760e81 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -1,6 +1,5 @@ /** * @file ReturnValue.cpp - * * @date Dec 1, 2011 * @author Alex Cunningham * @author Andrew Melim @@ -15,62 +14,11 @@ using namespace std; using namespace wrap; -/* ************************************************************************* */ -string ReturnType::str(bool add_ptr) const { - return maybe_shared_ptr(add_ptr && isPtr, qualifiedName("::"), name); -} - -/* ************************************************************************* */ -void ReturnType::wrap_result(const string& out, const string& result, - FileWriter& file, const TypeAttributesTable& typeAttributes) const { - - string cppType = qualifiedName("::"), matlabType = qualifiedName("."); - - if (category == CLASS) { - string objCopy, ptrType; - ptrType = "Shared" + name; - const bool isVirtual = typeAttributes.at(cppType).isVirtual; - if (isVirtual) { - if (isPtr) - objCopy = result; - else - objCopy = result + ".clone()"; - } else { - if (isPtr) - objCopy = result; - else - objCopy = ptrType + "(new " + cppType + "(" + result + "))"; - } - file.oss << out << " = wrap_shared_ptr(" << objCopy << ",\"" << matlabType - << "\", " << (isVirtual ? "true" : "false") << ");\n"; - } else if (isPtr) { - file.oss << " Shared" << name << "* ret = new Shared" << name << "(" - << result << ");" << endl; - file.oss << out << " = wrap_shared_ptr(ret,\"" << matlabType << "\");\n"; - } else if (matlabType != "void") - file.oss << out << " = wrap< " << str(false) << " >(" << result << ");\n"; -} - -/* ************************************************************************* */ -void ReturnType::wrapTypeUnwrap(FileWriter& wrapperFile) const { - if (category == CLASS) - wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedName("::") - << "> Shared" << name << ";" << endl; -} - /* ************************************************************************* */ ReturnValue ReturnValue::expandTemplate(const TemplateSubstitution& ts) const { ReturnValue instRetVal = *this; - if (type1.name == ts.templateArg) { - instRetVal.type1.rename(ts.qualifiedType); - } else if (type1.name == "This") { - instRetVal.type1.rename(ts.expandedClass); - } - if (type2.name == ts.templateArg) { - instRetVal.type2.rename(ts.qualifiedType); - } else if (type2.name == "This") { - instRetVal.type2.rename(ts.expandedClass); - } + instRetVal.type1 = ts(type1); + if (isPair) instRetVal.type2 = ts(type2); return instRetVal; } diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index 55ebf8c57..e7206b494 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -2,12 +2,12 @@ * @file ReturnValue.h * * @brief Encapsulates a return value from a method - * * @date Dec 1, 2011 * @author Alex Cunningham * @author Richard Roberts */ +#include "ReturnType.h" #include "TemplateSubstitution.h" #include "FileWriter.h" #include "TypeAttributesTable.h" @@ -18,57 +18,7 @@ namespace wrap { /** - * Encapsulates return value of a method or function - */ -struct ReturnType: Qualified { - - /// the different supported return value categories - typedef enum { - CLASS = 1, EIGEN = 2, BASIS = 3, VOID = 4 - } return_category; - - bool isPtr; - return_category category; - - ReturnType() : - isPtr(false), category(CLASS) { - } - - ReturnType(const std::string& name) : - isPtr(false), category(CLASS) { - Qualified::name = name; - } - - void rename(const Qualified& q) { - name = q.name; - namespaces = q.namespaces; - } - - /// Check if this type is in a set of valid types - template - void verify(TYPES validtypes, const std::string& s) const { - std::string key = qualifiedName("::"); - if (find(validtypes.begin(), validtypes.end(), key) == validtypes.end()) - throw DependencyMissing(key, s); - } - -private: - - friend struct ReturnValue; - - std::string str(bool add_ptr) const; - - /// Example: out[1] = wrap_shared_ptr(pairResult.second,"Test", false); - void wrap_result(const std::string& out, const std::string& result, - FileWriter& file, const TypeAttributesTable& typeAttributes) const; - - /// Creates typedef - void wrapTypeUnwrap(FileWriter& wrapperFile) const; - -}; - -/** - * Encapsulates return value of a method or function, possibly a pair + * Encapsulates return type of a method or function, possibly a pair */ struct ReturnValue { diff --git a/wrap/TemplateSubstitution.h b/wrap/TemplateSubstitution.h index 5ce2f3a86..fd031024e 100644 --- a/wrap/TemplateSubstitution.h +++ b/wrap/TemplateSubstitution.h @@ -11,28 +11,61 @@ /** * @file TemplateSubstitution.h - * @brief Auxiliary class for template sunstitutions + * @brief Auxiliary class for template substitutions * @author Frank Dellaert * @date Nov 13, 2014 **/ #pragma once -#include "Qualified.h" +#include "ReturnType.h" #include +#include namespace wrap { /** * e.g. TemplateSubstitution("T", gtsam::Point2, gtsam::PriorFactorPoint2) */ -struct TemplateSubstitution { +class TemplateSubstitution { + + std::string templateArg_; + Qualified qualifiedType_, expandedClass_; + +public: + TemplateSubstitution(const std::string& a, const Qualified& t, const Qualified& e) : - templateArg(a), qualifiedType(t), expandedClass(e) { + templateArg_(a), qualifiedType_(t), expandedClass_(e) { } - std::string templateArg; - Qualified qualifiedType, expandedClass; + + // Substitute if needed + Qualified operator()(const Qualified& type) const { + if (type.name == templateArg_ && type.namespaces.empty()) + return qualifiedType_; + else if (type.name == "This") + return expandedClass_; + else + return type; + } + + // Substitute if needed + ReturnType operator()(const ReturnType& type) const { + ReturnType instType; + if (type.name == templateArg_ && type.namespaces.empty()) + instType.rename(qualifiedType_); + else if (type.name == "This") + instType.rename(expandedClass_); + return instType; + } + + friend std::ostream& operator<<(std::ostream& os, + const TemplateSubstitution& ts) { + os << ts.templateArg_ << '/' << ts.qualifiedType_.qualifiedName("::") + << " (" << ts.expandedClass_.qualifiedName("::") << ")"; + return os; + } + }; } // \namespace wrap