1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
10 #define _LIBCPP___UTILITY_INTEGER_SEQUENCE_H
13 #include <__type_traits/is_integral.h>
16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17 # pragma GCC system_header
20 _LIBCPP_BEGIN_NAMESPACE_STD
22 template <size_t...> struct __tuple_indices
;
24 template <class _IdxType
, _IdxType
... _Values
>
25 struct __integer_sequence
{
26 template <template <class _OIdxType
, _OIdxType
...> class _ToIndexSeq
, class _ToIndexType
>
27 using __convert
= _ToIndexSeq
<_ToIndexType
, _Values
...>;
30 using __to_tuple_indices
= __tuple_indices
<(_Values
+ _Sp
)...>;
33 #if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
37 template<typename _Tp
, size_t ..._Extra
> struct __repeat
;
38 template<typename _Tp
, _Tp
..._Np
, size_t ..._Extra
> struct __repeat
<__integer_sequence
<_Tp
, _Np
...>, _Extra
...> {
39 typedef _LIBCPP_NODEBUG __integer_sequence
<_Tp
,
41 sizeof...(_Np
) + _Np
...,
42 2 * sizeof...(_Np
) + _Np
...,
43 3 * sizeof...(_Np
) + _Np
...,
44 4 * sizeof...(_Np
) + _Np
...,
45 5 * sizeof...(_Np
) + _Np
...,
46 6 * sizeof...(_Np
) + _Np
...,
47 7 * sizeof...(_Np
) + _Np
...,
51 template<size_t _Np
> struct __parity
;
52 template<size_t _Np
> struct __make
: __parity
<_Np
% 8>::template __pmake
<_Np
> {};
54 template<> struct __make
<0> { typedef __integer_sequence
<size_t> type
; };
55 template<> struct __make
<1> { typedef __integer_sequence
<size_t, 0> type
; };
56 template<> struct __make
<2> { typedef __integer_sequence
<size_t, 0, 1> type
; };
57 template<> struct __make
<3> { typedef __integer_sequence
<size_t, 0, 1, 2> type
; };
58 template<> struct __make
<4> { typedef __integer_sequence
<size_t, 0, 1, 2, 3> type
; };
59 template<> struct __make
<5> { typedef __integer_sequence
<size_t, 0, 1, 2, 3, 4> type
; };
60 template<> struct __make
<6> { typedef __integer_sequence
<size_t, 0, 1, 2, 3, 4, 5> type
; };
61 template<> struct __make
<7> { typedef __integer_sequence
<size_t, 0, 1, 2, 3, 4, 5, 6> type
; };
63 template<> struct __parity
<0> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
> {}; };
64 template<> struct __parity
<1> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 1> {}; };
65 template<> struct __parity
<2> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 2, _Np
- 1> {}; };
66 template<> struct __parity
<3> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 3, _Np
- 2, _Np
- 1> {}; };
67 template<> struct __parity
<4> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 4, _Np
- 3, _Np
- 2, _Np
- 1> {}; };
68 template<> struct __parity
<5> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 5, _Np
- 4, _Np
- 3, _Np
- 2, _Np
- 1> {}; };
69 template<> struct __parity
<6> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 6, _Np
- 5, _Np
- 4, _Np
- 3, _Np
- 2, _Np
- 1> {}; };
70 template<> struct __parity
<7> { template<size_t _Np
> struct __pmake
: __repeat
<typename __make
<_Np
/ 8>::type
, _Np
- 7, _Np
- 6, _Np
- 5, _Np
- 4, _Np
- 3, _Np
- 2, _Np
- 1> {}; };
76 #if __has_builtin(__make_integer_seq)
77 template <size_t _Ep
, size_t _Sp
>
78 using __make_indices_imp
=
79 typename __make_integer_seq
<__integer_sequence
, size_t, _Ep
- _Sp
>::template
80 __to_tuple_indices
<_Sp
>;
82 template <size_t _Ep
, size_t _Sp
>
83 using __make_indices_imp
=
84 typename
__detail::__make
<_Ep
- _Sp
>::type::template __to_tuple_indices
<_Sp
>;
88 #if _LIBCPP_STD_VER >= 14
90 template<class _Tp
, _Tp
... _Ip
>
91 struct _LIBCPP_TEMPLATE_VIS integer_sequence
93 typedef _Tp value_type
;
94 static_assert( is_integral
<_Tp
>::value
,
95 "std::integer_sequence can only be instantiated with an integral type" );
97 _LIBCPP_INLINE_VISIBILITY
100 size() noexcept
{ return sizeof...(_Ip
); }
103 template<size_t... _Ip
>
104 using index_sequence
= integer_sequence
<size_t, _Ip
...>;
106 #if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
108 template <class _Tp
, _Tp _Ep
>
109 using __make_integer_sequence _LIBCPP_NODEBUG
= __make_integer_seq
<integer_sequence
, _Tp
, _Ep
>;
113 template<typename _Tp
, _Tp _Np
> using __make_integer_sequence_unchecked _LIBCPP_NODEBUG
=
114 typename
__detail::__make
<_Np
>::type::template __convert
<integer_sequence
, _Tp
>;
116 template <class _Tp
, _Tp _Ep
>
117 struct __make_integer_sequence_checked
119 static_assert(is_integral
<_Tp
>::value
,
120 "std::make_integer_sequence can only be instantiated with an integral type" );
121 static_assert(0 <= _Ep
, "std::make_integer_sequence must have a non-negative sequence length");
122 // Workaround GCC bug by preventing bad installations when 0 <= _Ep
123 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
124 typedef _LIBCPP_NODEBUG __make_integer_sequence_unchecked
<_Tp
, 0 <= _Ep
? _Ep
: 0> type
;
127 template <class _Tp
, _Tp _Ep
>
128 using __make_integer_sequence _LIBCPP_NODEBUG
= typename __make_integer_sequence_checked
<_Tp
, _Ep
>::type
;
132 template<class _Tp
, _Tp _Np
>
133 using make_integer_sequence
= __make_integer_sequence
<_Tp
, _Np
>;
136 using make_index_sequence
= make_integer_sequence
<size_t, _Np
>;
138 template<class... _Tp
>
139 using index_sequence_for
= make_index_sequence
<sizeof...(_Tp
)>;
141 # if _LIBCPP_STD_VER >= 20
142 // Executes __func for every element in an index_sequence.
143 template <size_t... _Index
, class _Function
>
144 _LIBCPP_HIDE_FROM_ABI
constexpr void __for_each_index_sequence(index_sequence
<_Index
...>, _Function __func
) {
145 (__func
.template operator()<_Index
>(), ...);
147 # endif // _LIBCPP_STD_VER >= 20
149 #endif // _LIBCPP_STD_VER >= 14
151 _LIBCPP_END_NAMESPACE_STD
153 #endif // _LIBCPP___UTILITY_INTEGER_SEQUENCE_H