134 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
		
		
			
		
	
	
			134 lines
		
	
	
		
			3.8 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"
 | ||
|  | 
 | ||
|  | 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
 | ||
|  | 
 |