1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #include <iostream> #include <functional> template <typename> class curry; template <typename _Res> class curry< _Res() > { public: typedef std::function< _Res() > _Fun; typedef _Res _Ret; private: _Fun _fun; public: explicit curry (_Fun fun) : _fun(fun) { } operator _Ret () { return _fun(); } }; template <typename> class decurry; template <typename _Res, typename _Arg, typename... _Args> class curry< _Res(_Arg, _Args...) > { public: typedef std::function< _Res(_Arg, _Args...) > _Fun; typedef curry< _Res(_Args...) > _Ret; private: class apply { private: _Fun _fun; _Arg _arg; public: apply (_Fun fun, _Arg arg) : _fun(fun), _arg(arg) { } _Res operator() (_Args... args) { return _fun(_arg, args...); } }; private: _Fun _fun; public: explicit curry (_Fun fun) : _fun(fun) { } _Ret operator() (_Arg arg) { return _Ret(apply(_fun, arg)); } friend class decurry< curry<_Res(_Arg, _Args...)> >; }; template <typename> class decurry; template <typename _Res, typename... _Args> class decurry< curry<_Res(_Args...)> > { public: typedef curry<_Res(_Args...)> _Curried; typedef typename curry<_Res(_Args...)>::_Fun _Raw; decurry(_Curried fn): _fn(fn) {} _Res operator() (_Args... rest) { return _fn._fun(rest...); } private: _Curried _fn; }; template <typename _Res, typename _Res2, typename... _Args2, typename... _Args> class curry< _Res(_Res2(_Args2...), _Args...) > { public: typedef curry< _Res2(_Args2...) > _Arg; typedef std::function< _Res2(_Args2...) > _RawFun; typedef std::function< _Res(_RawFun, _Args...) > _Fun; typedef curry< _Res(_Args...) > _Ret; private: class apply { private: _Fun _fun; _RawFun _arg; public: apply (_Fun fun, _RawFun arg) : _fun(fun), _arg(arg) { } _Res operator() (_Args... args) { return _fun(_arg, args...); } }; private: _Fun _fun; public: explicit curry (_Fun fun) : _fun(fun) { } _Ret operator() (_Arg arg) { return _Ret(apply(_fun, decurry<_Arg>(arg))); } }; int test(std::function<int(int,int)> f, int x) { return f(3, 4) * x; } int main () { auto func_xy = curry<int(int(int,int),int)>(test); auto plus_xy = curry<int(int,int)>(std::plus<int>()); auto func_px = func_xy(plus_xy); auto func_p5 = func_px(5); std::cout << func_p5 << std::endl; return 0; } |
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnRlbXBsYXRlIDx0eXBlbmFtZT4gY2xhc3MgY3Vycnk7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgX1Jlcz4KY2xhc3MgY3Vycnk8IF9SZXMoKSA+CnsKcHVibGljOgogICAgdHlwZWRlZiBzdGQ6OmZ1bmN0aW9uPCBfUmVzKCkgPiBfRnVuOwogICAgdHlwZWRlZiBfUmVzIF9SZXQ7Cgpwcml2YXRlOgogICAgX0Z1biBfZnVuOwoKcHVibGljOgogICAgZXhwbGljaXQgY3VycnkgKF9GdW4gZnVuKQogICAgICAgIDogX2Z1bihmdW4pIHsgfQoKICAgIG9wZXJhdG9yIF9SZXQgKCkKICAgIHsgcmV0dXJuIF9mdW4oKTsgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lPgpjbGFzcyBkZWN1cnJ5OwoKdGVtcGxhdGUgPHR5cGVuYW1lIF9SZXMsIHR5cGVuYW1lIF9BcmcsIHR5cGVuYW1lLi4uIF9BcmdzPgpjbGFzcyBjdXJyeTwgX1JlcyhfQXJnLCBfQXJncy4uLikgPgp7CnB1YmxpYzoKICAgIHR5cGVkZWYgc3RkOjpmdW5jdGlvbjwgX1JlcyhfQXJnLCBfQXJncy4uLikgPiBfRnVuOwogICAgdHlwZWRlZiBjdXJyeTwgX1JlcyhfQXJncy4uLikgPiBfUmV0OwoKcHJpdmF0ZToKICAgIGNsYXNzIGFwcGx5CiAgICB7CiAgICBwcml2YXRlOgogICAgICAgIF9GdW4gX2Z1bjsKICAgICAgICBfQXJnIF9hcmc7CgogICAgcHVibGljOgogICAgICAgIGFwcGx5IChfRnVuIGZ1biwgX0FyZyBhcmcpCiAgICAgICAgICAgIDogX2Z1bihmdW4pLCBfYXJnKGFyZykgeyB9CgogICAgICAgIF9SZXMgb3BlcmF0b3IoKSAoX0FyZ3MuLi4gYXJncykKICAgICAgICB7IHJldHVybiBfZnVuKF9hcmcsIGFyZ3MuLi4pOyB9CiAgICB9OwoKcHJpdmF0ZToKICAgIF9GdW4gX2Z1bjsKCnB1YmxpYzoKICAgIGV4cGxpY2l0IGN1cnJ5IChfRnVuIGZ1bikKICAgICAgICA6IF9mdW4oZnVuKSB7IH0KCiAgICBfUmV0IG9wZXJhdG9yKCkgKF9BcmcgYXJnKQogICAgeyByZXR1cm4gX1JldChhcHBseShfZnVuLCBhcmcpKTsgfQoKCiAgICBmcmllbmQgY2xhc3MgZGVjdXJyeTwgY3Vycnk8X1JlcyhfQXJnLCBfQXJncy4uLik+ID47Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWU+CmNsYXNzIGRlY3Vycnk7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgX1JlcywgdHlwZW5hbWUuLi4gX0FyZ3M+CmNsYXNzIGRlY3Vycnk8IGN1cnJ5PF9SZXMoX0FyZ3MuLi4pPiA+IHsKcHVibGljOgogICAgdHlwZWRlZiBjdXJyeTxfUmVzKF9BcmdzLi4uKT4gX0N1cnJpZWQ7CiAgICB0eXBlZGVmIHR5cGVuYW1lIGN1cnJ5PF9SZXMoX0FyZ3MuLi4pPjo6X0Z1biBfUmF3OwoKICAgIGRlY3VycnkoX0N1cnJpZWQgZm4pOiBfZm4oZm4pIHt9CgogICAgX1JlcyBvcGVyYXRvcigpIChfQXJncy4uLiByZXN0KSB7CiAgICAgICAgcmV0dXJuIF9mbi5fZnVuKHJlc3QuLi4pOwogICAgfQpwcml2YXRlOgogICAgX0N1cnJpZWQgX2ZuOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIF9SZXMsIHR5cGVuYW1lIF9SZXMyLCB0eXBlbmFtZS4uLiBfQXJnczIsIHR5cGVuYW1lLi4uIF9BcmdzPgpjbGFzcyBjdXJyeTwgX1JlcyhfUmVzMihfQXJnczIuLi4pLCBfQXJncy4uLikgPgp7CnB1YmxpYzoKICAgIHR5cGVkZWYgY3Vycnk8IF9SZXMyKF9BcmdzMi4uLikgPiBfQXJnOwogICAgdHlwZWRlZiBzdGQ6OmZ1bmN0aW9uPCBfUmVzMihfQXJnczIuLi4pID4gX1Jhd0Z1bjsKICAgIHR5cGVkZWYgc3RkOjpmdW5jdGlvbjwgX1JlcyhfUmF3RnVuLCBfQXJncy4uLikgPiBfRnVuOwogICAgdHlwZWRlZiBjdXJyeTwgX1JlcyhfQXJncy4uLikgPiBfUmV0OwoKcHJpdmF0ZToKICAgIGNsYXNzIGFwcGx5CiAgICB7CiAgICBwcml2YXRlOgogICAgICAgIF9GdW4gX2Z1bjsKICAgICAgICBfUmF3RnVuIF9hcmc7CgogICAgcHVibGljOgogICAgICAgIGFwcGx5IChfRnVuIGZ1biwgX1Jhd0Z1biBhcmcpCiAgICAgICAgICAgIDogX2Z1bihmdW4pLCBfYXJnKGFyZykgeyB9CgogICAgICAgIF9SZXMgb3BlcmF0b3IoKSAoX0FyZ3MuLi4gYXJncykKICAgICAgICB7IHJldHVybiBfZnVuKF9hcmcsIGFyZ3MuLi4pOyB9CiAgICB9OwoKcHJpdmF0ZToKICAgIF9GdW4gX2Z1bjsKCnB1YmxpYzoKICAgIGV4cGxpY2l0IGN1cnJ5IChfRnVuIGZ1bikKICAgICAgICA6IF9mdW4oZnVuKSB7IH0KCiAgICBfUmV0IG9wZXJhdG9yKCkgKF9BcmcgYXJnKQogICAgeyByZXR1cm4gX1JldChhcHBseShfZnVuLCBkZWN1cnJ5PF9Bcmc+KGFyZykpKTsgfQp9OwoKaW50IHRlc3Qoc3RkOjpmdW5jdGlvbjxpbnQoaW50LGludCk+IGYsIGludCB4KQp7IHJldHVybiBmKDMsIDQpICogeDsgfQoKaW50IG1haW4gKCkKewogICAgYXV0byBmdW5jX3h5ID0gY3Vycnk8aW50KGludChpbnQsaW50KSxpbnQpPih0ZXN0KTsKICAgIGF1dG8gcGx1c194eSA9IGN1cnJ5PGludChpbnQsaW50KT4oc3RkOjpwbHVzPGludD4oKSk7CiAgICBhdXRvIGZ1bmNfcHggPSBmdW5jX3h5KHBsdXNfeHkpOwogICAgYXV0byBmdW5jX3A1ID0gZnVuY19weCg1KTsKICAgIHN0ZDo6Y291dCA8PCBmdW5jX3A1IDw8IHN0ZDo6ZW5kbDsKCiAgICByZXR1cm4gMDsKfQo=
-
upload with new input
-
result: Success time: 0s memory: 2968 kB returned value: 0
35


