Semi-private name/namespaces

release/4.3a0
dellaert 2014-11-30 20:12:03 +01:00
parent f1c91d5d4b
commit 6d916c6b75
20 changed files with 445 additions and 388 deletions

View File

@ -50,25 +50,25 @@ ArgumentList ArgumentList::expandTemplate(
/* ************************************************************************* */ /* ************************************************************************* */
string Argument::matlabClass(const string& delim) const { string Argument::matlabClass(const string& delim) const {
string result; string result;
BOOST_FOREACH(const string& ns, type.namespaces) BOOST_FOREACH(const string& ns, type.namespaces())
result += ns + delim; result += ns + delim;
if (type.name == "string" || type.name == "unsigned char" if (type.name() == "string" || type.name() == "unsigned char"
|| type.name == "char") || type.name() == "char")
return result + "char"; return result + "char";
if (type.name == "Vector" || type.name == "Matrix") if (type.name() == "Vector" || type.name() == "Matrix")
return result + "double"; return result + "double";
if (type.name == "int" || type.name == "size_t") if (type.name() == "int" || type.name() == "size_t")
return result + "numeric"; return result + "numeric";
if (type.name == "bool") if (type.name() == "bool")
return result + "logical"; return result + "logical";
return result + type.name; return result + type.name();
} }
/* ************************************************************************* */ /* ************************************************************************* */
bool Argument::isScalar() const { bool Argument::isScalar() const {
return (type.name == "bool" || type.name == "char" return (type.name() == "bool" || type.name() == "char"
|| type.name == "unsigned char" || type.name == "int" || type.name() == "unsigned char" || type.name() == "int"
|| type.name == "size_t" || type.name == "double"); || type.name() == "size_t" || type.name() == "double");
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -102,7 +102,7 @@ void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const {
/* ************************************************************************* */ /* ************************************************************************* */
void Argument::proxy_check(FileWriter& proxyFile, const string& s) const { void Argument::proxy_check(FileWriter& proxyFile, const string& s) const {
proxyFile.oss << "isa(" << s << ",'" << matlabClass(".") << "')"; proxyFile.oss << "isa(" << s << ",'" << matlabClass(".") << "')";
if (type.name == "Vector") if (type.name() == "Vector")
proxyFile.oss << " && size(" << s << ",2)==1"; proxyFile.oss << " && size(" << s << ",2)==1";
} }
@ -113,7 +113,7 @@ string ArgumentList::types() const {
BOOST_FOREACH(Argument arg, *this) { BOOST_FOREACH(Argument arg, *this) {
if (!first) if (!first)
str += ","; str += ",";
str += arg.type.name; str += arg.type.name();
first = false; first = false;
} }
return str; return str;
@ -125,14 +125,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.name) 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.name[0]; sig += arg.type.name()[0];
//Reset to default //Reset to default
cap = false; cap = false;
} }
@ -179,7 +179,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.name << " " << arg.name; file.oss << arg.type.name() << " " << arg.name;
first = false; first = false;
} }
file.oss << ")"; file.oss << ")";

View File

