callback-connector.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #ifndef CALLBACKCONNECTOR_H
  2. #define CALLBACKCONNECTOR_H
  3. #include <functional>
  4. namespace cbc {
  5. namespace Details {
  6. template <std::size_t Tag, typename T, typename Ret, typename... Args> class FuncMemberWrapper {
  7. public:
  8. FuncMemberWrapper() = delete;
  9. using member_fun_t = Ret (T::*)(Args...);
  10. using const_member_fun_t = Ret (T::*)(Args...) const;
  11. static auto instantiate(T* t, member_fun_t ptr) {
  12. obj = t;
  13. member = ptr;
  14. return MetaCall;
  15. }
  16. static auto instantiate(T* t, const_member_fun_t ptr) {
  17. obj = t;
  18. const_member = ptr;
  19. return ConstMetaCall;
  20. }
  21. private:
  22. static auto MetaCall(Args... args) {
  23. return (*obj.*member)(args...);
  24. }
  25. static auto ConstMetaCall(Args... args) {
  26. return (*obj.*const_member)(args...);
  27. }
  28. static T* obj;
  29. static member_fun_t member;
  30. static const_member_fun_t const_member;
  31. };
  32. template <std::size_t Tag, typename T, typename Ret, typename... Args>
  33. T* FuncMemberWrapper<Tag, T, Ret, Args...>::obj{};
  34. template <std::size_t Tag, typename T, typename Ret, typename... Args>
  35. typename FuncMemberWrapper<Tag, T, Ret, Args...>::member_fun_t
  36. FuncMemberWrapper<Tag, T, Ret, Args...>::member{};
  37. template <std::size_t Tag, typename T, typename Ret, typename... Args>
  38. typename FuncMemberWrapper<Tag, T, Ret, Args...>::const_member_fun_t
  39. FuncMemberWrapper<Tag, T, Ret, Args...>::const_member{};
  40. template <typename Functor, typename Ret, typename... Args> struct FunctorWrapper {
  41. public:
  42. static std::function<Ret(Args...)> functor;
  43. static auto instatiate(Functor fn) {
  44. functor = std::move(fn);
  45. return MetaCall;
  46. }
  47. private:
  48. static auto MetaCall(Args... args) {
  49. return functor(args...);
  50. }
  51. };
  52. template <typename Functor, typename Ret, typename... Args>
  53. std::function<Ret(Args...)> FunctorWrapper<Functor, Ret, Args...>::functor;
  54. template <typename Functor, typename Ret, typename T, typename... Args>
  55. auto deducer(Functor obj, Ret (T::*)(Args...) const) {
  56. return FunctorWrapper<Functor, Ret, Args...>::instatiate(std::move(obj));
  57. }
  58. template <typename Functor, typename Ret, typename T, typename... Args>
  59. auto deducer(Functor obj, Ret (T::*)(Args...)) {
  60. return FunctorWrapper<Functor, Ret, Args...>::instatiate(std::move(obj));
  61. }
  62. template <std::size_t tag, typename T, typename Ret, typename... Args>
  63. auto const_instantiate(T* t, Ret (T::*ptr)(Args...) const) {
  64. return FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
  65. }
  66. template <std::size_t tag, typename T, typename Func> auto const_instantiate(T* t, Func ptr) {
  67. return const_instantiate(t, ptr);
  68. }
  69. } //end of Details scope
  70. template <std::size_t tag = 0, typename T, typename Ret, typename... Args>
  71. auto obtain_connector(T* t, Ret (T::*ptr)(Args...)) {
  72. return Details::FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
  73. }
  74. template <std::size_t tag = 0, typename T, typename Ret, typename... Args>
  75. auto obtain_connector(T* t, Ret (T::*ptr)(Args...) const) {
  76. return Details::FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
  77. }
  78. template <typename Functor> auto obtain_connector(Functor functor) {
  79. return Details::deducer(std::move(functor), &Functor::operator());
  80. }
  81. } //end of cbc scope
  82. #endif // CALLBACKCONNECTOR_H