Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

244 Zeilen
10 KiB

  1. #pragma once
  2. #include <utility>
  3. #include <cpputils/mp/misc/when.h>
  4. namespace utl {
  5. namespace mp {
  6. namespace intern {
  7. namespace __impl
  8. {
  9. template <unsigned int n, typename = when<true>>
  10. struct fold_right_impl;
  11. template<>
  12. struct fold_right_impl<1>
  13. {
  14. template<typename F, typename X1>
  15. static constexpr X1 apply(F&&, X1&& x1)
  16. { return std::forward<X1>(x1); }
  17. };
  18. template<>
  19. struct fold_right_impl<2>
  20. {
  21. template<typename F, typename X1, typename X2>
  22. static constexpr auto apply(F&& f, X1&& x1, X2&& x2)
  23. {
  24. return f(
  25. std::forward<X1>(x1),
  26. std::forward<X2>(x2));
  27. }
  28. };
  29. template<>
  30. struct fold_right_impl<3>
  31. {
  32. template<typename F, typename X1, typename X2, typename X3>
  33. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3)
  34. {
  35. return f(std::forward<X1>(x1),
  36. f(std::forward<X2>(x2),
  37. std::forward<X3>(x3)));
  38. }
  39. };
  40. template<>
  41. struct fold_right_impl<4>
  42. {
  43. template<typename F, typename X1, typename X2, typename X3, typename X4>
  44. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4)
  45. {
  46. return f(std::forward<X1>(x1),
  47. f(std::forward<X2>(x2),
  48. f(std::forward<X3>(x3),
  49. std::forward<X4>(x4))));
  50. }
  51. };
  52. template<>
  53. struct fold_right_impl<5>
  54. {
  55. template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
  56. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5)
  57. {
  58. return f(std::forward<X1>(x1),
  59. f(std::forward<X2>(x2),
  60. f(std::forward<X3>(x3),
  61. f(std::forward<X4>(x4),
  62. std::forward<X5>(x5)))));
  63. }
  64. };
  65. template<>
  66. struct fold_right_impl<6>
  67. {
  68. template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
  69. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6)
  70. {
  71. return f(std::forward<X1>(x1),
  72. f(std::forward<X2>(x2),
  73. f(std::forward<X3>(x3),
  74. f(std::forward<X4>(x4),
  75. f(std::forward<X5>(x5),
  76. std::forward<X6>(x6))))));
  77. }
  78. };
  79. template<>
  80. struct fold_right_impl<7>
  81. {
  82. template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7>
  83. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7)
  84. {
  85. return f(std::forward<X1>(x1),
  86. f(std::forward<X2>(x2),
  87. f(std::forward<X3>(x3),
  88. f(std::forward<X4>(x4),
  89. f(std::forward<X5>(x5),
  90. f(std::forward<X6>(x6),
  91. std::forward<X7>(x7)))))));
  92. }
  93. };
  94. template<>
  95. struct fold_right_impl<8>
  96. {
  97. template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8>
  98. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8)
  99. {
  100. return f(std::forward<X1>(x1),
  101. f(std::forward<X2>(x2),
  102. f(std::forward<X3>(x3),
  103. f(std::forward<X4>(x4),
  104. f(std::forward<X5>(x5),
  105. f(std::forward<X6>(x6),
  106. f(std::forward<X7>(x7),
  107. std::forward<X8>(x8))))))));
  108. }
  109. };
  110. template<unsigned int n>
  111. struct fold_right_impl<n, when<(n >= 9) && (n < 18)>>
  112. {
  113. template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, typename... Xn>
  114. static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, Xn&&... xn)
  115. {
  116. return f(std::forward<X1>(x1),
  117. f(std::forward<X2>(x2),
  118. f(std::forward<X3>(x3),
  119. f(std::forward<X4>(x4),
  120. f(std::forward<X5>(x5),
  121. f(std::forward<X6>(x6),
  122. f(std::forward<X7>(x7),
  123. f(std::forward<X8>(x8),
  124. fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X9>(x9), std::forward<Xn>(xn)...)))))))));
  125. }
  126. };
  127. template<unsigned int n>
  128. struct fold_right_impl<n, when<(n >= 18) && (n < 36)>>
  129. {
  130. template<
  131. typename F,
  132. typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9,
  133. typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18,
  134. typename... Xn>
  135. static constexpr auto apply(
  136. F&& f,
  137. X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9,
  138. X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18,
  139. Xn&&... xn)
  140. {
  141. return f(std::forward<X1> (x1),
  142. f(std::forward<X2> (x2),
  143. f(std::forward<X3> (x3),
  144. f(std::forward<X4> (x4),
  145. f(std::forward<X5> (x5),
  146. f(std::forward<X6> (x6),
  147. f(std::forward<X7> (x7),
  148. f(std::forward<X8> (x8),
  149. f(std::forward<X9> (x9),
  150. f(std::forward<X10>(x10),
  151. f(std::forward<X11>(x11),
  152. f(std::forward<X12>(x12),
  153. f(std::forward<X13>(x13),
  154. f(std::forward<X14>(x14),
  155. f(std::forward<X15>(x15),
  156. f(std::forward<X16>(x16),
  157. f(std::forward<X17>(x17),
  158. fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X18>(x18), std::forward<Xn>(xn)...))))))))))))))))));
  159. }
  160. };
  161. template<unsigned int n>
  162. struct fold_right_impl<n, when<(n >= 36)>>
  163. {
  164. template<
  165. typename F,
  166. typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9,
  167. typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18,
  168. typename X19, typename X20, typename X21, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27,
  169. typename X28, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35, typename X36,
  170. typename... Xn>
  171. static constexpr auto apply(
  172. F&& f,
  173. X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9,
  174. X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18,
  175. X19&& x19, X20&& x20, X21&& x21, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27,
  176. X28&& x28, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35, X36&& x36,
  177. Xn&&... xn)
  178. {
  179. return f(std::forward<X1> (x1),
  180. f(std::forward<X2> (x2),
  181. f(std::forward<X3> (x3),
  182. f(std::forward<X4> (x4),
  183. f(std::forward<X5> (x5),
  184. f(std::forward<X6> (x6),
  185. f(std::forward<X7> (x7),
  186. f(std::forward<X8> (x8),
  187. f(std::forward<X9> (x9),
  188. f(std::forward<X10>(x10),
  189. f(std::forward<X11>(x11),
  190. f(std::forward<X12>(x12),
  191. f(std::forward<X13>(x13),
  192. f(std::forward<X14>(x14),
  193. f(std::forward<X15>(x15),
  194. f(std::forward<X16>(x16),
  195. f(std::forward<X17>(x17),
  196. f(std::forward<X18>(x18),
  197. f(std::forward<X19>(x19),
  198. f(std::forward<X20>(x20),
  199. f(std::forward<X21>(x21),
  200. f(std::forward<X22>(x22),
  201. f(std::forward<X23>(x23),
  202. f(std::forward<X24>(x24),
  203. f(std::forward<X25>(x25),
  204. f(std::forward<X26>(x26),
  205. f(std::forward<X27>(x27),
  206. f(std::forward<X28>(x28),
  207. f(std::forward<X29>(x29),
  208. f(std::forward<X30>(x30),
  209. f(std::forward<X31>(x31),
  210. f(std::forward<X32>(x32),
  211. f(std::forward<X33>(x33),
  212. f(std::forward<X34>(x34),
  213. f(std::forward<X35>(x35),
  214. fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X36>(x36), std::forward<Xn>(xn)...))))))))))))))))))))))))))))))))))));
  215. }
  216. };
  217. struct fold_right_t
  218. {
  219. template<typename F, typename X1, typename... Xn>
  220. constexpr auto operator()(F&& f, X1&& x1, Xn&&... xn) const
  221. { return fold_right_impl<sizeof...(xn) + 1>::apply(std::forward<F>(f), std::forward<X1>(x1), std::forward<Xn>(xn)...); }
  222. };
  223. }
  224. constexpr __impl::fold_right_t fold_right { };
  225. }
  226. }
  227. }