Massive edit: new Qualified type groups namespaces with name, eliminates a lot of clutter.

release/4.3a0
dellaert 2014-11-12 02:49:23 +01:00
parent 6f333965a9
commit 77935bd631
17 changed files with 310 additions and 288 deletions

View File

@ -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)

View File

@ -19,20 +19,17 @@
#pragma once
#include "Qualified.h"
#include "FileWriter.h"
#include "ReturnValue.h"
#include <string>
#include <vector>
namespace wrap {
/// Argument class
struct Argument {
Qualified type;
bool is_const, is_ref, is_ptr;
std::string type;
std::string name;
std::vector<std::string> 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;
};

View File

@ -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<string>& 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<ArgumentList> expandArgumentListsTemplate(
static vector<ArgumentList> expandArgumentListsTemplate(
const vector<ArgumentList>& argLists, const string& templateArg,
const vector<string>& instName,
const vector<string>& expandedClassNamespace,
const string& expandedClassName) {
const Qualified& qualifiedType, const Qualified& expandedClass) {
vector<ArgumentList> 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<ArgumentList> expandArgumentListsTemplate(
/* ************************************************************************* */
template<class METHOD>
map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods,
const string& templateArg, const vector<string>& instName,
const vector<string>& expandedClassNamespace,
const string& expandedClassName) {
const string& templateArg, const Qualified& qualifiedType,
const Qualified& expandedClass) {
map<string, METHOD> result;
typedef pair<const string, METHOD> 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<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods,
/* ************************************************************************* */
Class Class::expandTemplate(const string& templateArg,
const vector<string>& instName,
const vector<string>& 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> Class::expandTemplate(const string& templateArg,
const vector<vector<string> >& instantiations) const {
const vector<Qualified >& instantiations) const {
vector<Class> result;
BOOST_FOREACH(const vector<string>& 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<string>(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<string>(deserialize_id);
functionNames.push_back(wrapFunctionNameDeserialize);

View File

@ -31,7 +31,7 @@
namespace wrap {
/// Class has name, constructors, methods
struct Class {
struct Class : public Qualified {
typedef std::map<std::string, Method> Methods;
typedef std::map<std::string, StaticMethod> 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<std::string> 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<std::string> 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<std::string> 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<std::string>& 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<std::string>& instantiation,
const std::vector<std::string>& expandedClassNamespace,
const std::string& expandedClassName) const;
const Qualified& instantiation,
const Qualified& expandedClass) const;
std::vector<Class> expandTemplate(const std::string& templateArg,
const std::vector<std::vector<std::string> >& instantiations) const;
const std::vector<Qualified >& instantiations) const;
// The typedef line for this class, if this class is a typedef, otherwise returns an empty string.
std::string getTypedef() const;

View File

@ -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<string, GlobalFunction> 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<std::string>& 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

View File

@ -16,15 +16,13 @@ namespace wrap {
struct GlobalFunction {
typedef std::vector<std::string> StrVec;
bool verbose_;
std::string name;
// each overload, regardless of namespace
std::vector<ArgumentList> argLists; ///< arugments for each overload
std::vector<ArgumentList> argLists; ///< arugments for each overload
std::vector<ReturnValue> returnVals; ///< returnVals for each overload
std::vector<StrVec> namespaces; ///< Stack of namespaces
std::vector<Qualified> 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,

View File

@ -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<bool>(self->return_field(t));
if (returnVal.type1 != "void")
if (returnVal.type1.name != "void")
returnVal.wrap_result("obj->" + name + "(" + args.names() + ")", file,
typeAttributes);
else

View File

@ -65,8 +65,7 @@ typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> 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<Class>& classes, const Class& cls,
const string& templateArgument,
const vector<vector<string> >& instantiations) {
const string& templateArgument, const vector<Qualified>& 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<string> templateArgumentValue;
vector<vector<string> > templateInstantiations;
Qualified argValue;
vector<Qualified> 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<CALIBRATION = {gtsam::Cal3DS2}>
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<vector<string> > methodInstantiations;
vector<Qualified> 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<CALIBRATION = {gtsam::Cal3DS2}>
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<gtsam::Pose2, gtsam::Point2> 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<string>& validArgs, const map<string,T>& 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<Method>(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<string, Method> 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());

64
wrap/Qualified.h Normal file
View File

@ -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 <string>
#include <vector>
namespace wrap {
/**
* Class to encapuslate a qualified name, i.e., with (nested) namespaces
*/
struct Qualified {
std::vector<std::string> 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

View File

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

View File

@ -10,8 +10,7 @@
#include "FileWriter.h"
#include "TypeAttributesTable.h"
#include <vector>
#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<std::string> namespaces1, namespaces2;
Qualified type1, type2;
/// Constructor
ReturnValue() :

View File

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

View File

@ -19,43 +19,48 @@
#include "TemplateInstantiationTypedef.h"
#include "utilities.h"
#include <iostream>
#include <boost/foreach.hpp>
#include <boost/optional.hpp>
using namespace std;
namespace wrap {
Class TemplateInstantiationTypedef::findAndExpand(const vector<Class>& classes) const {
// Find matching class
std::vector<Class>::const_iterator clsIt = classes.end();
for(std::vector<Class>::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<Class>& classes) const {
// Find matching class
boost::optional<Class const &> 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;
}
}
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;
}
}

View File

@ -26,14 +26,11 @@
namespace wrap {
struct TemplateInstantiationTypedef {
std::vector<std::string> classNamespaces;
std::string className;
std::vector<std::string> namespaces;
std::string name;
std::vector<std::vector<std::string> > typeList;
struct TemplateInstantiationTypedef : public Qualified {
Qualified class_;
std::vector<Qualified> typeList;
Class findAndExpand(const std::vector<Class>& classes) const;
};
}
}

View File

@ -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<Test*,Test*> 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));
}
}

View File

@ -118,23 +118,19 @@ string maybe_shared_ptr(bool add, const string& qtype, const string& type) {
}
/* ************************************************************************* */
string qualifiedName(const string& separator, const vector<string>& names, const string& finalName) {
string qualifiedName(const string& separator, const vector<string>& 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<std::string>& namespaces, const std::string& toolboxPath) {
void createNamespaceStructure(const std::vector<std::string>& namespaces,
const std::string& toolboxPath) {
using namespace boost::filesystem;
path curPath = toolboxPath;
BOOST_FOREACH(const string& subdir, namespaces) {

View File

@ -123,12 +123,12 @@ bool assert_equal(const std::vector<std::string>& expected, const std::vector<st
std::string maybe_shared_ptr(bool add, const std::string& qtype, const std::string& type);
/**
* Return a qualified name, if finalName is empty, only the names vector will
* be used (i.e. there won't be a trailing separator on the qualified name).
* Return a qualified name
*/
std::string qualifiedName(const std::string& separator, const std::vector<std::string>& names, const std::string& finalName = "");
std::string qualifiedName(const std::string& separator, const std::vector<std::string>& names);
/** creates the necessary folders for namespaces, as specified by a namespace stack */
void createNamespaceStructure(const std::vector<std::string>& namespaces, const std::string& toolboxPath);
void createNamespaceStructure(const std::vector<std::string>& namespaces,
const std::string& toolboxPath);
} // \namespace wrap