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