Fixed ambiguity issues with returning non-ptr classes, added new copies of functions to gtsam.h and depreciated old ones
parent
1e1511950c
commit
92a0cf67c9
96
gtsam.h
96
gtsam.h
|
@ -1,37 +1,61 @@
|
|||
/**
|
||||
* GTSAM Wrap Module definition
|
||||
* GTSAM Wrap Module Definition
|
||||
*
|
||||
* These are the current classes available through the matlab toolbox interface,
|
||||
* add more functions/classes as they are available.
|
||||
*
|
||||
* Requirements:
|
||||
* Constructors must appear in a class before any methods
|
||||
* Methods can only return Matrix, Vector, double, int, void, and a shared_ptr to any other object
|
||||
* Comments can use either C++ or C style
|
||||
* Classes must start with an uppercase letter
|
||||
* Only one Method/Constructor per line
|
||||
* Methods can return
|
||||
* - Eigen types: Matrix, Vector
|
||||
* - C/C++ basic types: string, bool, size_t, int, double
|
||||
* - void
|
||||
* - Any class with which be copied with boost::make_shared()
|
||||
* - boost::shared_ptr of any object type
|
||||
* Arguments to functions any of
|
||||
* - Eigen types: Matrix, Vector
|
||||
* - Eigen types and classes as an optionally const reference
|
||||
* - C/C++ basic types: string, bool, size_t, int, double
|
||||
* - Any class with which be copied with boost::make_shared() (except Eigen)
|
||||
* - boost::shared_ptr of any object type (except Eigen)
|
||||
* Comments can use either C++ or C style, with multiple lines
|
||||
* Methods must start with a lowercase letter
|
||||
* Static methods must start with a letter (upper or lowercase) and use the "static" keyword
|
||||
* Classes must start with an uppercase letter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Status:
|
||||
* - Depreciated versions of functions that return a shared_ptr unnecessarily are still present
|
||||
* - TODO: global functions
|
||||
* - TODO: namespace detection to handle nested namespaces
|
||||
*/
|
||||
|
||||
class Point2 {
|
||||
Point2();
|
||||
Point2(double x, double y);
|
||||
static Point2* Expmap_(Vector v);
|
||||
static Point2 Expmap(Vector v);
|
||||
static Vector Logmap(const Point2& p);
|
||||
void print(string s) const;
|
||||
double x();
|
||||
double y();
|
||||
Vector localCoordinates(const Point2& p);
|
||||
Point2 compose(const Point2& p2);
|
||||
Point2 between(const Point2& p2);
|
||||
Point2 retract(Vector v);
|
||||
|
||||
// Depreciated interface
|
||||
Point2* compose_(const Point2& p2);
|
||||
Point2* between_(const Point2& p2);
|
||||
Vector localCoordinates(const Point2& p);
|
||||
Point2* retract_(Vector v);
|
||||
static Point2* Expmap_(Vector v);
|
||||
};
|
||||
|
||||
class Point3 {
|
||||
Point3();
|
||||
Point3(double x, double y, double z);
|
||||
Point3(Vector v);
|
||||
static Point3* Expmap_(Vector v);
|
||||
static Point3 Expmap(Vector v);
|
||||
static Vector Logmap(const Point3& p);
|
||||
void print(string s) const;
|
||||
bool equals(const Point3& p, double tol);
|
||||
|
@ -39,31 +63,43 @@ class Point3 {
|
|||
double x();
|
||||
double y();
|
||||
double z();
|
||||
Vector localCoordinates(const Point3& p);
|
||||
Point3 retract(Vector v);
|
||||
Point3 compose(const Point3& p2);
|
||||
Point3 between(const Point3& p2);
|
||||
|
||||
// Depreciated interface
|
||||
static Point3* Expmap_(Vector v);
|
||||
Point3* compose_(const Point3& p2);
|
||||
Point3* between_(const Point3& p2);
|
||||
Vector localCoordinates(const Point3& p);
|
||||
Point3* retract_(Vector v);
|
||||
};
|
||||
|
||||
class Rot2 {
|
||||
Rot2();
|
||||
Rot2(double theta);
|
||||
static Rot2* Expmap_(Vector v);
|
||||
static Rot2 Expmap(Vector v);
|
||||
static Vector Logmap(const Rot2& p);
|
||||
void print(string s) const;
|
||||
bool equals(const Rot2& rot, double tol) const;
|
||||
double c() const;
|
||||
double s() const;
|
||||
Vector localCoordinates(const Rot2& p);
|
||||
Rot2 retract(Vector v);
|
||||
Rot2 compose(const Rot2& p2);
|
||||
Rot2 between(const Rot2& p2);
|
||||
|
||||
// Depreciated interface
|
||||
Rot2* compose_(const Rot2& p2);
|
||||
Rot2* between_(const Rot2& p2);
|
||||
Vector localCoordinates(const Rot2& p);
|
||||
Rot2* retract_(Vector v);
|
||||
static Rot2* Expmap_(Vector v);
|
||||
};
|
||||
|
||||
class Rot3 {
|
||||
Rot3();
|
||||
Rot3(Matrix R);
|
||||
static Rot3* Expmap_(Vector v);
|
||||
static Rot3 Expmap(Vector v);
|
||||
static Vector Logmap(const Rot3& p);
|
||||
static Rot3 ypr(double y, double p, double r);
|
||||
Matrix matrix() const;
|
||||
|
@ -72,10 +108,16 @@ class Rot3 {
|
|||
Vector ypr() const;
|
||||
void print(string s) const;
|
||||
bool equals(const Rot3& rot, double tol) const;
|
||||
Vector localCoordinates(const Rot3& p);
|
||||
Rot3 retract(Vector v);
|
||||
Rot3 compose(const Rot3& p2);
|
||||
Rot3 between(const Rot3& p2);
|
||||
|
||||
// Depreciated interface
|
||||
Rot3* compose_(const Rot3& p2);
|
||||
Rot3* between_(const Rot3& p2);
|
||||
Vector localCoordinates(const Rot3& p);
|
||||
Rot3* retract_(Vector v);
|
||||
static Rot3* Expmap_(Vector v);
|
||||
};
|
||||
|
||||
class Pose2 {
|
||||
|
@ -84,7 +126,7 @@ class Pose2 {
|
|||
Pose2(double theta, const Point2& t);
|
||||
Pose2(const Rot2& r, const Point2& t);
|
||||
Pose2(Vector v);
|
||||
static Pose2* Expmap_(Vector v);
|
||||
static Pose2 Expmap(Vector v);
|
||||
static Vector Logmap(const Pose2& p);
|
||||
void print(string s) const;
|
||||
bool equals(const Pose2& pose, double tol) const;
|
||||
|
@ -92,10 +134,16 @@ class Pose2 {
|
|||
double y() const;
|
||||
double theta() const;
|
||||
int dim() const;
|
||||
Vector localCoordinates(const Pose2& p);
|
||||
Pose2 retract(Vector v);
|
||||
Pose2 compose(const Pose2& p2);
|
||||
Pose2 between(const Pose2& p2);
|
||||
|
||||
// Depreciated interface
|
||||
Pose2* compose_(const Pose2& p2);
|
||||
Pose2* between_(const Pose2& p2);
|
||||
Vector localCoordinates(const Pose2& p);
|
||||
Pose2* retract_(Vector v);
|
||||
static Pose2* Expmap_(Vector v);
|
||||
};
|
||||
|
||||
class Pose3 {
|
||||
|
@ -103,7 +151,7 @@ class Pose3 {
|
|||
Pose3(const Rot3& r, const Point3& t);
|
||||
Pose3(Vector v);
|
||||
Pose3(Matrix t);
|
||||
static Pose3* Expmap_(Vector v);
|
||||
static Pose3 Expmap(Vector v);
|
||||
static Vector Logmap(const Pose3& p);
|
||||
void print(string s) const;
|
||||
bool equals(const Pose3& pose, double tol) const;
|
||||
|
@ -112,9 +160,16 @@ class Pose3 {
|
|||
double z() const;
|
||||
Matrix matrix() const;
|
||||
Matrix adjointMap() const;
|
||||
Pose3 compose(const Pose3& p2);
|
||||
Pose3 between(const Pose3& p2);
|
||||
Pose3 retract(Vector v);
|
||||
Point3 translation() const;
|
||||
Rot3 rotation() const;
|
||||
|
||||
// Depreciated interface
|
||||
static Pose3* Expmap_(Vector v);
|
||||
Pose3* compose_(const Pose3& p2);
|
||||
Pose3* between_(const Pose3& p2);
|
||||
Vector localCoordinates(const Pose3& p);
|
||||
Pose3* retract_(Vector v);
|
||||
Point3* translation_() const;
|
||||
Rot3* rotation_() const;
|
||||
|
@ -259,17 +314,12 @@ class PlanarSLAMOdometry {
|
|||
class GaussianSequentialSolver {
|
||||
GaussianSequentialSolver(const GaussianFactorGraph& graph, bool useQR);
|
||||
GaussianBayesNet* eliminate() const;
|
||||
// VectorValues* optimize() const; // FAIL: parse error here
|
||||
VectorValues* optimize() const; // FAIL: parse error here
|
||||
GaussianFactor* marginalFactor(int j) const;
|
||||
Matrix marginalCovariance(int j) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//// These are considered to be broken and will be added back as they start working
|
||||
//// It's assumed that there have been interface changes that might break this
|
||||
//
|
||||
|
|
|
@ -86,7 +86,7 @@ void Class::matlab_make_fragment(ofstream& ofs,
|
|||
BOOST_FOREACH(Constructor c, constructors)
|
||||
ofs << mex << c.matlab_wrapper_name(name) << ".cpp" << endl;
|
||||
BOOST_FOREACH(StaticMethod sm, static_methods)
|
||||
ofs << mex << name + "_" + sm.name_ << ".cpp" << endl;
|
||||
ofs << mex << name + "_" + sm.name << ".cpp" << endl;
|
||||
ofs << endl << "cd @" << name << endl;
|
||||
BOOST_FOREACH(Method m, methods)
|
||||
ofs << mex << m.name_ << ".cpp" << endl;
|
||||
|
@ -115,7 +115,7 @@ void Class::makefile_fragment(ofstream& ofs) {
|
|||
file_names.push_back(file_base);
|
||||
}
|
||||
BOOST_FOREACH(StaticMethod c, static_methods) {
|
||||
string file_base = name + "_" + c.name_;
|
||||
string file_base = name + "_" + c.name;
|
||||
file_names.push_back(file_base);
|
||||
}
|
||||
BOOST_FOREACH(Method c, methods) {
|
||||
|
|
|
@ -87,7 +87,7 @@ void Method::matlab_wrapper(const string& classPath,
|
|||
// call method
|
||||
// example: bool result = self->return_field(t);
|
||||
ofs << " ";
|
||||
if (returnVal_.returns_!="void")
|
||||
if (returnVal_.type1!="void")
|
||||
ofs << returnVal_.return_type(true,ReturnValue::pair) << " result = ";
|
||||
ofs << "self->" << name_ << "(" << args_.names() << ");\n";
|
||||
|
||||
|
|
|
@ -39,8 +39,6 @@ struct Method {
|
|||
ArgumentList args_;
|
||||
ReturnValue returnVal_;
|
||||
|
||||
// std::string return_type(bool add_ptr, pairing p);
|
||||
|
||||
// MATLAB code generation
|
||||
// classPath is class directory, e.g., ../matlab/@Point2
|
||||
|
||||
|
|
|
@ -40,17 +40,17 @@ typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> Rule;
|
|||
/* ************************************************************************* */
|
||||
|
||||
Module::Module(const string& interfacePath,
|
||||
const string& moduleName, bool verbose) : name(moduleName), verbose_(verbose)
|
||||
const string& moduleName, bool enable_verbose) : name(moduleName), verbose(enable_verbose)
|
||||
{
|
||||
// these variables will be imperatively updated to gradually build [cls]
|
||||
// The one with postfix 0 are used to reset the variables after parse.
|
||||
ReturnValue retVal0, retVal;
|
||||
Argument arg0, arg;
|
||||
ArgumentList args0, args;
|
||||
Constructor constructor0(verbose), constructor(verbose);
|
||||
Method method0(verbose), method(verbose);
|
||||
StaticMethod static_method0(verbose), static_method(verbose);
|
||||
Class cls0(verbose),cls(verbose);
|
||||
Constructor constructor0(enable_verbose), constructor(enable_verbose);
|
||||
Method method0(enable_verbose), method(enable_verbose);
|
||||
StaticMethod static_method0(enable_verbose), static_method(enable_verbose);
|
||||
Class cls0(enable_verbose),cls(enable_verbose);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Grammar with actions that build the Class object. Actions are
|
||||
|
@ -68,7 +68,13 @@ Module::Module(const string& interfacePath,
|
|||
// lexeme_d turns off white space skipping
|
||||
// http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html
|
||||
|
||||
Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')];
|
||||
Rule basisType_p =
|
||||
(str_p("string") | "bool" | "size_t" | "int" | "double");
|
||||
|
||||
Rule eigenType_p =
|
||||
(str_p("Vector") | "Matrix");
|
||||
|
||||
Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - basisType_p;
|
||||
|
||||
Rule classPtr_p =
|
||||
className_p [assign_a(arg.type)] >>
|
||||
|
@ -79,21 +85,19 @@ Module::Module(const string& interfacePath,
|
|||
className_p [assign_a(arg.type)] >>
|
||||
ch_p('&') [assign_a(arg.is_ref,true)];
|
||||
|
||||
Rule basisType_p =
|
||||
(str_p("string") | "bool" | "size_t" | "int" | "double");
|
||||
|
||||
// FAIL: this will match against VectorValues in returntype
|
||||
Rule eigenType_p =
|
||||
(str_p("Vector") | "Matrix");
|
||||
|
||||
Rule argEigenType =
|
||||
Rule argEigenType_p =
|
||||
eigenType_p[assign_a(arg.type)] >>
|
||||
!ch_p('*')[assign_a(arg.is_ptr,true)];
|
||||
|
||||
Rule eigenRef_p =
|
||||
!str_p("const") [assign_a(arg.is_const,true)] >>
|
||||
eigenType_p [assign_a(arg.type)] >>
|
||||
ch_p('&') [assign_a(arg.is_ref,true)];
|
||||
|
||||
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
||||
|
||||
Rule argument_p =
|
||||
((basisType_p[assign_a(arg.type)] | argEigenType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)])
|
||||
((basisType_p[assign_a(arg.type)] | argEigenType_p | classRef_p | eigenRef_p | classPtr_p) >> name_p[assign_a(arg.name)])
|
||||
[push_back_a(args, arg)]
|
||||
[assign_a(arg,arg0)];
|
||||
|
||||
|
@ -107,22 +111,22 @@ Module::Module(const string& interfacePath,
|
|||
[assign_a(constructor,constructor0)];
|
||||
|
||||
Rule returnType1_p =
|
||||
(basisType_p[assign_a(retVal.returns_)][assign_a(retVal.return1, ReturnValue::BASIS)]) |
|
||||
(eigenType_p[assign_a(retVal.returns_)][assign_a(retVal.return1, ReturnValue::EIGEN)]) |
|
||||
(className_p[assign_a(retVal.returns_)][assign_a(retVal.return1, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*') [assign_a(retVal.returns_ptr_,true)];
|
||||
(basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) |
|
||||
((className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*')[assign_a(retVal.isPtr1,true)]) |
|
||||
(eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]);
|
||||
|
||||
Rule returnType2_p =
|
||||
(basisType_p[assign_a(retVal.returns2_)][assign_a(retVal.return2, ReturnValue::BASIS)]) |
|
||||
(eigenType_p[assign_a(retVal.returns2_)][assign_a(retVal.return2, ReturnValue::EIGEN)]) |
|
||||
(className_p[assign_a(retVal.returns2_)][assign_a(retVal.return2, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*') [assign_a(retVal.returns_ptr2_,true)];
|
||||
(basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) |
|
||||
((className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >>
|
||||
!ch_p('*') [assign_a(retVal.isPtr2,true)]) |
|
||||
(eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]);
|
||||
|
||||
Rule pair_p =
|
||||
(str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>')
|
||||
[assign_a(retVal.returns_pair_,true)];
|
||||
[assign_a(retVal.isPair,true)];
|
||||
|
||||
Rule void_p = str_p("void")[assign_a(retVal.returns_)];
|
||||
Rule void_p = str_p("void")[assign_a(retVal.type1)];
|
||||
|
||||
Rule returnType_p = void_p | returnType1_p | pair_p;
|
||||
|
||||
|
@ -142,23 +146,19 @@ Module::Module(const string& interfacePath,
|
|||
Rule staticMethodName_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')];
|
||||
|
||||
Rule static_method_p =
|
||||
(str_p("static") >> returnType_p >> staticMethodName_p[assign_a(static_method.name_)] >>
|
||||
(str_p("static") >> returnType_p >> staticMethodName_p[assign_a(static_method.name)] >>
|
||||
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
||||
[assign_a(static_method.args_,args)]
|
||||
[assign_a(static_method.args,args)]
|
||||
[assign_a(args,args0)]
|
||||
[assign_a(static_method.returnVal_,retVal)]
|
||||
[assign_a(static_method.returnVal,retVal)]
|
||||
[assign_a(retVal,retVal0)]
|
||||
[push_back_a(cls.static_methods, static_method)]
|
||||
[assign_a(static_method,static_method0)];
|
||||
|
||||
Rule methods_p = method_p | static_method_p;
|
||||
Rule functions_p = constructor_p | method_p | static_method_p;
|
||||
|
||||
Rule class_p = str_p("class") >> className_p[assign_a(cls.name)] >> '{' >>
|
||||
*comments_p >>
|
||||
*constructor_p >>
|
||||
*comments_p >>
|
||||
*methods_p >>
|
||||
*comments_p >>
|
||||
*(functions_p | comments_p) >>
|
||||
'}' >> ";";
|
||||
|
||||
Rule module_p = *comments_p >> +(class_p
|
||||
|
@ -223,7 +223,7 @@ void Module::matlab_code(const string& toolboxPath,
|
|||
ofstream make_ofs(makeFile.c_str());
|
||||
if(!make_ofs) throw CantOpenFile(makeFile);
|
||||
|
||||
if (verbose_) cerr << "generating " << matlabMakeFile << endl;
|
||||
if (verbose) cerr << "generating " << matlabMakeFile << endl;
|
||||
emit_header_comment(ofs,"%");
|
||||
ofs << "echo on" << endl << endl;
|
||||
ofs << "toolboxpath = mfilename('fullpath');" << endl;
|
||||
|
@ -232,7 +232,7 @@ void Module::matlab_code(const string& toolboxPath,
|
|||
ofs << "clear delims" << endl;
|
||||
ofs << "addpath(toolboxpath);" << endl << endl;
|
||||
|
||||
if (verbose_) cerr << "generating " << makeFile << endl;
|
||||
if (verbose) cerr << "generating " << makeFile << endl;
|
||||
emit_header_comment(make_ofs,"#");
|
||||
make_ofs << "\nMEX = mex\n";
|
||||
make_ofs << "MEXENDING = " << mexExt << "\n";
|
||||
|
|
|
@ -30,12 +30,12 @@ namespace wrap {
|
|||
struct Module {
|
||||
std::string name; ///< module name
|
||||
std::vector<Class> classes; ///< list of classes
|
||||
bool verbose_; ///< verbose flag
|
||||
bool verbose; ///< verbose flag
|
||||
|
||||
/// constructor that parses interface file
|
||||
Module(const std::string& interfacePath,
|
||||
const std::string& moduleName,
|
||||
bool verbose=true);
|
||||
bool enable_verbose=true);
|
||||
|
||||
/// MATLAB code generation:
|
||||
void matlab_code(const std::string& path,
|
||||
|
|
|
@ -13,39 +13,39 @@ using namespace wrap;
|
|||
|
||||
/* ************************************************************************* */
|
||||
string ReturnValue::return_type(bool add_ptr, pairing p) {
|
||||
if (p==pair && returns_pair_) {
|
||||
if (p==pair && isPair) {
|
||||
string str = "pair< " +
|
||||
wrap::maybe_shared_ptr(add_ptr && returns_ptr_, returns_) + ", " +
|
||||
wrap::maybe_shared_ptr(add_ptr && returns_ptr2_, returns2_) + " >";
|
||||
wrap::maybe_shared_ptr(add_ptr && isPtr1, type1) + ", " +
|
||||
wrap::maybe_shared_ptr(add_ptr && isPtr2, type2) + " >";
|
||||
return str;
|
||||
} else
|
||||
return wrap::maybe_shared_ptr(add_ptr && returns_ptr_, (p==arg2)? returns2_ : returns_);
|
||||
return wrap::maybe_shared_ptr(add_ptr && isPtr1, (p==arg2)? type2 : type1);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void ReturnValue::wrap_result(std::ostream& ofs) {
|
||||
if (returns_pair_) {
|
||||
if (isPair) {
|
||||
// first return value in pair
|
||||
if (returns_ptr_) // if we already have a pointer
|
||||
ofs << " out[0] = wrap_shared_ptr(result.first,\"" << returns_ << "\");\n";
|
||||
else if (return1 == ReturnValue::CLASS) // if we are going to make one
|
||||
ofs << " out[0] = wrap_shared_ptr(make_shared< " << returns_ << " >(result.first),\"" << returns_ << "\");\n";
|
||||
if (isPtr1) // if we already have a pointer
|
||||
ofs << " out[0] = wrap_shared_ptr(result.first,\"" << type1 << "\");\n";
|
||||
else if (category1 == ReturnValue::CLASS) // if we are going to make one
|
||||
ofs << " out[0] = wrap_shared_ptr(make_shared< " << type1 << " >(result.first),\"" << type1 << "\");\n";
|
||||
else // if basis type
|
||||
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n";
|
||||
|
||||
// second return value in pair
|
||||
if (returns_ptr2_) // if we already have a pointer
|
||||
ofs << " out[1] = wrap_shared_ptr(result.second,\"" << returns2_ << "\");\n";
|
||||
else if (return2 == ReturnValue::CLASS) // if we are going to make one
|
||||
ofs << " out[1] = wrap_shared_ptr(make_shared< " << returns2_ << " >(result.second),\"" << returns2_ << "\");\n";
|
||||
if (isPtr2) // if we already have a pointer
|
||||
ofs << " out[1] = wrap_shared_ptr(result.second,\"" << type2 << "\");\n";
|
||||
else if (category2 == ReturnValue::CLASS) // if we are going to make one
|
||||
ofs << " out[1] = wrap_shared_ptr(make_shared< " << type2 << " >(result.second),\"" << type2 << "\");\n";
|
||||
else
|
||||
ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n";
|
||||
}
|
||||
else if (returns_ptr_)
|
||||
ofs << " out[0] = wrap_shared_ptr(result,\"" << returns_ << "\");\n";
|
||||
else if (return1 == ReturnValue::CLASS)
|
||||
ofs << " out[0] = wrap_shared_ptr(make_shared< " << returns_ << " >(result),\"" << returns_ << "\");\n";
|
||||
else if (returns_!="void")
|
||||
else if (isPtr1)
|
||||
ofs << " out[0] = wrap_shared_ptr(result,\"" << type1 << "\");\n";
|
||||
else if (category1 == ReturnValue::CLASS)
|
||||
ofs << " out[0] = wrap_shared_ptr(make_shared< " << type1 << " >(result),\"" << type1 << "\");\n";
|
||||
else if (type1!="void")
|
||||
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -22,16 +22,16 @@ struct ReturnValue {
|
|||
VOID
|
||||
} return_category;
|
||||
|
||||
ReturnValue(bool verbose = true)
|
||||
: verbose_(verbose), returns_ptr_(false), returns_ptr2_(false),
|
||||
returns_pair_(false), return1(VOID), return2(VOID)
|
||||
ReturnValue(bool enable_verbosity = true)
|
||||
: verbose(enable_verbosity), isPtr1(false), isPtr2(false),
|
||||
isPair(false), category1(VOID), category2(VOID)
|
||||
{}
|
||||
|
||||
bool verbose_;
|
||||
std::string returns_, returns2_;
|
||||
bool returns_ptr_, returns_ptr2_, returns_pair_;
|
||||
bool verbose;
|
||||
std::string type1, type2;
|
||||
bool isPtr1, isPtr2, isPair;
|
||||
|
||||
return_category return1, return2;
|
||||
return_category category1, category2;
|
||||
|
||||
typedef enum {
|
||||
arg1, arg2, pair
|
||||
|
@ -39,7 +39,7 @@ struct ReturnValue {
|
|||
|
||||
std::string return_type(bool add_ptr, pairing p);
|
||||
|
||||
std::string matlab_returnType() const { return returns_pair_? "[first,second]" : "result"; }
|
||||
std::string matlab_returnType() const { return isPair? "[first,second]" : "result"; }
|
||||
|
||||
void wrap_result(std::ostream& ofs);
|
||||
|
||||
|
|
|
@ -29,18 +29,18 @@ using namespace wrap;
|
|||
void StaticMethod::matlab_mfile(const string& toolboxPath, const string& className) {
|
||||
|
||||
// open destination m-file
|
||||
string full_name = className + "_" + name_;
|
||||
string full_name = className + "_" + name;
|
||||
string wrapperFile = toolboxPath + "/" + full_name + ".m";
|
||||
ofstream ofs(wrapperFile.c_str());
|
||||
if(!ofs) throw CantOpenFile(wrapperFile);
|
||||
if(verbose_) cerr << "generating " << wrapperFile << endl;
|
||||
if(verbose) cerr << "generating " << wrapperFile << endl;
|
||||
|
||||
// generate code
|
||||
string returnType = returnVal_.matlab_returnType();
|
||||
string returnType = returnVal.matlab_returnType();
|
||||
ofs << "function " << returnType << " = " << full_name << "(";
|
||||
if (args_.size()) ofs << args_.names();
|
||||
if (args.size()) ofs << args.names();
|
||||
ofs << ")" << endl;
|
||||
ofs << "% usage: x = " << full_name << "(" << args_.names() << ")" << endl;
|
||||
ofs << "% usage: x = " << full_name << "(" << args.names() << ")" << endl;
|
||||
ofs << " error('need to compile " << full_name << ".cpp');" << endl;
|
||||
ofs << "end" << endl;
|
||||
|
||||
|
@ -53,11 +53,11 @@ void StaticMethod::matlab_wrapper(const string& toolboxPath,
|
|||
const string& className, const string& nameSpace)
|
||||
{
|
||||
// open destination wrapperFile
|
||||
string full_name = className + "_" + name_;
|
||||
string full_name = className + "_" + name;
|
||||
string wrapperFile = toolboxPath + "/" + full_name + ".cpp";
|
||||
ofstream ofs(wrapperFile.c_str());
|
||||
if(!ofs) throw CantOpenFile(wrapperFile);
|
||||
if(verbose_) cerr << "generating " << wrapperFile << endl;
|
||||
if(verbose) cerr << "generating " << wrapperFile << endl;
|
||||
|
||||
// generate code
|
||||
|
||||
|
@ -74,21 +74,21 @@ void StaticMethod::matlab_wrapper(const string& toolboxPath,
|
|||
|
||||
// check arguments
|
||||
// NOTE: for static functions, there is no object passed
|
||||
ofs << " checkArguments(\"" << full_name << "\",nargout,nargin," << args_.size() << ");\n";
|
||||
ofs << " checkArguments(\"" << full_name << "\",nargout,nargin," << args.size() << ");\n";
|
||||
|
||||
// unwrap arguments, see Argument.cpp
|
||||
args_.matlab_unwrap(ofs,0); // We start at 0 because there is no self object
|
||||
args.matlab_unwrap(ofs,0); // We start at 0 because there is no self object
|
||||
|
||||
ofs << " ";
|
||||
|
||||
// call method with default type
|
||||
if (returnVal_.returns_!="void")
|
||||
ofs << returnVal_.return_type(true,ReturnValue::pair) << " result = ";
|
||||
ofs << className << "::" << name_ << "(" << args_.names() << ");\n";
|
||||
if (returnVal.type1!="void")
|
||||
ofs << returnVal.return_type(true,ReturnValue::pair) << " result = ";
|
||||
ofs << className << "::" << name << "(" << args.names() << ");\n";
|
||||
|
||||
// wrap result
|
||||
// example: out[0]=wrap<bool>(result);
|
||||
returnVal_.wrap_result(ofs);
|
||||
returnVal.wrap_result(ofs);
|
||||
|
||||
// finish
|
||||
ofs << "}\n";
|
||||
|
|
|
@ -30,14 +30,14 @@ namespace wrap {
|
|||
struct StaticMethod {
|
||||
|
||||
/// Constructor creates empty object
|
||||
StaticMethod(bool verbose = true) :
|
||||
verbose_(verbose) {}
|
||||
StaticMethod(bool verbosity = true) :
|
||||
verbose(verbosity) {}
|
||||
|
||||
// Then the instance variables are set directly by the Module constructor
|
||||
bool verbose_;
|
||||
std::string name_;
|
||||
ArgumentList args_;
|
||||
ReturnValue returnVal_;
|
||||
bool verbose;
|
||||
std::string name;
|
||||
ArgumentList args;
|
||||
ReturnValue returnVal;
|
||||
|
||||
// MATLAB code generation
|
||||
// toolboxPath is the core toolbox directory, e.g., ../matlab
|
||||
|
|
|
@ -6,6 +6,7 @@ class Point2 {
|
|||
double x() const;
|
||||
double y() const;
|
||||
int dim() const;
|
||||
VectorNotEigen vectorConfusion();
|
||||
};
|
||||
|
||||
class Point3 {
|
||||
|
@ -19,6 +20,10 @@ class Point3 {
|
|||
|
||||
// another comment
|
||||
|
||||
/**
|
||||
* A multi-line comment!
|
||||
*/
|
||||
|
||||
class Test {
|
||||
/* a comment! */
|
||||
// another comment
|
||||
|
@ -31,6 +36,8 @@ class Test {
|
|||
int return_int (int value) const;
|
||||
double return_double (double value) const;
|
||||
|
||||
Test(double a, Matrix b); // a constructor in the middle of a class
|
||||
|
||||
// comments in the middle!
|
||||
|
||||
// (more) comments in the middle!
|
||||
|
@ -40,6 +47,7 @@ class Test {
|
|||
Matrix return_matrix1(Matrix value) const;
|
||||
Vector return_vector2(Vector value) const;
|
||||
Matrix return_matrix2(Matrix value) const;
|
||||
void arg_EigenConstRef(const Matrix& value) const;
|
||||
|
||||
bool return_field(const Test& t) const;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ classdef Test
|
|||
methods
|
||||
function obj = Test(varargin)
|
||||
if nargin == 0, obj.self = new_Test_(); end
|
||||
if nargin == 2, obj.self = new_Test_dM(varargin{1},varargin{2}); end
|
||||
if nargin ~= 13 && obj.self == 0, error('Test constructor failed'); end
|
||||
end
|
||||
function display(obj), obj.print(''); end
|
||||
|
|
|
@ -17,8 +17,10 @@ new_Point2_dd.$(MEXENDING): new_Point2_dd.cpp
|
|||
$(MEX) $(mex_flags) @Point2/y.cpp -output @Point2/y
|
||||
@Point2/dim.$(MEXENDING): @Point2/dim.cpp
|
||||
$(MEX) $(mex_flags) @Point2/dim.cpp -output @Point2/dim
|
||||
@Point2/vectorConfusion.$(MEXENDING): @Point2/vectorConfusion.cpp
|
||||
$(MEX) $(mex_flags) @Point2/vectorConfusion.cpp -output @Point2/vectorConfusion
|
||||
|
||||
Point2: new_Point2_.$(MEXENDING) new_Point2_dd.$(MEXENDING) @Point2/x.$(MEXENDING) @Point2/y.$(MEXENDING) @Point2/dim.$(MEXENDING)
|
||||
Point2: new_Point2_.$(MEXENDING) new_Point2_dd.$(MEXENDING) @Point2/x.$(MEXENDING) @Point2/y.$(MEXENDING) @Point2/dim.$(MEXENDING) @Point2/vectorConfusion.$(MEXENDING)
|
||||
|
||||
# Point3
|
||||
new_Point3_ddd.$(MEXENDING): new_Point3_ddd.cpp
|
||||
|
@ -35,6 +37,8 @@ Point3: new_Point3_ddd.$(MEXENDING) Point3_staticFunction.$(MEXENDING) Point3_St
|
|||
# Test
|
||||
new_Test_.$(MEXENDING): new_Test_.cpp
|
||||
$(MEX) $(mex_flags) new_Test_.cpp -output new_Test_
|
||||
new_Test_dM.$(MEXENDING): new_Test_dM.cpp
|
||||
$(MEX) $(mex_flags) new_Test_dM.cpp -output new_Test_dM
|
||||
@Test/return_pair.$(MEXENDING): @Test/return_pair.cpp
|
||||
$(MEX) $(mex_flags) @Test/return_pair.cpp -output @Test/return_pair
|
||||
@Test/return_bool.$(MEXENDING): @Test/return_bool.cpp
|
||||
|
@ -55,6 +59,8 @@ new_Test_.$(MEXENDING): new_Test_.cpp
|
|||
$(MEX) $(mex_flags) @Test/return_vector2.cpp -output @Test/return_vector2
|
||||
@Test/return_matrix2.$(MEXENDING): @Test/return_matrix2.cpp
|
||||
$(MEX) $(mex_flags) @Test/return_matrix2.cpp -output @Test/return_matrix2
|
||||
@Test/arg_EigenConstRef.$(MEXENDING): @Test/arg_EigenConstRef.cpp
|
||||
$(MEX) $(mex_flags) @Test/arg_EigenConstRef.cpp -output @Test/arg_EigenConstRef
|
||||
@Test/return_field.$(MEXENDING): @Test/return_field.cpp
|
||||
$(MEX) $(mex_flags) @Test/return_field.cpp -output @Test/return_field
|
||||
@Test/return_TestPtr.$(MEXENDING): @Test/return_TestPtr.cpp
|
||||
|
@ -72,7 +78,7 @@ new_Test_.$(MEXENDING): new_Test_.cpp
|
|||
@Test/print.$(MEXENDING): @Test/print.cpp
|
||||
$(MEX) $(mex_flags) @Test/print.cpp -output @Test/print
|
||||
|
||||
Test: new_Test_.$(MEXENDING) @Test/return_pair.$(MEXENDING) @Test/return_bool.$(MEXENDING) @Test/return_size_t.$(MEXENDING) @Test/return_int.$(MEXENDING) @Test/return_double.$(MEXENDING) @Test/return_string.$(MEXENDING) @Test/return_vector1.$(MEXENDING) @Test/return_matrix1.$(MEXENDING) @Test/return_vector2.$(MEXENDING) @Test/return_matrix2.$(MEXENDING) @Test/return_field.$(MEXENDING) @Test/return_TestPtr.$(MEXENDING) @Test/return_Test.$(MEXENDING) @Test/return_Point2Ptr.$(MEXENDING) @Test/create_ptrs.$(MEXENDING) @Test/create_MixedPtrs.$(MEXENDING) @Test/return_ptrs.$(MEXENDING) @Test/print.$(MEXENDING)
|
||||
Test: new_Test_.$(MEXENDING) new_Test_dM.$(MEXENDING) @Test/return_pair.$(MEXENDING) @Test/return_bool.$(MEXENDING) @Test/return_size_t.$(MEXENDING) @Test/return_int.$(MEXENDING) @Test/return_double.$(MEXENDING) @Test/return_string.$(MEXENDING) @Test/return_vector1.$(MEXENDING) @Test/return_matrix1.$(MEXENDING) @Test/return_vector2.$(MEXENDING) @Test/return_matrix2.$(MEXENDING) @Test/arg_EigenConstRef.$(MEXENDING) @Test/return_field.$(MEXENDING) @Test/return_TestPtr.$(MEXENDING) @Test/return_Test.$(MEXENDING) @Test/return_Point2Ptr.$(MEXENDING) @Test/create_ptrs.$(MEXENDING) @Test/create_MixedPtrs.$(MEXENDING) @Test/return_ptrs.$(MEXENDING) @Test/print.$(MEXENDING)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ cd @Point2
|
|||
mex -O5 x.cpp
|
||||
mex -O5 y.cpp
|
||||
mex -O5 dim.cpp
|
||||
mex -O5 vectorConfusion.cpp
|
||||
|
||||
%% Point3
|
||||
cd(toolboxpath)
|
||||
|
@ -29,6 +30,7 @@ mex -O5 norm.cpp
|
|||
%% Test
|
||||
cd(toolboxpath)
|
||||
mex -O5 new_Test_.cpp
|
||||
mex -O5 new_Test_dM.cpp
|
||||
|
||||
cd @Test
|
||||
mex -O5 return_pair.cpp
|
||||
|
@ -41,6 +43,7 @@ mex -O5 return_vector1.cpp
|
|||
mex -O5 return_matrix1.cpp
|
||||
mex -O5 return_vector2.cpp
|
||||
mex -O5 return_matrix2.cpp
|
||||
mex -O5 arg_EigenConstRef.cpp
|
||||
mex -O5 return_field.cpp
|
||||
mex -O5 return_TestPtr.cpp
|
||||
mex -O5 return_Test.cpp
|
||||
|
|
|
@ -102,6 +102,40 @@ TEST( spirit, constMethod_p ) {
|
|||
EXPECT(parse("double norm() const;", constMethod_p, space_p).full);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( spirit, return_value_p ) {
|
||||
bool isEigen = true;
|
||||
string actual_return_type;
|
||||
string actual_function_name;
|
||||
|
||||
Rule basisType_p =
|
||||
(str_p("string") | "bool" | "size_t" | "int" | "double");
|
||||
|
||||
Rule eigenType_p =
|
||||
(str_p("Vector") | "Matrix");
|
||||
|
||||
Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - basisType_p;
|
||||
|
||||
Rule funcName_p = lexeme_d[lower_p >> *(alnum_p | '_')];
|
||||
|
||||
Rule returnType_p =
|
||||
(basisType_p[assign_a(actual_return_type)][assign_a(isEigen, true)]) |
|
||||
(className_p[assign_a(actual_return_type)][assign_a(isEigen,false)]) |
|
||||
(eigenType_p[assign_a(actual_return_type)][assign_a(isEigen, true)]);
|
||||
|
||||
Rule testFunc_p = returnType_p >> funcName_p[assign_a(actual_function_name)] >> str_p("();");
|
||||
|
||||
EXPECT(parse("VectorNotEigen doesNotReturnAnEigenVector();", testFunc_p, space_p).full);
|
||||
EXPECT(!isEigen);
|
||||
EXPECT(actual_return_type == "VectorNotEigen");
|
||||
EXPECT(actual_function_name == "doesNotReturnAnEigenVector");
|
||||
|
||||
EXPECT(parse("Vector actuallyAVector();", testFunc_p, space_p).full);
|
||||
EXPECT(isEigen);
|
||||
EXPECT(actual_return_type == "Vector");
|
||||
EXPECT(actual_function_name == "actuallyAVector");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace wrap;
|
||||
static bool verbose = false;
|
||||
static bool enable_verbose = false;
|
||||
#ifdef TOPSRCDIR
|
||||
static string topdir = TOPSRCDIR;
|
||||
#else
|
||||
|
@ -46,15 +46,15 @@ TEST( wrap, ArgumentList ) {
|
|||
|
||||
/* ************************************************************************* */
|
||||
TEST( wrap, check_exception ) {
|
||||
THROWS_EXCEPTION(Module("/notarealpath", "geometry",verbose));
|
||||
CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",verbose), CantOpenFile);
|
||||
THROWS_EXCEPTION(Module("/notarealpath", "geometry",enable_verbose));
|
||||
CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",enable_verbose), CantOpenFile);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( wrap, parse ) {
|
||||
string path = topdir + "/wrap";
|
||||
|
||||
Module module(path.c_str(), "geometry",verbose);
|
||||
Module module(path.c_str(), "geometry",enable_verbose);
|
||||
CHECK(module.classes.size()==3);
|
||||
|
||||
// check second class, Point3
|
||||
|
@ -77,29 +77,29 @@ TEST( wrap, parse ) {
|
|||
|
||||
// check method
|
||||
Method m1 = cls.methods.front();
|
||||
EXPECT(m1.returnVal_.returns_=="double");
|
||||
EXPECT(m1.returnVal_.type1=="double");
|
||||
EXPECT(m1.name_=="norm");
|
||||
EXPECT(m1.args_.size()==0);
|
||||
EXPECT(m1.is_const_);
|
||||
|
||||
// Test class is the third one
|
||||
Class testCls = module.classes.at(2);
|
||||
EXPECT_LONGS_EQUAL( 1, testCls.constructors.size());
|
||||
EXPECT_LONGS_EQUAL(18, testCls.methods.size());
|
||||
EXPECT_LONGS_EQUAL( 2, testCls.constructors.size());
|
||||
EXPECT_LONGS_EQUAL(19, testCls.methods.size());
|
||||
EXPECT_LONGS_EQUAL( 0, testCls.static_methods.size());
|
||||
|
||||
// pair<Vector,Matrix> return_pair (Vector v, Matrix A) const;
|
||||
// function to parse: pair<Vector,Matrix> return_pair (Vector v, Matrix A) const;
|
||||
Method m2 = testCls.methods.front();
|
||||
EXPECT(m2.returnVal_.returns_pair_);
|
||||
EXPECT(m2.returnVal_.return1 == ReturnValue::EIGEN);
|
||||
EXPECT(m2.returnVal_.return2 == ReturnValue::EIGEN);
|
||||
EXPECT(m2.returnVal_.isPair);
|
||||
EXPECT(m2.returnVal_.category1 == ReturnValue::EIGEN);
|
||||
EXPECT(m2.returnVal_.category2 == ReturnValue::EIGEN);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( wrap, matlab_code ) {
|
||||
// Parse into class object
|
||||
string path = topdir + "/wrap";
|
||||
Module module(path,"geometry",verbose);
|
||||
Module module(path,"geometry",enable_verbose);
|
||||
|
||||
// emit MATLAB code
|
||||
// make_geometry will not compile, use make testwrap to generate real make
|
||||
|
|
Loading…
Reference in New Issue