diff options
author | Josh Blum | 2013-07-05 16:10:49 -0700 |
---|---|---|
committer | Josh Blum | 2013-07-05 16:10:49 -0700 |
commit | aa2c285ac86e5671fa418d336920c1c300cf9737 (patch) | |
tree | 33dfab03ddb43b4865ce59b89f421741460d6c24 /include/gras/detail | |
parent | e23e5f43a97c72f1bf0dd240376bf89ff19f356c (diff) | |
download | sandhi-aa2c285ac86e5671fa418d336920c1c300cf9737.tar.gz sandhi-aa2c285ac86e5671fa418d336920c1c300cf9737.tar.bz2 sandhi-aa2c285ac86e5671fa418d336920c1c300cf9737.zip |
gras: serious template insanity
Diffstat (limited to 'include/gras/detail')
-rw-r--r-- | include/gras/detail/callable.hpp | 255 |
1 files changed, 210 insertions, 45 deletions
diff --git a/include/gras/detail/callable.hpp b/include/gras/detail/callable.hpp index 5e7854a..23e3ab6 100644 --- a/include/gras/detail/callable.hpp +++ b/include/gras/detail/callable.hpp @@ -8,112 +8,277 @@ namespace gras { +/*********************************************************************** + * Registration entry base class + **********************************************************************/ struct GRAS_API CallableRegistryEntry { CallableRegistryEntry(void); virtual ~CallableRegistryEntry(void); - virtual PMCC call(const std::vector<PMCC> &args) = 0; + virtual PMCC call(const PMCC *args) = 0; }; -template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1> -class CallableRegistryEntryImpl : public CallableRegistryEntry +/*********************************************************************** + * Registration for return with 0 args + **********************************************************************/ +template <typename ClassType, typename ReturnType> +struct CallableRegistryEntryImpl0 : CallableRegistryEntry { -public: - - typedef ReturnType(ClassType::*Fcn0)(void); - typedef ReturnType(ClassType::*Fcn1)(const Arg0 &); - typedef ReturnType(ClassType::*Fcn2)(const Arg0 &, const Arg1 &); - - CallableRegistryEntryImpl(ClassType *obj, Fcn0 fcn0, Fcn1 fcn1 = NULL, Fcn2 fcn2 = NULL): - _obj(obj), _fcn0(fcn0), _fcn1(fcn1), _fcn2(fcn2) - {} - virtual ~CallableRegistryEntryImpl(void){} - - PMCC call(const std::vector<PMCC> &args) + typedef ReturnType(ClassType::*Fcn)(void); + CallableRegistryEntryImpl0(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) { - if (_fcn0) return PMC_M((_obj->*_fcn0)()); - if (_fcn1) return PMC_M((_obj->*_fcn1)(args[0].safe_as<Arg0>())); - if (_fcn2) return PMC_M((_obj->*_fcn2)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>())); - return PMCC();//should not get here + return PMC_M((_obj->*_fcn)()); } - -private: - ClassType *_obj; - Fcn0 _fcn0; Fcn1 _fcn1; Fcn2 _fcn2; + ClassType *_obj; Fcn _fcn; }; template <typename ClassType, typename ReturnType> void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(void)) { ClassType *obj = dynamic_cast<ClassType *>(this); - void *fr = new CallableRegistryEntryImpl<ClassType, ReturnType, int, int>(obj, fcn); + void *fr = new CallableRegistryEntryImpl0<ClassType, ReturnType>(obj, fcn); _register_call(key, fr); } +template <typename ClassType> +struct CallableRegistryEntryImplVoid0 : CallableRegistryEntry +{ + typedef void(ClassType::*Fcn)(void); + CallableRegistryEntryImplVoid0(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + (_obj->*_fcn)(); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template <typename ClassType> +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(void)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new CallableRegistryEntryImplVoid0<ClassType>(obj, fcn); + _register_call(key, fr); +} + +/*********************************************************************** + * Registration for return with 1 args + **********************************************************************/ +template <typename ClassType, typename ReturnType, typename Arg0> +struct CallableRegistryEntryImpl1 : CallableRegistryEntry +{ + typedef ReturnType(ClassType::*Fcn)(const Arg0 &); + CallableRegistryEntryImpl1(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>())); + } + ClassType *_obj; Fcn _fcn; +}; + template <typename ClassType, typename ReturnType, typename Arg0> void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &)) { ClassType *obj = dynamic_cast<ClassType *>(this); - void *fr = new CallableRegistryEntryImpl<ClassType, ReturnType, Arg0, int>(obj, NULL, fcn); + void *fr = new CallableRegistryEntryImpl1<ClassType, ReturnType, Arg0>(obj, fcn); + _register_call(key, fr); +} + +template <typename ClassType, typename Arg0> +struct CallableRegistryEntryImplVoid1 : CallableRegistryEntry +{ + typedef void(ClassType::*Fcn)(const Arg0 &); + CallableRegistryEntryImplVoid1(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + (_obj->*_fcn)(args[0].safe_as<Arg0>()); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template <typename ClassType, typename Arg0> +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new CallableRegistryEntryImplVoid1<ClassType, Arg0>(obj, fcn); _register_call(key, fr); } +/*********************************************************************** + * Registration for return with 2 args + **********************************************************************/ +template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1> +struct CallableRegistryEntryImpl2 : CallableRegistryEntry +{ + typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &); + CallableRegistryEntryImpl2(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>())); + } + ClassType *_obj; Fcn _fcn; +}; + template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1> void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &)) { ClassType *obj = dynamic_cast<ClassType *>(this); - void *fr = new CallableRegistryEntryImpl<ClassType, ReturnType, Arg0, Arg1>(obj, NULL, NULL, fcn); + void *fr = new CallableRegistryEntryImpl2<ClassType, ReturnType, Arg0, Arg1>(obj, fcn); _register_call(key, fr); } +template <typename ClassType, typename Arg0, typename Arg1> +struct CallableRegistryEntryImplVoid2 : CallableRegistryEntry +{ + typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &); + CallableRegistryEntryImplVoid2(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + (_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>()); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template <typename ClassType, typename Arg0, typename Arg1> +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &, const Arg1 &)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new CallableRegistryEntryImplVoid2<ClassType, Arg0, Arg1>(obj, fcn); + _register_call(key, fr); +} + +/*********************************************************************** + * Registration for return with 3 args + **********************************************************************/ +template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2> +struct CallableRegistryEntryImpl3 : CallableRegistryEntry +{ + typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &); + CallableRegistryEntryImpl3(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>(), args[2].safe_as<Arg2>())); + } + ClassType *_obj; Fcn _fcn; +}; + +template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2> +void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new CallableRegistryEntryImpl3<ClassType, ReturnType, Arg0, Arg1, Arg2>(obj, fcn); + _register_call(key, fr); +} + +template <typename ClassType, typename Arg0, typename Arg1, typename Arg2> +struct CallableRegistryEntryImplVoid3 : CallableRegistryEntry +{ + typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &); + CallableRegistryEntryImplVoid3(ClassType *obj, Fcn fcn): + _obj(obj), _fcn(fcn){} + PMCC call(const PMCC *args) + { + (_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>(), args[2].safe_as<Arg2>()); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template <typename ClassType, typename Arg0, typename Arg1, typename Arg2> +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &)) +{ + ClassType *obj = dynamic_cast<ClassType *>(this); + void *fr = new CallableRegistryEntryImplVoid3<ClassType, Arg0, Arg1, Arg2>(obj, fcn); + _register_call(key, fr); +} + +/*********************************************************************** + * Call implementations with 0 args + **********************************************************************/ template <typename ReturnType> ReturnType Callable::call(const std::string &key) { - std::vector<PMCC> args; + PMCC args[0]; PMCC r = _handle_call(key, args); return r.safe_as<ReturnType>(); } +inline +void Callable::call(const std::string &key) +{ + PMCC args[0]; + _handle_call(key, args); +} + +/*********************************************************************** + * Call implementations with 1 args + **********************************************************************/ template <typename ReturnType, typename Arg0> ReturnType Callable::call(const std::string &key, const Arg0 &a0) { - std::vector<PMCC> args; - args.push_back(PMC_M(a0)); + PMCC args[1]; + args[0] = PMC_M(a0); PMCC r = _handle_call(key, args); return r.safe_as<ReturnType>(); } +template <typename Arg0> +void Callable::call(const std::string &key, const Arg0 &a0) +{ + PMCC args[1]; + args[0] = PMC_M(a0); + _handle_call(key, args); +} + +/*********************************************************************** + * Call implementations with 2 args + **********************************************************************/ template <typename ReturnType, typename Arg0, typename Arg1> ReturnType Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) { - std::vector<PMCC> args; - args.push_back(PMC_M(a0)); - args.push_back(PMC_M(a1)); + PMCC args[2]; + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); PMCC r = _handle_call(key, args); return r.safe_as<ReturnType>(); } -inline -void Callable::call(const std::string &key) +template <typename Arg0, typename Arg1> +void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) { - std::vector<PMCC> args; + PMCC args[2]; + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); _handle_call(key, args); } -template <typename Arg0> -void Callable::call(const std::string &key, const Arg0 &a0) +/*********************************************************************** + * Call implementations with 3 args + **********************************************************************/ +template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2> +ReturnType Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) { - std::vector<PMCC> args; - args.push_back(PMC_M(a0)); - _handle_call(key, args); + PMCC args[3]; + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); + args[2] = PMC_M(a2); + PMCC r = _handle_call(key, args); + return r.safe_as<ReturnType>(); } -template <typename Arg0, typename Arg1> -void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) +template <typename Arg0, typename Arg1, typename Arg2> +void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) { - std::vector<PMCC> args; - args.push_back(PMC_M(a0)); - args.push_back(PMC_M(a1)); + PMCC args[3]; + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); + args[2] = PMC_M(a2); _handle_call(key, args); } |