#ifndef CPPDELEGATE_H_E100A24F_F4CD_4D35_AED1_C5BE1FBD1CDD #define CPPDELEGATE_H_E100A24F_F4CD_4D35_AED1_C5BE1FBD1CDD #include using namespace std; template class DelegateBase { protected: typedef DelegateBase DLGTBASE; private: T* obj; F func; protected: DelegateBase(T* t, F f) : obj(t), func(f){} DelegateBase(F f) : obj((void*)0), func(f){} T* GetObject(){return obj;} F GetFunction(){return func;} bool Equals(DLGTBASE* other){return obj == other->obj && func == other->func;} }; template class DelegateX { protected: typedef _DLGT* DLGT; private: list m_list; class Remover : public unary_function { private: DLGT comparand; public: Remover(DLGT p) : comparand(p){} bool operator() (DLGT& p){return comparand->Equals(p);} }; protected: DelegateX(){m_list.push_back(static_cast(this));} void CopyInnerList(list& var){var.assign(m_list.begin(), m_list.end());} virtual bool Equals(DLGT dlgt) = 0; public: void Add(DLGT p) { for (list::iterator i = p->m_list.begin(); i != p->m_list.end(); i++) m_list.push_back(*i); } void Remove(DLGT p) { for (list::iterator i = p->m_list.begin(); i != p->m_list.end(); i++) m_list.remove_if(Remover(*i)); } void operator +=(DLGT p){return Add(p);} void operator -=(DLGT p){return Remove(p);} }; //R DelegateA0(); template class DelegateA0 : public DelegateX> { protected: virtual R Invoke() = 0; public: R Call() { list dlgtx; CopyInnerList(dlgtx); for (list::iterator i = dlgtx.begin(); i != --dlgtx.end(); i++) (*i)->Invoke(); return dlgtx.back()->Invoke(); } R operator ()(){return Call();} }; template class DelegateA0I : public DelegateBase, public DelegateA0 { protected: R Invoke() {return (GetObject()->*GetFunction())();} bool Equals(DLGT dlgt) {return DLGTBASE::Equals(static_cast*>(dlgt));} public: DelegateA0I(T* t, R (T::*f)()) : DLGTBASE(t, f){} }; template DelegateA0* CreateDelegate(T* obj, R (T::*f)()){return new DelegateA0I(obj, f);} template class DelegateA0S : public DelegateBase, public DelegateA0 { protected: R Invoke() {return (GetFunction())();} bool Equals(DLGT dlgt) {return DLGTBASE::Equals(static_cast*>(dlgt));} public: DelegateA0S(R (*f)()) : DLGTBASE(f){} }; template DelegateA0* CreateDelegate(R (*f)()){return new DelegateA0S(f);} //R DelegateA1(A1); template class DelegateA1 : public DelegateX> { protected: virtual R Invoke(A1 a1) = 0; public: R Call(A1 a1) { list dlgtx; CopyInnerList(dlgtx); for (list::iterator i = dlgtx.begin(); i != --dlgtx.end(); i++) (*i)->Invoke(a1); return dlgtx.back()->Invoke(a1); } R operator ()(A1 a1){return Call(a1);} }; template class DelegateA1I : public DelegateBase, public DelegateA1 { protected: R Invoke(A1 a1) {return (GetObject()->*GetFunction())(a1);} bool Equals(DLGT dlgt) {return DLGTBASE::Equals(static_cast*>(dlgt));} public: DelegateA1I(T* t, R (T::*f)(A1)) : DLGTBASE(t, f){} }; template DelegateA1* CreateDelegate(T* obj, R (T::*f)(A1)){return new DelegateA1I(obj, f);} template class DelegateA1S : public DelegateBase, public DelegateA1 { protected: R Invoke(A1 a1) {return (GetFunction())(a1);} bool Equals(DLGT dlgt) {return DLGTBASE::Equals(static_cast*>(dlgt));} public: DelegateA1S(R (*f)(A1)) : DLGTBASE(f){} }; template DelegateA1* CreateDelegate(R (*f)(A1)){return new DelegateA1S(f);} //R DelegateA2(A1, A2); template class DelegateA2 : public DelegateX> { protected: virtual R Invoke(A1 a1, A2 a2) = 0; public: R Call(A1 a1, A2 a2) { list dlgtx; CopyInnerList(dlgtx); for (list::iterator i = dlgtx.begin(); i != --dlgtx.end(); i++) (*i)->Invoke(a1, a2); return dlgtx.back()->Invoke(a1, a2); } R operator ()(A1 a1, A2 a2){return Call(a1, a2);} }; template class DelegateA2I : public DelegateBase, public DelegateA2 { protected: R Invoke(A1 a1, A2 a2) {return (GetObject()->*GetFunction())(a1, a2);} bool Equals(DLGT dlgt) {return DLGTBASE::Equals(static_cast*>(dlgt));} public: DelegateA2I(T* t, R (T::*f)(A1, A2)) : DLGTBASE(t, f){} }; template DelegateA2* CreateDelegate(T* obj, R (T::*f)(A1, A2)){return new DelegateA2I(obj, f);} template class DelegateA2S : public DelegateBase, public DelegateA2 { protected: R Invoke(A1 a1, A2 a2) {return (GetFunction())(a1, a2);} bool Equals(DLGT dlgt) {return DLGTBASE::Equals(static_cast*>(dlgt));} public: DelegateA2S(R (*f)(A1, A2)) : DLGTBASE(f){} }; template DelegateA2* CreateDelegate(R (*f)(A1, A2)){return new DelegateA2S(f);} #endif //CPPDELEGATE_H_E100A24F_F4CD_4D35_AED1_C5BE1FBD1CDD