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 Argument::matlabClass(const string& delim) const {
|
||||||
string result;
|
string result;
|
||||||
BOOST_FOREACH(const string& ns, namespaces)
|
BOOST_FOREACH(const string& ns, type.namespaces)
|
||||||
result += ns + delim;
|
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";
|
return result + "char";
|
||||||
if (type == "Vector" || type == "Matrix")
|
if (type.name == "Vector" || type.name == "Matrix")
|
||||||
return result + "double";
|
return result + "double";
|
||||||
if (type == "int" || type == "size_t")
|
if (type.name == "int" || type.name == "size_t")
|
||||||
return result + "numeric";
|
return result + "numeric";
|
||||||
if (type == "bool")
|
if (type.name == "bool")
|
||||||
return result + "logical";
|
return result + "logical";
|
||||||
return result + type;
|
return result + type.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
bool Argument::isScalar() const {
|
bool Argument::isScalar() const {
|
||||||
return (type == "bool" || type == "char" || type == "unsigned char"
|
return (type.name == "bool" || type.name == "char" || type.name == "unsigned char"
|
||||||
|| type == "int" || type == "size_t" || type == "double");
|
|| type.name == "int" || type.name == "size_t" || type.name == "double");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const {
|
void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const {
|
||||||
file.oss << " ";
|
file.oss << " ";
|
||||||
|
|
||||||
string cppType = qualifiedType("::");
|
string cppType = type.qualifiedName("::");
|
||||||
string matlabUniqueType = qualifiedType();
|
string matlabUniqueType = type.qualifiedName();
|
||||||
|
|
||||||
if (is_ptr)
|
if (is_ptr)
|
||||||
// A pointer: emit an "unwrap_shared_ptr" call which returns a pointer
|
// 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;
|
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 ArgumentList::types() const {
|
||||||
string str;
|
string str;
|
||||||
|
@ -93,7 +85,7 @@ string ArgumentList::types() const {
|
||||||
BOOST_FOREACH(Argument arg, *this) {
|
BOOST_FOREACH(Argument arg, *this) {
|
||||||
if (!first)
|
if (!first)
|
||||||
str += ",";
|
str += ",";
|
||||||
str += arg.type;
|
str += arg.type.name;
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
@ -105,14 +97,14 @@ string ArgumentList::signature() const {
|
||||||
bool cap = false;
|
bool cap = false;
|
||||||
|
|
||||||
BOOST_FOREACH(Argument arg, *this) {
|
BOOST_FOREACH(Argument arg, *this) {
|
||||||
BOOST_FOREACH(char ch, arg.type)
|
BOOST_FOREACH(char ch, arg.type.name)
|
||||||
if (isupper(ch)) {
|
if (isupper(ch)) {
|
||||||
sig += ch;
|
sig += ch;
|
||||||
//If there is a capital letter, we don't want to read it below
|
//If there is a capital letter, we don't want to read it below
|
||||||
cap = true;
|
cap = true;
|
||||||
}
|
}
|
||||||
if (!cap)
|
if (!cap)
|
||||||
sig += arg.type[0];
|
sig += arg.type.name[0];
|
||||||
//Reset to default
|
//Reset to default
|
||||||
cap = false;
|
cap = false;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +150,7 @@ void ArgumentList::emit_prototype(FileWriter& file, const string& name) const {
|
||||||
BOOST_FOREACH(Argument arg, *this) {
|
BOOST_FOREACH(Argument arg, *this) {
|
||||||
if (!first)
|
if (!first)
|
||||||
file.oss << ", ";
|
file.oss << ", ";
|
||||||
file.oss << arg.type << " " << arg.name;
|
file.oss << arg.type.name << " " << arg.name;
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
file.oss << ")";
|
file.oss << ")";
|
||||||
|
@ -180,7 +172,7 @@ void ArgumentList::emit_conditional_call(FileWriter& file,
|
||||||
file.oss << "if length(varargin) == " << size();
|
file.oss << "if length(varargin) == " << size();
|
||||||
if (size() > 0)
|
if (size() > 0)
|
||||||
file.oss << " && ";
|
file.oss << " && ";
|
||||||
// ...and their types
|
// ...and their type.names
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (size_t i = 0; i < size(); i++) {
|
for (size_t i = 0; i < size(); i++) {
|
||||||
if (!first)
|
if (!first)
|
||||||
|
|
|
@ -19,20 +19,17 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Qualified.h"
|
||||||
#include "FileWriter.h"
|
#include "FileWriter.h"
|
||||||
#include "ReturnValue.h"
|
#include "ReturnValue.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
/// Argument class
|
/// Argument class
|
||||||
struct Argument {
|
struct Argument {
|
||||||
|
Qualified type;
|
||||||
bool is_const, is_ref, is_ptr;
|
bool is_const, is_ref, is_ptr;
|
||||||
std::string type;
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> namespaces;
|
|
||||||
|
|
||||||
Argument() :
|
Argument() :
|
||||||
is_const(false), is_ref(false), is_ptr(false) {
|
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
|
/// Check if will be unwrapped using scalar login in wrap/matlab.h
|
||||||
bool isScalar() const;
|
bool isScalar() const;
|
||||||
|
|
||||||
/// adds namespaces to type
|
|
||||||
std::string qualifiedType(const std::string& delim = "") const;
|
|
||||||
|
|
||||||
/// MATLAB code generation, MATLAB to C++
|
/// MATLAB code generation, MATLAB to C++
|
||||||
void matlab_unwrap(FileWriter& file, const std::string& matlabName) const;
|
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);
|
createNamespaceStructure(namespaces, toolboxPath);
|
||||||
|
|
||||||
// open destination classFile
|
// open destination classFile
|
||||||
string classFile = toolboxPath;
|
string classFile = matlabName(toolboxPath);
|
||||||
if (!namespaces.empty())
|
|
||||||
classFile += "/+" + wrap::qualifiedName("/+", namespaces);
|
|
||||||
classFile += "/" + name + ".m";
|
|
||||||
FileWriter proxyFile(classFile, verbose_, "%");
|
FileWriter proxyFile(classFile, verbose_, "%");
|
||||||
|
|
||||||
// get the name of actual matlab object
|
// get the name of actual matlab object
|
||||||
const string matlabQualName = qualifiedName("."), matlabUniqueName =
|
const string matlabQualName = qualifiedName(".");
|
||||||
qualifiedName(), cppName = qualifiedName("::");
|
const string matlabUniqueName = qualifiedName();
|
||||||
const string matlabBaseName = wrap::qualifiedName(".", qualifiedParent);
|
const string cppName = qualifiedName("::");
|
||||||
const string cppBaseName = wrap::qualifiedName("::", qualifiedParent);
|
const string matlabBaseName = qualifiedParent.qualifiedName(".");
|
||||||
|
const string cppBaseName = qualifiedParent.qualifiedName("::");
|
||||||
|
|
||||||
// emit class proxy code
|
// emit class proxy code
|
||||||
// we want our class to inherit the handle class for memory purposes
|
// 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);
|
proxyFile.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
string Class::qualifiedName(const string& delim) const {
|
|
||||||
return ::wrap::qualifiedName(delim, namespaces, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Class::pointer_constructor_fragments(FileWriter& proxyFile,
|
void Class::pointer_constructor_fragments(FileWriter& proxyFile,
|
||||||
FileWriter& wrapperFile, const string& wrapperName,
|
FileWriter& wrapperFile, const string& wrapperName,
|
||||||
vector<string>& functionNames) const {
|
vector<string>& functionNames) const {
|
||||||
|
|
||||||
const string matlabUniqueName = qualifiedName(), cppName = qualifiedName(
|
const string matlabUniqueName = qualifiedName();
|
||||||
"::");
|
const string cppName = qualifiedName("::");
|
||||||
const string baseCppName = wrap::qualifiedName("::", qualifiedParent);
|
const string baseCppName = qualifiedParent.qualifiedName("::");
|
||||||
|
|
||||||
const int collectorInsertId = (int) functionNames.size();
|
const int collectorInsertId = (int) functionNames.size();
|
||||||
const string collectorInsertFunctionName = matlabUniqueName
|
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<ArgumentList>& argLists, const string& templateArg,
|
||||||
const vector<string>& instName,
|
const Qualified& qualifiedType, const Qualified& expandedClass) {
|
||||||
const vector<string>& expandedClassNamespace,
|
|
||||||
const string& expandedClassName) {
|
|
||||||
vector<ArgumentList> result;
|
vector<ArgumentList> result;
|
||||||
BOOST_FOREACH(const ArgumentList& argList, argLists) {
|
BOOST_FOREACH(const ArgumentList& argList, argLists) {
|
||||||
ArgumentList instArgList;
|
ArgumentList instArgList;
|
||||||
BOOST_FOREACH(const Argument& arg, argList) {
|
BOOST_FOREACH(const Argument& arg, argList) {
|
||||||
Argument instArg = arg;
|
Argument instArg = arg;
|
||||||
if (arg.type == templateArg) {
|
if (arg.type.name == templateArg) {
|
||||||
instArg.namespaces.assign(instName.begin(), instName.end() - 1);
|
instArg.type = qualifiedType;
|
||||||
instArg.type = instName.back();
|
} else if (arg.type.name == "This") {
|
||||||
} else if (arg.type == "This") {
|
instArg.type = expandedClass;
|
||||||
instArg.namespaces.assign(expandedClassNamespace.begin(),
|
|
||||||
expandedClassNamespace.end());
|
|
||||||
instArg.type = expandedClassName;
|
|
||||||
}
|
}
|
||||||
instArgList.push_back(instArg);
|
instArgList.push_back(instArg);
|
||||||
}
|
}
|
||||||
|
@ -275,34 +263,27 @@ vector<ArgumentList> expandArgumentListsTemplate(
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
template<class METHOD>
|
template<class METHOD>
|
||||||
map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods,
|
map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods,
|
||||||
const string& templateArg, const vector<string>& instName,
|
const string& templateArg, const Qualified& qualifiedType,
|
||||||
const vector<string>& expandedClassNamespace,
|
const Qualified& expandedClass) {
|
||||||
const string& expandedClassName) {
|
|
||||||
map<string, METHOD> result;
|
map<string, METHOD> result;
|
||||||
typedef pair<const string, METHOD> Name_Method;
|
typedef pair<const string, METHOD> Name_Method;
|
||||||
BOOST_FOREACH(const Name_Method& name_method, methods) {
|
BOOST_FOREACH(const Name_Method& name_method, methods) {
|
||||||
const METHOD& method = name_method.second;
|
const METHOD& method = name_method.second;
|
||||||
METHOD instMethod = method;
|
METHOD instMethod = method;
|
||||||
instMethod.argLists = expandArgumentListsTemplate(method.argLists,
|
instMethod.argLists = expandArgumentListsTemplate(method.argLists,
|
||||||
templateArg, instName, expandedClassNamespace, expandedClassName);
|
templateArg, qualifiedType, expandedClass);
|
||||||
instMethod.returnVals.clear();
|
instMethod.returnVals.clear();
|
||||||
BOOST_FOREACH(const ReturnValue& retVal, method.returnVals) {
|
BOOST_FOREACH(const ReturnValue& retVal, method.returnVals) {
|
||||||
ReturnValue instRetVal = retVal;
|
ReturnValue instRetVal = retVal;
|
||||||
if (retVal.type1 == templateArg) {
|
if (retVal.type1.name == templateArg) {
|
||||||
instRetVal.namespaces1.assign(instName.begin(), instName.end() - 1);
|
instRetVal.type1 = qualifiedType;
|
||||||
instRetVal.type1 = instName.back();
|
} else if (retVal.type1.name == "This") {
|
||||||
} else if (retVal.type1 == "This") {
|
instRetVal.type1 = expandedClass;
|
||||||
instRetVal.namespaces1.assign(expandedClassNamespace.begin(),
|
|
||||||
expandedClassNamespace.end());
|
|
||||||
instRetVal.type1 = expandedClassName;
|
|
||||||
}
|
}
|
||||||
if (retVal.type2 == templateArg) {
|
if (retVal.type2.name == templateArg) {
|
||||||
instRetVal.namespaces2.assign(instName.begin(), instName.end() - 1);
|
instRetVal.type2 = qualifiedType;
|
||||||
instRetVal.type2 = instName.back();
|
} else if (retVal.type2.name == "This") {
|
||||||
} else if (retVal.type1 == "This") {
|
instRetVal.type2 = expandedClass;
|
||||||
instRetVal.namespaces2.assign(expandedClassNamespace.begin(),
|
|
||||||
expandedClassNamespace.end());
|
|
||||||
instRetVal.type2 = expandedClassName;
|
|
||||||
}
|
}
|
||||||
instMethod.returnVals.push_back(instRetVal);
|
instMethod.returnVals.push_back(instRetVal);
|
||||||
}
|
}
|
||||||
|
@ -313,17 +294,14 @@ map<string, METHOD> expandMethodTemplate(const map<string, METHOD>& methods,
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Class Class::expandTemplate(const string& templateArg,
|
Class Class::expandTemplate(const string& templateArg,
|
||||||
const vector<string>& instName,
|
const Qualified& instName, const Qualified& expandedClass) const {
|
||||||
const vector<string>& expandedClassNamespace,
|
|
||||||
const string& expandedClassName) const {
|
|
||||||
Class inst = *this;
|
Class inst = *this;
|
||||||
inst.methods = expandMethodTemplate(methods, templateArg, instName,
|
inst.methods = expandMethodTemplate(methods, templateArg, instName,
|
||||||
expandedClassNamespace, expandedClassName);
|
expandedClass);
|
||||||
inst.static_methods = expandMethodTemplate(static_methods, templateArg,
|
inst.static_methods = expandMethodTemplate(static_methods, templateArg,
|
||||||
instName, expandedClassNamespace, expandedClassName);
|
instName, expandedClass);
|
||||||
inst.constructor.args_list = expandArgumentListsTemplate(
|
inst.constructor.args_list = expandArgumentListsTemplate(
|
||||||
constructor.args_list, templateArg, instName, expandedClassNamespace,
|
constructor.args_list, templateArg, instName, expandedClass);
|
||||||
expandedClassName);
|
|
||||||
inst.constructor.name = inst.name;
|
inst.constructor.name = inst.name;
|
||||||
inst.deconstructor.name = inst.name;
|
inst.deconstructor.name = inst.name;
|
||||||
return inst;
|
return inst;
|
||||||
|
@ -331,16 +309,16 @@ Class Class::expandTemplate(const string& templateArg,
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
vector<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;
|
vector<Class> result;
|
||||||
BOOST_FOREACH(const vector<string>& instName, instantiations) {
|
BOOST_FOREACH(const Qualified& instName, instantiations) {
|
||||||
const string expandedName = name + instName.back();
|
Qualified expandedClass = (Qualified)(*this);
|
||||||
Class inst = expandTemplate(templateArg, instName, namespaces,
|
expandedClass.name += instName.name;
|
||||||
expandedName);
|
Class inst = expandTemplate(templateArg, instName, expandedClass);
|
||||||
inst.name = expandedName;
|
inst.name = expandedClass.name;
|
||||||
inst.templateArgs.clear();
|
inst.templateArgs.clear();
|
||||||
inst.typedefName = qualifiedName("::") + "<"
|
inst.typedefName = qualifiedName("::") + "<" + instName.qualifiedName("::")
|
||||||
+ wrap::qualifiedName("::", instName) + ">";
|
+ ">";
|
||||||
result.push_back(inst);
|
result.push_back(inst);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -425,8 +403,9 @@ void Class::serialization_fragments(FileWriter& proxyFile,
|
||||||
//}
|
//}
|
||||||
|
|
||||||
int serialize_id = functionNames.size();
|
int serialize_id = functionNames.size();
|
||||||
const string matlabQualName = qualifiedName("."), matlabUniqueName =
|
const string matlabQualName = qualifiedName(".");
|
||||||
qualifiedName(), cppClassName = qualifiedName("::");
|
const string matlabUniqueName = qualifiedName();
|
||||||
|
const string cppClassName = qualifiedName("::");
|
||||||
const string wrapFunctionNameSerialize = matlabUniqueName
|
const string wrapFunctionNameSerialize = matlabUniqueName
|
||||||
+ "_string_serialize_" + boost::lexical_cast<string>(serialize_id);
|
+ "_string_serialize_" + boost::lexical_cast<string>(serialize_id);
|
||||||
functionNames.push_back(wrapFunctionNameSerialize);
|
functionNames.push_back(wrapFunctionNameSerialize);
|
||||||
|
@ -515,8 +494,9 @@ void Class::deserialization_fragments(FileWriter& proxyFile,
|
||||||
// out[0] = wrap_shared_ptr(output,"Point3", false);
|
// out[0] = wrap_shared_ptr(output,"Point3", false);
|
||||||
//}
|
//}
|
||||||
int deserialize_id = functionNames.size();
|
int deserialize_id = functionNames.size();
|
||||||
const string matlabQualName = qualifiedName("."), matlabUniqueName =
|
const string matlabQualName = qualifiedName(".");
|
||||||
qualifiedName(), cppClassName = qualifiedName("::");
|
const string matlabUniqueName = qualifiedName();
|
||||||
|
const string cppClassName = qualifiedName("::");
|
||||||
const string wrapFunctionNameDeserialize = matlabUniqueName
|
const string wrapFunctionNameDeserialize = matlabUniqueName
|
||||||
+ "_string_deserialize_" + boost::lexical_cast<string>(deserialize_id);
|
+ "_string_deserialize_" + boost::lexical_cast<string>(deserialize_id);
|
||||||
functionNames.push_back(wrapFunctionNameDeserialize);
|
functionNames.push_back(wrapFunctionNameDeserialize);
|
||||||
|
|
15
wrap/Class.h
15
wrap/Class.h
|
@ -31,7 +31,7 @@
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
/// Class has name, constructors, methods
|
/// Class has name, constructors, methods
|
||||||
struct Class {
|
struct Class : public Qualified {
|
||||||
typedef std::map<std::string, Method> Methods;
|
typedef std::map<std::string, Method> Methods;
|
||||||
typedef std::map<std::string, StaticMethod> StaticMethods;
|
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) {}
|
Class(bool verbose=true) : isVirtual(false), isSerializable(false), hasSerialization(false), verbose_(verbose) {}
|
||||||
|
|
||||||
// Then the instance variables are set directly by the Module constructor
|
// Then the instance variables are set directly by the Module constructor
|
||||||
std::string name; ///< Class name
|
|
||||||
std::vector<std::string> templateArgs; ///< Template arguments
|
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]
|
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 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 isSerializable; ///< Whether we can use boost.serialization to serialize the class - creates exports
|
||||||
bool hasSerialization; ///< Whether we should create the serialization functions
|
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
|
Methods methods; ///< Class methods
|
||||||
StaticMethods static_methods; ///< Static methods
|
StaticMethods static_methods; ///< Static methods
|
||||||
std::vector<std::string> namespaces; ///< Stack of namespaces
|
|
||||||
Constructor constructor; ///< Class constructors
|
Constructor constructor; ///< Class constructors
|
||||||
Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object
|
Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object
|
||||||
bool verbose_; ///< verbose flag
|
bool verbose_; ///< verbose flag
|
||||||
|
@ -57,15 +55,12 @@ struct Class {
|
||||||
void matlab_proxy(const std::string& toolboxPath, const std::string& wrapperName, const TypeAttributesTable& typeAttributes,
|
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
|
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,
|
Class expandTemplate(const std::string& templateArg,
|
||||||
const std::vector<std::string>& instantiation,
|
const Qualified& instantiation,
|
||||||
const std::vector<std::string>& expandedClassNamespace,
|
const Qualified& expandedClass) const;
|
||||||
const std::string& expandedClassName) const;
|
|
||||||
|
|
||||||
std::vector<Class> expandTemplate(const std::string& templateArg,
|
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.
|
// The typedef line for this class, if this class is a typedef, otherwise returns an empty string.
|
||||||
std::string getTypedef() const;
|
std::string getTypedef() const;
|
||||||
|
|
|
@ -16,14 +16,18 @@ namespace wrap {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void GlobalFunction::addOverload(bool verbose, const std::string& name,
|
void GlobalFunction::addOverload(bool verbose, const Qualified& overload,
|
||||||
const ArgumentList& args, const ReturnValue& retVal,
|
const ArgumentList& args, const ReturnValue& retVal) {
|
||||||
const StrVec& ns_stack) {
|
if (name.empty())
|
||||||
this->verbose_ = verbose;
|
name = overload.name;
|
||||||
this->name = name;
|
else if (overload.name != name)
|
||||||
this->argLists.push_back(args);
|
throw std::runtime_error(
|
||||||
this->returnVals.push_back(retVal);
|
"GlobalFunction::addOverload: tried to add overload with name "
|
||||||
this->namespaces.push_back(ns_stack);
|
+ 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
|
// map of namespace to global function
|
||||||
typedef map<string, GlobalFunction> GlobalFunctionMap;
|
typedef map<string, GlobalFunction> GlobalFunctionMap;
|
||||||
GlobalFunctionMap grouped_functions;
|
GlobalFunctionMap grouped_functions;
|
||||||
for (size_t i = 0; i < namespaces.size(); ++i) {
|
for (size_t i = 0; i < overloads.size(); ++i) {
|
||||||
StrVec ns = namespaces.at(i);
|
Qualified overload = overloads.at(i);
|
||||||
string str_ns = qualifiedName("", ns, "");
|
// use concatenated namespaces as key
|
||||||
|
string str_ns = qualifiedName("", overload.namespaces);
|
||||||
ReturnValue ret = returnVals.at(i);
|
ReturnValue ret = returnVals.at(i);
|
||||||
ArgumentList args = argLists.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].argLists.push_back(args);
|
||||||
grouped_functions[str_ns].returnVals.push_back(ret);
|
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();
|
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 {
|
FileWriter& file, std::vector<std::string>& functionNames) const {
|
||||||
|
|
||||||
// create the folder for the namespace
|
// create the folder for the namespace
|
||||||
const StrVec& ns = namespaces.front();
|
const Qualified& overload1 = overloads.front();
|
||||||
createNamespaceStructure(ns, toolboxPath);
|
createNamespaceStructure(overload1.namespaces, toolboxPath);
|
||||||
|
|
||||||
// open destination mfunctionFileName
|
// open destination mfunctionFileName
|
||||||
string mfunctionFileName = toolboxPath;
|
string mfunctionFileName = overload1.matlabName(toolboxPath);
|
||||||
if (!ns.empty())
|
|
||||||
mfunctionFileName += "/+" + wrap::qualifiedName("/+", ns);
|
|
||||||
mfunctionFileName += "/" + name + ".m";
|
|
||||||
FileWriter mfunctionFile(mfunctionFileName, verbose_, "%");
|
FileWriter mfunctionFile(mfunctionFileName, verbose_, "%");
|
||||||
|
|
||||||
// get the name of actual matlab object
|
// get the name of actual matlab object
|
||||||
const string matlabQualName = qualifiedName(".", ns, name), matlabUniqueName =
|
const string matlabQualName = overload1.qualifiedName(".");
|
||||||
qualifiedName("", ns, name), cppName = qualifiedName("::", ns, name);
|
const string matlabUniqueName = overload1.qualifiedName("");
|
||||||
|
const string cppName = overload1.qualifiedName("::");
|
||||||
|
|
||||||
mfunctionFile.oss << "function varargout = " << name << "(varargin)\n";
|
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
|
args.matlab_unwrap(file, 0); // We start at 0 because there is no self object
|
||||||
|
|
||||||
// call method with default type and wrap result
|
// call method with default type and wrap result
|
||||||
if (returnVal.type1 != "void")
|
if (returnVal.type1.name != "void")
|
||||||
returnVal.wrap_result(cppName + "(" + args.names() + ")", file,
|
returnVal.wrap_result(cppName + "(" + args.names() + ")", file,
|
||||||
typeAttributes);
|
typeAttributes);
|
||||||
else
|
else
|
||||||
|
|
|
@ -16,15 +16,13 @@ namespace wrap {
|
||||||
|
|
||||||
struct GlobalFunction {
|
struct GlobalFunction {
|
||||||
|
|
||||||
typedef std::vector<std::string> StrVec;
|
|
||||||
|
|
||||||
bool verbose_;
|
bool verbose_;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
// each overload, regardless of namespace
|
// 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<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
|
// Constructor only used in Module
|
||||||
GlobalFunction(bool verbose = true) :
|
GlobalFunction(bool verbose = true) :
|
||||||
|
@ -37,9 +35,8 @@ struct GlobalFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds an overloaded version of this function
|
// adds an overloaded version of this function
|
||||||
void addOverload(bool verbose, const std::string& name,
|
void addOverload(bool verbose, const Qualified& overload,
|
||||||
const ArgumentList& args, const ReturnValue& retVal,
|
const ArgumentList& args, const ReturnValue& retVal);
|
||||||
const StrVec& ns_stack);
|
|
||||||
|
|
||||||
// codegen function called from Module to build the cpp and matlab versions of the function
|
// codegen function called from Module to build the cpp and matlab versions of the function
|
||||||
void matlab_proxy(const std::string& toolboxPath,
|
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.isPair) {
|
||||||
if (returnVal.category1 == ReturnValue::CLASS)
|
if (returnVal.category1 == ReturnValue::CLASS)
|
||||||
file.oss << " typedef boost::shared_ptr<"
|
file.oss << " typedef boost::shared_ptr<"
|
||||||
<< returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1
|
<< returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1.name
|
||||||
<< ";" << endl;
|
<< ";" << endl;
|
||||||
if (returnVal.category2 == ReturnValue::CLASS)
|
if (returnVal.category2 == ReturnValue::CLASS)
|
||||||
file.oss << " typedef boost::shared_ptr<"
|
file.oss << " typedef boost::shared_ptr<"
|
||||||
<< returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2
|
<< returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2.name
|
||||||
<< ";" << endl;
|
<< ";" << endl;
|
||||||
} else if (returnVal.category1 == ReturnValue::CLASS)
|
} else if (returnVal.category1 == ReturnValue::CLASS)
|
||||||
file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::")
|
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;"
|
file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
@ -168,7 +168,7 @@ string Method::wrapper_fragment(FileWriter& file, const string& cppClassName,
|
||||||
|
|
||||||
// call method and wrap result
|
// call method and wrap result
|
||||||
// example: out[0]=wrap<bool>(self->return_field(t));
|
// 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,
|
returnVal.wrap_result("obj->" + name + "(" + args.names() + ")", file,
|
||||||
typeAttributes);
|
typeAttributes);
|
||||||
else
|
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
|
// If a number of template arguments were given, generate a number of expanded
|
||||||
// class names, e.g., PriorFactor -> PriorFactorPose2, and add those classes
|
// class names, e.g., PriorFactor -> PriorFactorPose2, and add those classes
|
||||||
static void handle_possible_template(vector<Class>& classes, const Class& cls,
|
static void handle_possible_template(vector<Class>& classes, const Class& cls,
|
||||||
const string& templateArgument,
|
const string& templateArgument, const vector<Qualified>& instantiations) {
|
||||||
const vector<vector<string> >& instantiations) {
|
|
||||||
if (instantiations.empty()) {
|
if (instantiations.empty()) {
|
||||||
classes.push_back(cls);
|
classes.push_back(cls);
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,7 +99,7 @@ Module::Module(const string& interfacePath,
|
||||||
void Module::parseMarkup(const std::string& data) {
|
void Module::parseMarkup(const std::string& data) {
|
||||||
// these variables will be imperatively updated to gradually build [cls]
|
// these variables will be imperatively updated to gradually build [cls]
|
||||||
// The one with postfix 0 are used to reset the variables after parse.
|
// The one with postfix 0 are used to reset the variables after parse.
|
||||||
string methodName, methodName0;
|
string methodName;
|
||||||
bool isConst, isConst0 = false;
|
bool isConst, isConst0 = false;
|
||||||
ReturnValue retVal0, retVal;
|
ReturnValue retVal0, retVal;
|
||||||
Argument arg0, arg;
|
Argument arg0, arg;
|
||||||
|
@ -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_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 =
|
Rule argEigenType_p =
|
||||||
eigenType_p[assign_a(arg.type)];
|
eigenType_p[assign_a(arg.type.name)];
|
||||||
|
|
||||||
Rule eigenRef_p =
|
Rule eigenRef_p =
|
||||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
!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)];
|
ch_p('&') [assign_a(arg.is_ref,true)];
|
||||||
|
|
||||||
Rule classArg_p =
|
Rule classArg_p =
|
||||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
!str_p("const") [assign_a(arg.is_const,true)] >>
|
||||||
*namespace_arg_p >>
|
*namespace_arg_p >>
|
||||||
className_p[assign_a(arg.type)] >>
|
className_p[assign_a(arg.type.name)] >>
|
||||||
!ch_p('&')[assign_a(arg.is_ref,true)];
|
!ch_p('&')[assign_a(arg.is_ref,true)];
|
||||||
|
|
||||||
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
||||||
|
|
||||||
Rule classParent_p =
|
Rule classParent_p =
|
||||||
*(namespace_name_p[push_back_a(cls.qualifiedParent)] >> str_p("::")) >>
|
*(namespace_name_p[push_back_a(cls.qualifiedParent.namespaces)] >> str_p("::")) >>
|
||||||
className_p[push_back_a(cls.qualifiedParent)];
|
className_p[assign_a(cls.qualifiedParent.name)];
|
||||||
|
|
||||||
// TODO: get rid of copy/paste below?
|
// TODO: get rid of copy/paste below?
|
||||||
|
|
||||||
// parse "gtsam::Pose2" and add to templateInstantiations
|
// parse "gtsam::Pose2" and add to templateInstantiations
|
||||||
vector<string> templateArgumentValue;
|
Qualified argValue;
|
||||||
vector<vector<string> > templateInstantiations;
|
vector<Qualified> templateInstantiations;
|
||||||
Rule templateInstantiation_p =
|
Rule templateInstantiation_p =
|
||||||
(*(namespace_name_p[push_back_a(templateArgumentValue)] >> str_p("::")) >>
|
(*(namespace_name_p[push_back_a(argValue.namespaces)] >> str_p("::")) >>
|
||||||
className_p[push_back_a(templateArgumentValue)])
|
className_p[assign_a(argValue.name)])
|
||||||
[push_back_a(templateInstantiations, templateArgumentValue)]
|
[push_back_a(templateInstantiations, argValue)]
|
||||||
[clear_a(templateArgumentValue)];
|
[clear_a(argValue)];
|
||||||
|
|
||||||
// template<CALIBRATION = {gtsam::Cal3DS2}>
|
// template<CALIBRATION = {gtsam::Cal3DS2}>
|
||||||
string templateArgument;
|
string templateArgument;
|
||||||
|
@ -187,12 +186,12 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
[push_back_a(cls.templateArgs, templateArgument)];
|
[push_back_a(cls.templateArgs, templateArgument)];
|
||||||
|
|
||||||
// parse "gtsam::Pose2" and add to methodInstantiations
|
// parse "gtsam::Pose2" and add to methodInstantiations
|
||||||
vector<vector<string> > methodInstantiations;
|
vector<Qualified> methodInstantiations;
|
||||||
Rule methodInstantiation_p =
|
Rule methodInstantiation_p =
|
||||||
(*(namespace_name_p[push_back_a(templateArgumentValue)] >> str_p("::")) >>
|
(*(namespace_name_p[push_back_a(argValue.namespaces)] >> str_p("::")) >>
|
||||||
className_p[push_back_a(templateArgumentValue)])
|
className_p[assign_a(argValue.name)])
|
||||||
[push_back_a(methodInstantiations, templateArgumentValue)]
|
[push_back_a(methodInstantiations, argValue)]
|
||||||
[clear_a(templateArgumentValue)];
|
[clear_a(argValue)];
|
||||||
|
|
||||||
// template<CALIBRATION = {gtsam::Cal3DS2}>
|
// template<CALIBRATION = {gtsam::Cal3DS2}>
|
||||||
string methodArgument;
|
string methodArgument;
|
||||||
|
@ -205,17 +204,17 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
// parse "gtsam::Pose2" and add to singleInstantiation.typeList
|
// parse "gtsam::Pose2" and add to singleInstantiation.typeList
|
||||||
TemplateInstantiationTypedef singleInstantiation;
|
TemplateInstantiationTypedef singleInstantiation;
|
||||||
Rule templateSingleInstantiationArg_p =
|
Rule templateSingleInstantiationArg_p =
|
||||||
(*(namespace_name_p[push_back_a(templateArgumentValue)] >> str_p("::")) >>
|
(*(namespace_name_p[push_back_a(argValue.namespaces)] >> str_p("::")) >>
|
||||||
className_p[push_back_a(templateArgumentValue)])
|
className_p[assign_a(argValue.name)])
|
||||||
[push_back_a(singleInstantiation.typeList, templateArgumentValue)]
|
[push_back_a(singleInstantiation.typeList, argValue)]
|
||||||
[clear_a(templateArgumentValue)];
|
[clear_a(argValue)];
|
||||||
|
|
||||||
// typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Point2> RangeFactorPosePoint2;
|
// typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Point2> RangeFactorPosePoint2;
|
||||||
TemplateInstantiationTypedef singleInstantiation0;
|
TemplateInstantiationTypedef singleInstantiation0;
|
||||||
Rule templateSingleInstantiation_p =
|
Rule templateSingleInstantiation_p =
|
||||||
(str_p("typedef") >>
|
(str_p("typedef") >>
|
||||||
*(namespace_name_p[push_back_a(singleInstantiation.classNamespaces)] >> str_p("::")) >>
|
*(namespace_name_p[push_back_a(singleInstantiation.class_.namespaces)] >> str_p("::")) >>
|
||||||
className_p[assign_a(singleInstantiation.className)] >>
|
className_p[assign_a(singleInstantiation.class_.name)] >>
|
||||||
'<' >> templateSingleInstantiationArg_p >> *(',' >> templateSingleInstantiationArg_p) >>
|
'<' >> templateSingleInstantiationArg_p >> *(',' >> templateSingleInstantiationArg_p) >>
|
||||||
'>' >>
|
'>' >>
|
||||||
className_p[assign_a(singleInstantiation.name)] >>
|
className_p[assign_a(singleInstantiation.name)] >>
|
||||||
|
@ -232,7 +231,7 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
|
|
||||||
// NOTE: allows for pointers to all types
|
// NOTE: allows for pointers to all types
|
||||||
Rule argument_p =
|
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)]
|
>> !ch_p('*')[assign_a(arg.is_ptr,true)]
|
||||||
>> name_p[assign_a(arg.name)])
|
>> name_p[assign_a(arg.name)])
|
||||||
[push_back_a(args, arg)]
|
[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;
|
static const ReturnValue::return_category RETURN_VOID = ReturnValue::VOID;
|
||||||
|
|
||||||
Rule returnType1_p =
|
Rule returnType1_p =
|
||||||
(basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, RETURN_BASIS)]) |
|
(basisType_p[assign_a(retVal.type1.name)][assign_a(retVal.category1, RETURN_BASIS)]) |
|
||||||
((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)]
|
((*namespace_ret_p)[assign_a(retVal.type1.namespaces, namespaces_return)][clear_a(namespaces_return)]
|
||||||
>> (className_p[assign_a(retVal.type1)][assign_a(retVal.category1, RETURN_CLASS)]) >>
|
>> (className_p[assign_a(retVal.type1.name)][assign_a(retVal.category1, RETURN_CLASS)]) >>
|
||||||
!ch_p('*')[assign_a(retVal.isPtr1,true)]) |
|
!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 =
|
Rule returnType2_p =
|
||||||
(basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, RETURN_BASIS)]) |
|
(basisType_p[assign_a(retVal.type2.name)][assign_a(retVal.category2, RETURN_BASIS)]) |
|
||||||
((*namespace_ret_p)[assign_a(retVal.namespaces2, namespaces_return)][clear_a(namespaces_return)]
|
((*namespace_ret_p)[assign_a(retVal.type2.namespaces, namespaces_return)][clear_a(namespaces_return)]
|
||||||
>> (className_p[assign_a(retVal.type2)][assign_a(retVal.category2, RETURN_CLASS)]) >>
|
>> (className_p[assign_a(retVal.type2.name)][assign_a(retVal.category2, RETURN_CLASS)]) >>
|
||||||
!ch_p('*') [assign_a(retVal.isPtr2,true)]) |
|
!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 =
|
Rule pair_p =
|
||||||
(str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>')
|
(str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>')
|
||||||
[assign_a(retVal.isPair,true)];
|
[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;
|
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(args),
|
||||||
bl::var(retVal))]
|
bl::var(retVal))]
|
||||||
[assign_a(isConst,isConst0)]
|
[assign_a(isConst,isConst0)]
|
||||||
[assign_a(methodName,methodName0)]
|
[clear_a(methodName)]
|
||||||
[assign_a(args,args0)]
|
[assign_a(args,args0)]
|
||||||
[assign_a(retVal,retVal0)];
|
[assign_a(retVal,retVal0)];
|
||||||
|
|
||||||
|
@ -310,7 +309,7 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
bl::var(methodName),
|
bl::var(methodName),
|
||||||
bl::var(args),
|
bl::var(args),
|
||||||
bl::var(retVal))]
|
bl::var(retVal))]
|
||||||
[assign_a(methodName,methodName0)]
|
[clear_a(methodName)]
|
||||||
[assign_a(args,args0)]
|
[assign_a(args,args0)]
|
||||||
[assign_a(retVal,retVal0)];
|
[assign_a(retVal,retVal0)];
|
||||||
|
|
||||||
|
@ -337,17 +336,18 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
[clear_a(templateArgument)]
|
[clear_a(templateArgument)]
|
||||||
[clear_a(templateInstantiations)];
|
[clear_a(templateInstantiations)];
|
||||||
|
|
||||||
|
Qualified globalFunction;
|
||||||
Rule global_function_p =
|
Rule global_function_p =
|
||||||
(returnType_p >> staticMethodName_p[assign_a(methodName)] >>
|
(returnType_p >> staticMethodName_p[assign_a(globalFunction.name)] >>
|
||||||
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
||||||
|
[assign_a(globalFunction.namespaces,namespaces)]
|
||||||
[bl::bind(&GlobalFunction::addOverload,
|
[bl::bind(&GlobalFunction::addOverload,
|
||||||
bl::var(global_functions)[bl::var(methodName)],
|
bl::var(global_functions)[bl::var(globalFunction.name)],
|
||||||
verbose,
|
verbose,
|
||||||
bl::var(methodName),
|
bl::var(globalFunction),
|
||||||
bl::var(args),
|
bl::var(args),
|
||||||
bl::var(retVal),
|
bl::var(retVal))]
|
||||||
bl::var(namespaces))]
|
[clear_a(globalFunction)]
|
||||||
[assign_a(methodName,methodName0)]
|
|
||||||
[assign_a(args,args0)]
|
[assign_a(args,args0)]
|
||||||
[assign_a(retVal,retVal0)];
|
[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;
|
const T& t = name_method.second;
|
||||||
BOOST_FOREACH(const ArgumentList& argList, t.argLists) {
|
BOOST_FOREACH(const ArgumentList& argList, t.argLists) {
|
||||||
BOOST_FOREACH(Argument arg, argList) {
|
BOOST_FOREACH(Argument arg, argList) {
|
||||||
string fullType = arg.qualifiedType("::");
|
string fullType = arg.type.qualifiedName("::");
|
||||||
if(find(validArgs.begin(), validArgs.end(), fullType)
|
if(find(validArgs.begin(), validArgs.end(), fullType)
|
||||||
== validArgs.end())
|
== validArgs.end())
|
||||||
throw DependencyMissing(fullType, t.name);
|
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);
|
verifyReturnTypes<Method>(validTypes, cls.methods);
|
||||||
|
|
||||||
// verify parents
|
// verify parents
|
||||||
if(!cls.qualifiedParent.empty() && std::find(validTypes.begin(), validTypes.end(), wrap::qualifiedName("::", cls.qualifiedParent)) == validTypes.end())
|
Qualified parent = cls.qualifiedParent;
|
||||||
throw DependencyMissing(wrap::qualifiedName("::", cls.qualifiedParent), cls.qualifiedName("::"));
|
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
|
// Create type attributes table and check validity
|
||||||
|
@ -606,7 +607,7 @@ map<string, Method> Module::appendInheretedMethods(const Class& cls, const vecto
|
||||||
//Find Class
|
//Find Class
|
||||||
BOOST_FOREACH(const Class& parent, classes) {
|
BOOST_FOREACH(const Class& parent, classes) {
|
||||||
//We found the class for our parent
|
//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 inhereted = appendInheretedMethods(parent, classes);
|
||||||
methods.insert(inhereted.begin(), inhereted.end());
|
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 {
|
string ReturnValue::return_type(bool add_ptr, pairing p) const {
|
||||||
if (p==pair && isPair) {
|
if (p == pair && isPair) {
|
||||||
string str = "pair< " +
|
string str = "pair< "
|
||||||
maybe_shared_ptr(add_ptr || isPtr1, qualifiedType1("::"), type1) + ", " +
|
+ maybe_shared_ptr(add_ptr || isPtr1, qualifiedType1("::"), type1.name)
|
||||||
maybe_shared_ptr(add_ptr || isPtr2, qualifiedType2("::"), type2) + " >";
|
+ ", "
|
||||||
|
+ maybe_shared_ptr(add_ptr || isPtr2, qualifiedType2("::"), type2.name)
|
||||||
|
+ " >";
|
||||||
return str;
|
return str;
|
||||||
} else
|
} 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 ReturnValue::qualifiedType1(const string& delim) const {
|
||||||
string result;
|
return type1.qualifiedName(delim);
|
||||||
BOOST_FOREACH(const string& ns, namespaces1) result += ns + delim;
|
|
||||||
return result + type1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
string ReturnValue::qualifiedType2(const string& delim) const {
|
string ReturnValue::qualifiedType2(const string& delim) const {
|
||||||
string result;
|
return type2.qualifiedName(delim);
|
||||||
BOOST_FOREACH(const string& ns, namespaces2) result += ns + delim;
|
|
||||||
return result + type2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -58,7 +58,7 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type
|
||||||
// first return value in pair
|
// first return value in pair
|
||||||
if (category1 == ReturnValue::CLASS) { // if we are going to make one
|
if (category1 == ReturnValue::CLASS) { // if we are going to make one
|
||||||
string objCopy, ptrType;
|
string objCopy, ptrType;
|
||||||
ptrType = "Shared" + type1;
|
ptrType = "Shared" + type1.name;
|
||||||
const bool isVirtual = typeAttributes.at(cppType1).isVirtual;
|
const bool isVirtual = typeAttributes.at(cppType1).isVirtual;
|
||||||
if(isVirtual) {
|
if(isVirtual) {
|
||||||
if(isPtr1)
|
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";
|
file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n";
|
||||||
} else if(isPtr1) {
|
} 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";
|
file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\", false);\n";
|
||||||
} else // if basis type
|
} else // if basis type
|
||||||
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(pairResult.first);\n";
|
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
|
// second return value in pair
|
||||||
if (category2 == ReturnValue::CLASS) { // if we are going to make one
|
if (category2 == ReturnValue::CLASS) { // if we are going to make one
|
||||||
string objCopy, ptrType;
|
string objCopy, ptrType;
|
||||||
ptrType = "Shared" + type2;
|
ptrType = "Shared" + type2.name;
|
||||||
const bool isVirtual = typeAttributes.at(cppType2).isVirtual;
|
const bool isVirtual = typeAttributes.at(cppType2).isVirtual;
|
||||||
if(isVirtual) {
|
if(isVirtual) {
|
||||||
if(isPtr2)
|
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";
|
file.oss << " out[1] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType2 << "\", " << (isVirtual ? "true" : "false") << ");\n";
|
||||||
} else if(isPtr2) {
|
} 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";
|
file.oss << " out[1] = wrap_shared_ptr(ret,\"" << matlabType2 << "\");\n";
|
||||||
} else
|
} else
|
||||||
file.oss << " out[1] = wrap< " << return_type(true,arg2) << " >(pairResult.second);\n";
|
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) {
|
if (category1 == ReturnValue::CLASS) {
|
||||||
string objCopy, ptrType;
|
string objCopy, ptrType;
|
||||||
ptrType = "Shared" + type1;
|
ptrType = "Shared" + type1.name;
|
||||||
const bool isVirtual = typeAttributes.at(cppType1).isVirtual;
|
const bool isVirtual = typeAttributes.at(cppType1).isVirtual;
|
||||||
if(isVirtual) {
|
if(isVirtual) {
|
||||||
if(isPtr1)
|
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";
|
file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n";
|
||||||
} else if(isPtr1) {
|
} 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";
|
file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\");\n";
|
||||||
} else if (matlabType1!="void")
|
} else if (matlabType1!="void")
|
||||||
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ");\n";
|
file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ");\n";
|
||||||
|
@ -131,13 +131,13 @@ void ReturnValue::wrapTypeUnwrap(FileWriter& wrapperFile) const {
|
||||||
if(isPair)
|
if(isPair)
|
||||||
{
|
{
|
||||||
if(category1 == ReturnValue::CLASS)
|
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)
|
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 {
|
else {
|
||||||
if (category1 == ReturnValue::CLASS)
|
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 "FileWriter.h"
|
||||||
#include "TypeAttributesTable.h"
|
#include "TypeAttributesTable.h"
|
||||||
|
#include "Qualified.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -29,8 +28,7 @@ struct ReturnValue {
|
||||||
|
|
||||||
bool isPtr1, isPtr2, isPair;
|
bool isPtr1, isPtr2, isPair;
|
||||||
return_category category1, category2;
|
return_category category1, category2;
|
||||||
std::string type1, type2;
|
Qualified type1, type2;
|
||||||
std::vector<std::string> namespaces1, namespaces2;
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ReturnValue() :
|
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
|
args.matlab_unwrap(file, 0); // We start at 0 because there is no self object
|
||||||
|
|
||||||
// call method with default type and wrap result
|
// call method with default type and wrap result
|
||||||
if (returnVal.type1 != "void")
|
if (returnVal.type1.name != "void")
|
||||||
returnVal.wrap_result(cppClassName + "::" + name + "(" + args.names() + ")",
|
returnVal.wrap_result(cppClassName + "::" + name + "(" + args.names() + ")",
|
||||||
file, typeAttributes);
|
file, typeAttributes);
|
||||||
else
|
else
|
||||||
|
|
|
@ -19,43 +19,48 @@
|
||||||
#include "TemplateInstantiationTypedef.h"
|
#include "TemplateInstantiationTypedef.h"
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
Class TemplateInstantiationTypedef::findAndExpand(const vector<Class>& classes) const {
|
Class TemplateInstantiationTypedef::findAndExpand(
|
||||||
// Find matching class
|
const vector<Class>& classes) const {
|
||||||
std::vector<Class>::const_iterator clsIt = classes.end();
|
// Find matching class
|
||||||
for(std::vector<Class>::const_iterator it = classes.begin(); it != classes.end(); ++it) {
|
boost::optional<Class const &> matchedClass;
|
||||||
if(it->name == className && it->namespaces == classNamespaces && it->templateArgs.size() == typeList.size()) {
|
BOOST_FOREACH(const Class& cls, classes) {
|
||||||
clsIt = it;
|
if (cls.name == class_.name && cls.namespaces == class_.namespaces
|
||||||
break;
|
&& 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,12 +26,9 @@
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
struct TemplateInstantiationTypedef {
|
struct TemplateInstantiationTypedef : public Qualified {
|
||||||
std::vector<std::string> classNamespaces;
|
Qualified class_;
|
||||||
std::string className;
|
std::vector<Qualified> typeList;
|
||||||
std::vector<std::string> namespaces;
|
|
||||||
std::string name;
|
|
||||||
std::vector<std::vector<std::string> > typeList;
|
|
||||||
|
|
||||||
Class findAndExpand(const std::vector<Class>& classes) const;
|
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 ) {
|
TEST( wrap, ArgumentList ) {
|
||||||
ArgumentList args;
|
ArgumentList args;
|
||||||
Argument arg1; arg1.type = "double"; arg1.name = "x";
|
Argument arg1; arg1.type.name = "double"; arg1.name = "x";
|
||||||
Argument arg2; arg2.type = "double"; arg2.name = "y";
|
Argument arg2; arg2.type.name = "double"; arg2.name = "y";
|
||||||
Argument arg3; arg3.type = "double"; arg3.name = "z";
|
Argument arg3; arg3.type.name = "double"; arg3.name = "z";
|
||||||
args.push_back(arg1);
|
args.push_back(arg1);
|
||||||
args.push_back(arg2);
|
args.push_back(arg2);
|
||||||
args.push_back(arg3);
|
args.push_back(arg3);
|
||||||
|
@ -105,7 +105,7 @@ TEST( wrap, small_parse ) {
|
||||||
ReturnValue rv1 = m1.returnVals.front();
|
ReturnValue rv1 = m1.returnVals.front();
|
||||||
EXPECT(!rv1.isPair);
|
EXPECT(!rv1.isPair);
|
||||||
EXPECT(!rv1.isPtr1);
|
EXPECT(!rv1.isPtr1);
|
||||||
EXPECT(assert_equal("double", rv1.type1));
|
EXPECT(assert_equal("double", rv1.type1.name));
|
||||||
EXPECT_LONGS_EQUAL(ReturnValue::BASIS, rv1.category1);
|
EXPECT_LONGS_EQUAL(ReturnValue::BASIS, rv1.category1);
|
||||||
|
|
||||||
// Method 2
|
// Method 2
|
||||||
|
@ -118,7 +118,7 @@ TEST( wrap, small_parse ) {
|
||||||
ReturnValue rv2 = m2.returnVals.front();
|
ReturnValue rv2 = m2.returnVals.front();
|
||||||
EXPECT(!rv2.isPair);
|
EXPECT(!rv2.isPair);
|
||||||
EXPECT(!rv2.isPtr1);
|
EXPECT(!rv2.isPtr1);
|
||||||
EXPECT(assert_equal("Matrix", rv2.type1));
|
EXPECT(assert_equal("Matrix", rv2.type1.name));
|
||||||
EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv2.category1);
|
EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv2.category1);
|
||||||
|
|
||||||
// Method 3
|
// Method 3
|
||||||
|
@ -131,7 +131,7 @@ TEST( wrap, small_parse ) {
|
||||||
ReturnValue rv3 = m3.returnVals.front();
|
ReturnValue rv3 = m3.returnVals.front();
|
||||||
EXPECT(!rv3.isPair);
|
EXPECT(!rv3.isPair);
|
||||||
EXPECT(!rv3.isPtr1);
|
EXPECT(!rv3.isPtr1);
|
||||||
EXPECT(assert_equal("Point2", rv3.type1));
|
EXPECT(assert_equal("Point2", rv3.type1.name));
|
||||||
EXPECT_LONGS_EQUAL(ReturnValue::CLASS, rv3.category1);
|
EXPECT_LONGS_EQUAL(ReturnValue::CLASS, rv3.category1);
|
||||||
|
|
||||||
// Static Method 1
|
// Static Method 1
|
||||||
|
@ -144,7 +144,7 @@ TEST( wrap, small_parse ) {
|
||||||
ReturnValue rv4 = sm1.returnVals.front();
|
ReturnValue rv4 = sm1.returnVals.front();
|
||||||
EXPECT(!rv4.isPair);
|
EXPECT(!rv4.isPair);
|
||||||
EXPECT(!rv4.isPtr1);
|
EXPECT(!rv4.isPtr1);
|
||||||
EXPECT(assert_equal("Vector", rv4.type1));
|
EXPECT(assert_equal("Vector", rv4.type1.name));
|
||||||
EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv4.category1);
|
EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv4.category1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ TEST( wrap, parse_geometry ) {
|
||||||
CHECK(cls.methods.find("returnChar") != cls.methods.end());
|
CHECK(cls.methods.find("returnChar") != cls.methods.end());
|
||||||
Method m1 = cls.methods.find("returnChar")->second;
|
Method m1 = cls.methods.find("returnChar")->second;
|
||||||
LONGS_EQUAL(1, m1.returnVals.size());
|
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_LONGS_EQUAL(ReturnValue::BASIS, m1.returnVals.front().category1);
|
||||||
EXPECT(!m1.returnVals.front().isPair);
|
EXPECT(!m1.returnVals.front().isPair);
|
||||||
EXPECT(assert_equal("returnChar", m1.name));
|
EXPECT(assert_equal("returnChar", m1.name));
|
||||||
|
@ -210,7 +210,7 @@ TEST( wrap, parse_geometry ) {
|
||||||
CHECK(cls.methods.find("vectorConfusion") != cls.methods.end());
|
CHECK(cls.methods.find("vectorConfusion") != cls.methods.end());
|
||||||
Method m1 = cls.methods.find("vectorConfusion")->second;
|
Method m1 = cls.methods.find("vectorConfusion")->second;
|
||||||
LONGS_EQUAL(1, m1.returnVals.size());
|
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_LONGS_EQUAL(ReturnValue::CLASS, m1.returnVals.front().category1);
|
||||||
EXPECT(!m1.returnVals.front().isPair);
|
EXPECT(!m1.returnVals.front().isPair);
|
||||||
EXPECT(assert_equal("vectorConfusion", m1.name));
|
EXPECT(assert_equal("vectorConfusion", m1.name));
|
||||||
|
@ -245,7 +245,7 @@ TEST( wrap, parse_geometry ) {
|
||||||
// check first double argument
|
// check first double argument
|
||||||
Argument a1 = c1.front();
|
Argument a1 = c1.front();
|
||||||
EXPECT(!a1.is_const);
|
EXPECT(!a1.is_const);
|
||||||
EXPECT(assert_equal("double", a1.type));
|
EXPECT(assert_equal("double", a1.type.name));
|
||||||
EXPECT(!a1.is_ref);
|
EXPECT(!a1.is_ref);
|
||||||
EXPECT(assert_equal("x", a1.name));
|
EXPECT(assert_equal("x", a1.name));
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ TEST( wrap, parse_geometry ) {
|
||||||
CHECK(cls.methods.find("norm") != cls.methods.end());
|
CHECK(cls.methods.find("norm") != cls.methods.end());
|
||||||
Method m1 = cls.methods.find("norm")->second;
|
Method m1 = cls.methods.find("norm")->second;
|
||||||
LONGS_EQUAL(1, m1.returnVals.size());
|
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_LONGS_EQUAL(ReturnValue::BASIS, m1.returnVals.front().category1);
|
||||||
EXPECT(assert_equal("norm", m1.name));
|
EXPECT(assert_equal("norm", m1.name));
|
||||||
LONGS_EQUAL(1, m1.argLists.size());
|
LONGS_EQUAL(1, m1.argLists.size());
|
||||||
|
@ -281,9 +281,9 @@ TEST( wrap, parse_geometry ) {
|
||||||
LONGS_EQUAL(1, m2.returnVals.size());
|
LONGS_EQUAL(1, m2.returnVals.size());
|
||||||
EXPECT(m2.returnVals.front().isPair);
|
EXPECT(m2.returnVals.front().isPair);
|
||||||
EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, m2.returnVals.front().category1);
|
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_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
|
// checking pointer args and return values
|
||||||
// pair<Test*,Test*> return_ptrs (Test* p1, Test* p2) const;
|
// 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_ptr);
|
||||||
EXPECT(!arg1.is_const);
|
EXPECT(!arg1.is_const);
|
||||||
EXPECT(!arg1.is_ref);
|
EXPECT(!arg1.is_ref);
|
||||||
EXPECT(assert_equal("Test", arg1.type));
|
EXPECT(assert_equal("Test", arg1.type.name));
|
||||||
EXPECT(assert_equal("p1", arg1.name));
|
EXPECT(assert_equal("p1", arg1.name));
|
||||||
EXPECT(arg1.namespaces.empty());
|
EXPECT(arg1.type.namespaces.empty());
|
||||||
|
|
||||||
Argument arg2 = args.at(1);
|
Argument arg2 = args.at(1);
|
||||||
EXPECT(arg2.is_ptr);
|
EXPECT(arg2.is_ptr);
|
||||||
EXPECT(!arg2.is_const);
|
EXPECT(!arg2.is_const);
|
||||||
EXPECT(!arg2.is_ref);
|
EXPECT(!arg2.is_ref);
|
||||||
EXPECT(assert_equal("Test", arg2.type));
|
EXPECT(assert_equal("Test", arg2.type.name));
|
||||||
EXPECT(assert_equal("p2", arg2.name));
|
EXPECT(assert_equal("p2", arg2.name));
|
||||||
EXPECT(arg2.namespaces.empty());
|
EXPECT(arg2.type.namespaces.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
// evaluate global functions
|
// evaluate global functions
|
||||||
|
@ -318,10 +318,10 @@ TEST( wrap, parse_geometry ) {
|
||||||
GlobalFunction gfunc = module.global_functions.at("aGlobalFunction");
|
GlobalFunction gfunc = module.global_functions.at("aGlobalFunction");
|
||||||
EXPECT(assert_equal("aGlobalFunction", gfunc.name));
|
EXPECT(assert_equal("aGlobalFunction", gfunc.name));
|
||||||
LONGS_EQUAL(1, gfunc.returnVals.size());
|
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());
|
EXPECT_LONGS_EQUAL(1, gfunc.argLists.size());
|
||||||
LONGS_EQUAL(1, gfunc.namespaces.size());
|
LONGS_EQUAL(1, gfunc.overloads.size());
|
||||||
EXPECT(gfunc.namespaces.front().empty());
|
EXPECT(gfunc.overloads.front().namespaces.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,16 +392,16 @@ TEST( wrap, parse_namespaces ) {
|
||||||
GlobalFunction gfunc = module.global_functions.at("aGlobalFunction");
|
GlobalFunction gfunc = module.global_functions.at("aGlobalFunction");
|
||||||
EXPECT(assert_equal("aGlobalFunction", gfunc.name));
|
EXPECT(assert_equal("aGlobalFunction", gfunc.name));
|
||||||
LONGS_EQUAL(2, gfunc.returnVals.size());
|
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());
|
EXPECT_LONGS_EQUAL(2, gfunc.argLists.size());
|
||||||
|
|
||||||
// check namespaces
|
// check namespaces
|
||||||
LONGS_EQUAL(2, gfunc.namespaces.size());
|
LONGS_EQUAL(2, gfunc.overloads.size());
|
||||||
strvec exp_namespaces1; exp_namespaces1 += "ns1";
|
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";
|
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;
|
string result;
|
||||||
if(!names.empty()) {
|
if (!names.empty()) {
|
||||||
for(size_t i = 0; i < names.size() - 1; ++i)
|
for (size_t i = 0; i < names.size() - 1; ++i)
|
||||||
result += (names[i] + separator);
|
result += (names[i] + separator);
|
||||||
if(finalName.empty())
|
result += names.back();
|
||||||
result += names.back();
|
|
||||||
else
|
|
||||||
result += (names.back() + separator + finalName);
|
|
||||||
} else if(!finalName.empty()) {
|
|
||||||
result = finalName;
|
|
||||||
}
|
}
|
||||||
return result;
|
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;
|
using namespace boost::filesystem;
|
||||||
path curPath = toolboxPath;
|
path curPath = toolboxPath;
|
||||||
BOOST_FOREACH(const string& subdir, namespaces) {
|
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);
|
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
|
* Return a qualified name
|
||||||
* be used (i.e. there won't be a trailing separator on the 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 */
|
/** 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
|
} // \namespace wrap
|
||||||
|
|
Loading…
Reference in New Issue