Simplified method/function hierarchy drastically, and renamed bottom addOverload to initializeOrCheck to reflect what it does. Also, gratuitous re-ordering of addOverload arguments.
parent
d4b868aa12
commit
7a4748d3dc
|
@ -122,13 +122,5 @@ struct ArgumentList: public std::vector<Argument> {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline void verifyArguments(const std::vector<std::string>& validArgs,
|
|
||||||
const std::map<std::string, T>& vt) {
|
|
||||||
typedef typename std::map<std::string, T>::value_type NamedMethod;
|
|
||||||
BOOST_FOREACH(const NamedMethod& namedMethod, vt)
|
|
||||||
namedMethod.second.verifyArguments(validArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // \namespace wrap
|
} // \namespace wrap
|
||||||
|
|
||||||
|
|
|
@ -286,13 +286,13 @@ void Class::addMethod(bool verbose, bool is_const, Str methodName,
|
||||||
// Now stick in new overload stack with expandedMethodName key
|
// Now stick in new overload stack with expandedMethodName key
|
||||||
// but note we use the same, unexpanded methodName in overload
|
// but note we use the same, unexpanded methodName in overload
|
||||||
string expandedMethodName = methodName + instName.name;
|
string expandedMethodName = methodName + instName.name;
|
||||||
methods[expandedMethodName].addOverload(verbose, is_const, methodName,
|
methods[expandedMethodName].addOverload(methodName, expandedArgs,
|
||||||
expandedArgs, expandedRetVal, instName);
|
expandedRetVal, is_const, instName, verbose);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
// just add overload
|
// just add overload
|
||||||
methods[methodName].addOverload(verbose, is_const, methodName, argumentList,
|
methods[methodName].addOverload(methodName, argumentList, returnValue,
|
||||||
returnValue);
|
is_const, Qualified(), verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Function.h"
|
#include "OverloadedFunction.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -26,21 +26,17 @@
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
// Constructor class
|
// Constructor class
|
||||||
struct Constructor: public ArgumentOverloads {
|
struct Constructor: public OverloadedFunction {
|
||||||
|
|
||||||
/// Constructor creates an empty class
|
/// Constructor creates an empty class
|
||||||
Constructor(bool verbose = false) :
|
Constructor(bool verbose = false) {
|
||||||
verbose_(verbose) {
|
verbose_ = verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then the instance variables are set directly by the Module constructor
|
|
||||||
std::string name;
|
|
||||||
bool verbose_;
|
|
||||||
|
|
||||||
Constructor expandTemplate(const TemplateSubstitution& ts) const {
|
Constructor expandTemplate(const TemplateSubstitution& ts) const {
|
||||||
Constructor inst = *this;
|
Constructor inst = *this;
|
||||||
inst.argLists_ = expandArgumentListsTemplate(ts);
|
inst.argLists_ = expandArgumentListsTemplate(ts);
|
||||||
inst.name = ts.expandedClassName();
|
inst.name_ = ts.expandedClassName();
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +52,7 @@ struct Constructor: public ArgumentOverloads {
|
||||||
proxyFile.oss << "%\n%-------Constructors-------\n";
|
proxyFile.oss << "%\n%-------Constructors-------\n";
|
||||||
for (size_t i = 0; i < nrOverloads(); i++) {
|
for (size_t i = 0; i < nrOverloads(); i++) {
|
||||||
proxyFile.oss << "%";
|
proxyFile.oss << "%";
|
||||||
argumentList(i).emit_prototype(proxyFile, name);
|
argumentList(i).emit_prototype(proxyFile, name_);
|
||||||
proxyFile.oss << "\n";
|
proxyFile.oss << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +76,7 @@ struct Constructor: public ArgumentOverloads {
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Constructor& m) {
|
friend std::ostream& operator<<(std::ostream& os, const Constructor& m) {
|
||||||
for (size_t i = 0; i < m.nrOverloads(); i++)
|
for (size_t i = 0; i < m.nrOverloads(); i++)
|
||||||
os << m.name << m.argLists_[i];
|
os << m.name_ << m.argLists_[i];
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||||
|
* Atlanta, Georgia 30332-0415
|
||||||
|
* All Rights Reserved
|
||||||
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||||
|
|
||||||
|
* See LICENSE for the license information
|
||||||
|
|
||||||
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file FullyOverloadedFunction.h
|
||||||
|
* @brief Function that can be fully overloaded: arguments and return values
|
||||||
|
* @author Frank Dellaert
|
||||||
|
* @date Nov 13, 2014
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "OverloadedFunction.h"
|
||||||
|
|
||||||
|
namespace wrap {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature Overload (including return value)
|
||||||
|
*/
|
||||||
|
class SignatureOverloads: public ArgumentOverloads {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::vector<ReturnValue> returnVals_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const ReturnValue& returnValue(size_t i) const {
|
||||||
|
return returnVals_.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const ArgumentList& args, const ReturnValue& retVal) {
|
||||||
|
argLists_.push_back(args);
|
||||||
|
returnVals_.push_back(retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void verifyReturnTypes(const std::vector<std::string>& validtypes,
|
||||||
|
const std::string& s) const {
|
||||||
|
BOOST_FOREACH(const ReturnValue& retval, returnVals_) {
|
||||||
|
retval.type1.verify(validtypes, s);
|
||||||
|
if (retval.isPair)
|
||||||
|
retval.type2.verify(validtypes, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO use transform ?
|
||||||
|
std::vector<ReturnValue> expandReturnValuesTemplate(
|
||||||
|
const TemplateSubstitution& ts) const {
|
||||||
|
std::vector<ReturnValue> result;
|
||||||
|
BOOST_FOREACH(const ReturnValue& retVal, returnVals_) {
|
||||||
|
ReturnValue instRetVal = retVal.expandTemplate(ts);
|
||||||
|
result.push_back(instRetVal);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Expand templates, imperative !
|
||||||
|
void expandTemplate(const TemplateSubstitution& ts) {
|
||||||
|
// substitute template in arguments
|
||||||
|
argLists_ = expandArgumentListsTemplate(ts);
|
||||||
|
// do the same for return types
|
||||||
|
returnVals_ = expandReturnValuesTemplate(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit a list of comments, one for each overload
|
||||||
|
void usage_fragment(FileWriter& proxyFile, const std::string& name) const {
|
||||||
|
unsigned int argLCount = 0;
|
||||||
|
BOOST_FOREACH(ArgumentList argList, argLists_) {
|
||||||
|
argList.emit_prototype(proxyFile, name);
|
||||||
|
if (argLCount != nrOverloads() - 1)
|
||||||
|
proxyFile.oss << ", ";
|
||||||
|
else
|
||||||
|
proxyFile.oss << " : returns " << returnValue(0).return_type(false)
|
||||||
|
<< std::endl;
|
||||||
|
argLCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit a list of comments, one for each overload
|
||||||
|
void comment_fragment(FileWriter& proxyFile, const std::string& name) const {
|
||||||
|
size_t i = 0;
|
||||||
|
BOOST_FOREACH(ArgumentList argList, argLists_) {
|
||||||
|
proxyFile.oss << "%";
|
||||||
|
argList.emit_prototype(proxyFile, name);
|
||||||
|
proxyFile.oss << " : returns " << returnVals_[i++].return_type(false)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os,
|
||||||
|
const SignatureOverloads& overloads) {
|
||||||
|
for (size_t i = 0; i < overloads.nrOverloads(); i++)
|
||||||
|
os << overloads.returnVals_[i] << overloads.argLists_[i] << std::endl;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class FullyOverloadedFunction: public Function, public SignatureOverloads {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool addOverload(const std::string& name, const ArgumentList& args,
|
||||||
|
const ReturnValue& retVal, const Qualified& instName = Qualified(),
|
||||||
|
bool verbose = false) {
|
||||||
|
bool first = initializeOrCheck(name, instName, verbose);
|
||||||
|
SignatureOverloads::push_back(args, retVal);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Templated checking functions
|
||||||
|
// TODO: do this via polymorphism, use transform ?
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
inline void verifyReturnTypes(const std::vector<std::string>& validTypes,
|
||||||
|
const std::map<std::string, F>& vt) {
|
||||||
|
typedef typename std::map<std::string, F>::value_type NamedMethod;
|
||||||
|
BOOST_FOREACH(const NamedMethod& namedMethod, vt)
|
||||||
|
namedMethod.second.verifyReturnTypes(validTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // \namespace wrap
|
||||||
|
|
|
@ -29,38 +29,29 @@ using namespace std;
|
||||||
using namespace wrap;
|
using namespace wrap;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Function::addOverload(bool verbose, const std::string& name,
|
bool Function::initializeOrCheck(const std::string& name,
|
||||||
const Qualified& instName) {
|
const Qualified& instName, bool verbose) {
|
||||||
|
|
||||||
|
if (name.empty())
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Function::initializeOrCheck called with empty name");
|
||||||
|
|
||||||
// Check if this overload is give to the correct method
|
// Check if this overload is give to the correct method
|
||||||
if (name_.empty())
|
if (name_.empty()) {
|
||||||
name_ = name;
|
name_ = name;
|
||||||
else if (name_ != name)
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Function::addOverload: tried to add overload with name " + name
|
|
||||||
+ " instead of expected " + name_);
|
|
||||||
|
|
||||||
// Check if this overload is give to the correct method
|
|
||||||
if (templateArgValue_.empty())
|
|
||||||
templateArgValue_ = instName;
|
templateArgValue_ = instName;
|
||||||
else if (templateArgValue_ != instName)
|
verbose_ = verbose;
|
||||||
throw std::runtime_error(
|
return true;
|
||||||
"Function::addOverload: tried to add overload with template argument "
|
} else {
|
||||||
+ instName.qualifiedName(":") + " instead of expected "
|
if (name_ != name || templateArgValue_ != instName || verbose_ != verbose)
|
||||||
+ templateArgValue_.qualifiedName(":"));
|
throw std::runtime_error(
|
||||||
|
"Function::initializeOrCheck called with different arguments: with name "
|
||||||
|
+ name + " instead of expected " + name_
|
||||||
|
+ ", or with template argument " + instName.qualifiedName(":")
|
||||||
|
+ " instead of expected " + templateArgValue_.qualifiedName(":"));
|
||||||
|
|
||||||
verbose_ = verbose;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
vector<ArgumentList> ArgumentOverloads::expandArgumentListsTemplate(
|
|
||||||
const TemplateSubstitution& ts) const {
|
|
||||||
vector<ArgumentList> result;
|
|
||||||
BOOST_FOREACH(const ArgumentList& argList, argLists_) {
|
|
||||||
ArgumentList instArgList = argList.expandTemplate(ts);
|
|
||||||
result.push_back(instArgList);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
186
wrap/Function.h
186
wrap/Function.h
|
@ -19,11 +19,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Argument.h"
|
#include "Argument.h"
|
||||||
#include "ReturnValue.h"
|
|
||||||
#include "TypeAttributesTable.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
|
@ -32,20 +27,18 @@ class Function {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool verbose_;
|
|
||||||
std::string name_; ///< name of method
|
std::string name_; ///< name of method
|
||||||
Qualified templateArgValue_; ///< value of template argument if applicable
|
Qualified templateArgValue_; ///< value of template argument if applicable
|
||||||
|
bool verbose_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Constructor creates empty object
|
/**
|
||||||
Function(bool verbose = true) :
|
* @brief first time, fill in instance variables, otherwise check if same
|
||||||
verbose_(verbose) {
|
* @return true if first time, false thereafter
|
||||||
}
|
*/
|
||||||
|
bool initializeOrCheck(const std::string& name, const Qualified& instName =
|
||||||
Function(const std::string& name, bool verbose = true) :
|
Qualified(), bool verbose = false);
|
||||||
verbose_(verbose), name_(name) {
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const {
|
std::string name() const {
|
||||||
return name_;
|
return name_;
|
||||||
|
@ -57,172 +50,7 @@ public:
|
||||||
else
|
else
|
||||||
return name_ + templateArgValue_.name;
|
return name_ + templateArgValue_.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first time this function is called, it initializes the class members
|
|
||||||
// with those in rhs, but in subsequent calls it adds additional argument
|
|
||||||
// lists as function overloads.
|
|
||||||
void addOverload(bool verbose, const std::string& name,
|
|
||||||
const Qualified& instName = Qualified());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* ArgumentList Overloads
|
|
||||||
*/
|
|
||||||
class ArgumentOverloads {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector<ArgumentList> argLists_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
size_t nrOverloads() const {
|
|
||||||
return argLists_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
const ArgumentList& argumentList(size_t i) const {
|
|
||||||
return argLists_.at(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addOverload(const ArgumentList& args) {
|
|
||||||
argLists_.push_back(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ArgumentList> expandArgumentListsTemplate(
|
|
||||||
const TemplateSubstitution& ts) const;
|
|
||||||
|
|
||||||
/// Expand templates, imperative !
|
|
||||||
virtual void ExpandTemplate(const TemplateSubstitution& ts) {
|
|
||||||
argLists_ = expandArgumentListsTemplate(ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
void verifyArguments(const std::vector<std::string>& validArgs,
|
|
||||||
const std::string s) const {
|
|
||||||
BOOST_FOREACH(const ArgumentList& argList, argLists_) {
|
|
||||||
BOOST_FOREACH(Argument arg, argList) {
|
|
||||||
std::string fullType = arg.type.qualifiedName("::");
|
|
||||||
if (find(validArgs.begin(), validArgs.end(), fullType)
|
|
||||||
== validArgs.end())
|
|
||||||
throw DependencyMissing(fullType, "checking argument of " + s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os,
|
|
||||||
const ArgumentOverloads& overloads) {
|
|
||||||
BOOST_FOREACH(const ArgumentList& argList, overloads.argLists_)
|
|
||||||
os << argList << std::endl;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signature Overload (including return value)
|
|
||||||
*/
|
|
||||||
class SignatureOverloads: public ArgumentOverloads {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector<ReturnValue> returnVals_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
const ReturnValue& returnValue(size_t i) const {
|
|
||||||
return returnVals_.at(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addOverload(const ArgumentList& args, const ReturnValue& retVal) {
|
|
||||||
argLists_.push_back(args);
|
|
||||||
returnVals_.push_back(retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void verifyReturnTypes(const std::vector<std::string>& validtypes,
|
|
||||||
const std::string& s) const {
|
|
||||||
BOOST_FOREACH(const ReturnValue& retval, returnVals_) {
|
|
||||||
retval.type1.verify(validtypes, s);
|
|
||||||
if (retval.isPair)
|
|
||||||
retval.type2.verify(validtypes, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO use transform ?
|
|
||||||
std::vector<ReturnValue> expandReturnValuesTemplate(
|
|
||||||
const TemplateSubstitution& ts) const {
|
|
||||||
std::vector<ReturnValue> result;
|
|
||||||
BOOST_FOREACH(const ReturnValue& retVal, returnVals_) {
|
|
||||||
ReturnValue instRetVal = retVal.expandTemplate(ts);
|
|
||||||
result.push_back(instRetVal);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Expand templates, imperative !
|
|
||||||
void expandTemplate(const TemplateSubstitution& ts) {
|
|
||||||
// substitute template in arguments
|
|
||||||
argLists_ = expandArgumentListsTemplate(ts);
|
|
||||||
// do the same for return types
|
|
||||||
returnVals_ = expandReturnValuesTemplate(ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// emit a list of comments, one for each overload
|
|
||||||
void usage_fragment(FileWriter& proxyFile, const std::string& name) const {
|
|
||||||
unsigned int argLCount = 0;
|
|
||||||
BOOST_FOREACH(ArgumentList argList, argLists_) {
|
|
||||||
argList.emit_prototype(proxyFile, name);
|
|
||||||
if (argLCount != nrOverloads() - 1)
|
|
||||||
proxyFile.oss << ", ";
|
|
||||||
else
|
|
||||||
proxyFile.oss << " : returns " << returnValue(0).return_type(false)
|
|
||||||
<< std::endl;
|
|
||||||
argLCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// emit a list of comments, one for each overload
|
|
||||||
void comment_fragment(FileWriter& proxyFile, const std::string& name) const {
|
|
||||||
size_t i = 0;
|
|
||||||
BOOST_FOREACH(ArgumentList argList, argLists_) {
|
|
||||||
proxyFile.oss << "%";
|
|
||||||
argList.emit_prototype(proxyFile, name);
|
|
||||||
proxyFile.oss << " : returns " << returnVals_[i++].return_type(false)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os,
|
|
||||||
const SignatureOverloads& overloads) {
|
|
||||||
for (size_t i = 0; i < overloads.nrOverloads(); i++)
|
|
||||||
os << overloads.returnVals_[i] << overloads.argLists_[i] << std::endl;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Templated checking functions
|
|
||||||
// TODO: do this via polymorphism ?
|
|
||||||
|
|
||||||
// TODO use transform
|
|
||||||
template<class F>
|
|
||||||
static std::map<std::string, F> expandMethodTemplate(
|
|
||||||
const std::map<std::string, F>& methods, const TemplateSubstitution& ts) {
|
|
||||||
std::map<std::string, F> result;
|
|
||||||
typedef std::pair<const std::string, F> NamedMethod;
|
|
||||||
BOOST_FOREACH(NamedMethod namedMethod, methods) {
|
|
||||||
F instMethod = namedMethod.second;
|
|
||||||
instMethod.expandTemplate(ts);
|
|
||||||
namedMethod.second = instMethod;
|
|
||||||
result.insert(namedMethod);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
template<class F>
|
|
||||||
inline void verifyReturnTypes(const std::vector<std::string>& validTypes,
|
|
||||||
const std::map<std::string, F>& vt) {
|
|
||||||
typedef typename std::map<std::string, F>::value_type NamedMethod;
|
|
||||||
BOOST_FOREACH(const NamedMethod& namedMethod, vt)
|
|
||||||
namedMethod.second.verifyReturnTypes(validTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // \namespace wrap
|
} // \namespace wrap
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,18 @@ namespace wrap {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void GlobalFunction::addOverload(bool verbose, const Qualified& overload,
|
void GlobalFunction::addOverload(const Qualified& overload,
|
||||||
const ArgumentList& args, const ReturnValue& retVal,
|
const ArgumentList& args, const ReturnValue& retVal,
|
||||||
const Qualified& instName) {
|
const Qualified& instName, bool verbose) {
|
||||||
Function::addOverload(verbose, overload.name, instName);
|
string name(overload.name);
|
||||||
SignatureOverloads::addOverload(args, retVal);
|
FullyOverloadedFunction::addOverload(name, args, retVal, instName, verbose);
|
||||||
overloads.push_back(overload);
|
overloads.push_back(overload);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void GlobalFunction::matlab_proxy(const std::string& toolboxPath,
|
void GlobalFunction::matlab_proxy(const string& toolboxPath,
|
||||||
const std::string& wrapperName, const TypeAttributesTable& typeAttributes,
|
const string& wrapperName, const TypeAttributesTable& typeAttributes,
|
||||||
FileWriter& file, std::vector<std::string>& functionNames) const {
|
FileWriter& file, vector<string>& functionNames) const {
|
||||||
|
|
||||||
// cluster overloads with same namespace
|
// cluster overloads with same namespace
|
||||||
// create new GlobalFunction structures around namespaces - same namespaces and names are overloads
|
// create new GlobalFunction structures around namespaces - same namespaces and names are overloads
|
||||||
|
@ -40,8 +40,7 @@ void GlobalFunction::matlab_proxy(const std::string& toolboxPath,
|
||||||
string str_ns = qualifiedName("", overload.namespaces);
|
string str_ns = qualifiedName("", overload.namespaces);
|
||||||
const ReturnValue& ret = returnValue(i);
|
const ReturnValue& ret = returnValue(i);
|
||||||
const ArgumentList& args = argumentList(i);
|
const ArgumentList& args = argumentList(i);
|
||||||
grouped_functions[str_ns].addOverload(verbose_, overload, args, ret,
|
grouped_functions[str_ns].addOverload(overload, args, ret);
|
||||||
templateArgValue_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t lastcheck = grouped_functions.size();
|
size_t lastcheck = grouped_functions.size();
|
||||||
|
@ -54,9 +53,9 @@ void GlobalFunction::matlab_proxy(const std::string& toolboxPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void GlobalFunction::generateSingleFunction(const std::string& toolboxPath,
|
void GlobalFunction::generateSingleFunction(const string& toolboxPath,
|
||||||
const std::string& wrapperName, const TypeAttributesTable& typeAttributes,
|
const string& wrapperName, const TypeAttributesTable& typeAttributes,
|
||||||
FileWriter& file, std::vector<std::string>& functionNames) const {
|
FileWriter& file, vector<string>& functionNames) const {
|
||||||
|
|
||||||
// create the folder for the namespace
|
// create the folder for the namespace
|
||||||
const Qualified& overload1 = overloads.front();
|
const Qualified& overload1 = overloads.front();
|
||||||
|
|
|
@ -9,23 +9,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Function.h"
|
#include "FullyOverloadedFunction.h"
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
struct GlobalFunction: public Function, public SignatureOverloads {
|
struct GlobalFunction: public FullyOverloadedFunction {
|
||||||
|
|
||||||
std::vector<Qualified> overloads; ///< Stack of qualified names
|
std::vector<Qualified> overloads; ///< Stack of qualified names
|
||||||
|
|
||||||
// Constructor only used in Module
|
// adds an overloaded version of this function,
|
||||||
GlobalFunction(bool verbose = true) :
|
void addOverload(const Qualified& overload, const ArgumentList& args,
|
||||||
Function(verbose) {
|
const ReturnValue& retVal, const Qualified& instName = Qualified(),
|
||||||
}
|
bool verbose = false);
|
||||||
|
|
||||||
// Used to reconstruct
|
|
||||||
GlobalFunction(const std::string& name, bool verbose = true) :
|
|
||||||
Function(name,verbose) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void verifyArguments(const std::vector<std::string>& validArgs) const {
|
void verifyArguments(const std::vector<std::string>& validArgs) const {
|
||||||
SignatureOverloads::verifyArguments(validArgs, name_);
|
SignatureOverloads::verifyArguments(validArgs, name_);
|
||||||
|
@ -35,11 +30,6 @@ struct GlobalFunction: public Function, public SignatureOverloads {
|
||||||
SignatureOverloads::verifyReturnTypes(validtypes, name_);
|
SignatureOverloads::verifyReturnTypes(validtypes, name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds an overloaded version of this function,
|
|
||||||
void addOverload(bool verbose, const Qualified& overload,
|
|
||||||
const ArgumentList& args, const ReturnValue& retVal,
|
|
||||||
const Qualified& instName = Qualified());
|
|
||||||
|
|
||||||
// codegen function called from Module to build the cpp and matlab versions of the function
|
// codegen function called from Module to build the cpp and matlab versions of the function
|
||||||
void matlab_proxy(const std::string& toolboxPath,
|
void matlab_proxy(const std::string& toolboxPath,
|
||||||
const std::string& wrapperName, const TypeAttributesTable& typeAttributes,
|
const std::string& wrapperName, const TypeAttributesTable& typeAttributes,
|
||||||
|
|
|
@ -29,17 +29,25 @@ using namespace std;
|
||||||
using namespace wrap;
|
using namespace wrap;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Method::addOverload(bool verbose, bool is_const, Str name,
|
bool Method::addOverload(Str name, const ArgumentList& args,
|
||||||
const ArgumentList& args, const ReturnValue& retVal,
|
const ReturnValue& retVal, bool is_const, const Qualified& instName,
|
||||||
const Qualified& instName) {
|
bool verbose) {
|
||||||
|
bool first = StaticMethod::addOverload(name, args, retVal, instName, verbose);
|
||||||
StaticMethod::addOverload(verbose, name, args, retVal, instName);
|
if (first)
|
||||||
is_const_ = is_const;
|
is_const_ = is_const;
|
||||||
|
else if (is_const && !is_const_)
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Method::addOverload now designated as const whereas before it was not");
|
||||||
|
else if (!is_const && is_const_)
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Method::addOverload now designated as non-const whereas before it was");
|
||||||
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void Method::proxy_header(FileWriter& proxyFile) const {
|
void Method::proxy_header(FileWriter& proxyFile) const {
|
||||||
proxyFile.oss << " function varargout = " << matlabName() << "(this, varargin)\n";
|
proxyFile.oss << " function varargout = " << matlabName()
|
||||||
|
<< "(this, varargin)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
@ -31,14 +31,9 @@ public:
|
||||||
|
|
||||||
typedef const std::string& Str;
|
typedef const std::string& Str;
|
||||||
|
|
||||||
/// Constructor creates empty object
|
bool addOverload(Str name, const ArgumentList& args,
|
||||||
Method(bool verbose = true) :
|
const ReturnValue& retVal, bool is_const, const Qualified& instName =
|
||||||
StaticMethod(verbose), is_const_(false) {
|
Qualified(), bool verbose = false);
|
||||||
}
|
|
||||||
|
|
||||||
Method(const std::string& name, bool verbose = true) :
|
|
||||||
StaticMethod(name,verbose), is_const_(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isStatic() const {
|
virtual bool isStatic() const {
|
||||||
return false;
|
return false;
|
||||||
|
@ -48,13 +43,6 @@ public:
|
||||||
return is_const_;
|
return is_const_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first time this function is called, it initializes the class members
|
|
||||||
// with those in rhs, but in subsequent calls it adds additional argument
|
|
||||||
// lists as function overloads.
|
|
||||||
void addOverload(bool verbose, bool is_const, Str name,
|
|
||||||
const ArgumentList& args, const ReturnValue& retVal,
|
|
||||||
const Qualified& instName = Qualified());
|
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Method& m) {
|
friend std::ostream& operator<<(std::ostream& os, const Method& m) {
|
||||||
for (size_t i = 0; i < m.nrOverloads(); i++)
|
for (size_t i = 0; i < m.nrOverloads(); i++)
|
||||||
os << m.returnVals_[i] << " " << m.name_ << m.argLists_[i];
|
os << m.returnVals_[i] << " " << m.name_ << m.argLists_[i];
|
||||||
|
|
|
@ -217,7 +217,7 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
Constructor constructor0(verbose), constructor(verbose);
|
Constructor constructor0(verbose), constructor(verbose);
|
||||||
Rule constructor_p =
|
Rule constructor_p =
|
||||||
(className_p >> '(' >> argumentList_p >> ')' >> ';' >> !comments_p)
|
(className_p >> '(' >> argumentList_p >> ')' >> ';' >> !comments_p)
|
||||||
[bl::bind(&Constructor::addOverload, bl::var(constructor), bl::var(args))]
|
[bl::bind(&Constructor::push_back, bl::var(constructor), bl::var(args))]
|
||||||
[clear_a(args)];
|
[clear_a(args)];
|
||||||
|
|
||||||
vector<string> namespaces_return; /// namespace for current return type
|
vector<string> namespaces_return; /// namespace for current return type
|
||||||
|
@ -274,7 +274,7 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
'(' >> argumentList_p >> ')' >> ';' >> *comments_p)
|
||||||
[bl::bind(&StaticMethod::addOverload,
|
[bl::bind(&StaticMethod::addOverload,
|
||||||
bl::var(cls.static_methods)[bl::var(methodName)],
|
bl::var(cls.static_methods)[bl::var(methodName)],
|
||||||
verbose, bl::var(methodName), bl::var(args), bl::var(retVal), Qualified())]
|
bl::var(methodName), bl::var(args), bl::var(retVal), Qualified(),verbose)]
|
||||||
[assign_a(retVal,retVal0)]
|
[assign_a(retVal,retVal0)]
|
||||||
[clear_a(args)];
|
[clear_a(args)];
|
||||||
|
|
||||||
|
@ -295,7 +295,8 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
>> ((':' >> classParent_p >> '{') | '{')
|
>> ((':' >> classParent_p >> '{') | '{')
|
||||||
>> *(functions_p | comments_p)
|
>> *(functions_p | comments_p)
|
||||||
>> str_p("};"))
|
>> str_p("};"))
|
||||||
[assign_a(constructor.name, cls.name)]
|
[bl::bind(&Constructor::initializeOrCheck, bl::var(constructor),
|
||||||
|
bl::var(cls.name), Qualified(), verbose)]
|
||||||
[assign_a(cls.constructor, constructor)]
|
[assign_a(cls.constructor, constructor)]
|
||||||
[assign_a(cls.namespaces, namespaces)]
|
[assign_a(cls.namespaces, namespaces)]
|
||||||
[assign_a(cls.deconstructor.name,cls.name)]
|
[assign_a(cls.deconstructor.name,cls.name)]
|
||||||
|
@ -313,7 +314,7 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
[assign_a(globalFunction.namespaces,namespaces)]
|
[assign_a(globalFunction.namespaces,namespaces)]
|
||||||
[bl::bind(&GlobalFunction::addOverload,
|
[bl::bind(&GlobalFunction::addOverload,
|
||||||
bl::var(global_functions)[bl::var(globalFunction.name)],
|
bl::var(global_functions)[bl::var(globalFunction.name)],
|
||||||
verbose, bl::var(globalFunction), bl::var(args), bl::var(retVal), Qualified())]
|
bl::var(globalFunction), bl::var(args), bl::var(retVal), Qualified(),verbose)]
|
||||||
[assign_a(retVal,retVal0)]
|
[assign_a(retVal,retVal0)]
|
||||||
[clear_a(globalFunction)]
|
[clear_a(globalFunction)]
|
||||||
[clear_a(args)];
|
[clear_a(args)];
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||||
|
* Atlanta, Georgia 30332-0415
|
||||||
|
* All Rights Reserved
|
||||||
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||||
|
|
||||||
|
* See LICENSE for the license information
|
||||||
|
|
||||||
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file OverloadedFunction.h
|
||||||
|
* @brief Function that can overload its arguments only
|
||||||
|
* @author Frank Dellaert
|
||||||
|
* @date Nov 13, 2014
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Function.h"
|
||||||
|
#include "Argument.h"
|
||||||
|
|
||||||
|
namespace wrap {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArgumentList Overloads
|
||||||
|
*/
|
||||||
|
class ArgumentOverloads {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::vector<ArgumentList> argLists_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
size_t nrOverloads() const {
|
||||||
|
return argLists_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ArgumentList& argumentList(size_t i) const {
|
||||||
|
return argLists_.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const ArgumentList& args) {
|
||||||
|
argLists_.push_back(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ArgumentList> expandArgumentListsTemplate(
|
||||||
|
const TemplateSubstitution& ts) const {
|
||||||
|
std::vector<ArgumentList> result;
|
||||||
|
BOOST_FOREACH(const ArgumentList& argList, argLists_) {
|
||||||
|
ArgumentList instArgList = argList.expandTemplate(ts);
|
||||||
|
result.push_back(instArgList);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Expand templates, imperative !
|
||||||
|
virtual void ExpandTemplate(const TemplateSubstitution& ts) {
|
||||||
|
argLists_ = expandArgumentListsTemplate(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void verifyArguments(const std::vector<std::string>& validArgs,
|
||||||
|
const std::string s) const {
|
||||||
|
BOOST_FOREACH(const ArgumentList& argList, argLists_) {
|
||||||
|
BOOST_FOREACH(Argument arg, argList) {
|
||||||
|
std::string fullType = arg.type.qualifiedName("::");
|
||||||
|
if (find(validArgs.begin(), validArgs.end(), fullType)
|
||||||
|
== validArgs.end())
|
||||||
|
throw DependencyMissing(fullType, "checking argument of " + s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os,
|
||||||
|
const ArgumentOverloads& overloads) {
|
||||||
|
BOOST_FOREACH(const ArgumentList& argList, overloads.argLists_)
|
||||||
|
os << argList << std::endl;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class OverloadedFunction: public Function, public ArgumentOverloads {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool addOverload(const std::string& name, const ArgumentList& args,
|
||||||
|
const Qualified& instName = Qualified(), bool verbose = false) {
|
||||||
|
bool first = initializeOrCheck(name, instName, verbose);
|
||||||
|
ArgumentOverloads::push_back(args);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Templated checking functions
|
||||||
|
// TODO: do this via polymorphism, use transform ?
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
static std::map<std::string, F> expandMethodTemplate(
|
||||||
|
const std::map<std::string, F>& methods, const TemplateSubstitution& ts) {
|
||||||
|
std::map<std::string, F> result;
|
||||||
|
typedef std::pair<const std::string, F> NamedMethod;
|
||||||
|
BOOST_FOREACH(NamedMethod namedMethod, methods) {
|
||||||
|
F instMethod = namedMethod.second;
|
||||||
|
instMethod.expandTemplate(ts);
|
||||||
|
namedMethod.second = instMethod;
|
||||||
|
result.insert(namedMethod);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
inline void verifyArguments(const std::vector<std::string>& validArgs,
|
||||||
|
const std::map<std::string, F>& vt) {
|
||||||
|
typedef typename std::map<std::string, F>::value_type NamedMethod;
|
||||||
|
BOOST_FOREACH(const NamedMethod& namedMethod, vt)
|
||||||
|
namedMethod.second.verifyArguments(validArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // \namespace wrap
|
||||||
|
|
|
@ -29,14 +29,6 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace wrap;
|
using namespace wrap;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
void StaticMethod::addOverload(bool verbose, Str name, const ArgumentList& args,
|
|
||||||
const ReturnValue& retVal, const Qualified& instName) {
|
|
||||||
|
|
||||||
Function::addOverload(verbose, name, instName);
|
|
||||||
SignatureOverloads::addOverload(args, retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void StaticMethod::proxy_header(FileWriter& proxyFile) const {
|
void StaticMethod::proxy_header(FileWriter& proxyFile) const {
|
||||||
string upperName = matlabName();
|
string upperName = matlabName();
|
||||||
|
|
|
@ -19,31 +19,19 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Function.h"
|
#include "FullyOverloadedFunction.h"
|
||||||
|
|
||||||
namespace wrap {
|
namespace wrap {
|
||||||
|
|
||||||
/// StaticMethod class
|
/// StaticMethod class
|
||||||
struct StaticMethod: public Function, public SignatureOverloads {
|
struct StaticMethod: public FullyOverloadedFunction {
|
||||||
|
|
||||||
typedef const std::string& Str;
|
typedef const std::string& Str;
|
||||||
|
|
||||||
/// Constructor creates empty object
|
|
||||||
StaticMethod(bool verbosity = true) :
|
|
||||||
Function(verbosity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticMethod(const std::string& name, bool verbose = true) :
|
|
||||||
Function(name,verbose) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isStatic() const {
|
virtual bool isStatic() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addOverload(bool verbose, Str name, const ArgumentList& args,
|
|
||||||
const ReturnValue& retVal, const Qualified& instName);
|
|
||||||
|
|
||||||
// emit a list of comments, one for each overload
|
// emit a list of comments, one for each overload
|
||||||
void comment_fragment(FileWriter& proxyFile) const {
|
void comment_fragment(FileWriter& proxyFile) const {
|
||||||
SignatureOverloads::comment_fragment(proxyFile, matlabName());
|
SignatureOverloads::comment_fragment(proxyFile, matlabName());
|
||||||
|
|
|
@ -32,12 +32,13 @@ TEST( Method, Constructor ) {
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// addOverload
|
// addOverload
|
||||||
TEST( Method, addOverload ) {
|
TEST( Method, addOverload ) {
|
||||||
Method method("myName");
|
Method method;
|
||||||
bool verbose = true, is_const = true;
|
method.initializeOrCheck("myName");
|
||||||
|
bool is_const = true;
|
||||||
ArgumentList args;
|
ArgumentList args;
|
||||||
const ReturnValue retVal(ReturnType("return_type"));
|
const ReturnValue retVal(ReturnType("return_type"));
|
||||||
method.addOverload(verbose, is_const, "myName", args, retVal);
|
method.addOverload("myName", args, retVal, is_const);
|
||||||
EXPECT_LONGS_EQUAL(1,method.nrOverloads());
|
EXPECT_LONGS_EQUAL(1, method.nrOverloads());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
Loading…
Reference in New Issue