Made TemplateSubstitution into an operator, and added stream operator

release/4.3a0
dellaert 2014-11-13 19:34:15 +01:00
parent fe481dc775
commit 482dbd9226
8 changed files with 178 additions and 121 deletions

View File

@ -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;
}

View File

@ -274,13 +274,15 @@ void Class::addMethod(bool verbose, bool is_const, Str methodName,
Str templateArgName, const vector<Qualified>& 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

View File

@ -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<ReturnValue> ExpandReturnValuesTemplate(
std::vector<ReturnValue> expandReturnValuesTemplate(
const TemplateSubstitution& ts) const {
std::vector<ReturnValue> 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

61
wrap/ReturnType.cpp Normal file
View File

@ -0,0 +1,61 @@
/**
* @file ReturnType.cpp
* @date Nov 13, 2014
* @author Frank Dellaert
*/
#include "ReturnType.h"
#include "utilities.h"
#include <boost/foreach.hpp>
#include <iostream>
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;
}
/* ************************************************************************* */

67
wrap/ReturnType.h Normal file
View File

@ -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<class TYPES>
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

View File

@ -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;
}

View File

@ -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<class TYPES>
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 {

View File

@ -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 <string>
#include <iostream>
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