Removing empty in favor of boost::optional

release/4.3a0
dellaert 2014-11-30 10:38:24 +01:00
parent 74361ce64a
commit 14ef786dfe
19 changed files with 105 additions and 93 deletions

View File

@ -29,11 +29,9 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <iterator> // std::ostream_iterator #include <iterator> // std::ostream_iterator
//#include <cstdint> // on Linux GCC: fails with error regarding needing C++0x std flags //#include <cstdint> // on Linux GCC: fails with error regarding needing C++0x std flags
//#include <cinttypes> // same failure as above //#include <cinttypes> // same failure as above
#include <stdint.h> // works on Linux GCC #include <stdint.h> // works on Linux GCC
using namespace std; using namespace std;
using namespace wrap; using namespace wrap;
@ -67,12 +65,11 @@ void Class::matlab_proxy(Str toolboxPath, Str wrapperName,
const string matlabQualName = qualifiedName("."); const string matlabQualName = qualifiedName(".");
const string matlabUniqueName = qualifiedName(); const string matlabUniqueName = qualifiedName();
const string cppName = qualifiedName("::"); const string cppName = qualifiedName("::");
const string matlabBaseName = qualifiedParent.qualifiedName(".");
const string cppBaseName = qualifiedParent.qualifiedName("::");
// emit class proxy code // emit class proxy code
// we want our class to inherit the handle class for memory purposes // we want our class to inherit the handle class for memory purposes
const string parent = qualifiedParent.empty() ? "handle" : matlabBaseName; const string parent =
parentClass ? "handle" : parentClass->qualifiedName(".");
comment_fragment(proxyFile); comment_fragment(proxyFile);
proxyFile.oss << "classdef " << name << " < " << parent << endl; proxyFile.oss << "classdef " << name << " < " << parent << endl;
proxyFile.oss << " properties\n"; proxyFile.oss << " properties\n";
@ -94,11 +91,14 @@ void Class::matlab_proxy(Str toolboxPath, Str wrapperName,
wrapperFile.oss << "\n"; wrapperFile.oss << "\n";
// Regular constructors // Regular constructors
boost::optional<string> cppBaseName;
if (parentClass)
cppBaseName = parentClass->qualifiedName("::");
for (size_t i = 0; i < constructor.nrOverloads(); i++) { for (size_t i = 0; i < constructor.nrOverloads(); i++) {
ArgumentList args = constructor.argumentList(i); ArgumentList args = constructor.argumentList(i);
const int id = (int) functionNames.size(); const int id = (int) functionNames.size();
constructor.proxy_fragment(proxyFile, wrapperName, !qualifiedParent.empty(), constructor.proxy_fragment(proxyFile, wrapperName, (bool) parentClass, id,
id, args); args);
const string wrapFunctionName = constructor.wrapper_fragment(wrapperFile, const string wrapFunctionName = constructor.wrapper_fragment(wrapperFile,
cppName, matlabUniqueName, cppBaseName, id, args); cppName, matlabUniqueName, cppBaseName, id, args);
wrapperFile.oss << "\n"; wrapperFile.oss << "\n";
@ -108,9 +108,9 @@ void Class::matlab_proxy(Str toolboxPath, Str wrapperName,
proxyFile.oss << " error('Arguments do not match any overload of " proxyFile.oss << " error('Arguments do not match any overload of "
<< matlabQualName << " constructor');\n"; << matlabQualName << " constructor');\n";
proxyFile.oss << " end\n"; proxyFile.oss << " end\n";
if (!qualifiedParent.empty()) if (parentClass)
proxyFile.oss << " obj = obj@" << matlabBaseName << "(uint64(" proxyFile.oss << " obj = obj@" << parentClass->qualifiedName(".")
<< ptr_constructor_key << "), base_ptr);\n"; << "(uint64(" << ptr_constructor_key << "), base_ptr);\n";
proxyFile.oss << " obj.ptr_" << matlabUniqueName << " = my_ptr;\n"; proxyFile.oss << " obj.ptr_" << matlabUniqueName << " = my_ptr;\n";
proxyFile.oss << " end\n\n"; proxyFile.oss << " end\n\n";
@ -170,7 +170,6 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile,
const string matlabUniqueName = qualifiedName(); const string matlabUniqueName = qualifiedName();
const string cppName = qualifiedName("::"); const string cppName = qualifiedName("::");
const string baseCppName = qualifiedParent.qualifiedName("::");
const int collectorInsertId = (int) functionNames.size(); const int collectorInsertId = (int) functionNames.size();
const string collectorInsertFunctionName = matlabUniqueName const string collectorInsertFunctionName = matlabUniqueName
@ -207,7 +206,7 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile,
} else { } else {
proxyFile.oss << " my_ptr = varargin{2};\n"; proxyFile.oss << " my_ptr = varargin{2};\n";
} }
if (qualifiedParent.empty()) // If this class has a base class, we'll get a base class pointer back if (!parentClass) // If this class has a base class, we'll get a base class pointer back
proxyFile.oss << " "; proxyFile.oss << " ";
else else
proxyFile.oss << " base_ptr = "; proxyFile.oss << " base_ptr = ";
@ -230,7 +229,8 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile,
// Add to collector // Add to collector
wrapperFile.oss << " collector_" << matlabUniqueName << ".insert(self);\n"; wrapperFile.oss << " collector_" << matlabUniqueName << ".insert(self);\n";
// If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy) // If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy)
if (!qualifiedParent.empty()) { if (parentClass) {
const string baseCppName = parentClass->qualifiedName("::");
wrapperFile.oss << "\n"; wrapperFile.oss << "\n";
wrapperFile.oss << " typedef boost::shared_ptr<" << baseCppName wrapperFile.oss << " typedef boost::shared_ptr<" << baseCppName
<< "> SharedBase;\n"; << "> SharedBase;\n";
@ -297,7 +297,7 @@ void Class::addMethod(bool verbose, bool is_const, Str methodName,
// Create method to expand // Create method to expand
// For all values of the template argument, create a new method // For all values of the template argument, create a new method
BOOST_FOREACH(const Qualified& instName, templateArgValues) { BOOST_FOREACH(const Qualified& instName, templateArgValues) {
const TemplateSubstitution ts(templateArgName, instName, this->name); const TemplateSubstitution ts(templateArgName, instName, *this);
// substitute template in arguments // substitute template in arguments
ArgumentList expandedArgs = argumentList.expandTemplate(ts); ArgumentList expandedArgs = argumentList.expandTemplate(ts);
// do the same for return type // do the same for return type
@ -353,10 +353,10 @@ void Class::verifyAll(vector<string>& validTypes, bool& hasSerialiable) const {
verifyReturnTypes<Method>(validTypes, methods_); verifyReturnTypes<Method>(validTypes, methods_);
// verify parents // verify parents
if (!qualifiedParent.empty() if (parentClass
&& find(validTypes.begin(), validTypes.end(), && find(validTypes.begin(), validTypes.end(),
qualifiedParent.qualifiedName("::")) == validTypes.end()) parentClass->qualifiedName("::")) == validTypes.end())
throw DependencyMissing(qualifiedParent.qualifiedName("::"), throw DependencyMissing(parentClass->qualifiedName("::"),
qualifiedName("::")); qualifiedName("::"));
} }
@ -364,12 +364,12 @@ void Class::verifyAll(vector<string>& validTypes, bool& hasSerialiable) const {
void Class::appendInheritedMethods(const Class& cls, void Class::appendInheritedMethods(const Class& cls,
const vector<Class>& classes) { const vector<Class>& classes) {
if (!cls.qualifiedParent.empty()) { if (cls.parentClass) {
// Find parent // Find parent
BOOST_FOREACH(const Class& parent, classes) { BOOST_FOREACH(const Class& parent, classes) {
// We found a parent class for our parent, TODO improve ! // We found a parent class for our parent, TODO improve !
if (parent.name == cls.qualifiedParent.name) { if (parent.name == cls.parentClass->name) {
methods_.insert(parent.methods_.begin(), parent.methods_.end()); methods_.insert(parent.methods_.begin(), parent.methods_.end());
appendInheritedMethods(parent, classes); appendInheritedMethods(parent, classes);
} }

View File

@ -27,6 +27,7 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/range/adaptor/map.hpp> #include <boost/range/adaptor/map.hpp>
#include <boost/optional.hpp>
#include <string> #include <string>
#include <map> #include <map>
@ -53,7 +54,7 @@ public:
bool isVirtual; ///< Whether the class is part of a virtual inheritance chain bool isVirtual; ///< Whether the class is part of a virtual inheritance chain
bool isSerializable; ///< Whether we can use boost.serialization to serialize the class - creates exports bool isSerializable; ///< Whether we can use boost.serialization to serialize the class - creates exports
bool hasSerialization; ///< Whether we should create the serialization functions bool hasSerialization; ///< Whether we should create the serialization functions
Qualified qualifiedParent; ///< The *single* parent boost::optional<Qualified> parentClass; ///< The *single* parent
Constructor constructor; ///< Class constructors Constructor constructor; ///< Class constructors
Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object
bool verbose_; ///< verbose flag bool verbose_; ///< verbose flag

View File

@ -69,7 +69,7 @@ void Constructor::proxy_fragment(FileWriter& file,
/* ************************************************************************* */ /* ************************************************************************* */
string Constructor::wrapper_fragment(FileWriter& file, Str cppClassName, string Constructor::wrapper_fragment(FileWriter& file, Str cppClassName,
Str matlabUniqueName, Str cppBaseClassName, int id, Str matlabUniqueName, boost::optional<string> cppBaseClassName, int id,
const ArgumentList& al) const { const ArgumentList& al) const {
const string wrapFunctionName = matlabUniqueName + "_constructor_" const string wrapFunctionName = matlabUniqueName + "_constructor_"
@ -100,9 +100,9 @@ string Constructor::wrapper_fragment(FileWriter& file, Str cppClassName,
<< endl; << endl;
// If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy) // If we have a base class, return the base class pointer (MATLAB will call the base class collectorInsertAndMakeBase to add this to the collector and recurse the heirarchy)
if (!cppBaseClassName.empty()) { if (cppBaseClassName) {
file.oss << "\n"; file.oss << "\n";
file.oss << " typedef boost::shared_ptr<" << cppBaseClassName file.oss << " typedef boost::shared_ptr<" << *cppBaseClassName
<< "> SharedBase;\n"; << "> SharedBase;\n";
file.oss file.oss
<< " out[1] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);\n"; << " out[1] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);\n";

View File

@ -19,7 +19,7 @@
#pragma once #pragma once
#include "OverloadedFunction.h" #include "OverloadedFunction.h"
#include <boost/optional.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -68,7 +68,7 @@ struct Constructor: public OverloadedFunction {
/// cpp wrapper /// cpp wrapper
std::string wrapper_fragment(FileWriter& file, Str cppClassName, std::string wrapper_fragment(FileWriter& file, Str cppClassName,
Str matlabUniqueName, Str cppBaseClassName, int id, Str matlabUniqueName, boost::optional<std::string> cppBaseClassName, int id,
const ArgumentList& al) const; const ArgumentList& al) const;
/// constructor function /// constructor function

View File

@ -29,8 +29,8 @@ using namespace std;
using namespace wrap; using namespace wrap;
/* ************************************************************************* */ /* ************************************************************************* */
bool Function::initializeOrCheck(const string& name, const Qualified& instName, bool Function::initializeOrCheck(const string& name,
bool verbose) { boost::optional<const Qualified> instName, bool verbose) {
if (name.empty()) if (name.empty())
throw runtime_error("Function::initializeOrCheck called with empty name"); throw runtime_error("Function::initializeOrCheck called with empty name");
@ -44,10 +44,7 @@ bool Function::initializeOrCheck(const string& name, const Qualified& instName,
} else { } else {
if (name_ != name || templateArgValue_ != instName || verbose_ != verbose) if (name_ != name || templateArgValue_ != instName || verbose_ != verbose)
throw runtime_error( throw runtime_error(
"Function::initializeOrCheck called with different arguments: with name " "Function::initializeOrCheck called with different arguments");
+ name + " instead of expected " + name_
+ ", or with template argument " + instName.qualifiedName(":")
+ " instead of expected " + templateArgValue_.qualifiedName(":"));
return false; return false;
} }

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "Argument.h" #include "Argument.h"
#include <boost/optional.hpp>
namespace wrap { namespace wrap {
@ -28,7 +29,7 @@ class Function {
protected: protected:
std::string name_; ///< name of method std::string name_; ///< name of method
Qualified templateArgValue_; ///< value of template argument if applicable boost::optional<Qualified> templateArgValue_; ///< value of template argument if applicable
bool verbose_; bool verbose_;
public: public:
@ -37,8 +38,8 @@ public:
* @brief first time, fill in instance variables, otherwise check if same * @brief first time, fill in instance variables, otherwise check if same
* @return true if first time, false thereafter * @return true if first time, false thereafter
*/ */
bool initializeOrCheck(const std::string& name, const Qualified& instName = bool initializeOrCheck(const std::string& name, boost::optional<const Qualified> instName =
Qualified(), bool verbose = false); boost::none, bool verbose = false);
std::string name() const { std::string name() const {
return name_; return name_;
@ -50,10 +51,10 @@ public:
} }
std::string matlabName() const { std::string matlabName() const {
if (templateArgValue_.empty()) if (templateArgValue_)
return name_; return name_;
else else
return name_ + templateArgValue_.name; return name_ + templateArgValue_->name;
} }
/// Emit function call to MATLAB (no argument checking) /// Emit function call to MATLAB (no argument checking)

View File

@ -52,8 +52,7 @@ void Method::proxy_header(FileWriter& proxyFile) const {
/* ************************************************************************* */ /* ************************************************************************* */
string Method::wrapper_call(FileWriter& wrapperFile, Str cppClassName, string Method::wrapper_call(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, const ArgumentList& args, Str matlabUniqueName, const ArgumentList& args) const {
const Qualified& instName) const {
// check arguments // check arguments
// extra argument obj -> nargin-1 is passed ! // extra argument obj -> nargin-1 is passed !
// example: checkArguments("equals",nargout,nargin-1,2); // example: checkArguments("equals",nargout,nargin-1,2);
@ -71,8 +70,8 @@ string Method::wrapper_call(FileWriter& wrapperFile, Str cppClassName,
// call method and wrap result // call method and wrap result
// example: out[0]=wrap<bool>(obj->return_field(t)); // example: out[0]=wrap<bool>(obj->return_field(t));
string expanded = "obj->" + name_; string expanded = "obj->" + name_;
if (!instName.empty()) if (templateArgValue_)
expanded += ("<" + instName.qualifiedName("::") + ">"); expanded += ("<" + templateArgValue_->qualifiedName("::") + ">");
return expanded; return expanded;
} }

View File

@ -55,8 +55,7 @@ private:
void proxy_header(FileWriter& proxyFile) const; void proxy_header(FileWriter& proxyFile) const;
virtual std::string wrapper_call(FileWriter& wrapperFile, Str cppClassName, virtual std::string wrapper_call(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, const ArgumentList& args, Str matlabUniqueName, const ArgumentList& args) const;
const Qualified& instName) const;
}; };
} // \namespace wrap } // \namespace wrap

View File

@ -59,7 +59,7 @@ void MethodBase::proxy_wrapper_fragments(FileWriter& proxyFile,
// Output C++ wrapper code // Output C++ wrapper code
const string wrapFunctionName = wrapper_fragment(wrapperFile, cppClassName, const string wrapFunctionName = wrapper_fragment(wrapperFile, cppClassName,
matlabUniqueName, 0, id, typeAttributes, templateArgValue_); matlabUniqueName, 0, id, typeAttributes);
// Add to function list // Add to function list
functionNames.push_back(wrapFunctionName); functionNames.push_back(wrapFunctionName);
@ -75,8 +75,7 @@ void MethodBase::proxy_wrapper_fragments(FileWriter& proxyFile,
// Output C++ wrapper code // Output C++ wrapper code
const string wrapFunctionName = wrapper_fragment(wrapperFile, const string wrapFunctionName = wrapper_fragment(wrapperFile,
cppClassName, matlabUniqueName, i, id, typeAttributes, cppClassName, matlabUniqueName, i, id, typeAttributes);
templateArgValue_);
// Add to function list // Add to function list
functionNames.push_back(wrapFunctionName); functionNames.push_back(wrapFunctionName);
@ -94,8 +93,7 @@ void MethodBase::proxy_wrapper_fragments(FileWriter& proxyFile,
/* ************************************************************************* */ /* ************************************************************************* */
string MethodBase::wrapper_fragment(FileWriter& wrapperFile, Str cppClassName, string MethodBase::wrapper_fragment(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, int overload, int id, Str matlabUniqueName, int overload, int id,
const TypeAttributesTable& typeAttributes, const TypeAttributesTable& typeAttributes) const {
const Qualified& instName) const {
// generate code // generate code
@ -120,7 +118,7 @@ string MethodBase::wrapper_fragment(FileWriter& wrapperFile, Str cppClassName,
// for static methods: cppClassName::staticMethod<TemplateVal> // for static methods: cppClassName::staticMethod<TemplateVal>
// for instance methods: obj->instanceMethod<TemplateVal> // for instance methods: obj->instanceMethod<TemplateVal>
string expanded = wrapper_call(wrapperFile, cppClassName, matlabUniqueName, string expanded = wrapper_call(wrapperFile, cppClassName, matlabUniqueName,
args, instName); args);
expanded += ("(" + args.names() + ")"); expanded += ("(" + args.names() + ")");
if (returnVal.type1.name != "void") if (returnVal.type1.name != "void")

View File

@ -57,12 +57,10 @@ protected:
std::string wrapper_fragment(FileWriter& wrapperFile, Str cppClassName, std::string wrapper_fragment(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, int overload, int id, Str matlabUniqueName, int overload, int id,
const TypeAttributesTable& typeAttributes, const Qualified& instName = const TypeAttributesTable& typeAttributes) const; ///< cpp wrapper
Qualified()) const; ///< cpp wrapper
virtual std::string wrapper_call(FileWriter& wrapperFile, Str cppClassName, virtual std::string wrapper_call(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, const ArgumentList& args, Str matlabUniqueName, const ArgumentList& args) const = 0;
const Qualified& instName) const = 0;
}; };
} // \namespace wrap } // \namespace wrap

View File

@ -26,26 +26,53 @@ namespace wrap {
/** /**
* Class to encapuslate a qualified name, i.e., with (nested) namespaces * Class to encapuslate a qualified name, i.e., with (nested) namespaces
*/ */
struct Qualified { class Qualified {
public:
std::vector<std::string> namespaces; ///< Stack of namespaces std::vector<std::string> namespaces; ///< Stack of namespaces
std::string name; ///< type name std::string name; ///< type name
Qualified(const std::string& name_ = "") : /// the different supported return value categories
name(name_) { typedef enum {
CLASS = 1, EIGEN = 2, BASIS = 3, VOID = 4
} Category;
Category category_;
Qualified() :
category_(CLASS) {
} }
bool empty() const { Qualified(std::vector<std::string> ns, const std::string& name) :
return namespaces.empty() && name.empty(); namespaces(ns), name(name), category_(CLASS) {
} }
void clear() { Qualified(const std::string& n, Category category) :
namespaces.clear(); name(n), category_(category) {
name.clear(); }
public:
static Qualified MakeClass(std::vector<std::string> namespaces,
const std::string& name) {
return Qualified(namespaces, name);
}
static Qualified MakeEigen(const std::string& name) {
return Qualified(name, EIGEN);
}
static Qualified MakeBasis(const std::string& name) {
return Qualified(name, BASIS);
}
static Qualified MakeVoid() {
return Qualified("void", VOID);
} }
bool operator!=(const Qualified& other) const { bool operator!=(const Qualified& other) const {
return other.name != name || other.namespaces != namespaces; return other.name != name || other.namespaces != namespaces
|| other.category_ != category_;
} }
/// Return a qualified string using given delimiter /// Return a qualified string using given delimiter

View File

@ -23,7 +23,7 @@ void ReturnType::wrap_result(const string& out, const string& result,
string cppType = qualifiedName("::"), matlabType = qualifiedName("."); string cppType = qualifiedName("::"), matlabType = qualifiedName(".");
if (category == CLASS) { if (category_ == CLASS) {
string objCopy, ptrType; string objCopy, ptrType;
ptrType = "Shared" + name; ptrType = "Shared" + name;
const bool isVirtual = typeAttributes.attributes(cppType).isVirtual; const bool isVirtual = typeAttributes.attributes(cppType).isVirtual;
@ -52,7 +52,7 @@ void ReturnType::wrap_result(const string& out, const string& result,
/* ************************************************************************* */ /* ************************************************************************* */
void ReturnType::wrapTypeUnwrap(FileWriter& wrapperFile) const { void ReturnType::wrapTypeUnwrap(FileWriter& wrapperFile) const {
if (category == CLASS) if (category_ == CLASS)
wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedName("::") wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedName("::")
<< "> Shared" << name << ";" << endl; << "> Shared" << name << ";" << endl;
} }

View File

@ -17,22 +17,16 @@ namespace wrap {
/** /**
* Encapsulates return value of a method or function * Encapsulates return value of a method or function
*/ */
struct ReturnType: Qualified { struct ReturnType: public Qualified {
/// the different supported return value categories
typedef enum {
CLASS = 1, EIGEN = 2, BASIS = 3, VOID = 4
} return_category;
bool isPtr; bool isPtr;
return_category category;
ReturnType() : ReturnType() :
isPtr(false), category(CLASS) { isPtr(false) {
} }
ReturnType(const std::string& name) : ReturnType(const std::string& name) :
isPtr(false), category(CLASS) { isPtr(false) {
Qualified::name = name; Qualified::name = name;
} }

View File

@ -64,7 +64,7 @@ void ReturnValue::emit_matlab(FileWriter& proxyFile) const {
string output; string output;
if (isPair) if (isPair)
proxyFile.oss << "[ varargout{1} varargout{2} ] = "; proxyFile.oss << "[ varargout{1} varargout{2} ] = ";
else if (type1.category != ReturnType::VOID) else if (type1.category_ != ReturnType::VOID)
proxyFile.oss << "varargout{1} = "; proxyFile.oss << "varargout{1} = ";
} }

View File

@ -50,7 +50,7 @@ struct ReturnValue {
void emit_matlab(FileWriter& proxyFile) const; void emit_matlab(FileWriter& proxyFile) const;
friend std::ostream& operator<<(std::ostream& os, const ReturnValue& r) { friend std::ostream& operator<<(std::ostream& os, const ReturnValue& r) {
if (!r.isPair && r.type1.category == ReturnType::VOID) if (!r.isPair && r.type1.category_ == ReturnType::VOID)
os << "void"; os << "void";
else else
os << r.return_type(true); os << r.return_type(true);

View File

@ -38,8 +38,7 @@ void StaticMethod::proxy_header(FileWriter& proxyFile) const {
/* ************************************************************************* */ /* ************************************************************************* */
string StaticMethod::wrapper_call(FileWriter& wrapperFile, Str cppClassName, string StaticMethod::wrapper_call(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, const ArgumentList& args, Str matlabUniqueName, const ArgumentList& args) const {
const Qualified& instName) const {
// check arguments // check arguments
// NOTE: for static functions, there is no object passed // NOTE: for static functions, there is no object passed
wrapperFile.oss << " checkArguments(\"" << matlabUniqueName << "." << name_ wrapperFile.oss << " checkArguments(\"" << matlabUniqueName << "." << name_
@ -51,8 +50,8 @@ string StaticMethod::wrapper_call(FileWriter& wrapperFile, Str cppClassName,
// call method and wrap result // call method and wrap result
// example: out[0]=wrap<bool>(staticMethod(t)); // example: out[0]=wrap<bool>(staticMethod(t));
string expanded = cppClassName + "::" + name_; string expanded = cppClassName + "::" + name_;
if (!instName.empty()) if (templateArgValue_)
expanded += ("<" + instName.qualifiedName("::") + ">"); expanded += ("<" + templateArgValue_->qualifiedName("::") + ">");
return expanded; return expanded;
} }

View File

@ -39,8 +39,7 @@ protected:
virtual void proxy_header(FileWriter& proxyFile) const; virtual void proxy_header(FileWriter& proxyFile) const;
virtual std::string wrapper_call(FileWriter& wrapperFile, Str cppClassName, virtual std::string wrapper_call(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName, const ArgumentList& args, Str matlabUniqueName, const ArgumentList& args) const;
const Qualified& instName) const;
}; };
} // \namespace wrap } // \namespace wrap

View File

@ -65,14 +65,14 @@ void TypeAttributesTable::addForwardDeclarations(
void TypeAttributesTable::checkValidity(const vector<Class>& classes) const { void TypeAttributesTable::checkValidity(const vector<Class>& classes) const {
BOOST_FOREACH(const Class& cls, classes) { BOOST_FOREACH(const Class& cls, classes) {
// Check that class is virtual if it has a parent // Check that class is virtual if it has a parent
if (!cls.qualifiedParent.empty() && !cls.isVirtual) if (cls.parentClass && !cls.isVirtual)
throw AttributeError(cls.qualifiedName("::"), throw AttributeError(cls.qualifiedName("::"),
"Has a base class so needs to be declared virtual, change to 'virtual class " "Has a base class so needs to be declared virtual, change to 'virtual class "
+ cls.name + " ...'"); + cls.name + " ...'");
// Check that parent is virtual as well // Check that parent is virtual as well
Qualified parent = cls.qualifiedParent; if (cls.parentClass
if (!parent.empty() && !table_.at(parent.qualifiedName("::")).isVirtual) && !table_.at(cls.parentClass->qualifiedName("::")).isVirtual)
throw AttributeError(parent.qualifiedName("::"), throw AttributeError(cls.parentClass->qualifiedName("::"),
"Is the base class of " + cls.qualifiedName("::") "Is the base class of " + cls.qualifiedName("::")
+ ", so needs to be declared virtual"); + ", so needs to be declared virtual");
} }

View File

@ -104,7 +104,7 @@ TEST( wrap, Small ) {
EXPECT(!rv1.isPair); EXPECT(!rv1.isPair);
EXPECT(!rv1.type1.isPtr); EXPECT(!rv1.type1.isPtr);
EXPECT(assert_equal("double", rv1.type1.name)); EXPECT(assert_equal("double", rv1.type1.name));
EXPECT_LONGS_EQUAL(ReturnType::BASIS, rv1.type1.category); EXPECT_LONGS_EQUAL(ReturnType::BASIS, rv1.type1.category_);
// Method 2 // Method 2
Method m2 = cls.method("returnMatrix"); Method m2 = cls.method("returnMatrix");
@ -116,7 +116,7 @@ TEST( wrap, Small ) {
EXPECT(!rv2.isPair); EXPECT(!rv2.isPair);
EXPECT(!rv2.type1.isPtr); EXPECT(!rv2.type1.isPtr);
EXPECT(assert_equal("Matrix", rv2.type1.name)); EXPECT(assert_equal("Matrix", rv2.type1.name));
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv2.type1.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv2.type1.category_);
// Method 3 // Method 3
Method m3 = cls.method("returnPoint2"); Method m3 = cls.method("returnPoint2");
@ -128,7 +128,7 @@ TEST( wrap, Small ) {
EXPECT(!rv3.isPair); EXPECT(!rv3.isPair);
EXPECT(!rv3.type1.isPtr); EXPECT(!rv3.type1.isPtr);
EXPECT(assert_equal("Point2", rv3.type1.name)); EXPECT(assert_equal("Point2", rv3.type1.name));
EXPECT_LONGS_EQUAL(ReturnType::CLASS, rv3.type1.category); EXPECT_LONGS_EQUAL(ReturnType::CLASS, rv3.type1.category_);
// Static Method 1 // Static Method 1
// static Vector returnVector(); // static Vector returnVector();
@ -140,7 +140,7 @@ TEST( wrap, Small ) {
EXPECT(!rv4.isPair); EXPECT(!rv4.isPair);
EXPECT(!rv4.type1.isPtr); EXPECT(!rv4.type1.isPtr);
EXPECT(assert_equal("Vector", rv4.type1.name)); EXPECT(assert_equal("Vector", rv4.type1.name));
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv4.type1.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, rv4.type1.category_);
} }
@ -192,7 +192,7 @@ TEST( wrap, Geometry ) {
Method m1 = cls.method("returnChar"); Method m1 = cls.method("returnChar");
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT(assert_equal("char", m1.returnValue(0).type1.name)); EXPECT(assert_equal("char", m1.returnValue(0).type1.name));
EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category_);
EXPECT(!m1.returnValue(0).isPair); EXPECT(!m1.returnValue(0).isPair);
EXPECT(assert_equal("returnChar", m1.name())); EXPECT(assert_equal("returnChar", m1.name()));
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
@ -206,7 +206,7 @@ TEST( wrap, Geometry ) {
Method m1 = cls.method("vectorConfusion"); Method m1 = cls.method("vectorConfusion");
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT(assert_equal("VectorNotEigen", m1.returnValue(0).type1.name)); EXPECT(assert_equal("VectorNotEigen", m1.returnValue(0).type1.name));
EXPECT_LONGS_EQUAL(ReturnType::CLASS, m1.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::CLASS, m1.returnValue(0).type1.category_);
EXPECT(!m1.returnValue(0).isPair); EXPECT(!m1.returnValue(0).isPair);
EXPECT(assert_equal("vectorConfusion", m1.name())); EXPECT(assert_equal("vectorConfusion", m1.name()));
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
@ -249,7 +249,7 @@ TEST( wrap, Geometry ) {
Method m1 = cls.method("norm"); Method m1 = cls.method("norm");
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT(assert_equal("double", m1.returnValue(0).type1.name)); EXPECT(assert_equal("double", m1.returnValue(0).type1.name));
EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::BASIS, m1.returnValue(0).type1.category_);
EXPECT(assert_equal("norm", m1.name())); EXPECT(assert_equal("norm", m1.name()));
LONGS_EQUAL(1, m1.nrOverloads()); LONGS_EQUAL(1, m1.nrOverloads());
EXPECT_LONGS_EQUAL(0, m1.argumentList(0).size()); EXPECT_LONGS_EQUAL(0, m1.argumentList(0).size());
@ -275,9 +275,9 @@ TEST( wrap, Geometry ) {
Method m2 = testCls.method("return_pair"); Method m2 = testCls.method("return_pair");
LONGS_EQUAL(1, m2.nrOverloads()); LONGS_EQUAL(1, m2.nrOverloads());
EXPECT(m2.returnValue(0).isPair); EXPECT(m2.returnValue(0).isPair);
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type1.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type1.category_);
EXPECT(assert_equal("Vector", m2.returnValue(0).type1.name)); EXPECT(assert_equal("Vector", m2.returnValue(0).type1.name));
EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type2.category); EXPECT_LONGS_EQUAL(ReturnType::EIGEN, m2.returnValue(0).type2.category_);
EXPECT(assert_equal("Matrix", m2.returnValue(0).type2.name)); EXPECT(assert_equal("Matrix", m2.returnValue(0).type2.name));
// checking pointer args and return values // checking pointer args and return values