rendered paste body#ifndef RDKFUNCTIONSIMPL_H_#define RDKFUNCTIONSIMPL_H_#include <RDKFunctions>#include <RDKUtility>#include <vector>using std::vector;using std::tuple;namespace RDKNAMESPACE{ template<typename... Args> class rdkArgsI : rdkArgs { private: const vector<const type> types; tuple<Args...> data; ~rdkArgsI() { } public: rdkArgsI(Args&&... arguments) : data(std::forward<Args>(arguments)...), types(typeid(Args)...) { } rdkArgsI(tuple<Args...> && arguments) : data(arguments), types(typeid(Args)...) { } size_t arguments() const throw() { return sizeof...(Args); } const type & operator[](size_t i) const throw(exception) { if(i < arguments()) return types[i]; throw rdkOutOfRange; } const tuple<Args...> & data get() { return data; } rdkArgs * pop() { if(!arguments()) throw rdkOutOfRange; rdkArgs * p = new rdkArgsI(pack<sizeof...(Args)-1>(data)); delete this; return p; } rdkArgs * shorten(size_t l) const throw(exception) { if(l > arguments()) throw rdkOutOfRange; else if(l == arguments()) return new rdkArgsI(data); else { rdkArgs * t = new rdkArgI(data); while(t->arguments() > l) t = t->pop(); return t; } } }; template<typename... Args> rdkArgs * pack_args(Args&&... a) { return new rdkArgsI(std::forward(a)...); } template<typename... Args> rdkArgs * pack_args(tuple<Args...> && t) { return new rdkArgsI(std::forward(t)); } template<typename... Args> class rdkFunctionBaseI : rdkFunction { protected: const vector<const type> types; public: virtual bool isMemberFunction() const throw() { return false; } bool callable(rdkArgs * args) const throw() { if(args->arguments() < arguments()) return false; for(size_t i = 0; i < arguments(); i++) if(args->operator[](i) != operator[](i)) return false; return true; } bool compatible(rdkFunction * rhs) const throw() { if(rhs.arguments() < arguments()) return false; for(size_t i = 0; i < arguments(); i++) if(rhs->opeartor[](i) != opeartor[](i)) return false; return true; } virtual const type & superClass() const throw(exception) { if(isMemberFunction()) return types.front(); else throw rdkNotAMember; } constexpr size_t arguments() const throw() { return sizeof...(Args); } const type & operator[](size_t i) const throw(exception) { if(i < arguments()) return types[i]; throw rdkOutOfRange(); } virtual void call(const tuple<Args...> &) const = delete; void operator()(rdkArgs * a) const throw(exception) { if(!compatible(a)) throw rdkNotCompatible; rdkArgsI<Args...> * args = a->shorten(arguments()); if(!args) throw rdkNotCompatible; call(args->get()); } }; template<typename... Args> class rdkFunctionI : rdkFunctionBaseI { private: function<void (Args...)> f; public: rdkFunctionI(void (*function)(Args...)) : types(typeid(Args)...), f(function) { } void call(const tuple<Args...> & a) const { unpack(f, a...); } }; template<typename T, typename... Args> class rdkFunctionMemberI : rdkFunctionBaseI { private: function<void (T*, Args...)> f; public: rdkFunctionMemberI(void (T::*function)(Args...)) : types(typeid(T*), typeid(Args)...), f(function) { } bool isMemberFunction() const throw() { return true; } void call(const tuple<Args...> & a) const { unpack(f, a...); } }; template<typename... Args> rdkFunction * pack_function(void (*f)(Args...)) { return new rdkFunctionI(f); } template<typename T, typename... Args> rdkFunction * pack_function(void (T::*f)(Args...)) { return new rdkFunctionMemberI(f); }}#endif