Fixed ambiguity issues with returning non-ptr classes, added new copies of functions to gtsam.h and depreciated old ones

release/4.3a0
Alex Cunningham 2011-12-07 03:05:37 +00:00
parent 1e1511950c
commit 92a0cf67c9
16 changed files with 225 additions and 125 deletions

96
gtsam.h
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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";
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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