/* ---------------------------------------------------------------------------- * 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 Function.h * @brief Base class for global functions and methods * @author Frank Dellaert * @date Nov 13, 2014 **/ #pragma once #include "Argument.h" #include "ReturnValue.h" #include "TypeAttributesTable.h" #include #include namespace wrap { /// Function class class Function { protected: bool verbose_; std::string name_; ///< name of method Qualified templateArgValue_; ///< value of template argument if applicable public: /// Constructor creates empty object Function(bool verbose = true) : verbose_(verbose) { } Function(const std::string& name, bool verbose = true) : verbose_(verbose), name_(name) { } std::string name() const { return name_; } std::string matlabName() const { if (templateArgValue_.empty()) return name_; else 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 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 expandArgumentListsTemplate( const TemplateSubstitution& ts) const; /// Expand templates, imperative ! virtual void ExpandTemplate(const TemplateSubstitution& ts) { argLists_ = expandArgumentListsTemplate(ts); } void verifyArguments(const std::vector& 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 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& 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 expandReturnValuesTemplate( const TemplateSubstitution& ts) const { std::vector 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 static std::map expandMethodTemplate( const std::map& methods, const TemplateSubstitution& ts) { std::map result; typedef std::pair NamedMethod; BOOST_FOREACH(NamedMethod namedMethod, methods) { F instMethod = namedMethod.second; instMethod.expandTemplate(ts); namedMethod.second = instMethod; result.insert(namedMethod); } return result; } template inline void verifyReturnTypes(const std::vector& validTypes, const std::map& vt) { typedef typename std::map::value_type NamedMethod; BOOST_FOREACH(const NamedMethod& namedMethod, vt) namedMethod.second.verifyReturnTypes(validTypes); } } // \namespace wrap