#include <memory>
#include <iostream>
#include <functional>
template<class... Args>
class DelegateTemplate;
class Delegate
{
std::unique_ptr<Delegate> mPtr;
public:
virtual ~Delegate() { }
template<class R, class T, class... Args>
void RegisterFunction(R(*target)(Args...), T(*callback)(R), Args&&... args)
{
mPtr.reset(new DelegateTemplate<R(Args&&...), T(R)>(target, callback, std::forward<Args...>(args...)));
}
/*
template<class R, class S, class T, class... Args>
void RegisterFunction(R(S::*target)(Args...), S* obj, T(*callback)(R), Args... args)
{
mPtr.reset(new DelegateTemplate<R(Args...), T(R)>(target, obj, callback, args...));
}
*/
virtual void CallFunction()
{
mPtr->CallFunction();
}
};
template<class R, class T, class... Args>
class DelegateTemplate<R(Args&&...), T(R)> : public Delegate
{
typedef R target_result_type;
typedef T callback_result_type;
private:
std::function<R()> mTarget;
std::function<T(R)> mCallback;
public:
DelegateTemplate(R(*target)(Args...), T(*callback)(R), Args&&... args)
: mTarget(std::bind(target, std::forward<Args...>(args...)))
, mCallback(callback)
{
}
/*
template<class S>
DelegateTemplate(R(S::*target)(Args...), S* obj, T(*callback)(R), Args... args)
: mTarget(std::bind(target, obj, args...))
, mCallback(callback)
{
}
*/
~DelegateTemplate() { }
void CallFunction() override
{
mCallback(mTarget());
}
};
int Foo1(int i)
{
std::cout << "Foo1.i = " << i << std::endl;
return i;
}
void Callback1(int i)
{
std::cout << "Callback1.i = " << i << std::endl;
}
const char* Foo2(double r)
{
std::cout << "Foo2.r = " << r << std::endl;
return "hello world";
}
void Callback2(const char* str)
{
std::cout << "Callback1.str = " << str << std::endl;
}
class Test
{
public:
int Foo3(const char* str)
{
std::cout << "Test::Foo3.str = " << str << std::endl;
return 4;
}
};
int main()
{
Delegate d;
d.RegisterFunction(&Foo1, &Callback1, 42);
d.CallFunction();
double x = 500.100;
d.RegisterFunction(&Foo2, &Callback2, 44.0);
d.CallFunction();
/*
Test test;
d.RegisterFunction(&Test::Foo3, &test, Callback1, "hello from main");
d.CallFunction();
*/
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnRlbXBsYXRlPGNsYXNzLi4uIEFyZ3M+CmNsYXNzIERlbGVnYXRlVGVtcGxhdGU7CgpjbGFzcyBEZWxlZ2F0ZQp7CiAgICBzdGQ6OnVuaXF1ZV9wdHI8RGVsZWdhdGU+IG1QdHI7CnB1YmxpYzoKICAgIHZpcnR1YWwgfkRlbGVnYXRlKCkgeyB9CgogICAgdGVtcGxhdGU8Y2xhc3MgUiwgY2xhc3MgVCwgY2xhc3MuLi4gQXJncz4KICAgIHZvaWQgUmVnaXN0ZXJGdW5jdGlvbihSKCp0YXJnZXQpKEFyZ3MuLi4pLCBUKCpjYWxsYmFjaykoUiksIEFyZ3MmJi4uLiBhcmdzKQogICAgewogICAgICAgIG1QdHIucmVzZXQobmV3IERlbGVnYXRlVGVtcGxhdGU8UihBcmdzJiYuLi4pLCBUKFIpPih0YXJnZXQsIGNhbGxiYWNrLCBzdGQ6OmZvcndhcmQ8QXJncy4uLj4oYXJncy4uLikpKTsKICAgIH0KLyoKICAgIHRlbXBsYXRlPGNsYXNzIFIsIGNsYXNzIFMsIGNsYXNzIFQsIGNsYXNzLi4uIEFyZ3M+CiAgICB2b2lkIFJlZ2lzdGVyRnVuY3Rpb24oUihTOjoqdGFyZ2V0KShBcmdzLi4uKSwgUyogb2JqLCBUKCpjYWxsYmFjaykoUiksIEFyZ3MuLi4gYXJncykKICAgIHsKICAgICAgICBtUHRyLnJlc2V0KG5ldyBEZWxlZ2F0ZVRlbXBsYXRlPFIoQXJncy4uLiksIFQoUik+KHRhcmdldCwgb2JqLCBjYWxsYmFjaywgYXJncy4uLikpOwogICAgfQoqLwogICAgdmlydHVhbCB2b2lkIENhbGxGdW5jdGlvbigpCiAgICB7CiAgICAgICAgbVB0ci0+Q2FsbEZ1bmN0aW9uKCk7CiAgICB9Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBSLCBjbGFzcyBULCBjbGFzcy4uLiBBcmdzPgpjbGFzcyBEZWxlZ2F0ZVRlbXBsYXRlPFIoQXJncyYmLi4uKSwgVChSKT4gOiBwdWJsaWMgRGVsZWdhdGUKewoJdHlwZWRlZiBSIHRhcmdldF9yZXN1bHRfdHlwZTsKCXR5cGVkZWYgVCBjYWxsYmFja19yZXN1bHRfdHlwZTsKcHJpdmF0ZToKICAgIHN0ZDo6ZnVuY3Rpb248UigpPiBtVGFyZ2V0OwogICAgc3RkOjpmdW5jdGlvbjxUKFIpPiBtQ2FsbGJhY2s7CnB1YmxpYzoKICAgIERlbGVnYXRlVGVtcGxhdGUoUigqdGFyZ2V0KShBcmdzLi4uKSwgVCgqY2FsbGJhY2spKFIpLCBBcmdzJiYuLi4gYXJncykKICAgIDogbVRhcmdldChzdGQ6OmJpbmQodGFyZ2V0LCBzdGQ6OmZvcndhcmQ8QXJncy4uLj4oYXJncy4uLikpKQogICAgLCBtQ2FsbGJhY2soY2FsbGJhY2spCiAgICB7CiAgICB9Ci8qCiAgICB0ZW1wbGF0ZTxjbGFzcyBTPgogICAgRGVsZWdhdGVUZW1wbGF0ZShSKFM6Oip0YXJnZXQpKEFyZ3MuLi4pLCBTKiBvYmosIFQoKmNhbGxiYWNrKShSKSwgQXJncy4uLiBhcmdzKQogICAgOiBtVGFyZ2V0KHN0ZDo6YmluZCh0YXJnZXQsIG9iaiwgYXJncy4uLikpCiAgICAsIG1DYWxsYmFjayhjYWxsYmFjaykKICAgIHsKICAgIH0KKi8KICAgIH5EZWxlZ2F0ZVRlbXBsYXRlKCkgeyB9CgogICAgdm9pZCBDYWxsRnVuY3Rpb24oKSBvdmVycmlkZQogICAgewogICAgICAgIG1DYWxsYmFjayhtVGFyZ2V0KCkpOwogICAgfQp9OwoKaW50IEZvbzEoaW50IGkpCnsKICAgIHN0ZDo6Y291dCA8PCAiRm9vMS5pID0gIiA8PCBpIDw8IHN0ZDo6ZW5kbDsKICAgIHJldHVybiBpOwp9Cgp2b2lkIENhbGxiYWNrMShpbnQgaSkKewogICAgc3RkOjpjb3V0IDw8ICJDYWxsYmFjazEuaSA9ICIgPDwgaSA8PCBzdGQ6OmVuZGw7Cn0KCmNvbnN0IGNoYXIqIEZvbzIoZG91YmxlIHIpCnsKICAgIHN0ZDo6Y291dCA8PCAiRm9vMi5yID0gIiA8PCByIDw8IHN0ZDo6ZW5kbDsKICAgIHJldHVybiAiaGVsbG8gd29ybGQiOwp9Cgp2b2lkIENhbGxiYWNrMihjb25zdCBjaGFyKiBzdHIpCnsKICAgIHN0ZDo6Y291dCA8PCAiQ2FsbGJhY2sxLnN0ciA9ICIgPDwgc3RyIDw8IHN0ZDo6ZW5kbDsKfQoKY2xhc3MgVGVzdAp7CnB1YmxpYzoKICAgIGludCBGb28zKGNvbnN0IGNoYXIqIHN0cikKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgIlRlc3Q6OkZvbzMuc3RyID0gIiA8PCBzdHIgPDwgc3RkOjplbmRsOwogICAgICAgIHJldHVybiA0OwogICAgfQp9OwoKaW50IG1haW4oKQp7CiAgICBEZWxlZ2F0ZSBkOwogICAgZC5SZWdpc3RlckZ1bmN0aW9uKCZGb28xLCAmQ2FsbGJhY2sxLCA0Mik7CiAgICBkLkNhbGxGdW5jdGlvbigpOwoKICAgIAogICAgZG91YmxlIHggPSA1MDAuMTAwOwogICAgZC5SZWdpc3RlckZ1bmN0aW9uKCZGb28yLCAmQ2FsbGJhY2syLCA0NC4wKTsKICAgIGQuQ2FsbEZ1bmN0aW9uKCk7Ci8qCiAgICBUZXN0IHRlc3Q7CiAgICBkLlJlZ2lzdGVyRnVuY3Rpb24oJlRlc3Q6OkZvbzMsICZ0ZXN0LCBDYWxsYmFjazEsICJoZWxsbyBmcm9tIG1haW4iKTsKICAgIGQuQ2FsbEZ1bmN0aW9uKCk7CiovCn0=