#include <iostream>
using namespace std;
typedef int (*ptr1)(int, int);
int add1(int a, int b){return a+b;}
typedef double (*ptr2)(double, double, double);
double add2(double a, double b, double c){return a+b+c;}
template <typename TResult>
class executor{
class executable;
template<typename T1, typename T2, typename Func>
class _e2;
public:
template <typename T1, typename T2, typename Func>
executor(T1 arg1, T2 arg2, Func f) : e(new _e2<T1,T2,Func>(arg1, arg2, f)){}
template <typename T1, typename T2, typename T3, typename Func>
executor(T1 arg1, T2 arg2, T3 arg3, Func f) : e(new _e3<T1,T2,T3,Func>(arg1, arg2, arg3, f)){}
TResult execute() {return e->execute();}
private:
executable *e;
private:
class executable{
public:
virtual TResult execute() = 0;
};
template<typename T1, typename T2, typename Func>
class _e2 : public executable{
public:
_e2(T1 arg1, T2 arg2, Func f) : _arg1(arg1), _arg2(arg2), _f(f) {}
public:
TResult execute() {return _f(_arg1, _arg2);}
private:
T1 _arg1;
T2 _arg2;
Func _f;
};
template<typename T1, typename T2, typename T3, typename Func>
class _e3 : public executable{
public:
_e3(T1 arg1, T2 arg2, T3 arg3, Func f) : _arg1(arg1), _arg2(arg2), _arg3(arg3), _f(f) {}
public:
TResult execute() {return _f(_arg1, _arg2, _arg3);}
private:
T1 _arg1;
T2 _arg2;
T3 _arg3;
Func _f;
};
};
int main()
{
executor<int> etor(1, 1, add1);
cout << etor.execute() << endl;
executor<double> etor2(1.0, 1.0, 1.0, add2);
cout << etor2.execute() << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiBpbnQgKCpwdHIxKShpbnQsIGludCk7CmludCBhZGQxKGludCBhLCBpbnQgYil7cmV0dXJuIGErYjt9Cgp0eXBlZGVmIGRvdWJsZSAoKnB0cjIpKGRvdWJsZSwgZG91YmxlLCBkb3VibGUpOwpkb3VibGUgYWRkMihkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjKXtyZXR1cm4gYStiK2M7fQoKdGVtcGxhdGUgPHR5cGVuYW1lIFRSZXN1bHQ+CmNsYXNzIGV4ZWN1dG9yewogICAgY2xhc3MgZXhlY3V0YWJsZTsKICAgIAogICAgdGVtcGxhdGU8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyLCB0eXBlbmFtZSBGdW5jPgogICAgY2xhc3MgX2UyOwpwdWJsaWM6CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyLCB0eXBlbmFtZSBGdW5jPgogICAgZXhlY3V0b3IoVDEgYXJnMSwgVDIgYXJnMiwgRnVuYyBmKSA6IGUobmV3IF9lMjxUMSxUMixGdW5jPihhcmcxLCBhcmcyLCBmKSl7fQogICAgCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyLCB0eXBlbmFtZSBUMywgdHlwZW5hbWUgRnVuYz4KICAgIGV4ZWN1dG9yKFQxIGFyZzEsIFQyIGFyZzIsIFQzIGFyZzMsIEZ1bmMgZikgOiBlKG5ldyBfZTM8VDEsVDIsVDMsRnVuYz4oYXJnMSwgYXJnMiwgYXJnMywgZikpe30KICAgIAogICAgCiAgICBUUmVzdWx0IGV4ZWN1dGUoKSB7cmV0dXJuIGUtPmV4ZWN1dGUoKTt9CnByaXZhdGU6CiAgICBleGVjdXRhYmxlICplOwpwcml2YXRlOgogICAgY2xhc3MgZXhlY3V0YWJsZXsKICAgIHB1YmxpYzoKICAgICAgICB2aXJ0dWFsIFRSZXN1bHQgZXhlY3V0ZSgpID0gMDsKICAgIH07CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMiwgdHlwZW5hbWUgRnVuYz4KICAgIGNsYXNzIF9lMiA6IHB1YmxpYyBleGVjdXRhYmxlewogICAgcHVibGljOgogICAgICAgIF9lMihUMSBhcmcxLCBUMiBhcmcyLCBGdW5jIGYpIDogX2FyZzEoYXJnMSksIF9hcmcyKGFyZzIpLCBfZihmKSB7fQogICAgcHVibGljOgogICAgICAgIFRSZXN1bHQgZXhlY3V0ZSgpIHtyZXR1cm4gX2YoX2FyZzEsIF9hcmcyKTt9CiAgICBwcml2YXRlOgogICAgICAgIFQxIF9hcmcxOwogICAgICAgIFQyIF9hcmcyOwogICAgICAgIEZ1bmMgX2Y7CiAgICB9OwogICAgCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDIsIHR5cGVuYW1lIFQzLCB0eXBlbmFtZSBGdW5jPgogICAgY2xhc3MgX2UzIDogcHVibGljIGV4ZWN1dGFibGV7CiAgICBwdWJsaWM6CiAgICAgICAgX2UzKFQxIGFyZzEsIFQyIGFyZzIsIFQzIGFyZzMsIEZ1bmMgZikgOiBfYXJnMShhcmcxKSwgX2FyZzIoYXJnMiksIF9hcmczKGFyZzMpLCBfZihmKSB7fQogICAgcHVibGljOgogICAgICAgIFRSZXN1bHQgZXhlY3V0ZSgpIHtyZXR1cm4gX2YoX2FyZzEsIF9hcmcyLCBfYXJnMyk7fQogICAgcHJpdmF0ZToKICAgICAgICBUMSBfYXJnMTsKICAgICAgICBUMiBfYXJnMjsKICAgICAgICBUMyBfYXJnMzsKICAgICAgICBGdW5jIF9mOwogICAgfTsKfTsKCgppbnQgbWFpbigpCnsKICAgIGV4ZWN1dG9yPGludD4gZXRvcigxLCAxLCBhZGQxKTsKICAgIGNvdXQgPDwgZXRvci5leGVjdXRlKCkgPDwgZW5kbDsKICAgIAogICAgZXhlY3V0b3I8ZG91YmxlPiBldG9yMigxLjAsIDEuMCwgMS4wLCBhZGQyKTsKICAgIGNvdXQgPDwgZXRvcjIuZXhlY3V0ZSgpIDw8IGVuZGw7CiAgICAKICAgIHJldHVybiAwOwp9Cg==