Здравствуйте, 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:09: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт