Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <map>
- #include <string>
- #include <iostream>
- #include <stdexcept>
- namespace dynamic_call
- {
- struct function_not_found: std::invalid_argument
- {
- explicit function_not_found(const std::string& msg)
- : std::invalid_argument(msg.c_str()) {}
- explicit function_not_found(const char* msg)
- : std::invalid_argument(msg) {}
- };
- struct function_type_unmatched: std::invalid_argument
- {
- explicit function_type_unmatched(const std::string& msg)
- : std::invalid_argument(msg.c_str()) {}
- explicit function_type_unmatched(const char* msg)
- : std::invalid_argument(msg) {}
- };
- struct func_type
- {
- virtual ~func_type() {};
- };
- template <typename FuncType>
- struct func_type_holder: func_type
- {
- func_type_holder(FuncType fn): fn_(fn) {}
- FuncType fn_;
- };
- template <typename ResType>
- struct func_call_impl
- {
- func_call_impl(func_type& func_): func(func_) {}
- public:
- ResType operator ()()
- {
- func_type_holder<ResType (*)()>* pFTH = dynamic_cast<func_type_holder<ResType (*)()>*>(&func);
- if (pFTH == NULL)
- throw function_type_unmatched("func_call_impl::operator ()()");
- return pFTH->fn_();
- }
- template <typename T1>
- ResType operator ()(T1 t1)
- {
- func_type_holder<ResType (*)(T1)>* pFTH = dynamic_cast<func_type_holder<ResType (*)(T1)>*>(&func);
- if (pFTH == NULL)
- throw function_type_unmatched("func_call_impl::operator ()(T1)");
- return pFTH->fn_(t1);
- }
- template <typename T1, typename T2>
- ResType operator ()(T1 t1, T2 t2)
- {
- func_type_holder<ResType (*)(T1, T2)>* pFTH = dynamic_cast<func_type_holder<ResType (*)(T1, T2)>*>(&func);
- if (pFTH == NULL)
- throw function_type_unmatched("func_call_impl::operator ()(T1, T2)");
- return pFTH->fn_(t1, t2);
- }
- template <typename T1, typename T2, typename T3>
- ResType operator ()(T1 t1, T2 t2, T3 t3)
- {
- func_type_holder<ResType (*)(T1, T2, T3)>* pFTH = dynamic_cast<func_type_holder<ResType (*)(T1, T2, T3)>*>(&func);
- if (pFTH == NULL)
- throw function_type_unmatched("func_call_impl::operator ()(T1, T2, T3)");
- return pFTH->fn_(t1, t2, t3);
- }
- private:
- func_type& func;
- };
- template <typename ResType, typename ObjType>
- struct mem_func_call_impl
- {
- mem_func_call_impl(ObjType& obj_, func_type& mem_func_): obj(obj_), mem_func(mem_func_) {}
- public:
- ResType operator ()()
- {
- func_type_holder<ResType (ObjType::*)()>* pFTH = dynamic_cast<func_type_holder<ResType (ObjType::*)()>*>(&mem_func);
- if (pFTH == NULL)
- throw function_type_unmatched("mem_func_call_impl::operator ()()");
- return (obj.*(pFTH->fn_))();
- }
- template <typename T1>
- ResType operator ()(T1 t1)
- {
- func_type_holder<ResType (ObjType::*)(T1)>* pFTH = dynamic_cast<func_type_holder<ResType (ObjType::*)(T1)>*>(&mem_func);
- if (pFTH == NULL)
- throw function_type_unmatched("mem_func_call_impl::operator ()(T1)");
- return (obj.*(pFTH->fn_))(t1);
- }
- template <typename T1, typename T2>
- ResType operator ()(T1 t1, T2 t2)
- {
- func_type_holder<ResType (ObjType::*)(T1, T2)>* pFTH = dynamic_cast<func_type_holder<ResType (ObjType::*)(T1, T2)>*>(&mem_func);
- if (pFTH == NULL)
- throw function_type_unmatched("mem_func_call_impl::operator ()(T1, T2)");
- return (obj.*(pFTH->fn_))(t1, t2);
- }
- template <typename T1, typename T2, typename T3>
- ResType operator ()(T1 t1, T2 t2, T3 t3)
- {
- func_type_holder<ResType (ObjType::*)(T1, T2, T3)>* pFTH = dynamic_cast<func_type_holder<ResType (ObjType::*)(T1, T2, T3)>*>(&mem_func);
- if (pFTH == NULL)
- throw function_type_unmatched("mem_func_call_impl::operator ()(T1, T2, T3)");
- return (obj.*(pFTH->fn_))(t1, t2, t3);
- }
- private:
- ObjType& obj;
- func_type& mem_func;
- };
- class dynamic_call
- {
- typedef std::map<std::string, func_type*> ContType;
- public:
- template <typename FuncType>
- bool regFunc(FuncType pfn, const std::string& fnName) // Return true if succeeded
- {
- return funcs_.insert(std::make_pair(fnName, new func_type_holder<FuncType>(pfn))).second;
- }
- bool unregFunc(const std::string& fnName) // Return true if succeeded
- {
- ContType::iterator it = funcs_.find(fnName);
- if (it == funcs_.end())
- return false;
- delete it->second;
- funcs_.erase(it);
- return true;
- }
- ~dynamic_call()
- {
- for (ContType::iterator it = funcs_.begin(); it != funcs_.end(); ++it)
- delete it->second;
- }
- template <typename ResType>
- func_call_impl<ResType> callFunc(const std::string& fnName)
- {
- ContType::iterator it = funcs_.find(fnName);
- if (it == funcs_.end())
- throw function_not_found(fnName);
- return func_call_impl<ResType>(*it->second);
- }
- template <typename ResType, typename ObjType>
- mem_func_call_impl<ResType, ObjType> callMemFunc(const std::string& fnName, ObjType& obj)
- {
- ContType::iterator it = funcs_.find(fnName);
- if (it == funcs_.end())
- throw function_not_found(fnName);
- return mem_func_call_impl<ResType, ObjType>(obj, *it->second);
- }
- private:
- ContType funcs_;
- };
- }
- #define REG_FUNC(func) regFunc(func, #func)
- #define REG_MEM_FUNC(mem_func) regFunc(&mem_func, #mem_func)
- void fn()
- {
- std::cout << "fn() is called" << std::endl;
- }
- struct A
- {
- A(int i_): i(i_) {};
- int fn1(int a)
- {
- std::cout << "A::fn1(" << a << ") is called, with A::i=" << i << std::endl;
- return a + i;
- }
- void fn2()
- {
- std::cout << "This should not be displayed" << std::endl;
- }
- int i;
- };
- struct B {};
- int main()
- {
- using namespace std;
- dynamic_call::dynamic_call fns;
- fns.REG_MEM_FUNC(A::fn1);
- fns.REG_FUNC(fn);
- fns.REG_MEM_FUNC(A::fn2);
- A a(10);
- B b;
- int res = fns.callMemFunc<int>("A::fn1", a)(10);
- cout << "Result of A::fn1 = " << res << endl;
- fns.callFunc<void>("fn")();
- try {
- fns.callMemFunc<void>("A::fn2", b)(10);
- } catch (exception& e) {
- cout << "Exception catched: " << e.what() << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement