[C++] Multicast delegates на FastDelegate
От: Disappear  
Дата: 03.03.06 15:08
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Fast C++ Delegate


SDB>An implementation of the fast C++ delegate which is portable and C++ Standard-compliant.


Недавно реализовал multicast delegates на основе FastDelegate от http://www.rsdn.ru/article/cpp/fastdelegate.xml
Автор(ы): Don Clugston
Дата: 27.07.2005
В данной статье предоставлен исчерпывающий материал по указателям на функции-члены, а также приведена реализация делегатов, которые занимают всего две операции на ассемблере.


Код:

#include <vector>
#include "FastDelegate.h"

#define DEFAULT_CRITICAL_SECTION func::dummy_section

using namespace fastdelegate;

namespace func
{   
  namespace detail
  {
    typedef fastdelegate::detail::DefaultVoid DefaultVoid;
  }
  
  class dummy_section
  {
  public:
    void lock() const {}
    void unlock() const {}
  };

  template<typename T>
  class auto_cs_t
  {
  public:
    auto_cs_t(const T& refcs) : m_refcs(refcs) { m_refcs.lock(); }
    ~auto_cs_t() { m_refcs.unlock(); }
  private:
    const T& m_refcs;
  };

  template<class RetType>
  class default_slot
  {
  public:
    template <typename F>
    void operator() (const F& func)     
    {
      vec_results.push_back(func());
    }  
    const std::vector<RetType>& get_results() const
    {
      return vec_results;
    }
  private:
    std::vector<RetType> vec_results;
  };

  template <>
  class default_slot<detail::DefaultVoid>
  {    
  public:    
    template <typename F>
    void operator() (const F& func) 
    {
      func();
    }    
  };

  namespace detail
  {
    template<class CritSect, class DelegateT>
    class delegate_base
    {
    public:    
      typedef DelegateT holder_type; 

      delegate_base() {}

    protected:
      void connect_delegate(const holder_type& dlghld)
      {
        auto_cs_t<CritSect> lock(cs);

        if (std::find(vec_subscribers.begin(), vec_subscribers.end(), dlghld) == vec_subscribers.end())
          vec_subscribers.push_back(dlghld);
      }
      bool disconnect_delegate(const holder_type& dlghld)
      {
        auto_cs_t<CritSect> lock(cs);

        std::vector<holder_type>::iterator iter = std::find(vec_subscribers.begin(), vec_subscribers.end(), dlghld);
        if (iter != vec_subscribers.end())
        {
          vec_subscribers.erase(iter);
          return true;
        }
        return false;
      }

      CritSect cs;
      std::vector<holder_type> vec_subscribers;
    };

    template<class Param1, class RetType, class DelegateT>
    struct caller1
    {
      caller1(const DelegateT& holder, Param1 param1) : dlgh(holder), p1(param1) {}
      RetType operator() () const { return dlgh(p1); }
      Param1 p1; 
      const DelegateT& dlgh;
    };
    template<class Param1, class Param2, class RetType, class DelegateT>
    struct caller2
    {
      caller2(const DelegateT& holder, Param1 param1, Param2 param2) : dlgh(holder), p1(param1), p2(param2) {}
      RetType operator() () const { return dlgh(p1, p2); }
      Param1 p1; Param2 p2; 
      const DelegateT& dlgh;
    };
    template<class Param1, class Param2, class Param3, class RetType, class DelegateT>
    struct caller3
    {
      caller3(const DelegateT& holder, Param1 param1, Param2 param2, Param3 param3) : dlgh(holder), p1(param1), p2(param2), p3(param3) {}
      RetType operator() () const { return dlgh(p1, p2, p3); }
      Param1 p1; Param2 p2; Param3 p3; 
      const DelegateT& dlgh;
    };
    template<class Param1, class Param2, class Param3, class Param4, class RetType, class DelegateT>
    struct caller4
    {
      caller4(const DelegateT& holder, Param1 param1, Param2 param2, Param3 param3, Param4 param4) : dlgh(holder), p1(param1), p2(param2), p3(param3), p4(param4) {}
      RetType operator() () const { return dlgh(p1, p2, p3, p4); }
      Param1 p1; Param2 p2; Param3 p3; Param4 p4; 
      const DelegateT& dlgh;
    };
    template<class Param1, class Param2, class Param3, class Param4, class Param5, class RetType, class DelegateT>
    struct caller5
    {
      caller5(const DelegateT& holder, Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5) : dlgh(holder), p1(param1), p2(param2), p3(param3), p4(param4), p5(param5) {}
      RetType operator() () const { return dlgh(p1, p2, p3, p4, p5); }
      Param1 p1; Param2 p2; Param3 p3; Param4 p4; Param5 p5; 
      const DelegateT& dlgh;
    };
    template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType, class DelegateT>
    struct caller6
    {
      caller6(const DelegateT& holder, Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5, Param6 param6) : dlgh(holder), p1(param1), p2(param2), p3(param3), p4(param4), p5(param5), p6(param6) {}
      RetType operator() () const { return dlgh(p1, p2, p3, p4, p5, p6); }
      Param1 p1; Param2 p2; Param3 p3; Param4 p4; Param5 p5; Param6 p6; 
      const DelegateT& dlgh;
    };
    template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType, class DelegateT>
    struct caller7
    {
      caller7(const DelegateT& holder, Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5, Param6 param6, Param7 param7) : dlgh(holder), p1(param1), p2(param2), p3(param3), p4(param4), p5(param5), p6(param6), p7(param7) {}
      RetType operator() () const { return dlgh(p1, p2, p3, p4, p5, p6, p7); }
      Param1 p1; Param2 p2; Param3 p3; Param4 p4; Param5 p5; Param6 p6; Param7 p7; 
      const DelegateT& dlgh;
    };
  } //detail namespace 

