split_at.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*!
  2. @file
  3. Defines `boost::hana::detail::variadic::split_at`.
  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_SPLIT_AT_HPP
  9. #define BOOST_HANA_DETAIL_VARIADIC_SPLIT_AT_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/functional/partial.hpp>
  12. #include <boost/hana/functional/reverse_partial.hpp>
  13. #include <cstddef>
  14. BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
  15. template <std::size_t n>
  16. struct split_at_t {
  17. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename ...Xs>
  18. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, Xs&& ...xs) const {
  19. return split_at_t<n - 8>{}(
  20. hana::partial(static_cast<F&&>(f),
  21. static_cast<X1&&>(x1),
  22. static_cast<X2&&>(x2),
  23. static_cast<X3&&>(x3),
  24. static_cast<X4&&>(x4),
  25. static_cast<X5&&>(x5),
  26. static_cast<X6&&>(x6),
  27. static_cast<X7&&>(x7),
  28. static_cast<X8&&>(x8)
  29. ),
  30. static_cast<Xs&&>(xs)...
  31. );
  32. }
  33. };
  34. template <>
  35. struct split_at_t<0> {
  36. template <typename F, typename ...Xs>
  37. constexpr decltype(auto) operator()(F&& f, Xs&& ...xs) const {
  38. return static_cast<F&&>(f)()(static_cast<Xs&&>(xs)...);
  39. }
  40. };
  41. template <>
  42. struct split_at_t<1> {
  43. template <typename F, typename X1, typename ...Xs>
  44. constexpr decltype(auto) operator()(F&& f, X1&& x1, Xs&& ...xs) const {
  45. return static_cast<F&&>(f)(
  46. static_cast<X1&&>(x1)
  47. )(static_cast<Xs&&>(xs)...);
  48. }
  49. };
  50. template <>
  51. struct split_at_t<2> {
  52. template <typename F, typename X1, typename X2, typename ...Xs>
  53. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, Xs&& ...xs) const {
  54. return static_cast<F&&>(f)(
  55. static_cast<X1&&>(x1),
  56. static_cast<X2&&>(x2)
  57. )(static_cast<Xs&&>(xs)...);
  58. }
  59. };
  60. template <>
  61. struct split_at_t<3> {
  62. template <typename F, typename X1, typename X2, typename X3, typename ...Xs>
  63. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, Xs&& ...xs) const {
  64. return static_cast<F&&>(f)(
  65. static_cast<X1&&>(x1),
  66. static_cast<X2&&>(x2),
  67. static_cast<X3&&>(x3)
  68. )(static_cast<Xs&&>(xs)...);
  69. }
  70. };
  71. template <>
  72. struct split_at_t<4> {
  73. template <typename F, typename X1, typename X2, typename X3, typename X4, typename ...Xs>
  74. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, Xs&& ...xs) const {
  75. return static_cast<F&&>(f)(
  76. static_cast<X1&&>(x1),
  77. static_cast<X2&&>(x2),
  78. static_cast<X3&&>(x3),
  79. static_cast<X4&&>(x4)
  80. )(static_cast<Xs&&>(xs)...);
  81. }
  82. };
  83. template <>
  84. struct split_at_t<5> {
  85. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename ...Xs>
  86. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, Xs&& ...xs) const {
  87. return static_cast<F&&>(f)(
  88. static_cast<X1&&>(x1),
  89. static_cast<X2&&>(x2),
  90. static_cast<X3&&>(x3),
  91. static_cast<X4&&>(x4),
  92. static_cast<X5&&>(x5)
  93. )(static_cast<Xs&&>(xs)...);
  94. }
  95. };
  96. template <>
  97. struct split_at_t<6> {
  98. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename ...Xs>
  99. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, Xs&& ...xs) const {
  100. return static_cast<F&&>(f)(
  101. static_cast<X1&&>(x1),
  102. static_cast<X2&&>(x2),
  103. static_cast<X3&&>(x3),
  104. static_cast<X4&&>(x4),
  105. static_cast<X5&&>(x5),
  106. static_cast<X6&&>(x6)
  107. )(static_cast<Xs&&>(xs)...);
  108. }
  109. };
  110. template <>
  111. struct split_at_t<7> {
  112. template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xs>
  113. constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, Xs&& ...xs) const {
  114. return static_cast<F&&>(f)(
  115. static_cast<X1&&>(x1),
  116. static_cast<X2&&>(x2),
  117. static_cast<X3&&>(x3),
  118. static_cast<X4&&>(x4),
  119. static_cast<X5&&>(x5),
  120. static_cast<X6&&>(x6),
  121. static_cast<X7&&>(x7)
  122. )(static_cast<Xs&&>(xs)...);
  123. }
  124. };
  125. template <std::size_t n>
  126. struct _makesplit_at_t {
  127. template <typename ...Xs>
  128. constexpr decltype(auto) operator()(Xs&& ...xs) const {
  129. return hana::reverse_partial(split_at_t<n>{},
  130. static_cast<Xs&&>(xs)...);
  131. }
  132. };
  133. template <std::size_t n>
  134. constexpr _makesplit_at_t<n> split_at{};
  135. }} BOOST_HANA_NAMESPACE_END
  136. #endif // !BOOST_HANA_DETAIL_VARIADIC_SPLIT_AT_HPP