@ -57,7 +57,7 @@ void Class::matlab_proxy(Str toolboxPath, Str wrapperName,
vector<string>& functionNames) const { vector<string>& functionNames) const {
// Create namespace folders // Create namespace folders
createNamespaceStructure(namespaces, toolboxPath); createNamespaceStructure(namespaces(), toolboxPath);
// open destination classFile // open destination classFile
string classFile = matlabName(toolboxPath); string classFile = matlabName(toolboxPath);
@ -74,14 +74,14 @@ void Class::matlab_proxy(Str toolboxPath, Str wrapperName,
// we want our class to inherit the handle class for memory purposes // we want our class to inherit the handle class for memory purposes
const string parent = qualifiedParent.empty() ? "handle" : matlabBaseName; const string parent = qualifiedParent.empty() ? "handle" : matlabBaseName;
comment_fragment(proxyFile); comment_fragment(proxyFile);
proxyFile.oss << "classdef " << name << " < " << parent << endl; proxyFile.oss << "classdef " << name() << " < " << parent << endl;
proxyFile.oss << " properties\n"; proxyFile.oss << " properties\n";
proxyFile.oss << " ptr_" << matlabUniqueName << " = 0\n"; proxyFile.oss << " ptr_" << matlabUniqueName << " = 0\n";
proxyFile.oss << " end\n"; proxyFile.oss << " end\n";
proxyFile.oss << " methods\n"; proxyFile.oss << " methods\n";
// Constructor // Constructor
proxyFile.oss << " function obj = " << name << "(varargin)\n"; proxyFile.oss << " function obj = " << name() << "(varargin)\n";
// Special pointer constructors - one in MATLAB to create an object and // Special pointer constructors - one in MATLAB to create an object and
// assign a pointer returned from a C++ function. In turn this MATLAB // assign a pointer returned from a C++ function. In turn this MATLAB
// constructor calls a special C++ function that just adds the object to // constructor calls a special C++ function that just adds the object to
@ -266,7 +266,7 @@ Class Class::expandTemplate(const TemplateSubstitution& ts) const {
inst.methods_ = expandMethodTemplate(methods_, ts); inst.methods_ = expandMethodTemplate(methods_, ts);
inst.static_methods = expandMethodTemplate(static_methods, ts); inst.static_methods = expandMethodTemplate(static_methods, ts);
inst.constructor = constructor.expandTemplate(ts); inst.constructor = constructor.expandTemplate(ts);
inst.deconstructor.name = inst.name; inst.deconstructor.name = inst.name();
return inst; return inst;
} }
@ -276,10 +276,10 @@ vector<Class> Class::expandTemplate(Str templateArg,
vector<Class> result; vector<Class> result;
BOOST_FOREACH(const Qualified& instName, instantiations) { BOOST_FOREACH(const Qualified& instName, instantiations) {
Qualified expandedClass = (Qualified) (*this); Qualified expandedClass = (Qualified) (*this);
expandedClass.name += instName.name; expandedClass.expand(instName.name());
const TemplateSubstitution ts(templateArg, instName, expandedClass); const TemplateSubstitution ts(templateArg, instName, expandedClass);
Class inst = expandTemplate(ts); Class inst = expandTemplate(ts);
inst.name = expandedClass.name; inst.name_ = expandedClass.name();
inst.templateArgs.clear(); inst.templateArgs.clear();
inst.typedefName = qualifiedName("::") + "<" + instName.qualifiedName("::") inst.typedefName = qualifiedName("::") + "<" + instName.qualifiedName("::")
+ ">"; + ">";
@ -297,14 +297,14 @@ void Class::addMethod(bool verbose, bool is_const, Str methodName,
// Create method to expand // Create method to expand
// For all values of the template argument, create a new method // For all values of the template argument, create a new method
BOOST_FOREACH(const Qualified& instName, templateArgValues) { BOOST_FOREACH(const Qualified& instName, templateArgValues) {
const TemplateSubstitution ts(templateArgName, instName, this->name); const TemplateSubstitution ts(templateArgName, instName, name());
// substitute template in arguments // substitute template in arguments
ArgumentList expandedArgs = argumentList.expandTemplate(ts); ArgumentList expandedArgs = argumentList.expandTemplate(ts);
// do the same for return type // do the same for return type
ReturnValue expandedRetVal = returnValue.expandTemplate(ts); ReturnValue expandedRetVal = returnValue.expandTemplate(ts);
// Now stick in new overload stack with expandedMethodName key // Now stick in new overload stack with expandedMethodName key
// but note we use the same, unexpanded methodName in overload // but note we use the same, unexpanded methodName in overload
string expandedMethodName = methodName + instName.name; string expandedMethodName = methodName + instName.name();
methods_[expandedMethodName].addOverload(methodName, expandedArgs, methods_[expandedMethodName].addOverload(methodName, expandedArgs,
expandedRetVal, is_const, instName, verbose); expandedRetVal, is_const, instName, verbose);
} }
@ -369,7 +369,7 @@ void Class::appendInheritedMethods(const Class& cls,
// Find parent // Find parent
BOOST_FOREACH(const Class& parent, classes) { BOOST_FOREACH(const Class& parent, classes) {
// We found a parent class for our parent, TODO improve ! // We found a parent class for our parent, TODO improve !
if (parent.name == cls.qualifiedParent.name) { if (parent.name() == cls.qualifiedParent.name()) {
methods_.insert(parent.methods_.begin(), parent.methods_.end()); methods_.insert(parent.methods_.begin(), parent.methods_.end());
appendInheritedMethods(parent, classes); appendInheritedMethods(parent, classes);
} }
@ -380,11 +380,11 @@ void Class::appendInheritedMethods(const Class& cls,
/* ************************************************************************* */ /* ************************************************************************* */
string Class::getTypedef() const { string Class::getTypedef() const {
string result; string result;
BOOST_FOREACH(Str namesp, namespaces) { BOOST_FOREACH(Str namesp, namespaces()) {
result += ("namespace " + namesp + " { "); result += ("namespace " + namesp + " { ");
} }
result += ("typedef " + typedefName + " " + name + ";"); result += ("typedef " + typedefName + " " + name() + ";");
for (size_t i = 0; i < namespaces.size(); ++i) { for (size_t i = 0; i < namespaces().size(); ++i) {
result += " }"; result += " }";
} }
return result; return result;
@ -392,7 +392,7 @@ string Class::getTypedef() const {
/* ************************************************************************* */ /* ************************************************************************* */
void Class::comment_fragment(FileWriter& proxyFile) const { void Class::comment_fragment(FileWriter& proxyFile) const {
proxyFile.oss << "%class " << name << ", see Doxygen page for details\n"; proxyFile.oss << "%class " << name() << ", see Doxygen page for details\n";
proxyFile.oss proxyFile.oss
<< "%at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html\n"; << "%at http://research.cc.gatech.edu/borg/sites/edu.borg/html/index.html\n";
@ -412,7 +412,7 @@ void Class::comment_fragment(FileWriter& proxyFile) const {
proxyFile.oss << "%\n%-------Serialization Interface-------\n"; proxyFile.oss << "%\n%-------Serialization Interface-------\n";
proxyFile.oss << "%string_serialize() : returns string\n"; proxyFile.oss << "%string_serialize() : returns string\n";
proxyFile.oss << "%string_deserialize(string serialized) : returns " proxyFile.oss << "%string_deserialize(string serialized) : returns "
<< this->name << "\n"; << name() << "\n";
} }
proxyFile.oss << "%\n"; proxyFile.oss << "%\n";
@ -605,12 +605,12 @@ string Class::getSerializationExport() const {
/* ************************************************************************* */ /* ************************************************************************* */
void Class::python_wrapper(FileWriter& wrapperFile) const { void Class::python_wrapper(FileWriter& wrapperFile) const {
wrapperFile.oss << "class_<" << name << ">(\"" << name << "\")\n"; wrapperFile.oss << "class_<" << name() << ">(\"" << name() << "\")\n";
constructor.python_wrapper(wrapperFile, name); constructor.python_wrapper(wrapperFile, name());
BOOST_FOREACH(const StaticMethod& m, static_methods | boost::adaptors::map_values) BOOST_FOREACH(const StaticMethod& m, static_methods | boost::adaptors::map_values)
m.python_wrapper(wrapperFile, name); m.python_wrapper(wrapperFile, name());
BOOST_FOREACH(const Method& m, methods_ | boost::adaptors::map_values) BOOST_FOREACH(const Method& m, methods_ | boost::adaptors::map_values)
m.python_wrapper(wrapperFile, name); m.python_wrapper(wrapperFile, name());
wrapperFile.oss << ";\n\n"; wrapperFile.oss << ";\n\n";
} }

View File

@ -117,7 +117,7 @@ public:
void python_wrapper(FileWriter& wrapperFile) const; void python_wrapper(FileWriter& wrapperFile) const;
friend std::ostream& operator<<(std::ostream& os, const Class& cls) { friend std::ostream& operator<<(std::ostream& os, const Class& cls) {
os << "class " << cls.name << "{\n"; os << "class " << cls.name() << "{\n";
os << cls.constructor << ";\n"; os << cls.constructor << ";\n";
BOOST_FOREACH(const StaticMethod& m, cls.static_methods | boost::adaptors::map_values) BOOST_FOREACH(const StaticMethod& m, cls.static_methods | boost::adaptors::map_values)
os << m << ";\n"; os << m << ";\n";

View File

@ -42,7 +42,7 @@ bool Function::initializeOrCheck(const string& name, const Qualified& instName,
verbose_ = verbose; verbose_ = verbose;
return true; return true;
} else { } else {
if (name_ != name || templateArgValue_ != instName || verbose_ != verbose) if (name_ != name || !(templateArgValue_ == instName) || verbose_ != verbose)
throw runtime_error( throw runtime_error(
"Function::initializeOrCheck called with different arguments: with name " "Function::initializeOrCheck called with different arguments: with name "
+ name + " instead of expected " + name_ + name + " instead of expected " + name_

View File

@ -53,7 +53,7 @@ public:
if (templateArgValue_.empty()) if (templateArgValue_.empty())
return name_; return name_;
else else
return name_ + templateArgValue_.name; return name_ + templateArgValue_.name();
} }
/// Emit function call to MATLAB (no argument checking) /// Emit function call to MATLAB (no argument checking)

View File

@ -19,8 +19,8 @@ using namespace std;
void GlobalFunction::addOverload(const Qualified& overload, void GlobalFunction::addOverload(const Qualified& overload,
const ArgumentList& args, const ReturnValue& retVal, const ArgumentList& args, const ReturnValue& retVal,
const Qualified& instName, bool verbose) { const Qualified& instName, bool verbose) {
string name(overload.name); FullyOverloadedFunction::addOverload(overload.name(), args, retVal, instName,
FullyOverloadedFunction::addOverload(name, args, retVal, instName, verbose); verbose);
overloads.push_back(overload); overloads.push_back(overload);
} }
@ -37,7 +37,7 @@ void GlobalFunction::matlab_proxy(const string& toolboxPath,
for (size_t i = 0; i < overloads.size(); ++i) { for (size_t i = 0; i < overloads.size(); ++i) {
Qualified overload = overloads.at(i); Qualified overload = overloads.at(i);
// use concatenated namespaces as key // use concatenated namespaces as key
string str_ns = qualifiedName("", overload.namespaces); string str_ns = qualifiedName("", overload.namespaces());
const ReturnValue& ret = returnValue(i); const ReturnValue& ret = returnValue(i);
const ArgumentList& args = argumentList(i); const ArgumentList& args = argumentList(i);
grouped_functions[str_ns].addOverload(overload, args, ret); grouped_functions[str_ns].addOverload(overload, args, ret);
@ -59,7 +59,7 @@ void GlobalFunction::generateSingleFunction(const string& toolboxPath,
// create the folder for the namespace // create the folder for the namespace
const Qualified& overload1 = overloads.front(); const Qualified& overload1 = overloads.front();
createNamespaceStructure(overload1.namespaces, toolboxPath); createNamespaceStructure(overload1.namespaces(), toolboxPath);
// open destination mfunctionFileName // open destination mfunctionFileName
string mfunctionFileName = overload1.matlabName(toolboxPath); string mfunctionFileName = overload1.matlabName(toolboxPath);
@ -104,7 +104,7 @@ void GlobalFunction::generateSingleFunction(const 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.name != "void") if (returnVal.type1.name() != "void")
returnVal.wrap_result(cppName + "(" + args.names() + ")", file, returnVal.wrap_result(cppName + "(" + args.names() + ")", file,
typeAttributes); typeAttributes);
else else

View File

@ -123,7 +123,7 @@ string MethodBase::wrapper_fragment(FileWriter& wrapperFile, Str cppClassName,
args, instName); args, instName);
expanded += ("(" + args.names() + ")"); expanded += ("(" + args.names() + ")");
if (returnVal.type1.name != "void") if (returnVal.type1.name() != "void")
returnVal.wrap_result(expanded, wrapperFile, typeAttributes); returnVal.wrap_result(expanded, wrapperFile, typeAttributes);
else else
wrapperFile.oss << " " + expanded + ";\n"; wrapperFile.oss << " " + expanded + ";\n";

View File

@ -25,9 +25,6 @@
//#define BOOST_SPIRIT_DEBUG //#define BOOST_SPIRIT_DEBUG
#include "spirit_actors.h" #include "spirit_actors.h"
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_clear_actor.hpp>
#include <boost/spirit/include/classic_insert_at_actor.hpp>
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-variable"
@ -51,8 +48,6 @@ using namespace BOOST_SPIRIT_CLASSIC_NS;
namespace bl = boost::lambda; namespace bl = boost::lambda;
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> Rule;
/* ************************************************************************* */ /* ************************************************************************* */
// We parse an interface file into a Module object. // We parse an interface file into a Module object.
// The grammar is defined using the boost/spirit combinatorial parser. // The grammar is defined using the boost/spirit combinatorial parser.
@ -102,7 +97,6 @@ Module::Module(const string& interfacePath,
void Module::parseMarkup(const std::string& data) { void Module::parseMarkup(const std::string& data) {
// The parse imperatively :-( updates variables gradually during parse // The parse imperatively :-( updates variables gradually during parse
// 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.
vector<string> namespaces; // current namespace tag
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Grammar with actions that build the Class object. Actions are // Grammar with actions that build the Class object. Actions are
@ -113,129 +107,74 @@ void Module::parseMarkup(const std::string& data) {
// http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html // http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Rule comments_p = comment_p("/*", "*/") | comment_p("//", eol_p); // Define Rule and instantiate basic rules
typedef rule<phrase_scanner_t> Rule;
Rule basisType_p = basic_rules<phrase_scanner_t> basic;
(str_p("string") | "bool" | "size_t" | "int" | "double" | "char" | "unsigned char");
Rule keywords_p =
(str_p("const") | "static" | "namespace" | "void" | basisType_p);
Rule eigenType_p =
(str_p("Vector") | "Matrix");
//Rule for STL Containers (class names are lowercase)
Rule stlType_p = (str_p("vector") | "list");
Rule className_p = (lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p) | stlType_p;
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
Argument arg0, arg;
Rule namespace_arg_p = namespace_name_p
[push_back_a(arg.type.namespaces)] >> str_p("::");
Rule argEigenType_p =
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.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.name)] >>
!ch_p('&')[assign_a(arg.is_ref,true)];
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
// TODO, do we really need cls here? Non-local // TODO, do we really need cls here? Non-local
Class cls0(verbose),cls(verbose); Class cls0(verbose),cls(verbose);
Rule classParent_p = TypeGrammar classParent_p(cls.qualifiedParent);
*(namespace_name_p[push_back_a(cls.qualifiedParent.namespaces)] >> str_p("::")) >>
className_p[assign_a(cls.qualifiedParent.name)];
// parse "gtsam::Pose2" and add to templateArgValues // parse "gtsam::Pose2" and add to templateArgValues
Qualified templateArgValue; Qualified templateArgValue;
vector<Qualified> templateArgValues; vector<Qualified> templateArgValues;
Rule templateArgValue_p = Rule templateArgValue_p =
(*(namespace_name_p[push_back_a(templateArgValue.namespaces)] >> str_p("::")) >> TypeGrammar(templateArgValue)
(className_p | eigenType_p)[assign_a(templateArgValue.name)]) [push_back_a( templateArgValues, templateArgValue)];
[push_back_a(templateArgValues, templateArgValue)]
[clear_a(templateArgValue)];
// template<CALIBRATION = {gtsam::Cal3DS2}> // template<CALIBRATION = {gtsam::Cal3DS2}>
string templateArgName; string templateArgName;
Rule templateArgValues_p = Rule templateArgValues_p =
(str_p("template") >> (str_p("template") >>
'<' >> name_p[assign_a(templateArgName)] >> '=' >> '<' >> basic.name_p[assign_a(templateArgName)] >> '=' >>
'{' >> !(templateArgValue_p >> *(',' >> templateArgValue_p)) >> '}' >> '{' >> !(templateArgValue_p >> *(',' >> templateArgValue_p)) >> '}' >>
'>'); '>');
// parse "gtsam::Pose2" and add to singleInstantiation.typeList // parse "gtsam::Pose2" and add to singleInstantiation.typeList
TemplateInstantiationTypedef singleInstantiation; TemplateInstantiationTypedef singleInstantiation, singleInstantiation0;
Rule templateSingleInstantiationArg_p = Rule templateSingleInstantiationArg_p =
(*(namespace_name_p[push_back_a(templateArgValue.namespaces)] >> str_p("::")) >> TypeGrammar(templateArgValue)
(className_p | eigenType_p)[assign_a(templateArgValue.name)]) [push_back_a(singleInstantiation.typeList, templateArgValue)];
[push_back_a(singleInstantiation.typeList, templateArgValue)]
[clear_a(templateArgValue)];
// typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Point2> RangeFactorPosePoint2; // typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Point2> RangeFactorPosePoint2;
TemplateInstantiationTypedef singleInstantiation0;
Rule templateSingleInstantiation_p = Rule templateSingleInstantiation_p =
(str_p("typedef") >> (str_p("typedef") >>
*(namespace_name_p[push_back_a(singleInstantiation.class_.namespaces)] >> str_p("::")) >> TypeGrammar(singleInstantiation.class_) >>
className_p[assign_a(singleInstantiation.class_.name)] >> '<' >> templateSingleInstantiationArg_p >> *(',' >> templateSingleInstantiationArg_p) >> '>' >>
'<' >> templateSingleInstantiationArg_p >> *(',' >> templateSingleInstantiationArg_p) >> TypeGrammar(singleInstantiation) >>
'>' >>
className_p[assign_a(singleInstantiation.name)] >>
';') ';')
[assign_a(singleInstantiation.namespaces, namespaces)]
[push_back_a(templateInstantiationTypedefs, singleInstantiation)] [push_back_a(templateInstantiationTypedefs, singleInstantiation)]
[assign_a(singleInstantiation, singleInstantiation0)]; [assign_a(singleInstantiation, singleInstantiation0)];
// template<POSE, POINT> // template<POSE, POINT>
Rule templateList_p = Rule templateList_p =
(str_p("template") >> (str_p("template") >>
'<' >> name_p[push_back_a(cls.templateArgs)] >> *(',' >> name_p[push_back_a(cls.templateArgs)]) >> '<' >> basic.name_p[push_back_a(cls.templateArgs)] >> *(',' >> basic.name_p[push_back_a(cls.templateArgs)]) >>
'>'); '>');
// NOTE: allows for pointers to all types // NOTE: allows for pointers to all types
// Slightly more permissive than before on basis/eigen type qualification
ArgumentList args; ArgumentList args;
Rule argument_p = Argument arg0, arg;
((basisType_p[assign_a(arg.type.name)] | argEigenType_p | eigenRef_p | classArg_p) TypeGrammar argument_type_g(arg.type);
>> !ch_p('*')[assign_a(arg.is_ptr,true)] Rule argument_p =
>> name_p[assign_a(arg.name)]) !str_p("const")[assign_a(arg.is_const, true)]
[push_back_a(args, arg)] >> argument_type_g
[assign_a(arg,arg0)]; >> (!ch_p('&')[assign_a(arg.is_ref, true)] | !ch_p('*')[assign_a(arg.is_ptr, true)])
[push_back_a(args, arg)]
[assign_a(arg,arg0)];
Rule argumentList_p = !argument_p >> * (',' >> argument_p); Rule argumentList_p = !argument_p >> * (',' >> argument_p);
// parse class constructor // parse class constructor
Constructor constructor0(verbose), constructor(verbose); Constructor constructor0(verbose), constructor(verbose);
Rule constructor_p = Rule constructor_p =
(className_p >> '(' >> argumentList_p >> ')' >> ';' >> !comments_p) (basic.className_p >> '(' >> argumentList_p >> ')' >> ';' >> !basic.comments_p)
[bl::bind(&Constructor::push_back, bl::var(constructor), bl::var(args))] [bl::bind(&Constructor::push_back, bl::var(constructor), bl::var(args))]
[clear_a(args)]; [clear_a(args)];
vector<string> namespaces_return; /// namespace for current return type
Rule namespace_ret_p = namespace_name_p[push_back_a(namespaces_return)] >> str_p("::");
// HACK: use const values instead of using enums themselves - somehow this doesn't result in values getting assigned to gibberish
static const ReturnType::return_category RETURN_EIGEN = ReturnType::EIGEN;
static const ReturnType::return_category RETURN_BASIS = ReturnType::BASIS;
static const ReturnType::return_category RETURN_CLASS = ReturnType::CLASS;
static const ReturnType::return_category RETURN_VOID = ReturnType::VOID;
ReturnType retType0, retType; ReturnType retType0, retType;
Rule returnType_p = Rule returnType_p = TypeGrammar(retType);
(basisType_p[assign_a(retType.name)][assign_a(retType.category, RETURN_BASIS)]) |
((*namespace_ret_p)[assign_a(retType.namespaces, namespaces_return)][clear_a(namespaces_return)]
>> (className_p[assign_a(retType.name)][assign_a(retType.category, RETURN_CLASS)]) >>
!ch_p('*')[assign_a(retType.isPtr,true)]) |
(eigenType_p[assign_a(retType.name)][assign_a(retType.category, RETURN_EIGEN)]);
ReturnValue retVal0, retVal; ReturnValue retVal0, retVal;
Rule returnType1_p = returnType_p[assign_a(retVal.type1,retType)][assign_a(retType,retType0)]; Rule returnType1_p = returnType_p[assign_a(retVal.type1,retType)][assign_a(retType,retType0)];
@ -245,9 +184,7 @@ void Module::parseMarkup(const std::string& data) {
(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.name)][assign_a(retVal.type1.category, RETURN_VOID)]; Rule returnValue_p = pair_p | returnType1_p;
Rule returnValue_p = void_p | pair_p | returnType1_p;
Rule methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')]; Rule methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
@ -258,7 +195,7 @@ void Module::parseMarkup(const std::string& data) {
!templateArgValues_p >> !templateArgValues_p >>
(returnValue_p >> methodName_p[assign_a(methodName)] >> (returnValue_p >> methodName_p[assign_a(methodName)] >>
'(' >> argumentList_p >> ')' >> '(' >> argumentList_p >> ')' >>
!str_p("const")[assign_a(isConst,true)] >> ';' >> *comments_p) !str_p("const")[assign_a(isConst,true)] >> ';' >> *basic.comments_p)
[bl::bind(&Class::addMethod, bl::var(cls), verbose, bl::var(isConst), [bl::bind(&Class::addMethod, bl::var(cls), verbose, bl::var(isConst),
bl::var(methodName), bl::var(args), bl::var(retVal), bl::var(methodName), bl::var(args), bl::var(retVal),
bl::var(templateArgName), bl::var(templateArgValues))] bl::var(templateArgName), bl::var(templateArgValues))]
@ -271,7 +208,7 @@ void Module::parseMarkup(const std::string& data) {
Rule static_method_p = Rule static_method_p =
(str_p("static") >> returnValue_p >> staticMethodName_p[assign_a(methodName)] >> (str_p("static") >> returnValue_p >> staticMethodName_p[assign_a(methodName)] >>
'(' >> argumentList_p >> ')' >> ';' >> *comments_p) '(' >> argumentList_p >> ')' >> ';' >> *basic.comments_p)
[bl::bind(&StaticMethod::addOverload, [bl::bind(&StaticMethod::addOverload,
bl::var(cls.static_methods)[bl::var(methodName)], bl::var(cls.static_methods)[bl::var(methodName)],
bl::var(methodName), bl::var(args), bl::var(retVal), Qualified(),verbose)] bl::var(methodName), bl::var(args), bl::var(retVal), Qualified(),verbose)]
@ -281,6 +218,7 @@ void Module::parseMarkup(const std::string& data) {
Rule functions_p = constructor_p | method_p | static_method_p; Rule functions_p = constructor_p | method_p | static_method_p;
// parse a full class // parse a full class
vector<string> namespaces; // current namespace tag
vector<Qualified> templateInstantiations; vector<Qualified> templateInstantiations;
Rule class_p = Rule class_p =
eps_p[assign_a(cls,cls0)] eps_p[assign_a(cls,cls0)]
@ -291,15 +229,15 @@ void Module::parseMarkup(const std::string& data) {
| templateList_p) | templateList_p)
>> !(str_p("virtual")[assign_a(cls.isVirtual, true)]) >> !(str_p("virtual")[assign_a(cls.isVirtual, true)])
>> str_p("class") >> str_p("class")
>> className_p[assign_a(cls.name)] >> basic.className_p[assign_a(cls.name_)]
>> ((':' >> classParent_p >> '{') | '{') >> ((':' >> classParent_p >> '{') | '{')
>> *(functions_p | comments_p) >> *(functions_p | basic.comments_p)
>> str_p("};")) >> str_p("};"))
[bl::bind(&Constructor::initializeOrCheck, bl::var(constructor), [bl::bind(&Constructor::initializeOrCheck, bl::var(constructor),
bl::var(cls.name), Qualified(), verbose)] bl::var(cls.name_), Qualified(), verbose)]
[assign_a(cls.constructor, constructor)] [assign_a(cls.constructor, constructor)]
[assign_a(cls.namespaces, namespaces)] [assign_a(cls.namespaces_, namespaces)]
[assign_a(cls.deconstructor.name,cls.name)] [assign_a(cls.deconstructor.name,cls.name_)]
[bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls), [bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls),
bl::var(templateInstantiations))] bl::var(templateInstantiations))]
[clear_a(templateInstantiations)] [clear_a(templateInstantiations)]
@ -309,11 +247,11 @@ void Module::parseMarkup(const std::string& data) {
// parse a global function // parse a global function
Qualified globalFunction; Qualified globalFunction;
Rule global_function_p = Rule global_function_p =
(returnValue_p >> staticMethodName_p[assign_a(globalFunction.name)] >> (returnValue_p >> staticMethodName_p[assign_a(globalFunction.name_)] >>
'(' >> argumentList_p >> ')' >> ';' >> *comments_p) '(' >> argumentList_p >> ')' >> ';' >> *basic.comments_p)
[assign_a(globalFunction.namespaces,namespaces)] [assign_a(globalFunction.namespaces_,namespaces)]
[bl::bind(&GlobalFunction::addOverload, [bl::bind(&GlobalFunction::addOverload,
bl::var(global_functions)[bl::var(globalFunction.name)], bl::var(global_functions)[bl::var(globalFunction.name_)],
bl::var(globalFunction), bl::var(args), bl::var(retVal), Qualified(),verbose)] bl::var(globalFunction), bl::var(args), bl::var(retVal), Qualified(),verbose)]
[assign_a(retVal,retVal0)] [assign_a(retVal,retVal0)]
[clear_a(globalFunction)] [clear_a(globalFunction)]
@ -328,9 +266,9 @@ void Module::parseMarkup(const std::string& data) {
Rule namespace_def_p = Rule namespace_def_p =
(str_p("namespace") (str_p("namespace")
>> namespace_name_p[push_back_a(namespaces)] >> basic.namepsace_p[push_back_a(namespaces)]
>> ch_p('{') >> ch_p('{')
>> *(include_p | class_p | templateSingleInstantiation_p | global_function_p | namespace_def_p | comments_p) >> *(include_p | class_p | templateSingleInstantiation_p | global_function_p | namespace_def_p | basic.comments_p)
>> ch_p('}')) >> ch_p('}'))
[pop_a(namespaces)]; [pop_a(namespaces)];
@ -343,17 +281,20 @@ void Module::parseMarkup(const std::string& data) {
Rule forward_declaration_p = Rule forward_declaration_p =
!(str_p("virtual")[assign_a(fwDec.isVirtual, true)]) !(str_p("virtual")[assign_a(fwDec.isVirtual, true)])
>> str_p("class") >> str_p("class")
>> (*(namespace_name_p >> str_p("::")) >> className_p)[assign_a(fwDec.name)] >> (*(basic.namepsace_p >> str_p("::")) >> basic.className_p)[assign_a(fwDec.name)]
>> ch_p(';') >> ch_p(';')
[push_back_a(forward_declarations, fwDec)] [push_back_a(forward_declarations, fwDec)]
[assign_a(fwDec, fwDec0)]; [assign_a(fwDec, fwDec0)];
Rule module_content_p = comments_p | include_p | class_p | templateSingleInstantiation_p | forward_declaration_p | global_function_p | namespace_def_p; Rule module_content_p = basic.comments_p | include_p | class_p
| templateSingleInstantiation_p | forward_declaration_p
| global_function_p | namespace_def_p;
Rule module_p = *module_content_p >> !end_p; Rule module_p = *module_content_p >> !end_p;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// for debugging, define BOOST_SPIRIT_DEBUG // for debugging, define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_DEBUG
# ifdef BOOST_SPIRIT_DEBUG # ifdef BOOST_SPIRIT_DEBUG
BOOST_SPIRIT_DEBUG_NODE(className_p); BOOST_SPIRIT_DEBUG_NODE(className_p);
BOOST_SPIRIT_DEBUG_NODE(classPtr_p); BOOST_SPIRIT_DEBUG_NODE(classPtr_p);
@ -381,7 +322,7 @@ void Module::parseMarkup(const std::string& data) {
if(!info.full) { if(!info.full) {
printf("parsing stopped at \n%.20s\n",info.stop); printf("parsing stopped at \n%.20s\n",info.stop);
cout << "Stopped near:\n" cout << "Stopped near:\n"
"class '" << cls.name << "'\n" "class '" << cls.name() << "'\n"
"method '" << methodName << "'\n" "method '" << methodName << "'\n"
"argument '" << arg.name << "'" << endl; "argument '" << arg.name << "'" << endl;
throw ParseFailed((int)info.length); throw ParseFailed((int)info.length);

View File

@ -34,10 +34,18 @@ namespace wrap {
/** /**
* Class to encapuslate a qualified name, i.e., with (nested) namespaces * Class to encapuslate a qualified name, i.e., with (nested) namespaces
*/ */
struct Qualified { class Qualified {
std::vector<std::string> namespaces; ///< Stack of namespaces //protected:
std::string name; ///< type name public:
std::vector<std::string> namespaces_; ///< Stack of namespaces
std::string name_; ///< type name
friend class TypeGrammar;
friend class TemplateSubstitution;
public:
/// the different categories /// the different categories
typedef enum { typedef enum {
@ -49,43 +57,76 @@ struct Qualified {
category(VOID) { category(VOID) {
} }
Qualified(const std::string& name_, Category c = CLASS) : Qualified(const std::string& n, Category c = CLASS) :
name(name_), category(c) { name_(n), category(c) {
}
Qualified(const std::string& ns1, const std::string& ns2,
const std::string& n, Category c = CLASS) :
name_(n), category(c) {
namespaces_.push_back(ns1);
namespaces_.push_back(ns2);
}
Qualified(const std::string& ns1, const std::string& n, Category c = CLASS) :
name_(n), category(c) {
namespaces_.push_back(ns1);
}
std::string name() const {
return name_;
}
std::vector<std::string> namespaces() const {
return namespaces_;
}
// Qualified is 'abused' as template argument name as well
// this function checks whether *this matches with templateArg
bool match(const std::string& templateArg) const {
return (name_ == templateArg && namespaces_.empty() && category == CLASS);
}
void rename(const Qualified& q) {
namespaces_ = q.namespaces_;
name_ = q.name_;
category = q.category;
}
void expand(const std::string& expansion) {
name_ += expansion;
} }
bool operator==(const Qualified& other) const { bool operator==(const Qualified& other) const {
return namespaces == other.namespaces && name == other.name return namespaces_ == other.namespaces_ && name_ == other.name_
&& category == other.category; && category == other.category;
} }
bool empty() const { bool empty() const {
return namespaces.empty() && name.empty(); return namespaces_.empty() && name_.empty();
} }
void clear() { void clear() {
namespaces.clear(); namespaces_.clear();
name.clear(); name_.clear();
} category = VOID;
bool operator!=(const Qualified& other) const {
return other.name != name || other.namespaces != namespaces;
} }
/// Return a qualified string using given delimiter /// Return a qualified string using given delimiter
std::string qualifiedName(const std::string& delimiter = "") const { std::string qualifiedName(const std::string& delimiter = "") const {
std::string result; std::string result;
for (std::size_t i = 0; i < namespaces.size(); ++i) for (std::size_t i = 0; i < namespaces_.size(); ++i)
result += (namespaces[i] + delimiter); result += (namespaces_[i] + delimiter);
result += name; result += name_;
return result; return result;
} }
/// Return a matlab file name, i.e. "toolboxPath/+ns1/+ns2/name.m" /// Return a matlab file name, i.e. "toolboxPath/+ns1/+ns2/name.m"
std::string matlabName(const std::string& toolboxPath) const { std::string matlabName(const std::string& toolboxPath) const {
std::string result = toolboxPath; std::string result = toolboxPath;
for (std::size_t i = 0; i < namespaces.size(); ++i) for (std::size_t i = 0; i < namespaces_.size(); ++i)
result += ("/+" + namespaces[i]); result += ("/+" + namespaces_[i]);
result += "/" + name + ".m"; result += "/" + name_ + ".m";
return result; return result;
} }
@ -130,12 +171,14 @@ struct basic_rules {
}; };
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html // http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
struct type_grammar: public classic::grammar<type_grammar> { class TypeGrammar: public classic::grammar<TypeGrammar> {
wrap::Qualified& result_; ///< successful parse will be placed in here wrap::Qualified& result_; ///< successful parse will be placed in here
public:
/// Construct type grammar and specify where result is placed /// Construct type grammar and specify where result is placed
type_grammar(wrap::Qualified& result) : TypeGrammar(wrap::Qualified& result) :
result_(result) { result_(result) {
} }
@ -148,7 +191,7 @@ struct type_grammar: public classic::grammar<type_grammar> {
Rule void_p, my_basisType_p, my_eigenType_p, namespace_del_p, class_p, Rule void_p, my_basisType_p, my_eigenType_p, namespace_del_p, class_p,
type_p; type_p;
definition(type_grammar const& self) { definition(TypeGrammar const& self) {
using namespace wrap; using namespace wrap;
using namespace classic; using namespace classic;
@ -159,22 +202,22 @@ struct type_grammar: public classic::grammar<type_grammar> {
static const Qualified::Category CLASS = Qualified::CLASS; static const Qualified::Category CLASS = Qualified::CLASS;
static const Qualified::Category VOID = Qualified::VOID; static const Qualified::Category VOID = Qualified::VOID;
void_p = str_p("void")[assign_a(self.result_.name)] // void_p = str_p("void")[assign_a(self.result_.name_)] //
[assign_a(self.result_.category, VOID)]; [assign_a(self.result_.category, VOID)];
my_basisType_p = basic_rules<ScannerT>::basisType_p // my_basisType_p = basic_rules<ScannerT>::basisType_p //
[assign_a(self.result_.name)] // [assign_a(self.result_.name_)] //
[assign_a(self.result_.category, BASIS)]; [assign_a(self.result_.category, BASIS)];
my_eigenType_p = basic_rules<ScannerT>::eigenType_p // my_eigenType_p = basic_rules<ScannerT>::eigenType_p //
[assign_a(self.result_.name)] // [assign_a(self.result_.name_)] //
[assign_a(self.result_.category, EIGEN)]; [assign_a(self.result_.category, EIGEN)];
namespace_del_p = basic_rules<ScannerT>::namepsace_p // namespace_del_p = basic_rules<ScannerT>::namepsace_p //
[push_back_a(self.result_.namespaces)] >> str_p("::"); [push_back_a(self.result_.namespaces_)] >> str_p("::");
class_p = *namespace_del_p >> basic_rules<ScannerT>::className_p // class_p = *namespace_del_p >> basic_rules<ScannerT>::className_p //
[assign_a(self.result_.name)] // [assign_a(self.result_.name_)] //
[assign_a(self.result_.category, CLASS)]; [assign_a(self.result_.category, CLASS)];
type_p = void_p | my_basisType_p | my_eigenType_p | class_p; type_p = void_p | my_basisType_p | my_eigenType_p | class_p;

View File

@ -14,7 +14,7 @@ using namespace wrap;
/* ************************************************************************* */ /* ************************************************************************* */
string ReturnType::str(bool add_ptr) const { string ReturnType::str(bool add_ptr) const {
return maybe_shared_ptr(add_ptr && isPtr, qualifiedName("::"), name); return maybe_shared_ptr(add_ptr && isPtr, qualifiedName("::"), name());
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -25,7 +25,7 @@ void ReturnType::wrap_result(const string& out, const string& result,
if (category == CLASS) { if (category == CLASS) {
string objCopy, ptrType; string objCopy, ptrType;
ptrType = "Shared" + name; ptrType = "Shared" + name();
const bool isVirtual = typeAttributes.attributes(cppType).isVirtual; const bool isVirtual = typeAttributes.attributes(cppType).isVirtual;
if (isVirtual) { if (isVirtual) {
if (isPtr) if (isPtr)
@ -41,7 +41,7 @@ void ReturnType::wrap_result(const string& out, const string& result,
wrapperFile.oss << out << " = wrap_shared_ptr(" << objCopy << ",\"" wrapperFile.oss << out << " = wrap_shared_ptr(" << objCopy << ",\""
<< matlabType << "\", " << (isVirtual ? "true" : "false") << ");\n"; << matlabType << "\", " << (isVirtual ? "true" : "false") << ");\n";
} else if (isPtr) { } else if (isPtr) {
wrapperFile.oss << " Shared" << name << "* ret = new Shared" << name << "(" wrapperFile.oss << " Shared" << name() << "* ret = new Shared" << name() << "("
<< result << ");" << endl; << result << ");" << endl;
wrapperFile.oss << out << " = wrap_shared_ptr(ret,\"" << matlabType wrapperFile.oss << out << " = wrap_shared_ptr(ret,\"" << matlabType
<< "\");\n"; << "\");\n";
@ -54,7 +54,7 @@ void ReturnType::wrap_result(const string& out, const string& result,
void ReturnType::wrapTypeUnwrap(FileWriter& wrapperFile) const { void ReturnType::wrapTypeUnwrap(FileWriter& wrapperFile) const {
if (category == CLASS) if (category == CLASS)
wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedName("::") wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedName("::")
<< "> Shared" << name << ";" << endl; << "> Shared" << name() << ";" << endl;
} }
/* ************************************************************************* */ /* ************************************************************************* */

View File

@ -21,18 +21,14 @@ struct ReturnType: Qualified {
bool isPtr; bool isPtr;
/// Makes a void type
ReturnType() : ReturnType() :
isPtr(false) { isPtr(false) {
} }
/// Make a Class type, no namespaces
ReturnType(const std::string& name) : ReturnType(const std::string& name) :
isPtr(false) { Qualified(name,Qualified::CLASS), isPtr(false) {
Qualified::name = name;
}
void rename(const Qualified& q) {
name = q.name;
namespaces = q.namespaces;
} }
/// Check if this type is in a set of valid types /// Check if this type is in a set of valid types

View File

@ -32,7 +32,7 @@ Class TemplateInstantiationTypedef::findAndExpand(
// Find matching class // Find matching class
boost::optional<Class const &> matchedClass; boost::optional<Class const &> matchedClass;
BOOST_FOREACH(const Class& cls, classes) { BOOST_FOREACH(const Class& cls, classes) {
if (cls.name == class_.name && cls.namespaces == class_.namespaces if (cls.name() == class_.name() && cls.namespaces() == class_.namespaces()
&& cls.templateArgs.size() == typeList.size()) { && cls.templateArgs.size() == typeList.size()) {
matchedClass.reset(cls); matchedClass.reset(cls);
break; break;
@ -52,7 +52,8 @@ Class TemplateInstantiationTypedef::findAndExpand(
} }
// Fix class properties // Fix class properties
classInst.name = name; classInst.name_ = name();
classInst.namespaces_ = namespaces();
classInst.templateArgs.clear(); classInst.templateArgs.clear();
classInst.typedefName = matchedClass->qualifiedName("::") + "<"; classInst.typedefName = matchedClass->qualifiedName("::") + "<";
if (typeList.size() > 0) if (typeList.size() > 0)
@ -60,7 +61,6 @@ Class TemplateInstantiationTypedef::findAndExpand(
for (size_t i = 1; i < typeList.size(); ++i) for (size_t i = 1; i < typeList.size(); ++i)
classInst.typedefName += (", " + typeList[i].qualifiedName("::")); classInst.typedefName += (", " + typeList[i].qualifiedName("::"));
classInst.typedefName += ">"; classInst.typedefName += ">";
classInst.namespaces = namespaces;
return classInst; return classInst;
} }

View File

@ -40,14 +40,14 @@ public:
} }
std::string expandedClassName() const { std::string expandedClassName() const {
return expandedClass_.name; return expandedClass_.name();
} }
// Substitute if needed // Substitute if needed
Qualified tryToSubstitite(const Qualified& type) const { Qualified tryToSubstitite(const Qualified& type) const {
if (type.name == templateArg_ && type.namespaces.empty()) if (type.match(templateArg_))
return qualifiedType_; return qualifiedType_;
else if (type.name == "This") else if (type.match("This"))
return expandedClass_; return expandedClass_;
else else
return type; return type;
@ -56,9 +56,9 @@ public:
// Substitute if needed // Substitute if needed
ReturnType tryToSubstitite(const ReturnType& type) const { ReturnType tryToSubstitite(const ReturnType& type) const {
ReturnType instType = type; ReturnType instType = type;
if (type.name == templateArg_ && type.namespaces.empty()) if (type.match(templateArg_))
instType.rename(qualifiedType_); instType.rename(qualifiedType_);
else if (type.name == "This") else if (type.match("This"))
instType.rename(expandedClass_); instType.rename(expandedClass_);
return instType; return instType;
} }

View File

@ -68,7 +68,7 @@ void TypeAttributesTable::checkValidity(const vector<Class>& classes) const {
if (!cls.qualifiedParent.empty() && !cls.isVirtual) if (!cls.qualifiedParent.empty() && !cls.isVirtual)
throw AttributeError(cls.qualifiedName("::"), throw AttributeError(cls.qualifiedName("::"),
"Has a base class so needs to be declared virtual, change to 'virtual class " "Has a base class so needs to be declared virtual, change to 'virtual class "
+ cls.name + " ...'"); + cls.name() + " ...'");
// Check that parent is virtual as well // Check that parent is virtual as well
Qualified parent = cls.qualifiedParent; Qualified parent = cls.qualifiedParent;
if (!parent.empty() && !table_.at(parent.qualifiedName("::")).isVirtual) if (!parent.empty() && !table_.at(parent.qualifiedName("::")).isVirtual)

View File

@ -7,126 +7,128 @@ namespace gtsam {
class Point2 { class Point2 {
Point2(); Point2();
Point2(double x, double y); // Point2(double x, double y);
double x() const; double x() const;
double y() const; // double y() const;
int dim() const; // int dim() const;
char returnChar() const; // char returnChar() const;
void argChar(char a) const; // void argChar(char a) const;
void argUChar(unsigned char a) const; // void argUChar(unsigned char a) const;
void eigenArguments(Vector v, Matrix m) const; // void eigenArguments(Vector v, Matrix m) const;
VectorNotEigen vectorConfusion(); // VectorNotEigen vectorConfusion();
//
void serializable() const; // Sets flag and creates export, but does not make serialization functions // void serializable() const; // Sets flag and creates export, but does not make serialization functions
}; };
class Point3 { } // end namespace should be removed
Point3(double x, double y, double z);
double norm() const;
// static functions - use static keyword and uppercase //class Point3 {
static double staticFunction(); // Point3(double x, double y, double z);
static gtsam::Point3 StaticFunctionRet(double z); // double norm() const;
//
// enabling serialization functionality // // static functions - use static keyword and uppercase
void serialize() const; // Just triggers a flag internally and removes actual function // static double staticFunction();
}; // static gtsam::Point3 StaticFunctionRet(double z);
//
} // // enabling serialization functionality
// another comment // void serialize() const; // Just triggers a flag internally and removes actual function
//};
// another comment //
//}
/** //// another comment
* A multi-line comment! //
*/ //// another comment
//
// An include! Can go anywhere outside of a class, in any order ///**
#include <folder/path/to/Test.h> // * A multi-line comment!
// */
class Test { //
//// An include! Can go anywhere outside of a class, in any order
/* a comment! */ //#include <folder/path/to/Test.h>
// another comment //
Test(); //class Test {
//
pair<Vector,Matrix> return_pair (Vector v, Matrix A) const; // intentionally the first method // /* a comment! */
// // another comment
bool return_bool (bool value) const; // comment after a line! // Test();
size_t return_size_t (size_t value) const; //
int return_int (int value) const; // pair<Vector,Matrix> return_pair (Vector v, Matrix A) const; // intentionally the first method
double return_double (double value) const; //
// bool return_bool (bool value) const; // comment after a line!
Test(double a, Matrix b); // a constructor in the middle of a class // size_t return_size_t (size_t value) const;
// int return_int (int value) const;
// comments in the middle! // double return_double (double value) const;
//
// (more) comments in the middle! // Test(double a, Matrix b); // a constructor in the middle of a class
//
string return_string (string value) const; // // comments in the middle!
Vector return_vector1(Vector value) const; //
Matrix return_matrix1(Matrix value) const; // // (more) comments in the middle!
Vector return_vector2(Vector value) const; //
Matrix return_matrix2(Matrix value) const; // string return_string (string value) const;
void arg_EigenConstRef(const Matrix& value) const; // Vector return_vector1(Vector value) const;
// Matrix return_matrix1(Matrix value) const;
bool return_field(const Test& t) const; // Vector return_vector2(Vector value) const;
// Matrix return_matrix2(Matrix value) const;
Test* return_TestPtr(Test* value) const; // void arg_EigenConstRef(const Matrix& value) const;
Test return_Test(Test* value) const; //
// bool return_field(const Test& t) const;
gtsam::Point2* return_Point2Ptr(bool value) const; //
// Test* return_TestPtr(Test* value) const;
pair<Test*,Test*> create_ptrs () const; // Test return_Test(Test* value) const;
pair<Test ,Test*> create_MixedPtrs () const; //
pair<Test*,Test*> return_ptrs (Test* p1, Test* p2) const; // gtsam::Point2* return_Point2Ptr(bool value) const;
//
void print() const; // pair<Test*,Test*> create_ptrs () const;
// pair<Test ,Test*> create_MixedPtrs () const;
// comments at the end! // pair<Test*,Test*> return_ptrs (Test* p1, Test* p2) const;
//
// even more comments at the end! // void print() const;
}; //
// // comments at the end!
//
Vector aGlobalFunction(); // // even more comments at the end!
//};
// An overloaded global function //
Vector overloadedGlobalFunction(int a); //
Vector overloadedGlobalFunction(int a, double b); //Vector aGlobalFunction();
//
// A base class //// An overloaded global function
virtual class MyBase { //Vector overloadedGlobalFunction(int a);
//Vector overloadedGlobalFunction(int a, double b);
}; //
//// A base class
// A templated class //virtual class MyBase {
template<T = {gtsam::Point2, gtsam::Point3}> //
virtual class MyTemplate : MyBase { //};
MyTemplate(); //
//// A templated class
template<ARG = {gtsam::Point2, gtsam::Point3, Vector, Matrix}> //template<T = {gtsam::Point2, gtsam::Point3}>
void templatedMethod(const ARG& t); //virtual class MyTemplate : MyBase {
// MyTemplate();
// Stress test templates and pointer combinations //
void accept_T(const T& value) const; // template<ARG = {gtsam::Point2, gtsam::Point3, Vector, Matrix}>
void accept_Tptr(T* value) const; // void templatedMethod(const ARG& t);
T* return_Tptr(T* value) const; //
T return_T(T* value) const; // // Stress test templates and pointer combinations
pair<T*,T*> create_ptrs () const; // void accept_T(const T& value) const;
pair<T ,T*> create_MixedPtrs () const; // void accept_Tptr(T* value) const;
pair<T*,T*> return_ptrs (T* p1, T* p2) const; // T* return_Tptr(T* value) const;
}; // T return_T(T* value) const;
// pair<T*,T*> create_ptrs () const;
// A doubly templated class // pair<T ,T*> create_MixedPtrs () const;
template<POSE, POINT> // pair<T*,T*> return_ptrs (T* p1, T* p2) const;
class MyFactor { //};
MyFactor(size_t key1, size_t key2, double measured, const gtsam::noiseModel::Base* noiseModel); //
}; //// A doubly templated class
//template<POSE, POINT>
// and a typedef specializing it //class MyFactor {
typedef MyFactor<gtsam::Pose2, Matrix> MyFactorPosePoint2; // MyFactor(size_t key1, size_t key2, double measured, const gtsam::noiseModel::Base* noiseModel);
//};
// comments at the end! //
//// and a typedef specializing it
// even more comments at the end! //typedef MyFactor<gtsam::Pose2, Matrix> MyFactorPosePoint2;
//
//// comments at the end!
//
//// even more comments at the end!

View File

@ -30,7 +30,7 @@ static const bool T = true;
struct ArgumentGrammar: public classic::grammar<ArgumentGrammar> { struct ArgumentGrammar: public classic::grammar<ArgumentGrammar> {
wrap::Argument& result_; ///< successful parse will be placed in here wrap::Argument& result_; ///< successful parse will be placed in here
type_grammar argument_type_g; TypeGrammar argument_type_g;
/// Construct type grammar and specify where result is placed /// Construct type grammar and specify where result is placed
ArgumentGrammar(wrap::Argument& result) : ArgumentGrammar(wrap::Argument& result) :
@ -78,9 +78,7 @@ TEST( Argument, grammar ) {
ArgumentGrammar g(actual); ArgumentGrammar g(actual);
EXPECT(parse("const gtsam::Point2& p4", g, space_p).full); EXPECT(parse("const gtsam::Point2& p4", g, space_p).full);
EXPECT_LONGS_EQUAL(1, actual.type.namespaces.size()); EXPECT(actual.type==Qualified("gtsam","Point2",Qualified::CLASS));
EXPECT(actual.type.namespaces[0]=="gtsam");
EXPECT(actual.type.name=="Point2");
EXPECT(actual.name=="p4"); EXPECT(actual.name=="p4");
EXPECT(actual.is_const); EXPECT(actual.is_const);
EXPECT(actual.is_ref); EXPECT(actual.is_ref);
@ -88,8 +86,7 @@ TEST( Argument, grammar ) {
actual = arg0; actual = arg0;
EXPECT(parse("Point2& p", g, space_p).full); EXPECT(parse("Point2& p", g, space_p).full);
EXPECT(actual.type.namespaces.empty()); EXPECT(actual.type==Qualified("Point2",Qualified::CLASS));
EXPECT(actual.type.name=="Point2");
EXPECT(actual.name=="p"); EXPECT(actual.name=="p");
EXPECT(!actual.is_const); EXPECT(!actual.is_const);
EXPECT(actual.is_ref); EXPECT(actual.is_ref);
@ -97,9 +94,7 @@ TEST( Argument, grammar ) {
actual = arg0; actual = arg0;
EXPECT(parse("gtsam::Point2* p3", g, space_p).full); EXPECT(parse("gtsam::Point2* p3", g, space_p).full);
EXPECT_LONGS_EQUAL(1, actual.type.namespaces.size()); EXPECT(actual.type==Qualified("gtsam","Point2",Qualified::CLASS));
EXPECT(actual.type.namespaces[0]=="gtsam");
EXPECT(actual.type.name=="Point2");
EXPECT(actual.name=="p3"); EXPECT(actual.name=="p3");
EXPECT(!actual.is_const); EXPECT(!actual.is_const);
EXPECT(!actual.is_ref); EXPECT(!actual.is_ref);
@ -119,8 +114,7 @@ TEST( Argument, grammar ) {
actual = arg0; actual = arg0;
EXPECT(parse("const Matrix& m", g, space_p).full); EXPECT(parse("const Matrix& m", g, space_p).full);
EXPECT(actual.type.namespaces.empty()); EXPECT(actual.type==Qualified("Matrix",Qualified::EIGEN));
EXPECT(actual.type.name=="Matrix");
EXPECT(actual.name=="m"); EXPECT(actual.name=="m");
EXPECT(actual.is_const); EXPECT(actual.is_const);
EXPECT(actual.is_ref); EXPECT(actual.is_ref);

View File

@ -64,7 +64,7 @@ TEST( Class, TemplatedMethods ) {
bool verbose = true, is_const = true; bool verbose = true, is_const = true;
ArgumentList args; ArgumentList args;
Argument arg; Argument arg;
arg.type.name = "T"; arg.type.name_ = "T";
args.push_back(arg); args.push_back(arg);
const ReturnValue retVal(ReturnType("T")); const ReturnValue retVal(ReturnType("T"));
const string templateArgName("T"); const string templateArgName("T");

View File

@ -42,6 +42,102 @@ TEST( Method, addOverload ) {
EXPECT_LONGS_EQUAL(2, method.nrOverloads()); EXPECT_LONGS_EQUAL(2, method.nrOverloads());
} }
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
struct method_grammar: public classic::grammar<method_grammar> {
wrap::Method& result_; ///< successful parse will be placed in here
ArgumentList args;
Argument arg0, arg;
TypeGrammar argument_type_g;
ReturnType retType0, retType;
TypeGrammar returntype_g;
ReturnValue retVal0, retVal;
/// Construct type grammar and specify where result is placed
method_grammar(wrap::Method& result) :
result_(result), argument_type_g(arg.type), returntype_g(retType) {
}
/// Definition of type grammar
template<typename ScannerT>
struct definition: basic_rules<ScannerT> {
typedef classic::rule<ScannerT> Rule;
Rule templateArgValue_p, templateArgValues_p, argument_p, argumentList_p,
returnType1_p, returnType2_p, pair_p, returnValue_p, methodName_p,
method_p;
definition(method_grammar const& self) {
using namespace wrap;
using namespace classic;
// Rule templateArgValue_p = type_grammar(self.templateArgValue);
//
// // template<CALIBRATION = {gtsam::Cal3DS2}>
// Rule templateArgValues_p = (str_p("template") >> '<' >> name_p >> '='
// >> '{' >> !(templateArgValue_p >> *(',' >> templateArgValue_p)) >> '}'
// >> '>');
//
// NOTE: allows for pointers to all types
// Slightly more permissive than before on basis/eigen type qualification
argument_p = //
!str_p("const")[assign_a(self.arg.is_const, true)] //
>> self.argument_type_g //
>> (!ch_p('&')[assign_a(self.arg.is_ref, true)]
| !ch_p('*')[assign_a(self.arg.is_ptr, true)]) //
[push_back_a(self.args, self.arg)] //
[assign_a(self.arg, self.arg0)];
argumentList_p = !argument_p >> *(',' >> argument_p);
//
returnType1_p = self.returntype_g //
[assign_a(self.retVal.type1, retType)] //
[assign_a(self.retType, self.retType0)];
returnType2_p = self.returntype_g //
[assign_a(self.retVal.type2, retType)] //
[assign_a(self.retType, self.retType0)];
pair_p = (str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p
>> '>')[assign_a(self.retVal.isPair, true)];
returnValue_p = pair_p | returnType1_p;
methodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
// gtsam::Values retract(const gtsam::VectorValues& delta) const;
method_p =
// !templateArgValues_p >>
(returnValue_p >> methodName_p >> '(' >> argumentList_p >> ')'
>> !str_p("const") >> ';' >> *basic_rules<ScannerT>::comments_p);
}
Rule const& start() const {
return method_p;
}
};
};
// method_grammar
//******************************************************************************
TEST( Method, grammar ) {
using classic::space_p;
// Create type grammar that will place result in actual
Method actual;
method_grammar method_g(actual);
// a class type with namespaces
EXPECT(parse("double x() const;", method_g, space_p).full);
}
/* ************************************************************************* */ /* ************************************************************************* */
int main() { int main() {
TestResult tr; TestResult tr;

View File

@ -29,51 +29,36 @@ TEST( Type, grammar ) {
// Create type grammar that will place result in actual // Create type grammar that will place result in actual
Qualified actual; Qualified actual;
type_grammar type_g(actual); TypeGrammar type_g(actual);
// a class type with 2 namespaces // a class type with 2 namespaces
EXPECT(parse("gtsam::internal::Point2", type_g, space_p).full); EXPECT(parse("gtsam::internal::Point2", type_g, space_p).full);
EXPECT(actual.name=="Point2"); EXPECT(actual==Qualified("gtsam","internal","Point2",Qualified::CLASS));
EXPECT_LONGS_EQUAL(2, actual.namespaces.size());
EXPECT(actual.namespaces[0]=="gtsam");
EXPECT(actual.namespaces[1]=="internal");
EXPECT(actual.category==Qualified::CLASS);
actual.clear(); actual.clear();
// a class type with 1 namespace // a class type with 1 namespace
EXPECT(parse("gtsam::Point2", type_g, space_p).full); EXPECT(parse("gtsam::Point2", type_g, space_p).full);
EXPECT(actual.name=="Point2"); EXPECT(actual==Qualified("gtsam","Point2",Qualified::CLASS));
EXPECT_LONGS_EQUAL(1, actual.namespaces.size());
EXPECT(actual.namespaces[0]=="gtsam");
EXPECT(actual.category==Qualified::CLASS);
actual.clear(); actual.clear();
// a class type with no namespaces // a class type with no namespaces
EXPECT(parse("Point2", type_g, space_p).full); EXPECT(parse("Point2", type_g, space_p).full);
EXPECT(actual.name=="Point2"); EXPECT(actual==Qualified("Point2",Qualified::CLASS));
EXPECT(actual.namespaces.empty());
EXPECT(actual.category==Qualified::CLASS);
actual.clear(); actual.clear();
// an Eigen type // an Eigen type
EXPECT(parse("Vector", type_g, space_p).full); EXPECT(parse("Vector", type_g, space_p).full);
EXPECT(actual.name=="Vector"); EXPECT(actual==Qualified("Vector",Qualified::EIGEN));
EXPECT(actual.namespaces.empty());
EXPECT(actual.category==Qualified::EIGEN);
actual.clear(); actual.clear();
// a basic type // a basic type
EXPECT(parse("double", type_g, space_p).full); EXPECT(parse("double", type_g, space_p).full);
EXPECT(actual.name=="double"); EXPECT(actual==Qualified("double",Qualified::BASIS));
EXPECT(actual.namespaces.empty());
EXPECT(actual.category==Qualified::BASIS);
actual.clear(); actual.clear();
// void // void
EXPECT(parse("void", type_g, space_p).full); EXPECT(parse("void", type_g, space_p).full);
EXPECT(actual.name=="void"); EXPECT(actual==Qualified("void",Qualified::VOID));
EXPECT(actual.namespaces.empty());
EXPECT(actual.category==Qualified::VOID);
actual.clear(); actual.clear();
} }

View File

@ -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.name = "double"; arg1.name = "x"; Argument arg1; arg1.type.name_ = "double"; arg1.name = "x";
Argument arg2; arg2.type.name = "double"; arg2.name = "y"; Argument arg2; arg2.type.name_ = "double"; arg2.name = "y";
Argument arg3; arg3.type.name = "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);
@ -88,9 +88,9 @@ TEST( wrap, Small ) {
// check return types // check return types
LONGS_EQUAL(1, module.classes.size()); LONGS_EQUAL(1, module.classes.size());
Class cls = module.classes.front(); Class cls = module.classes.front();
EXPECT(assert_equal("Point2", cls.name)); EXPECT(assert_equal("Point2", cls.name()));
EXPECT(!cls.isVirtual); EXPECT(!cls.isVirtual);
EXPECT(cls.namespaces.empty()); EXPECT(cls.namespaces().empty());
LONGS_EQUAL(3, cls.nrMethods()); LONGS_EQUAL(3, cls.nrMethods());
LONGS_EQUAL(1, cls.static_methods.size()); LONGS_EQUAL(1, cls.static_methods.size());
@ -103,7 +103,7 @@ TEST( wrap, Small ) {
ReturnValue rv1 = m1.returnValue(0); ReturnValue rv1 = m1.returnValue(0);
EXPECT(!rv1.isPair); EXPECT(!rv1.isPair);
EXPECT(!rv1.type1.isPtr); EXPECT(!rv1.type1.isPtr);
EXPECT(assert_equal("double", rv1.type1.name)); EXPECT(assert_equal("double", rv1.type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::BASIS, rv1.type1.category); EXPECT_LONGS_EQUAL(ReturnType::BASIS, rv1.type1.category);
// Method 2 // Method 2
@ -115,7 +115,7 @@ TEST( wrap, Small ) {
ReturnValue rv2 = m2.returnValue(0); ReturnValue rv2 = m2.returnValue(0);
EXPECT(!rv2.isPair); EXPECT(!rv2.isPair);
EXPECT(!rv2.type1.isPtr); EXPECT(!rv2.type1.isPtr);
EXPECT(assert_equal("Matrix", rv2.type1.name)); EXPECT(assert_equal("Matrix", rv2.type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv2.type1.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv2.type1.category);
// Method 3 // Method 3
@ -127,7 +127,7 @@ TEST( wrap, Small ) {
ReturnValue rv3 = m3.returnValue(0); ReturnValue rv3 = m3.returnValue(0);
EXPECT(!rv3.isPair); EXPECT(!rv3.isPair);
EXPECT(!rv3.type1.isPtr); EXPECT(!rv3.type1.isPtr);
EXPECT(assert_equal("Point2", rv3.type1.name)); EXPECT(assert_equal("Point2", rv3.type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::CLASS, rv3.type1.category); EXPECT_LONGS_EQUAL(ReturnType::CLASS, rv3.type1.category);
// Static Method 1 // Static Method 1
@ -139,7 +139,7 @@ TEST( wrap, Small ) {
ReturnValue rv4 = sm1.returnValue(0); ReturnValue rv4 = sm1.returnValue(0);
EXPECT(!rv4.isPair); EXPECT(!rv4.isPair);
EXPECT(!rv4.type1.isPtr); EXPECT(!rv4.type1.isPtr);
EXPECT(assert_equal("Vector", rv4.type1.name)); EXPECT(assert_equal("Vector", rv4.type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv4.type1.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv4.type1.category);
} }
@ -182,7 +182,7 @@ TEST( wrap, Geometry ) {
// }; // };
Class cls = module.classes.at(0); Class cls = module.classes.at(0);
EXPECT(assert_equal("Point2", cls.name)); EXPECT(assert_equal("Point2", cls.name()));
EXPECT_LONGS_EQUAL(2, cls.constructor.nrOverloads()); EXPECT_LONGS_EQUAL(2, cls.constructor.nrOverloads());
EXPECT_LONGS_EQUAL(8, cls.nrMethods()); EXPECT_LONGS_EQUAL(8, cls.nrMethods());
@ -191,7 +191,7 @@ TEST( wrap, Geometry ) {
CHECK(cls.exists("returnChar")); CHECK(cls.exists("returnChar"));
Method m1 = cls.method("returnChar"); Method m1 = cls.method("returnChar");
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT(assert_equal("char", m1.returnValue(0).type1.name)); EXPECT(assert_equal("char", m1.returnValue(0).type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category);
EXPECT(!m1.returnValue(0).isPair); EXPECT(!m1.returnValue(0).isPair);
EXPECT(assert_equal("returnChar", m1.name())); EXPECT(assert_equal("returnChar", m1.name()));
@ -205,7 +205,7 @@ TEST( wrap, Geometry ) {
CHECK(cls.exists("vectorConfusion")); CHECK(cls.exists("vectorConfusion"));
Method m1 = cls.method("vectorConfusion"); Method m1 = cls.method("vectorConfusion");
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT(assert_equal("VectorNotEigen", m1.returnValue(0).type1.name)); EXPECT(assert_equal("VectorNotEigen", m1.returnValue(0).type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::CLASS, m1.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::CLASS, m1.returnValue(0).type1.category);
EXPECT(!m1.returnValue(0).isPair); EXPECT(!m1.returnValue(0).isPair);
EXPECT(assert_equal("vectorConfusion", m1.name())); EXPECT(assert_equal("vectorConfusion", m1.name()));
@ -215,7 +215,7 @@ TEST( wrap, Geometry ) {
} }
EXPECT_LONGS_EQUAL(0, cls.static_methods.size()); EXPECT_LONGS_EQUAL(0, cls.static_methods.size());
EXPECT_LONGS_EQUAL(1, cls.namespaces.size()); EXPECT_LONGS_EQUAL(1, cls.namespaces().size());
#ifndef WRAP_DISABLE_SERIALIZE #ifndef WRAP_DISABLE_SERIALIZE
// check serialization flag // check serialization flag
@ -227,11 +227,11 @@ TEST( wrap, Geometry ) {
// check second class, Point3 // check second class, Point3
{ {
Class cls = module.classes.at(1); Class cls = module.classes.at(1);
EXPECT(assert_equal("Point3", cls.name)); EXPECT(assert_equal("Point3", cls.name()));
EXPECT_LONGS_EQUAL(1, cls.constructor.nrOverloads()); EXPECT_LONGS_EQUAL(1, cls.constructor.nrOverloads());
EXPECT_LONGS_EQUAL(1, cls.nrMethods()); EXPECT_LONGS_EQUAL(1, cls.nrMethods());
EXPECT_LONGS_EQUAL(2, cls.static_methods.size()); EXPECT_LONGS_EQUAL(2, cls.static_methods.size());
EXPECT_LONGS_EQUAL(1, cls.namespaces.size()); EXPECT_LONGS_EQUAL(1, cls.namespaces().size());
// first constructor takes 3 doubles // first constructor takes 3 doubles
ArgumentList c1 = cls.constructor.argumentList(0); ArgumentList c1 = cls.constructor.argumentList(0);
@ -240,7 +240,7 @@ TEST( wrap, 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.name)); 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));
@ -248,7 +248,7 @@ TEST( wrap, Geometry ) {
CHECK(cls.exists("norm")); CHECK(cls.exists("norm"));
Method m1 = cls.method("norm"); Method m1 = cls.method("norm");
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT(assert_equal("double", m1.returnValue(0).type1.name)); EXPECT(assert_equal("double", m1.returnValue(0).type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category);
EXPECT(assert_equal("norm", m1.name())); EXPECT(assert_equal("norm", m1.name()));
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
@ -268,7 +268,7 @@ TEST( wrap, Geometry ) {
EXPECT_LONGS_EQUAL( 2, testCls.constructor.nrOverloads()); EXPECT_LONGS_EQUAL( 2, testCls.constructor.nrOverloads());
EXPECT_LONGS_EQUAL(19, testCls.nrMethods()); EXPECT_LONGS_EQUAL(19, testCls.nrMethods());
EXPECT_LONGS_EQUAL( 0, testCls.static_methods.size()); EXPECT_LONGS_EQUAL( 0, testCls.static_methods.size());
EXPECT_LONGS_EQUAL( 0, testCls.namespaces.size()); EXPECT_LONGS_EQUAL( 0, testCls.namespaces().size());
// function to parse: pair<Vector,Matrix> return_pair (Vector v, Matrix A) const; // function to parse: pair<Vector,Matrix> return_pair (Vector v, Matrix A) const;
CHECK(testCls.exists("return_pair")); CHECK(testCls.exists("return_pair"));
@ -276,9 +276,9 @@ TEST( wrap, Geometry ) {
LONGS_EQUAL(1, m2.nrOverloads()); LONGS_EQUAL(1, m2.nrOverloads());
EXPECT(m2.returnValue(0).isPair); EXPECT(m2.returnValue(0).isPair);
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type1.category);
EXPECT(assert_equal("Vector", m2.returnValue(0).type1.name)); EXPECT(assert_equal("Vector", m2.returnValue(0).type1.name()));
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type2.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type2.category);
EXPECT(assert_equal("Matrix", m2.returnValue(0).type2.name)); EXPECT(assert_equal("Matrix", m2.returnValue(0).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;
@ -292,17 +292,17 @@ TEST( wrap, 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.name)); EXPECT(assert_equal("Test", arg1.type.name_));
EXPECT(assert_equal("p1", arg1.name)); EXPECT(assert_equal("p1", arg1.name));
EXPECT(arg1.type.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.name)); EXPECT(assert_equal("Test", arg2.type.name_));
EXPECT(assert_equal("p2", arg2.name)); EXPECT(assert_equal("p2", arg2.name));
EXPECT(arg2.type.namespaces.empty()); EXPECT(arg2.type.namespaces_.empty());
} }
// evaluate global functions // evaluate global functions
@ -313,10 +313,10 @@ TEST( wrap, 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.nrOverloads()); LONGS_EQUAL(1, gfunc.nrOverloads());
EXPECT(assert_equal("Vector", gfunc.returnValue(0).type1.name)); EXPECT(assert_equal("Vector", gfunc.returnValue(0).type1.name()));
EXPECT_LONGS_EQUAL(1, gfunc.nrOverloads()); EXPECT_LONGS_EQUAL(1, gfunc.nrOverloads());
LONGS_EQUAL(1, gfunc.overloads.size()); LONGS_EQUAL(1, gfunc.overloads.size());
EXPECT(gfunc.overloads.front().namespaces.empty()); EXPECT(gfunc.overloads.front().namespaces().empty());
} }
} }
@ -338,44 +338,44 @@ TEST( wrap, parse_namespaces ) {
{ {
Class cls = module.classes.at(0); Class cls = module.classes.at(0);
EXPECT(assert_equal("ClassA", cls.name)); EXPECT(assert_equal("ClassA", cls.name()));
strvec exp_namespaces; exp_namespaces += "ns1"; strvec exp_namespaces; exp_namespaces += "ns1";
EXPECT(assert_equal(exp_namespaces, cls.namespaces)); EXPECT(assert_equal(exp_namespaces, cls.namespaces()));
} }
{ {
Class cls = module.classes.at(1); Class cls = module.classes.at(1);
EXPECT(assert_equal("ClassB", cls.name)); EXPECT(assert_equal("ClassB", cls.name()));
strvec exp_namespaces; exp_namespaces += "ns1"; strvec exp_namespaces; exp_namespaces += "ns1";
EXPECT(assert_equal(exp_namespaces, cls.namespaces)); EXPECT(assert_equal(exp_namespaces, cls.namespaces()));
} }
{ {
Class cls = module.classes.at(2); Class cls = module.classes.at(2);
EXPECT(assert_equal("ClassA", cls.name)); EXPECT(assert_equal("ClassA", cls.name()));
strvec exp_namespaces; exp_namespaces += "ns2"; strvec exp_namespaces; exp_namespaces += "ns2";
EXPECT(assert_equal(exp_namespaces, cls.namespaces)); EXPECT(assert_equal(exp_namespaces, cls.namespaces()));
} }
{ {
Class cls = module.classes.at(3); Class cls = module.classes.at(3);
EXPECT(assert_equal("ClassB", cls.name)); EXPECT(assert_equal("ClassB", cls.name()));
strvec exp_namespaces; exp_namespaces += "ns2", "ns3"; strvec exp_namespaces; exp_namespaces += "ns2", "ns3";
EXPECT(assert_equal(exp_namespaces, cls.namespaces)); EXPECT(assert_equal(exp_namespaces, cls.namespaces()));
} }
{ {
Class cls = module.classes.at(4); Class cls = module.classes.at(4);
EXPECT(assert_equal("ClassC", cls.name)); EXPECT(assert_equal("ClassC", cls.name()));
strvec exp_namespaces; exp_namespaces += "ns2"; strvec exp_namespaces; exp_namespaces += "ns2";
EXPECT(assert_equal(exp_namespaces, cls.namespaces)); EXPECT(assert_equal(exp_namespaces, cls.namespaces()));
} }
{ {
Class cls = module.classes.at(5); Class cls = module.classes.at(5);
EXPECT(assert_equal("ClassD", cls.name)); EXPECT(assert_equal("ClassD", cls.name()));
strvec exp_namespaces; strvec exp_namespaces;
EXPECT(assert_equal(exp_namespaces, cls.namespaces)); EXPECT(assert_equal(exp_namespaces, cls.namespaces()));
} }
// evaluate global functions // evaluate global functions
@ -387,15 +387,15 @@ 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.nrOverloads()); LONGS_EQUAL(2, gfunc.nrOverloads());
EXPECT(assert_equal("Vector", gfunc.returnValue(0).type1.name)); EXPECT(assert_equal("Vector", gfunc.returnValue(0).type1.name()));
// check namespaces // check namespaces
LONGS_EQUAL(2, gfunc.overloads.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.overloads.at(0).namespaces)); 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.overloads.at(1).namespaces)); EXPECT(assert_equal(exp_namespaces2, gfunc.overloads.at(1).namespaces()));
} }
} }