// #include #include #include namespace CXXHelper { template class Dispatch { protected: std::map <_Key, std::function <_Ret (Args...)> > m_handlers; public: Dispatch () { } Dispatch (Dispatch && from) { m_handlers.swap (from.m_handlers); } Dispatch (const Dispatch & from) { from.CopyTo (*this); } Dispatch & operator = (const Dispatch & from) { from.CopyTo (*this); return (*this); } Dispatch & operator = (Dispatch && from) { m_handlers.swap (from.m_handlers); return (*this); } void swap (Dispatch & from) { m_handlers.swap (from.m_handlers); } void CopyTo (Dispatch & to) const { to.m_handlers = m_handlers; } void Release () { m_handlers.clear (); } auto begin () { return m_handlers.begin (); } auto end () { return m_handlers.end (); } auto begin () const { return m_handlers.cbegin (); } auto end () const { return m_handlers.cend (); } public: template std::enable_if_t ::value, U> operator () (const _Key k, Args... arg) { return Invoke (k, arg...); } template std::enable_if_t ::value, U> operator () (Args... arg) { Invoke (arg...); } template std::enable_if_t ::value, U> Invoke (const _Key k, Args... arg) { auto Iter = m_handlers.find (k); if (Iter != m_handlers.end ()) { return (*Iter).second (arg...); } return U { }; } template std::enable_if_t ::value, U> Invoke (const _Key k, Args... arg) { auto Iter = m_handlers.find (k); if (Iter != m_handlers.end ()) { (*Iter).second (arg...); } } public: inline void RemoveAll () { Release (); } inline bool IsEmpty () const { return m_handlers.empty (); } inline int GetSize () const { return (int)m_handlers.size (); } inline void AppendFrom (const Dispatch & from) { for (auto h : from.m_handlers) this->m_handlers.push_back (h); } public: Dispatch & operator += (Dispatch & from) { AppendFrom (from); return (*this); } public: template Dispatch & operator += (TA v) { Push (v); return (*this); } public: // lambda 表达式会到这里 // Binder (bind 结果) 会到这里 template // inline void Push (const TX & handler) inline void Push (const _Key K, TX handler) { m_handlers.emplace (K, std::move (handler)); } // 静态函数会到这里 inline void Push (const _Key K, _Ret (*fn) (Args...)) { m_handlers.emplace (K, std::move (fn)); } #if 1 // 类的成员函数会到这里 - 3 个 // 这里用了个小技巧: 把类实例和成员函数转换成一个临时的 lambda 函数 // 另外, 不管 _Ret 是否为 void, 下面的代码都能通过编译 ! 暂不清楚 C++ 编译器是如何区分的 ! template inline void Push (const _Key K, TC * inst, _Ret (TC::* mfn) (Args...)) { m_handlers.emplace (K, [inst, mfn] (Args... args) { return (*inst.*mfn) (args...); }); } template void Push (const _Key K, TC * inst, _Ret (TC::* mfn) (Args...) const) { m_handlers.emplace (K, [inst, mfn] (Args... args) { return (*inst.*mfn) (args...); }); } template void Push (const _Key K, const TC * inst, _Ret (TC::* mfn) (Args...) const) { m_handlers.emplace (K, [inst, mfn] (Args... args) {return (*inst.*mfn) (args...); }); } #endif }; }