2#include <boost/preprocessor/repetition/repeat.hpp>
17 constexpr operator T();
19#pragma clang diagnostic push
20#pragma clang diagnostic ignored "-Wmissing-field-initializers"
21template <
class T, std::size_t... I>
22decltype(void(T{(I, std::declval<any_type>())...}), std::true_type{})
23 test_is_braces_constructible_n(std::index_sequence<I...>);
24#pragma clang diagnostic pop
25template <
class,
class...>
26std::false_type test_is_braces_constructible_n(...);
27template <
class T, std::
size_t N>
28using is_braces_constructible_n
29 =
decltype(test_is_braces_constructible_n<T>(std::make_index_sequence<N>{}));
31template <
class T, std::
size_t L = 0u, std::
size_t R = sizeof(T) + 1u>
32constexpr std::size_t to_tuple_size_f()
34 constexpr std::size_t M = (L + R) / 2u;
36 return std::is_empty<T>{} ? 0u :
throw "Unable to determine number of elements";
37 else if constexpr(L == M)
39 else if constexpr(is_braces_constructible_n<T, M>{})
40 return to_tuple_size_f<T, M, R>();
42 return to_tuple_size_f<T, L, M>();
45using to_tuple_size = std::integral_constant<std::size_t, to_tuple_size_f<T>()>;
52auto to_tuple_impl(T&&, std::integral_constant<std::size_t, 0>)
noexcept
54 return std::make_tuple();
57#define TO_TUPLE_P(Z, N, _) , p##N
58#define TO_TUPLE_SPECIALIZATION(Z, N, _) \
60 auto to_tuple_impl(T&& object, std::integral_constant<std::size_t, N + 1>) noexcept \
62 auto&& [p BOOST_PP_REPEAT_##Z(N, TO_TUPLE_P, nil)] = object; \
63 return std::make_tuple(p BOOST_PP_REPEAT_##Z(N, TO_TUPLE_P, nil)); \
65BOOST_PP_REPEAT(TO_TUPLE_MAX, TO_TUPLE_SPECIALIZATION, nil)
66#undef TO_TUPLE_SPECIALIZATION
70 class T,
class =
struct current_value, std::size_t = TO_TUPLE_MAX,
71 class =
struct required_value, std::size_t N>
72auto to_tuple_impl(T&&, std::integral_constant<std::size_t, N>)
noexcept
74 static_assert(N <= TO_TUPLE_MAX,
"Please increase TO_TUPLE_MAX");
79 class T,
class = std::enable_if_t<
80 std::is_class<T>::value && std::is_standard_layout<T>::value>>
81auto to_tuple(T&&
object)
noexcept
83 return detail::to_tuple_impl(
84 std::forward<T>(
object), detail::to_tuple_size<std::decay_t<T>>{});