Dispatch.tlh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //
  2. #include <string>
  3. #include <map>
  4. #include <functional>
  5. namespace CXXHelper
  6. {
  7. template <typename _Ret, typename _Key, typename... Args>
  8. class Dispatch
  9. {
  10. protected:
  11. std::map <_Key, std::function <_Ret (Args...)> > m_handlers;
  12. public:
  13. Dispatch () { }
  14. Dispatch (Dispatch && from)
  15. {
  16. m_handlers.swap (from.m_handlers);
  17. }
  18. Dispatch (const Dispatch & from)
  19. {
  20. from.CopyTo (*this);
  21. }
  22. Dispatch & operator = (const Dispatch & from)
  23. {
  24. from.CopyTo (*this);
  25. return (*this);
  26. }
  27. Dispatch & operator = (Dispatch && from)
  28. {
  29. m_handlers.swap (from.m_handlers);
  30. return (*this);
  31. }
  32. void swap (Dispatch & from)
  33. {
  34. m_handlers.swap (from.m_handlers);
  35. }
  36. void CopyTo (Dispatch & to) const
  37. {
  38. to.m_handlers = m_handlers;
  39. }
  40. void Release ()
  41. {
  42. m_handlers.clear ();
  43. }
  44. auto begin ()
  45. {
  46. return m_handlers.begin ();
  47. }
  48. auto end ()
  49. {
  50. return m_handlers.end ();
  51. }
  52. auto begin () const
  53. {
  54. return m_handlers.cbegin ();
  55. }
  56. auto end () const
  57. {
  58. return m_handlers.cend ();
  59. }
  60. public:
  61. template <typename U = _Ret>
  62. std::enable_if_t <! std::is_void <U>::value, U>
  63. operator () (const _Key k, Args... arg)
  64. {
  65. return Invoke (k, arg...);
  66. }
  67. template <typename U = _Ret>
  68. std::enable_if_t <std::is_void <U>::value, U>
  69. operator () (Args... arg)
  70. {
  71. Invoke (arg...);
  72. }
  73. template <typename U = _Ret>
  74. std::enable_if_t <! std::is_void <U>::value, U>
  75. Invoke (const _Key k, Args... arg)
  76. {
  77. auto Iter = m_handlers.find (k);
  78. if (Iter != m_handlers.end ())
  79. {
  80. return (*Iter).second (arg...);
  81. }
  82. return U { };
  83. }
  84. template <typename U = _Ret>
  85. std::enable_if_t <std::is_void <U>::value, U>
  86. Invoke (const _Key k, Args... arg)
  87. {
  88. auto Iter = m_handlers.find (k);
  89. if (Iter != m_handlers.end ())
  90. {
  91. (*Iter).second (arg...);
  92. }
  93. }
  94. public:
  95. inline void RemoveAll ()
  96. {
  97. Release ();
  98. }
  99. inline bool IsEmpty () const
  100. {
  101. return m_handlers.empty ();
  102. }
  103. inline int GetSize () const
  104. {
  105. return (int)m_handlers.size ();
  106. }
  107. inline void AppendFrom (const Dispatch & from)
  108. {
  109. for (auto h : from.m_handlers)
  110. this->m_handlers.push_back (h);
  111. }
  112. public:
  113. Dispatch & operator += (Dispatch & from)
  114. {
  115. AppendFrom (from);
  116. return (*this);
  117. }
  118. public:
  119. template <typename TA>
  120. Dispatch & operator += (TA v)
  121. {
  122. Push (v);
  123. return (*this);
  124. }
  125. public:
  126. // lambda 表达式会到这里
  127. // Binder (bind 结果) 会到这里
  128. template <typename TX>
  129. // inline void Push (const TX & handler)
  130. inline void Push (const _Key K, TX handler)
  131. {
  132. m_handlers.emplace (K, std::move (handler));
  133. }
  134. // 静态函数会到这里
  135. inline void Push (const _Key K, _Ret (*fn) (Args...))
  136. {
  137. m_handlers.emplace (K, std::move (fn));
  138. }
  139. #if 1
  140. // 类的成员函数会到这里 - 3 个
  141. // 这里用了个小技巧: 把类实例和成员函数转换成一个临时的 lambda 函数
  142. // 另外, 不管 _Ret 是否为 void, 下面的代码都能通过编译 ! 暂不清楚 C++ 编译器是如何区分的 !
  143. template <typename TC>
  144. inline void Push (const _Key K, TC * inst, _Ret (TC::* mfn) (Args...))
  145. {
  146. m_handlers.emplace (K, [inst, mfn] (Args... args) { return (*inst.*mfn) (args...); });
  147. }
  148. template <typename TC>
  149. void Push (const _Key K, TC * inst, _Ret (TC::* mfn) (Args...) const)
  150. {
  151. m_handlers.emplace (K, [inst, mfn] (Args... args) { return (*inst.*mfn) (args...); });
  152. }
  153. template<typename TC>
  154. void Push (const _Key K, const TC * inst, _Ret (TC::* mfn) (Args...) const)
  155. {
  156. m_handlers.emplace (K, [inst, mfn] (Args... args) {return (*inst.*mfn) (args...); });
  157. }
  158. #endif
  159. };
  160. }