From aa2c285ac86e5671fa418d336920c1c300cf9737 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 5 Jul 2013 16:10:49 -0700 Subject: gras: serious template insanity --- include/gras/detail/callable.hpp | 255 ++++++++++++++++++++++++++++++++------- 1 file changed, 210 insertions(+), 45 deletions(-) (limited to 'include/gras/detail') 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 &args) = 0; + virtual PMCC call(const PMCC *args) = 0; }; -template -class CallableRegistryEntryImpl : public CallableRegistryEntry +/*********************************************************************** + * Registration for return with 0 args + **********************************************************************/ +template +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 &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())); - if (_fcn2) return PMC_M((_obj->*_fcn2)(args[0].safe_as(), args[1].safe_as())); - 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 void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(void)) { ClassType *obj = dynamic_cast(this); - void *fr = new CallableRegistryEntryImpl(obj, fcn); + void *fr = new CallableRegistryEntryImpl0(obj, fcn); _register_call(key, fr); } +template +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 +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(void)) +{ + ClassType *obj = dynamic_cast(this); + void *fr = new CallableRegistryEntryImplVoid0(obj, fcn); + _register_call(key, fr); +} + +/*********************************************************************** + * Registration for return with 1 args + **********************************************************************/ +template +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())); + } + ClassType *_obj; Fcn _fcn; +}; + template void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &)) { ClassType *obj = dynamic_cast(this); - void *fr = new CallableRegistryEntryImpl(obj, NULL, fcn); + void *fr = new CallableRegistryEntryImpl1(obj, fcn); + _register_call(key, fr); +} + +template +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()); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &)) +{ + ClassType *obj = dynamic_cast(this); + void *fr = new CallableRegistryEntryImplVoid1(obj, fcn); _register_call(key, fr); } +/*********************************************************************** + * Registration for return with 2 args + **********************************************************************/ +template +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(), args[1].safe_as())); + } + ClassType *_obj; Fcn _fcn; +}; + template void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &)) { ClassType *obj = dynamic_cast(this); - void *fr = new CallableRegistryEntryImpl(obj, NULL, NULL, fcn); + void *fr = new CallableRegistryEntryImpl2(obj, fcn); _register_call(key, fr); } +template +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(), args[1].safe_as()); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &, const Arg1 &)) +{ + ClassType *obj = dynamic_cast(this); + void *fr = new CallableRegistryEntryImplVoid2(obj, fcn); + _register_call(key, fr); +} + +/*********************************************************************** + * Registration for return with 3 args + **********************************************************************/ +template +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(), args[1].safe_as(), args[2].safe_as())); + } + ClassType *_obj; Fcn _fcn; +}; + +template +void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &)) +{ + ClassType *obj = dynamic_cast(this); + void *fr = new CallableRegistryEntryImpl3(obj, fcn); + _register_call(key, fr); +} + +template +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(), args[1].safe_as(), args[2].safe_as()); return PMCC(); + } + ClassType *_obj; Fcn _fcn; +}; + +template +void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &)) +{ + ClassType *obj = dynamic_cast(this); + void *fr = new CallableRegistryEntryImplVoid3(obj, fcn); + _register_call(key, fr); +} + +/*********************************************************************** + * Call implementations with 0 args + **********************************************************************/ template ReturnType Callable::call(const std::string &key) { - std::vector args; + PMCC args[0]; PMCC r = _handle_call(key, args); return r.safe_as(); } +inline +void Callable::call(const std::string &key) +{ + PMCC args[0]; + _handle_call(key, args); +} + +/*********************************************************************** + * Call implementations with 1 args + **********************************************************************/ template ReturnType Callable::call(const std::string &key, const Arg0 &a0) { - std::vector 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(); } +template +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 ReturnType Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) { - std::vector 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(); } -inline -void Callable::call(const std::string &key) +template +void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) { - std::vector args; + PMCC args[2]; + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); _handle_call(key, args); } -template -void Callable::call(const std::string &key, const Arg0 &a0) +/*********************************************************************** + * Call implementations with 3 args + **********************************************************************/ +template +ReturnType Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) { - std::vector 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(); } -template -void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1) +template +void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) { - std::vector 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); } -- cgit