#ifndef CALLBACKCONNECTOR_H #define CALLBACKCONNECTOR_H #include namespace cbc { namespace Details { template class FuncMemberWrapper { public: FuncMemberWrapper() = delete; using member_fun_t = Ret (T::*)(Args...); using const_member_fun_t = Ret (T::*)(Args...) const; static auto instantiate(T* t, member_fun_t ptr) { obj = t; member = ptr; return MetaCall; } static auto instantiate(T* t, const_member_fun_t ptr) { obj = t; const_member = ptr; return ConstMetaCall; } private: static auto MetaCall(Args... args) { return (*obj.*member)(args...); } static auto ConstMetaCall(Args... args) { return (*obj.*const_member)(args...); } static T* obj; static member_fun_t member; static const_member_fun_t const_member; }; template T* FuncMemberWrapper::obj{}; template typename FuncMemberWrapper::member_fun_t FuncMemberWrapper::member{}; template typename FuncMemberWrapper::const_member_fun_t FuncMemberWrapper::const_member{}; template struct FunctorWrapper { public: static std::function functor; static auto instatiate(Functor fn) { functor = std::move(fn); return MetaCall; } private: static auto MetaCall(Args... args) { return functor(args...); } }; template std::function FunctorWrapper::functor; template auto deducer(Functor obj, Ret (T::*)(Args...) const) { return FunctorWrapper::instatiate(std::move(obj)); } template auto deducer(Functor obj, Ret (T::*)(Args...)) { return FunctorWrapper::instatiate(std::move(obj)); } template auto const_instantiate(T* t, Ret (T::*ptr)(Args...) const) { return FuncMemberWrapper::instantiate(t, ptr); } template auto const_instantiate(T* t, Func ptr) { return const_instantiate(t, ptr); } } //end of Details scope template auto obtain_connector(T* t, Ret (T::*ptr)(Args...)) { return Details::FuncMemberWrapper::instantiate(t, ptr); } template auto obtain_connector(T* t, Ret (T::*ptr)(Args...) const) { return Details::FuncMemberWrapper::instantiate(t, ptr); } template auto obtain_connector(Functor functor) { return Details::deducer(std::move(functor), &Functor::operator()); } } //end of cbc scope #endif // CALLBACKCONNECTOR_H