Added namespace support to return classes

release/4.3a0
Alex Cunningham 2011-12-08 20:51:17 +00:00
parent 66711e1faa
commit ead8247bd7
6 changed files with 55 additions and 14 deletions

View File

@ -21,6 +21,7 @@
//#define BOOST_SPIRIT_DEBUG //#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/classic_core.hpp> #include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp> #include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_clear_actor.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <iostream> #include <iostream>
@ -52,7 +53,7 @@ Module::Module(const string& interfacePath,
Method method0(enable_verbose), method(enable_verbose); Method method0(enable_verbose), method(enable_verbose);
StaticMethod static_method0(enable_verbose), static_method(enable_verbose); StaticMethod static_method0(enable_verbose), static_method(enable_verbose);
Class cls0(enable_verbose),cls(enable_verbose); Class cls0(enable_verbose),cls(enable_verbose);
vector<string> namespaces, namespaces_parent, namespaces_temp; vector<string> namespaces, namespaces_return;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Grammar with actions that build the Class object. Actions are // Grammar with actions that build the Class object. Actions are
@ -69,12 +70,15 @@ Module::Module(const string& interfacePath,
Rule basisType_p = Rule basisType_p =
(str_p("string") | "bool" | "size_t" | "int" | "double"); (str_p("string") | "bool" | "size_t" | "int" | "double");
Rule keywords_p =
(str_p("const") | "static" | "namespace" | basisType_p);
Rule eigenType_p = Rule eigenType_p =
(str_p("Vector") | "Matrix"); (str_p("Vector") | "Matrix");
Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - basisType_p; Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p;
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')]; Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::"); Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::");
@ -116,15 +120,19 @@ Module::Module(const string& interfacePath,
[push_back_a(cls.constructors, constructor)] [push_back_a(cls.constructors, constructor)]
[assign_a(constructor,constructor0)]; [assign_a(constructor,constructor0)];
Rule namespace_ret_p = namespace_name_p[push_back_a(namespaces_return)] >> str_p("::");
Rule returnType1_p = Rule returnType1_p =
(basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) | (basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) |
((className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >> ((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)]
>> (className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >>
!ch_p('*')[assign_a(retVal.isPtr1,true)]) | !ch_p('*')[assign_a(retVal.isPtr1,true)]) |
(eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]); (eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]);
Rule returnType2_p = Rule returnType2_p =
(basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) | (basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) |
((className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >> ((*namespace_ret_p)[assign_a(retVal.namespaces2, namespaces_return)][clear_a(namespaces_return)]
>> (className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >>
!ch_p('*') [assign_a(retVal.isPtr2,true)]) | !ch_p('*') [assign_a(retVal.isPtr2,true)]) |
(eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]); (eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]);

View File

@ -5,6 +5,8 @@
* @author Alex Cunningham * @author Alex Cunningham
*/ */
#include <boost/foreach.hpp>
#include "ReturnValue.h" #include "ReturnValue.h"
#include "utilities.h" #include "utilities.h"
@ -15,21 +17,43 @@ using namespace wrap;
string ReturnValue::return_type(bool add_ptr, pairing p) { string ReturnValue::return_type(bool add_ptr, pairing p) {
if (p==pair && isPair) { if (p==pair && isPair) {
string str = "pair< " + string str = "pair< " +
wrap::maybe_shared_ptr(add_ptr && isPtr1, type1) + ", " + maybe_shared_ptr(add_ptr && isPtr1, qualifiedType1("::")) + ", " +
wrap::maybe_shared_ptr(add_ptr && isPtr2, type2) + " >"; maybe_shared_ptr(add_ptr && isPtr2, qualifiedType2("::")) + " >";
return str; return str;
} else } else
return wrap::maybe_shared_ptr(add_ptr && isPtr1, (p==arg2)? type2 : type1); return maybe_shared_ptr(add_ptr && isPtr1, (p==arg2)? qualifiedType2("::") : qualifiedType1("::"));
}
/* ************************************************************************* */
string ReturnValue::matlab_returnType() const {
return isPair? "[first,second]" : "result";
}
/* ************************************************************************* */
string ReturnValue::qualifiedType1(const string& delim) {
string result;
BOOST_FOREACH(const string& ns, namespaces1) result += ns + delim;
return result + type1;
}
/* ************************************************************************* */
string ReturnValue::qualifiedType2(const string& delim) {
string result;
BOOST_FOREACH(const string& ns, namespaces2) result += ns + delim;
return result + type2;
} }
/* ************************************************************************* */ /* ************************************************************************* */
void ReturnValue::wrap_result(std::ostream& ofs) { void ReturnValue::wrap_result(std::ostream& ofs) {
string cppType1 = qualifiedType1("::"), matlabType1 = qualifiedType1();
string cppType2 = qualifiedType2("::"), matlabType2 = qualifiedType2();
if (isPair) { if (isPair) {
// first return value in pair // first return value in pair
if (isPtr1) // if we already have a pointer if (isPtr1) // if we already have a pointer
ofs << " out[0] = wrap_shared_ptr(result.first,\"" << type1 << "\");\n"; ofs << " out[0] = wrap_shared_ptr(result.first,\"" << matlabType1 << "\");\n";
else if (category1 == ReturnValue::CLASS) // if we are going to make one 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"; ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result.first),\"" << matlabType1 << "\");\n";
else // if basis type else // if basis type
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n"; ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n";
@ -37,14 +61,14 @@ void ReturnValue::wrap_result(std::ostream& ofs) {
if (isPtr2) // if we already have a pointer if (isPtr2) // if we already have a pointer
ofs << " out[1] = wrap_shared_ptr(result.second,\"" << type2 << "\");\n"; ofs << " out[1] = wrap_shared_ptr(result.second,\"" << type2 << "\");\n";
else if (category2 == ReturnValue::CLASS) // if we are going to make one 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"; ofs << " out[1] = wrap_shared_ptr(make_shared< " << cppType2 << " >(result.second),\"" << matlabType2 << "\");\n";
else else
ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n"; ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n";
} }
else if (isPtr1) else if (isPtr1)
ofs << " out[0] = wrap_shared_ptr(result,\"" << type1 << "\");\n"; ofs << " out[0] = wrap_shared_ptr(result,\"" << type1 << "\");\n";
else if (category1 == ReturnValue::CLASS) else if (category1 == ReturnValue::CLASS)
ofs << " out[0] = wrap_shared_ptr(make_shared< " << type1 << " >(result),\"" << type1 << "\");\n"; ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result),\"" << matlabType1 << "\");\n";
else if (type1!="void") else if (type1!="void")
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n"; ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n";
} }

View File

@ -7,6 +7,7 @@
* @author Alex Cunningham * @author Alex Cunningham
*/ */
#include <vector>
#include <ostream> #include <ostream>
#pragma once #pragma once
@ -30,6 +31,7 @@ struct ReturnValue {
bool verbose; bool verbose;
std::string type1, type2; std::string type1, type2;
bool isPtr1, isPtr2, isPair; bool isPtr1, isPtr2, isPair;
std::vector<std::string> namespaces1, namespaces2;
return_category category1, category2; return_category category1, category2;
@ -39,7 +41,10 @@ struct ReturnValue {
std::string return_type(bool add_ptr, pairing p); std::string return_type(bool add_ptr, pairing p);
std::string matlab_returnType() const { return isPair? "[first,second]" : "result"; } std::string qualifiedType1(const std::string& delim = "");
std::string qualifiedType2(const std::string& delim = "");
std::string matlab_returnType() const;
void wrap_result(std::ostream& ofs); void wrap_result(std::ostream& ofs);

View File

@ -27,8 +27,10 @@ ns2ClassA_afunction.$(MEXENDING): ns2ClassA_afunction.cpp
$(MEX) $(mex_flags) @ns2ClassA/memberFunction.cpp -output @ns2ClassA/memberFunction $(MEX) $(mex_flags) @ns2ClassA/memberFunction.cpp -output @ns2ClassA/memberFunction
@ns2ClassA/nsArg.$(MEXENDING): @ns2ClassA/nsArg.cpp @ns2ClassA/nsArg.$(MEXENDING): @ns2ClassA/nsArg.cpp
$(MEX) $(mex_flags) @ns2ClassA/nsArg.cpp -output @ns2ClassA/nsArg $(MEX) $(mex_flags) @ns2ClassA/nsArg.cpp -output @ns2ClassA/nsArg
@ns2ClassA/nsReturn.$(MEXENDING): @ns2ClassA/nsReturn.cpp
$(MEX) $(mex_flags) @ns2ClassA/nsReturn.cpp -output @ns2ClassA/nsReturn
ns2ClassA: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING) @ns2ClassA/nsArg.$(MEXENDING) ns2ClassA: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING) @ns2ClassA/nsArg.$(MEXENDING) @ns2ClassA/nsReturn.$(MEXENDING)
# ns2ns3ClassB # ns2ns3ClassB
new_ns2ns3ClassB_.$(MEXENDING): new_ns2ns3ClassB_.cpp new_ns2ns3ClassB_.$(MEXENDING): new_ns2ns3ClassB_.cpp

View File

@ -27,6 +27,7 @@ mex -O5 ns2ClassA_afunction.cpp
cd @ns2ClassA cd @ns2ClassA
mex -O5 memberFunction.cpp mex -O5 memberFunction.cpp
mex -O5 nsArg.cpp mex -O5 nsArg.cpp
mex -O5 nsReturn.cpp
%% ns2ns3ClassB %% ns2ns3ClassB
cd(toolboxpath) cd(toolboxpath)

View File

@ -21,6 +21,7 @@ class ClassA {
static double afunction(); static double afunction();
double memberFunction(); double memberFunction();
int nsArg(const ns1::ClassB& arg); int nsArg(const ns1::ClassB& arg);
ns2::ns3::ClassB nsReturn(double q);
}; };
namespace ns3 { namespace ns3 {