  template< class RetType=detail::DefaultVoid, 
  class CritSect = DEFAULT_CRITICAL_SECTION, 
  class SlotT=default_slot<RetType> >
  class delegate0 : 
    detail::delegate_base< CritSect, FastDelegate0<RetType> >
  {
  public:
    delegate0() {}
    template < class X, class Y >
    delegate0(const Y *pthis, RetType (X::* fn)() const) 
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate0(Y *pthis, RetType (X::* fn)()) 
    { connect_delegate(holder_type(pthis, fn)); }
    delegate0(RetType (*fn)()) 
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)() const) 
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)()) 
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)()) 
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)() const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)())
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)()) 
    { return disconnect_delegate(holder_type(fn)); }
    void operator() () const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)();
    }
    SlotT invoke() const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(*iter);
      return slot;
    }
  };
  template< class Param1, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate1 :
    detail::delegate_base< CritSect, FastDelegate1<Param1, RetType> >
  {
  public:
    delegate1() {}
    template < class X, class Y >
    delegate1(const Y *pthis, RetType (X::* fn)(Param1 p1) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate1(Y *pthis, RetType (X::* fn)(Param1 p1))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate1(RetType (*fn)(Param1 p1))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1);
    }
    SlotT invoke(Param1 p1) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller1<Param1, RetType, holder_type>((*iter), p1));
      return slot;
    }
  };
  template< class Param1, class Param2, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate2 :
    detail::delegate_base< CritSect, FastDelegate2<Param1, Param2, RetType> >
  {
  public:
    delegate2() {}
    template < class X, class Y >
    delegate2(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate2(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate2(RetType (*fn)(Param1 p1, Param2 p2))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1, Param2 p2))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1, Param2 p2))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1, Param2 p2) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1, p2);
    }
    SlotT invoke(Param1 p1, Param2 p2) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller2<Param1, Param2, RetType, holder_type>((*iter), p1, p2));
      return slot;
    }
  };
  template< class Param1, class Param2, class Param3, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate3 :
    detail::delegate_base< CritSect, FastDelegate3<Param1, Param2, Param3, RetType> >
  {
  public:
    delegate3() {}
    template < class X, class Y >
    delegate3(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate3(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate3(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1, Param2 p2, Param3 p3) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1, p2, p3);
    }
    SlotT invoke(Param1 p1, Param2 p2, Param3 p3) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller3<Param1, Param2, Param3, RetType, holder_type>((*iter), p1, p2, p3));
      return slot;
    }
  };
  template< class Param1, class Param2, class Param3, class Param4, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate4 :
    detail::delegate_base< CritSect, FastDelegate4<Param1, Param2, Param3, Param4, RetType> >
  {
  public:
    delegate4() {}
    template < class X, class Y >
    delegate4(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate4(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate4(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1, p2, p3, p4);
    }
    SlotT invoke(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller4<Param1, Param2, Param3, Param4, RetType, holder_type>((*iter), p1, p2, p3, p4));
      return slot;
    }
  };
  template< class Param1, class Param2, class Param3, class Param4, class Param5, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate5 :
    detail::delegate_base< CritSect, FastDelegate5<Param1, Param2, Param3, Param4, Param5, RetType> >
  {
  public:
    delegate5() {}
    template < class X, class Y >
    delegate5(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate5(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate5(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1, p2, p3, p4, p5);
    }
    SlotT invoke(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller5<Param1, Param2, Param3, Param4, Param5, RetType, holder_type>((*iter), p1, p2, p3, p4, p5));
      return slot;
    }
  };
  template< class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate6 :
    detail::delegate_base< CritSect, FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, RetType> >
  {
  public:
    delegate6() {}
    template < class X, class Y >
    delegate6(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate6(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate6(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1, p2, p3, p4, p5, p6);
    }
    SlotT invoke(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller6<Param1, Param2, Param3, Param4, Param5, Param6, RetType, holder_type>((*iter), p1, p2, p3, p4, p5, p6));
      return slot;
    }
  };
  template< class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, 
  class RetType=detail::DefaultVoid,
  class CritSect = DEFAULT_CRITICAL_SECTION,
  class SlotT=default_slot<RetType> >
  class delegate7 :
    detail::delegate_base< CritSect, FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, RetType> >
  {
  public:
    delegate7() {}
    template < class X, class Y >
    delegate7(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    delegate7(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7))
    { connect_delegate(holder_type(pthis, fn)); }
    delegate7(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    void connect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const)
    { connect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    void connect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7))
    { connect_delegate(holder_type(pthis, fn)); }
    void connect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7))
    { connect_delegate(holder_type(fn)); }
    template < class X, class Y >
    bool disconnect(const Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const)
    { return disconnect_delegate(holder_type(pthis, fn)); }
    template < class X, class Y >
    bool disconnect(Y *pthis, RetType (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7))
    { return disconnect_delegate(holder_type(pthis, fn)); }
    bool disconnect(RetType (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7))
    { return disconnect_delegate(holder_type(fn)); }
    void operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const
    {
      auto_cs_t<CritSect> lock(cs);
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) (*iter)(p1, p2, p3, p4, p5, p6, p7);
    }
    SlotT invoke(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const
    {
      auto_cs_t<CritSect> lock(cs);
      SlotT slot;
      std::vector<holder_type>::const_iterator iter = vec_subscribers.begin();
      for (;iter != vec_subscribers.end();++iter) slot(detail::caller7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, RetType, holder_type>((*iter), p1, p2, p3, p4, p5, p6, p7));
      return slot;
    }
  };

  template <typename Function> class delegate;

  template <typename R>
  class delegate< R () > 
    : public delegate0<R>
  {    
  public:
    typedef delegate0<R> base_type;

    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)() const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)()) : base_type(pthis, fn) {}
    delegate(R (*fn)()) : base_type(fn) {}
  };
  template <typename R, class Param1>
  class delegate< R (Param1) >
    : public delegate1<Param1, R>
  {
  public:
    typedef delegate1<Param1, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1)) : base_type(fn) {}
  };
  template <typename R, class Param1, class Param2>
  class delegate< R (Param1, Param2) >
    : public delegate2<Param1, Param2, R>
  {
  public:
    typedef delegate2<Param1, Param2, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1, Param2 p2) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1, Param2 p2)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1, Param2 p2)) : base_type(fn) {}
  };
  template <typename R, class Param1, class Param2, class Param3>
  class delegate< R (Param1, Param2, Param3) >
    : public delegate3<Param1, Param2, Param3, R>
  {
  public:
    typedef delegate3<Param1, Param2, Param3, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1, Param2 p2, Param3 p3)) : base_type(fn) {}
  };
  template <typename R, class Param1, class Param2, class Param3, class Param4>
  class delegate< R (Param1, Param2, Param3, Param4) >
    : public delegate4<Param1, Param2, Param3, Param4, R>
  {
  public:
    typedef delegate4<Param1, Param2, Param3, Param4, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) : base_type(fn) {}
  };
  template <typename R, class Param1, class Param2, class Param3, class Param4, class Param5>
  class delegate< R (Param1, Param2, Param3, Param4, Param5) >
    : public delegate5<Param1, Param2, Param3, Param4, Param5, R>
  {
  public:
    typedef delegate5<Param1, Param2, Param3, Param4, Param5, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) : base_type(fn) {}
  };
  template <typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
  class delegate< R (Param1, Param2, Param3, Param4, Param5, Param6) >
    : public delegate6<Param1, Param2, Param3, Param4, Param5, Param6, R>
  {
  public:
    typedef delegate6<Param1, Param2, Param3, Param4, Param5, Param6, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) : base_type(fn) {}
  };
  template <typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
  class delegate< R (Param1, Param2, Param3, Param4, Param5, Param6, Param7) >
    : public delegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, R>
  {
  public:
    typedef delegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, R> base_type;
    delegate() : base_type() {}
    template < class X, class Y >
    delegate(const Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) : base_type(pthis, fn) {}
    template < class X, class Y >
    delegate(Y *pthis, R (X::* fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) : base_type(pthis, fn) {}
    delegate(R (*fn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) : base_type(fn) {}
  };
}


Пример:

class A
{
public:
  int OnEventInstance(int a, float b)
  {
    cout << "OnEventInstance " << a << " " << b << "\n";
    return 555;
  };
};

int OnEventStatic(int a, float b)
{
  cout << "OnEventStatic " << a << " " << b << "\n";
  return 777;
};

void main()
{  
  A a;

  //connect to delegate
  delegate<int (int, float)> myEvent;

  myEvent.connect(&a, &A::OnEventInstance);
  myEvent.connect(&OnEventStatic);

  //simple invoke
  myEvent(1,2);

  //get returned values
  vector<int> returns = myEvent.invoke(3,4).get_results();
  
  //output to console
  copy(returns.begin(), returns.end(), ostream_iterator<int>(cout, " "));
}


Есть поддержка мультитридинга — нужно переопределить класс через макрос DEFAULT_CRITICAL_SECTION
Поддержка слотов (наподобие boost::signals) — см. класс default_slot

Для генерации некоторых шаблонов использовались python скрипты. Если кому нужно, спрашивайте.

Пользуйтесь наздоровье

03.03.06 19:08: Ветка выделена из темы [ANN] Fast C++ Delegate
Автор: SchweinDeBurg
Дата: 03.03.06
— Кодт
03.03.06 19:09: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.