Advertisement
Guest User

Untitled

a guest
Aug 22nd, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.87 KB | None | 0 0
  1. #pragma once
  2.  
  3. template <typename Return_type, typename ...Args>
  4. constexpr auto curry(Return_type (*fun)(std::tuple<Args...>)) {
  5.     struct Curry_helper {
  6.         constexpr Curry_helper(Return_type (*fun)(std::tuple<Args...>)) :
  7.             fun(fun)
  8.         {}
  9.         Return_type (*const fun)(std::tuple<Args...>);
  10.  
  11.         auto constexpr operator()(Args ...args) const {
  12.             return fun(std::make_tuple(args...));
  13.         }
  14.     } ret(fun);
  15.     return ret;
  16. }
  17.  
  18. namespace tuple_details {
  19.  
  20. template <typename Func>
  21. struct Curry_helper {};
  22.  
  23. template <typename Func, typename Return_type, typename ...Args>
  24. struct Curry_helper<Return_type (Func::*)(std::tuple<Args...>)> {
  25.     constexpr Curry_helper(Func func) :
  26.         func(func)
  27.     {}
  28.     Func const func;
  29.  
  30.     auto constexpr operator()(Args ...args) const {
  31.         return func(std::make_tuple(args...));
  32.     }
  33. };
  34.  
  35. template <size_t ...I>
  36. struct I_container;
  37.  
  38. template <size_t i, typename added>
  39. struct I_container_adder;
  40.  
  41. template <size_t i, size_t ...I>
  42. struct I_container_adder<i, I_container<I...>> {
  43.     using val = I_container<I..., i>;
  44. };
  45.  
  46. template <size_t i>
  47. struct I_container_helper {
  48.     using val = typename I_container_adder<i - 1, typename I_container_helper<i - 1>::val>::val;
  49. };
  50.  
  51. template <>
  52. struct I_container_helper<0> {
  53.     using val = I_container<>;
  54. };
  55.  
  56. template <typename T, typename U>
  57. struct apply;
  58.  
  59. template <typename ...Args, size_t ...I>
  60. struct apply<std::tuple<Args...>, I_container<I...>> {
  61.     template <typename Functor>
  62.     constexpr static auto val(Functor fun, std::tuple<Args...> tup) {
  63.         return fun(std::get<I>(tup)...);
  64.     }
  65. };
  66.  
  67. template <typename>
  68. struct Uncurry_helper;
  69.  
  70. template <typename Func, typename Return_type, typename ...Args>
  71. struct Uncurry_helper<Return_type (Func::*)(Args...)> {
  72.     constexpr Uncurry_helper(Func func) :
  73.         func(func)
  74.     {}
  75.     Func const func;
  76.  
  77.     auto constexpr operator()(std::tuple<Args...> tup) const {
  78.         using tuple_type = std::tuple<Args...>;
  79.         return apply<tuple_type, typename I_container_helper<std::tuple_size<tuple_type>::value>::val>::val(func, tup);
  80.     }
  81. };
  82.  
  83. } // end of namespace tuple_details
  84.  
  85. template <typename Functor>
  86. constexpr auto curry(Functor func) {
  87.     return tuple_details::Curry_helper<decltype(&Functor::operator())>(func);
  88. }
  89.  
  90. template <typename Return_type, typename ...Args>
  91. constexpr auto uncurry(Return_type (*fun)(Args...)) {
  92.     struct Uncurry_helper {
  93.         constexpr Uncurry_helper(Return_type (*fun)(Args...)) :
  94.             fun(fun)
  95.         {}
  96.         Return_type (*const fun)(Args...);
  97.  
  98.         auto constexpr operator()(std::tuple<Args...> tup) const {
  99.             using tuple_type = std::tuple<Args...>;
  100.             return tuple_details::apply<tuple_type, typename tuple_details::I_container_helper<std::tuple_size<tuple_type>::value>::val>::val(fun, tup);
  101.         }
  102.     } ret(fun);
  103.     return ret;
  104. }
  105.  
  106. template <typename Functor>
  107. constexpr auto uncurry(Functor func) {
  108.     return tuple_details::Uncurry_helper<decltype(&Functor::operator())>(func);;
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement