foldr1.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*!
  2. @file
  3. Defines `boost::hana::detail::variadic::foldr1`.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP
  9. #define BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/core/when.hpp>
  12. BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
  13. //! @cond
  14. template <unsigned int n, typename = when<true>>
  15. struct foldr1_impl;
  16. template <>
  17. struct foldr1_impl<1> {
  18. template <typename F, typename X1>
  19. static constexpr X1 apply(F&&, X1&& x1)
  20. { return static_cast<X1&&>(x1); }
  21. };
  22. template <>
  23. struct foldr1_impl<2> {
  24. template <typename F, typename X1, typename X2>
  25. static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2) {
  26. return static_cast<F&&>(f)(static_cast<X1&&>(x1),
  27. static_cast<X2&&>(x2));
  28. }
  29. };
  30. template <>
  31. struct foldr1_impl<3> {
  32. template <typename F, typename X1, typename X2, typename X3>
  33. static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3) {
  34. return f(static_cast<X1&&>(x1),
  35. f(static_cast<X2&&>(x2),
  36. static_cast<X3&&>(x3)));
  37. }
  38. };
  39. template <>
  40. struct foldr1_impl<4> {
  41. template <typename F, typename X1, typename X2, typename X3, typename X4>
  42. static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) {
  43. return f(static_cast<X1&&>(x1),
  44. f(static_cast<X2&&>(x2),
  45. f(static_cast<X3&&>(x3),
  46. static_cast<X4&&>(x4))));
  47. }
  48. };
  49. template <>
  50. struct foldr1_impl<5> {
  51. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
  52. static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) {
  53. return f(static_cast<X1&&>(x1),
  54. f(static_cast<X2&&>(x2),
  55. f(static_cast<X3&&>(x3),
  56. f(static_cast<X4&&>(x4),
  57. static_cast<X5&&>(x5)))));
  58. }
  59. };
  60. template <>
  61. struct foldr1_impl<6> {
  62. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
  63. static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) {
  64. return f(static_cast<X1&&>(x1),
  65. f(static_cast<X2&&>(x2),
  66. f(static_cast<X3&&>(x3),
  67. f(static_cast<X4&&>(x4),
  68. f(static_cast<X5&&>(x5),
  69. static_cast<X6&&>(x6))))));
  70. }
  71. };
  72. template <unsigned int n>
  73. struct foldr1_impl<n, when<(n >= 7) && (n < 14)>> {
  74. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xn>
  75. static constexpr decltype(auto)
  76. apply(F&& f
  77. , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
  78. , Xn&& ...xn)
  79. {
  80. return f(static_cast<X1&&>(x1),
  81. f(static_cast<X2&&>(x2),
  82. f(static_cast<X3&&>(x3),
  83. f(static_cast<X4&&>(x4),
  84. f(static_cast<X5&&>(x5),
  85. f(static_cast<X6&&>(x6),
  86. foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X7&&>(x7), static_cast<Xn&&>(xn)...)))))));
  87. }
  88. };
  89. template <unsigned int n>
  90. struct foldr1_impl<n, when<(n >= 14) && (n < 28)>> {
  91. template <
  92. typename F
  93. , typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
  94. , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
  95. , typename ...Xn
  96. >
  97. static constexpr decltype(auto)
  98. apply(F&& f
  99. , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
  100. , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
  101. , Xn&& ...xn)
  102. {
  103. return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7),
  104. f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13),
  105. foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X14&&>(x14), static_cast<Xn&&>(xn)...))))))))))))));
  106. }
  107. };
  108. template <unsigned int n>
  109. struct foldr1_impl<n, when<(n >= 28) && (n < 56)>> {
  110. template <
  111. typename F
  112. , typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
  113. , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
  114. , typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
  115. , typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
  116. , typename ...Xn
  117. >
  118. static constexpr decltype(auto)
  119. apply(F&& f
  120. , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
  121. , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
  122. , X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
  123. , X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
  124. , Xn&& ...xn)
  125. {
  126. return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7),
  127. f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), f(static_cast<X14&&>(x14),
  128. f(static_cast<X15&&>(x15), f(static_cast<X16&&>(x16), f(static_cast<X17&&>(x17), f(static_cast<X18&&>(x18), f(static_cast<X19&&>(x19), f(static_cast<X20&&>(x20), f(static_cast<X21&&>(x21),
  129. f(static_cast<X22&&>(x22), f(static_cast<X23&&>(x23), f(static_cast<X24&&>(x24), f(static_cast<X25&&>(x25), f(static_cast<X26&&>(x26), f(static_cast<X27&&>(x27),
  130. foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X28&&>(x28), static_cast<Xn&&>(xn)...))))))))))))))))))))))))))));
  131. }
  132. };
  133. template <unsigned int n>
  134. struct foldr1_impl<n, when<(n >= 56)>> {
  135. template <
  136. typename F
  137. , typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
  138. , typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
  139. , typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
  140. , typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
  141. , typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35
  142. , typename X36, typename X37, typename X38, typename X39, typename X40, typename X41, typename X42
  143. , typename X43, typename X44, typename X45, typename X46, typename X47, typename X48, typename X49
  144. , typename X50, typename X51, typename X52, typename X53, typename X54, typename X55, typename X56
  145. , typename ...Xn
  146. >
  147. static constexpr decltype(auto)
  148. apply(F&& f
  149. , X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
  150. , X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
  151. , X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
  152. , X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
  153. , X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35
  154. , X36&& x36, X37&& x37, X38&& x38, X39&& x39, X40&& x40, X41&& x41, X42&& x42
  155. , X43&& x43, X44&& x44, X45&& x45, X46&& x46, X47&& x47, X48&& x48, X49&& x49
  156. , X50&& x50, X51&& x51, X52&& x52, X53&& x53, X54&& x54, X55&& x55, X56&& x56
  157. , Xn&& ...xn)
  158. {
  159. return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7),
  160. f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), f(static_cast<X14&&>(x14),
  161. f(static_cast<X15&&>(x15), f(static_cast<X16&&>(x16), f(static_cast<X17&&>(x17), f(static_cast<X18&&>(x18), f(static_cast<X19&&>(x19), f(static_cast<X20&&>(x20), f(static_cast<X21&&>(x21),
  162. f(static_cast<X22&&>(x22), f(static_cast<X23&&>(x23), f(static_cast<X24&&>(x24), f(static_cast<X25&&>(x25), f(static_cast<X26&&>(x26), f(static_cast<X27&&>(x27), f(static_cast<X28&&>(x28),
  163. f(static_cast<X29&&>(x29), f(static_cast<X30&&>(x30), f(static_cast<X31&&>(x31), f(static_cast<X32&&>(x32), f(static_cast<X33&&>(x33), f(static_cast<X34&&>(x34), f(static_cast<X35&&>(x35),
  164. f(static_cast<X36&&>(x36), f(static_cast<X37&&>(x37), f(static_cast<X38&&>(x38), f(static_cast<X39&&>(x39), f(static_cast<X40&&>(x40), f(static_cast<X41&&>(x41), f(static_cast<X42&&>(x42),
  165. f(static_cast<X43&&>(x43), f(static_cast<X44&&>(x44), f(static_cast<X45&&>(x45), f(static_cast<X46&&>(x46), f(static_cast<X47&&>(x47), f(static_cast<X48&&>(x48), f(static_cast<X49&&>(x49),
  166. f(static_cast<X50&&>(x50), f(static_cast<X51&&>(x51), f(static_cast<X52&&>(x52), f(static_cast<X53&&>(x53), f(static_cast<X54&&>(x54), f(static_cast<X55&&>(x55),
  167. foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X56&&>(x56), static_cast<Xn&&>(xn)...))))))))))))))))))))))))))))))))))))))))))))))))))))))));
  168. }
  169. };
  170. //! @endcond
  171. struct foldr1_t {
  172. template <typename F, typename X1, typename ...Xn>
  173. constexpr decltype(auto) operator()(F&& f, X1&& x1, Xn&& ...xn) const {
  174. return foldr1_impl<sizeof...(xn) + 1>::apply(
  175. static_cast<F&&>(f), static_cast<X1&&>(x1), static_cast<Xn&&>(xn)...
  176. );
  177. }
  178. };
  179. constexpr foldr1_t foldr1{};
  180. struct foldr_t {
  181. template <typename F, typename State, typename ...Xn>
  182. constexpr decltype(auto) operator()(F&& f, State&& state, Xn&& ...xn) const {
  183. return foldr1_impl<sizeof...(xn) + 1>::apply(
  184. static_cast<F&&>(f), static_cast<Xn&&>(xn)..., static_cast<State&&>(state)
  185. );
  186. }
  187. };
  188. constexpr foldr_t foldr{};
  189. }} BOOST_HANA_NAMESPACE_END
  190. #endif // !BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP