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
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_clear_actor.hpp>
#include <boost/foreach.hpp>
#include <iostream>
@ -52,7 +53,7 @@ Module::Module(const string& interfacePath,
Method method0(enable_verbose), method(enable_verbose);
StaticMethod static_method0(enable_verbose), static_method(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
@ -69,12 +70,15 @@ Module::Module(const string& interfacePath,
Rule basisType_p =
(str_p("string") | "bool" | "size_t" | "int" | "double");
Rule keywords_p =
(str_p("const") | "static" | "namespace" | basisType_p);
Rule eigenType_p =
(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("::");
@ -116,15 +120,19 @@ Module::Module(const string& interfacePath,
[push_back_a(cls.constructors, constructor)]
[assign_a(constructor,constructor0)];
Rule namespace_ret_p = namespace_name_p[push_back_a(namespaces_return)] >> str_p("::");
Rule returnType1_p =
(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)]) |
(eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]);
Rule returnType2_p =
(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)]) |
(eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]);

View File

@ -5,6 +5,8 @@
* @author Alex Cunningham
*/
#include <boost/foreach.hpp>
#include "ReturnValue.h"
#include "utilities.h"
@ -15,21 +17,43 @@ using namespace wrap;
string ReturnValue::return_type(bool add_ptr, pairing p) {
if (p==pair && isPair) {
string str = "pair< " +
wrap::maybe_shared_ptr(add_ptr && isPtr1, type1) + ", " +
wrap::maybe_shared_ptr(add_ptr && isPtr2, type2) + " >";
maybe_shared_ptr(add_ptr && isPtr1, qualifiedType1("::")) + ", " +
maybe_shared_ptr(add_ptr && isPtr2, qualifiedType2("::")) + " >";
return str;
} 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) {
string cppType1 = qualifiedType1("::"), matlabType1 = qualifiedType1();
string cppType2 = qualifiedType2("::"), matlabType2 = qualifiedType2();
if (isPair) {
// first return value in pair
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
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
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
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";
ofs << " out[1] = wrap_shared_ptr(make_shared< " << cppType2 << " >(result.second),\"" << matlabType2 << "\");\n";
else
ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n";
}
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";
ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result),\"" << matlabType1 << "\");\n";
else if (type1!="void")
ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n";
}

View File

@ -7,6 +7,7 @@
* @author Alex Cunningham
*/
#include <vector>
#include <ostream>
#pragma once
@ -30,6 +31,7 @@ struct ReturnValue {
bool verbose;
std::string type1, type2;
bool isPtr1, isPtr2, isPair;
std::vector<std::string> namespaces1, namespaces2;
return_category category1, category2;
@ -39,7 +41,10 @@ struct ReturnValue {
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);

View File

@ -27,8 +27,10 @@ ns2ClassA_afunction.$(MEXENDING): ns2ClassA_afunction.cpp
$(MEX) $(mex_flags) @ns2ClassA/memberFunction.cpp -output @ns2ClassA/memberFunction
@ns2ClassA/nsArg.$(MEXENDING): @ns2ClassA/nsArg.cpp
$(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
new_ns2ns3ClassB_.$(MEXENDING): new_ns2ns3ClassB_.cpp

View File

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

View File

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