Added better handling for pairs of classes with/without pointers

release/4.3a0
Alex Cunningham 2011-12-07 03:05:33 +00:00
parent dcc3e8d0f1
commit f5f59bd213
12 changed files with 96 additions and 30 deletions

View File

@ -82,14 +82,17 @@ Module::Module(const string& interfacePath,
Rule basisType_p =
(str_p("string") | "bool" | "size_t" | "int" | "double");
Rule eigenType =
(str_p("Vector") | "Matrix")[assign_a(arg.type)] >>
!ch_p('*')[assign_a(arg.is_ptr,true)];
Rule eigenType_p =
(str_p("Vector") | "Matrix");
Rule argEigenType =
eigenType_p[assign_a(arg.type)] >>
!ch_p('*')[assign_a(arg.is_ptr,true)];
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
Rule argument_p =
((basisType_p[assign_a(arg.type)] | eigenType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)])
((basisType_p[assign_a(arg.type)] | argEigenType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)])
[push_back_a(args, arg)]
[assign_a(arg,arg0)];
@ -102,19 +105,17 @@ Module::Module(const string& interfacePath,
[push_back_a(cls.constructors, constructor)]
[assign_a(constructor,constructor0)];
Rule returnClass1_p = className_p [assign_a(retVal.returns_class_, true)];
Rule returnClass2_p = className_p [assign_a(retVal.returns_class2_, true)];
Rule returnType1_p =
basisType_p[assign_a(retVal.returns_)] |
((returnClass1_p | "Vector" | "Matrix")[assign_a(retVal.returns_)] >>
!ch_p('*') [assign_a(retVal.returns_ptr_,true)]);
(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)];
Rule returnType2_p =
basisType_p[assign_a(retVal.returns2_)] |
((returnClass2_p | "Vector" | "Matrix")[assign_a(retVal.returns2_)] >>
!ch_p('*') [assign_a(retVal.returns_ptr2_,true)]);
(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)];
Rule pair_p =
(str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>')

View File

@ -18,7 +18,7 @@
#pragma once
#include <string>
#include <list>
#include <vector>
#include "Class.h"
@ -29,7 +29,7 @@ namespace wrap {
*/
struct Module {
std::string name; ///< module name
std::list<Class> classes; ///< list of classes
std::vector<Class> classes; ///< list of classes
bool verbose_; ///< verbose flag
/// constructor that parses interface file

View File

@ -16,7 +16,7 @@ string ReturnValue::return_type(bool add_ptr, pairing p) {
if (p==pair && returns_pair_) {
string str = "pair< " +
wrap::maybe_shared_ptr(add_ptr && returns_ptr_, returns_) + ", " +
wrap::maybe_shared_ptr(add_ptr && returns_ptr_, returns2_) + " >";
wrap::maybe_shared_ptr(add_ptr && returns_ptr2_, returns2_) + " >";
return str;
} else
return wrap::maybe_shared_ptr(add_ptr && returns_ptr_, (p==arg2)? returns2_ : returns_);
@ -26,20 +26,24 @@ string ReturnValue::return_type(bool add_ptr, pairing p) {
void ReturnValue::wrap_result(std::ostream& ofs) {
if (returns_pair_) {
// first return value in pair
if (returns_ptr_)
if (returns_ptr_) // if we already have a pointer
ofs << " out[0] = wrap_shared_ptr(result.first,\"" << returns_ << "\");\n";
else
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";
else // if basis type
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n";
// second return value in pair
if (returns_ptr2_)
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";
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 (returns_class_)
else if (return1 == ReturnValue::CLASS)
ofs << " out[0] = wrap_shared_ptr(make_shared< " << returns_ << " >(result),\"" << returns_ << "\");\n";
else if (returns_!="void")
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n";

View File

@ -15,14 +15,23 @@ namespace wrap {
struct ReturnValue {
typedef enum {
CLASS,
EIGEN,
BASIS,
VOID
} return_category;
ReturnValue(bool verbose = true)
: verbose_(verbose), returns_ptr_(false), returns_ptr2_(false),
returns_pair_(false), returns_class_(false)
returns_pair_(false), return1(VOID), return2(VOID)
{}
bool verbose_;
std::string returns_, returns2_;
bool returns_ptr_, returns_ptr2_, returns_pair_, returns_class_, returns_class2_;
bool returns_ptr_, returns_ptr2_, returns_pair_;
return_category return1, return2;
typedef enum {
arg1, arg2, pair

View File

@ -24,6 +24,8 @@ class Test {
// another comment
Test();
pair<Vector,Matrix> return_pair (Vector v, Matrix A) const; // intentionally the first method
bool return_bool (bool value) const; // comment after a line!
size_t return_size_t (size_t value) const;
int return_int (int value) const;
@ -39,15 +41,15 @@ class Test {
Vector return_vector2(Vector value) const;
Matrix return_matrix2(Matrix value) const;
pair<Vector,Matrix> return_pair (Vector v, Matrix A) const;
bool return_field(const Test& t) const;
Test* return_TestPtr(Test* value) const;
Test return_Test(Test* value) const;
Point2* return_Point2Ptr(bool value) const;
pair<Test*,Test*> create_ptrs () const;
pair<Test ,Test*> create_MixedPtrs () const;
pair<Test*,Test*> return_ptrs (Test* p1, Test* p2) const;
void print() const;

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2011-Dec-06
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("create_MixedPtrs",nargout,nargin-1,0);
shared_ptr<Test> self = unwrap_shared_ptr< Test >(in[0],"Test");
pair< Test, shared_ptr<Test> > result = self->create_MixedPtrs();
out[0] = wrap_shared_ptr(make_shared< Test >(result.first),"Test");
out[1] = wrap_shared_ptr(result.second,"Test");
}

View File

@ -0,0 +1,4 @@
function [first,second] = create_MixedPtrs(obj)
% usage: obj.create_MixedPtrs()
error('need to compile create_MixedPtrs.cpp');
end

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2011-Dec-06
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_Test",nargout,nargin-1,1);
shared_ptr<Test> self = unwrap_shared_ptr< Test >(in[0],"Test");
shared_ptr<Test> value = unwrap_shared_ptr< Test >(in[1], "Test");
Test result = self->return_Test(value);
out[0] = wrap_shared_ptr(make_shared< Test >(result),"Test");
}

View File

@ -0,0 +1,4 @@
function result = return_Test(obj,value)
% usage: obj.return_Test(value)
error('need to compile return_Test.cpp');
end

View File

@ -35,6 +35,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_
@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
$(MEX) $(mex_flags) @Test/return_bool.cpp -output @Test/return_bool
@Test/return_size_t.$(MEXENDING): @Test/return_size_t.cpp
@ -53,22 +55,24 @@ 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/return_pair.$(MEXENDING): @Test/return_pair.cpp
$(MEX) $(mex_flags) @Test/return_pair.cpp -output @Test/return_pair
@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
$(MEX) $(mex_flags) @Test/return_TestPtr.cpp -output @Test/return_TestPtr
@Test/return_Test.$(MEXENDING): @Test/return_Test.cpp
$(MEX) $(mex_flags) @Test/return_Test.cpp -output @Test/return_Test
@Test/return_Point2Ptr.$(MEXENDING): @Test/return_Point2Ptr.cpp
$(MEX) $(mex_flags) @Test/return_Point2Ptr.cpp -output @Test/return_Point2Ptr
@Test/create_ptrs.$(MEXENDING): @Test/create_ptrs.cpp
$(MEX) $(mex_flags) @Test/create_ptrs.cpp -output @Test/create_ptrs
@Test/create_MixedPtrs.$(MEXENDING): @Test/create_MixedPtrs.cpp
$(MEX) $(mex_flags) @Test/create_MixedPtrs.cpp -output @Test/create_MixedPtrs
@Test/return_ptrs.$(MEXENDING): @Test/return_ptrs.cpp
$(MEX) $(mex_flags) @Test/return_ptrs.cpp -output @Test/return_ptrs
@Test/print.$(MEXENDING): @Test/print.cpp
$(MEX) $(mex_flags) @Test/print.cpp -output @Test/print
Test: new_Test_.$(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_pair.$(MEXENDING) @Test/return_field.$(MEXENDING) @Test/return_TestPtr.$(MEXENDING) @Test/return_Point2Ptr.$(MEXENDING) @Test/create_ptrs.$(MEXENDING) @Test/return_ptrs.$(MEXENDING) @Test/print.$(MEXENDING)
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)

View File

@ -31,6 +31,7 @@ cd(toolboxpath)
mex -O5 new_Test_.cpp
cd @Test
mex -O5 return_pair.cpp
mex -O5 return_bool.cpp
mex -O5 return_size_t.cpp
mex -O5 return_int.cpp
@ -40,11 +41,12 @@ mex -O5 return_vector1.cpp
mex -O5 return_matrix1.cpp
mex -O5 return_vector2.cpp
mex -O5 return_matrix2.cpp
mex -O5 return_pair.cpp
mex -O5 return_field.cpp
mex -O5 return_TestPtr.cpp
mex -O5 return_Test.cpp
mex -O5 return_Point2Ptr.cpp
mex -O5 create_ptrs.cpp
mex -O5 create_MixedPtrs.cpp
mex -O5 return_ptrs.cpp
mex -O5 print.cpp

View File

@ -55,7 +55,7 @@ TEST( wrap, parse ) {
string path = topdir + "/wrap";
Module module(path.c_str(), "geometry",verbose);
EXPECT(module.classes.size()==3);
CHECK(module.classes.size()==3);
// check second class, Point3
Class cls = *(++module.classes.begin());
@ -81,6 +81,18 @@ TEST( wrap, parse ) {
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( 0, testCls.static_methods.size());
// 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);
}
/* ************************************************************************* */
@ -107,8 +119,10 @@ TEST( wrap, matlab_code ) {
EXPECT(files_equal(path + "/tests/expected/@Test/Test.m" , "actual/@Test/Test.m" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_string.cpp" , "actual/@Test/return_string.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_pair.cpp" , "actual/@Test/return_pair.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/create_MixedPtrs.cpp", "actual/@Test/create_MixedPtrs.cpp"));
EXPECT(files_equal(path + "/tests/expected/@Test/return_field.cpp" , "actual/@Test/return_field.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_TestPtr.cpp", "actual/@Test/return_TestPtr.cpp"));
EXPECT(files_equal(path + "/tests/expected/@Test/return_Test.cpp" , "actual/@Test/return_Test.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_Point2Ptr.cpp", "actual/@Test/return_Point2Ptr.cpp"));
EXPECT(files_equal(path + "/tests/expected/@Test/return_ptrs.cpp" , "actual/@Test/return_ptrs.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/print.m" , "actual/@Test/print.m" ));