| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #ifndef CALLBACKCONNECTOR_H
- #define CALLBACKCONNECTOR_H
- #include <functional>
- namespace cbc {
- namespace Details {
- template <std::size_t Tag, typename T, typename Ret, typename... Args> 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 <std::size_t Tag, typename T, typename Ret, typename... Args>
- T* FuncMemberWrapper<Tag, T, Ret, Args...>::obj{};
- template <std::size_t Tag, typename T, typename Ret, typename... Args>
- typename FuncMemberWrapper<Tag, T, Ret, Args...>::member_fun_t
- FuncMemberWrapper<Tag, T, Ret, Args...>::member{};
- template <std::size_t Tag, typename T, typename Ret, typename... Args>
- typename FuncMemberWrapper<Tag, T, Ret, Args...>::const_member_fun_t
- FuncMemberWrapper<Tag, T, Ret, Args...>::const_member{};
- template <typename Functor, typename Ret, typename... Args> struct FunctorWrapper {
- public:
- static std::function<Ret(Args...)> functor;
- static auto instatiate(Functor fn) {
- functor = std::move(fn);
- return MetaCall;
- }
- private:
- static auto MetaCall(Args... args) {
- return functor(args...);
- }
- };
- template <typename Functor, typename Ret, typename... Args>
- std::function<Ret(Args...)> FunctorWrapper<Functor, Ret, Args...>::functor;
- template <typename Functor, typename Ret, typename T, typename... Args>
- auto deducer(Functor obj, Ret (T::*)(Args...) const) {
- return FunctorWrapper<Functor, Ret, Args...>::instatiate(std::move(obj));
- }
- template <typename Functor, typename Ret, typename T, typename... Args>
- auto deducer(Functor obj, Ret (T::*)(Args...)) {
- return FunctorWrapper<Functor, Ret, Args...>::instatiate(std::move(obj));
- }
- template <std::size_t tag, typename T, typename Ret, typename... Args>
- auto const_instantiate(T* t, Ret (T::*ptr)(Args...) const) {
- return FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
- }
- template <std::size_t tag, typename T, typename Func> auto const_instantiate(T* t, Func ptr) {
- return const_instantiate(t, ptr);
- }
- } //end of Details scope
- template <std::size_t tag = 0, typename T, typename Ret, typename... Args>
- auto obtain_connector(T* t, Ret (T::*ptr)(Args...)) {
- return Details::FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
- }
- template <std::size_t tag = 0, typename T, typename Ret, typename... Args>
- auto obtain_connector(T* t, Ret (T::*ptr)(Args...) const) {
- return Details::FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
- }
- template <typename Functor> auto obtain_connector(Functor functor) {
- return Details::deducer(std::move(functor), &Functor::operator());
- }
- } //end of cbc scope
- #endif // CALLBACKCONNECTOR_H
|