// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information. #ifndef INCLUDED_GRAS_DETAIL_CALLABLE_HPP #define INCLUDED_GRAS_DETAIL_CALLABLE_HPP #include namespace gras { struct GRAS_API CallableRegistry { CallableRegistry(void); virtual ~CallableRegistry(void); virtual PMCC call(const std::vector &args) = 0; }; template class CallableRegistryImpl : public CallableRegistry { public: typedef ReturnType(ClassType::*Fcn0)(void); typedef ReturnType(ClassType::*Fcn1)(const Arg0 &); typedef ReturnType(ClassType::*Fcn2)(const Arg0 &, const Arg1 &); CallableRegistryImpl(ClassType *obj, Fcn0 fcn0, Fcn1 fcn1 = NULL, Fcn2 fcn2 = NULL): _obj(obj), _fcn0(fcn0), _fcn1(fcn1), _fcn2(fcn2) {} virtual ~CallableRegistryImpl(void){} PMCC call(const std::vector &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 } private: ClassType *_obj; Fcn0 _fcn0; Fcn1 _fcn1; Fcn2 _fcn2; }; template void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(void)) { ClassType *obj = dynamic_cast(this); void *fr = new CallableRegistryImpl(obj, fcn); _register_call(key, fr); } template void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &)) { ClassType *obj = dynamic_cast(this); void *fr = new CallableRegistryImpl(obj, NULL, fcn); _register_call(key, fr); } template void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &)) { ClassType *obj = dynamic_cast(this); void *fr = new CallableRegistryImpl(obj, NULL, NULL, fcn); _register_call(key, fr); } template ReturnType Callable::call(const std::string &key) { std::vector args; PMCC r = _handle_call(key, args); return r.safe_as(); } template ReturnType Callable::call(const std::string &key, const Arg0 &a0) { std::vector args; args.push_back(PMC_M(a0)); PMCC r = _handle_call(key, args); return r.safe_as(); } 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 r = _handle_call(key, args); return r.safe_as(); } inline void Callable::call(const std::string &key) { std::vector args; _handle_call(key, args); } template void Callable::call(const std::string &key, const Arg0 &a0) { std::vector args; args.push_back(PMC_M(a0)); _handle_call(key, args); } template void 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)); _handle_call(key, args); } } //namespace gras #endif /*INCLUDED_GRAS_DETAIL_CALLABLE_HPP*/