2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BEAST_DETAIL_INTEGER_SEQUENCE_H_INCLUDED
9 #define BEAST_DETAIL_INTEGER_SEQUENCE_H_INCLUDED
12 #include <type_traits>
18 template<class T, T... Ints>
19 struct integer_sequence
22 static_assert (std::is_integral<T>::value,
23 "std::integer_sequence can only be instantiated with an integral type" );
25 static std::size_t constexpr static_size = sizeof...(Ints);
27 static std::size_t constexpr size()
29 return sizeof...(Ints);
33 template<std::size_t... Ints>
34 using index_sequence = integer_sequence<std::size_t, Ints...>;
36 // This workaround is needed for broken sizeof...
37 template<class... Args>
38 struct sizeof_workaround
40 static std::size_t constexpr size = sizeof... (Args);
45 // This implementation compiles on MSVC and clang but not gcc
47 template<class T, unsigned long long N, class Seq>
48 struct make_integer_sequence_unchecked;
50 template<class T, unsigned long long N, unsigned long long ...Indices>
51 struct make_integer_sequence_unchecked<
52 T, N, integer_sequence<T, Indices...>>
54 using type = typename make_integer_sequence_unchecked<
55 T, N-1, integer_sequence<T, N-1, Indices...>>::type;
58 template<class T, unsigned long long ...Indices>
59 struct make_integer_sequence_unchecked<
60 T, 0, integer_sequence<T, Indices...>>
62 using type = integer_sequence<T, Indices...>;
65 template<class T, T N>
66 struct make_integer_sequence_checked
68 static_assert (std::is_integral<T>::value,
69 "T must be an integral type");
71 static_assert (N >= 0,
72 "N must be non-negative");
74 using type = typename make_integer_sequence_unchecked<
75 T, N, integer_sequence<T>>::type;
78 template<class T, T N>
79 using make_integer_sequence =
80 typename make_integer_sequence_checked<T, N>::type;
82 template<std::size_t N>
83 using make_index_sequence = make_integer_sequence<std::size_t, N>;
85 template<class... Args>
86 using index_sequence_for =
87 make_index_sequence<sizeof_workaround<Args...>::size>;
91 // This implementation compiles on gcc but not MSVC
93 template<std::size_t... Ints>
96 using next = index_tuple<Ints..., sizeof... (Ints)>;
100 template<std::size_t N>
101 struct build_index_tuple
103 using type = typename build_index_tuple<N-1>::type::next;
107 struct build_index_tuple<0>
109 using type = index_tuple<>;
112 template<class T, T N,
113 class Seq = typename build_index_tuple<N>::type
115 struct integer_sequence_helper;
117 template<class T, T N, std::size_t... Ints>
118 struct integer_sequence_helper<T, N, index_tuple<Ints...>>
120 static_assert (std::is_integral<T>::value,
121 "T must be an integral type");
123 static_assert (N >= 0,
124 "N must be non-negative");
126 using type = integer_sequence<T, static_cast<T> (Ints)...>;
129 template<class T, T N>
130 using make_integer_sequence =
131 typename integer_sequence_helper<T, N>::type;
133 template<std::size_t N>
134 using make_index_sequence = make_integer_sequence<std::size_t, N>;
136 template<class... Args>
137 using index_sequence_for =
138 make_index_sequence<sizeof_workaround<Args...>::size>;