Massive edit: new Qualified type groups namespaces with name, eliminates a lot of clutter.
parent
6f333965a9
commit
77935bd631
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
108
wrap/Class.cpp
108
wrap/Class.cpp
|
@ -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);
|
||||
|
|
15
wrap/Class.h
15
wrap/Class.h
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -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() :
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue