gtsam/wrap/FullyOverloadedFunction.h

148 lines
4.3 KiB
C++

/* ----------------------------------------------------------------------------
* 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"
#include <array>
namespace wrap {
/**
* Signature Overload (including return value)
*/
class SignatureOverloads: public ArgumentOverloads {
public:
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 {
for(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;
for(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;
for(ArgumentList argList: argLists_) {
argList.emit_prototype(proxyFile, name);
if (argLCount != nrOverloads() - 1)
proxyFile.oss << ", ";
else
proxyFile.oss << " : returns " << returnValue(0).returnType()
<< 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;
for(ArgumentList argList: argLists_) {
proxyFile.oss << "%";
argList.emit_prototype(proxyFile, name);
proxyFile.oss << " : returns " << returnVals_[i++].returnType()
<< 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, boost::optional<const Qualified> instName =
boost::none, bool verbose = false) {
bool first = initializeOrCheck(name, instName, verbose);
SignatureOverloads::push_back(args, retVal);
return first;
}
// emit cython pyx function call
std::string pyx_functionCall(const std::string& caller, const std::string& funcName,
size_t iOverload) const;
/// Cython: Rename functions which names are python keywords
static const std::array<std::string, 2> pythonKeywords;
static std::string pyRename(const std::string& name) {
if (std::find(pythonKeywords.begin(), pythonKeywords.end(), name) ==
pythonKeywords.end())
return name;
else
return name + "_";
}
};
// 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;
for(const NamedMethod& namedMethod: vt)
namedMethod.second.verifyReturnTypes(validTypes);
}
} // \namespace wrap