/* ---------------------------------------------------------------------------- * 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 namespace wrap { /** * Signature Overload (including return value) */ class SignatureOverloads: public ArgumentOverloads { public: std::vector 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& 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 expandReturnValuesTemplate( const TemplateSubstitution& ts) const { std::vector 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 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 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 inline void verifyReturnTypes(const std::vector& validTypes, const std::map& vt) { typedef typename std::map::value_type NamedMethod; for(const NamedMethod& namedMethod: vt) namedMethod.second.verifyReturnTypes(validTypes); } } // \namespace wrap