#include<iostream>
#include<vector>
#include "Functional"
class TestA
{
public:
void FunNoparam()
{
std::cout << "Hello Delegate"<<std::endl;
};
void FunTwoParam(int a, int b)
{
std::cout << "a + b = " << a + b << std::endl;
}
};
typedef void (*FunMethodNoParam1)(void);
using FunMethodNoParam = void(TestA::*)(void);
#define DECLARE_DELEGATE(DelegateName)\
class F##DelegateName\
{\
public:\
void BindRaw2(TestA * UserClass, FunMethodNoParam FunPtr)\
{\
Fun = std::bind(FunPtr, UserClass); \
}\
bool IsBound()\
{\
return Fun ? true : false; \
}\
void Excute()\
{\
Fun(); \
}\
bool ExcuteIfBound()\
{\
if (IsBound())\
{\
Excute(); \
return true; \
}\
return false; \
}\
private:\
std::function<void()> Fun; \
};
typedef void (TestA::* FunMethodTwoParam1)(int, int);
using FunMethodTwoParam = void(TestA::*)(int, int);
#define DECLARE_DELEGATE_TwoParams(DelegateName, ParamType1, ParamType2)\
class F##DelegateName\
{\
public:\
void BindRaw2(TestA * UserClass, FunMethodTwoParam FunPtr, ParamType1 t1, ParamType2 t2)\
{\
Fun = std::bind(FunPtr, UserClass, t1, t2); \
}\
bool IsBound()\
{\
return Fun ? true : false; \
}\
void Excute()\
{\
Fun(); \
}\
bool ExcuteIfBound()\
{\
if (IsBound())\
{\
Excute(); \
return true; \
}\
return false; \
}\
private:\
std::function<void()> Fun; \
};
DECLARE_DELEGATE(TestDelegateNoParam);
DECLARE_DELEGATE_TwoParams(TestDelegateTwoParam, int, int);
template<typename Class,typename RetType,typename...ArgTypes>
struct TMemFunPtrType
{
typedef RetType(Class::* Type)(ArgTypes...);
};
template<typename RetValType,typename... ParamTypes>
class TBaseDelegate
{
public:
template<typename UserClass, typename... Types>
void BindRaw(UserClass* MyUserClass,
typename TMemFunPtrType<UserClass, RetValType, Types...>::Type FunPtr, Types... Vars)
{
Fun = std::bind(FunPtr, MyUserClass, Vars...);
}
bool IsBound()
{
return Fun ? true : false;
}
void Excute()
{
Fun();
}
bool ExcuteIfBound()
{
if (IsBound())
{
Excute();
return true;
}
return false;
}
private:
std::function<RetValType()>Fun;
};
#define DECLARE_DELEGATE(DelegateName) \
class DelegateName : public TBaseDelegate<void>{};
#define DECLARE_DELEGATE_TwoParam(DelegateName,ParamType1,ParamType2)\
class DelegateName : public TBaseDelegate<void, ParamType1, ParamType2>{};
#define DECLARE_DELEGATE_RetVal_TwoParam(RetType,DelegateName,ParamType1,ParamType2)\
class DelegateName : public TBaseDelegate<RetType, ParamType1, ParamType2>{};
DECLARE_DELEGATE(TestDelegateNameNoParam);
DECLARE_DELEGATE_TwoParam(TestDelegateTwoParam, int, int);
DECLARE_DELEGATE_RetVal_TwoParam(int, TestDelegateTwoParamRet, int, int);
class TestB
{
public:
void T()
{
std::cout << "Hello World !!!" << std::endl;
}
void TA(int a, int b)
{
std::cout << "a + b = " << a + b << std::endl;
}
int Minus(int c, int d)
{
std::cout << "c - d : " << std::endl;
return c - d;
}
};
int main()
{
TestDelegateNameNoParam TDelegate;
TestB ObjPtr;
TDelegate.BindRaw(&ObjPtr, &TestB::T);
TDelegate.Excute();
TestDelegateTwoParam Delegate;
Delegate.BindRaw(&ObjPtr, &TestB::TA, 90, 10);
Delegate.Excute();
TestDelegateTwoParamRet DelegateRet;
DelegateRet.BindRaw(&ObjPtr, &TestB::Minus, 100, 10);
DelegateRet.Excute();
system("pause");
}