Skip to content

Commit 21c7bc5

Browse files
authored
[libc++] Use __integer_pack to implement integer_sequence on GCC (llvm#82983)
This significantly simplifies the implementation.
1 parent 777ac46 commit 21c7bc5

File tree

3 files changed

+12
-118
lines changed

3 files changed

+12
-118
lines changed

libcxx/include/__utility/integer_sequence.h

Lines changed: 12 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -31,65 +31,16 @@ struct __integer_sequence {
3131
using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>;
3232
};
3333

34-
#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
35-
36-
namespace __detail {
37-
38-
template <typename _Tp, size_t... _Extra>
39-
struct __repeat;
40-
template <typename _Tp, _Tp... _Np, size_t... _Extra>
41-
struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> {
42-
typedef _LIBCPP_NODEBUG __integer_sequence<
43-
_Tp,
44-
_Np...,
45-
sizeof...(_Np) + _Np...,
46-
2 * sizeof...(_Np) + _Np...,
47-
3 * sizeof...(_Np) + _Np...,
48-
4 * sizeof...(_Np) + _Np...,
49-
5 * sizeof...(_Np) + _Np...,
50-
6 * sizeof...(_Np) + _Np...,
51-
7 * sizeof...(_Np) + _Np...,
52-
_Extra...>
53-
type;
54-
};
55-
56-
template <size_t _Np>
57-
struct __parity;
58-
template <size_t _Np>
59-
struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
60-
61-
// clang-format off
62-
template<> struct __make<0> { typedef __integer_sequence<size_t> type; };
63-
template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; };
64-
template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; };
65-
template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; };
66-
template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; };
67-
template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; };
68-
template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };
69-
template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };
70-
71-
template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
72-
template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
73-
template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
74-
template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
75-
template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
76-
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> {}; };
77-
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> {}; };
78-
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> {}; };
79-
// clang-format on
80-
81-
} // namespace __detail
82-
83-
#endif
84-
8534
#if __has_builtin(__make_integer_seq)
8635
template <size_t _Ep, size_t _Sp>
8736
using __make_indices_imp =
8837
typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>;
89-
#else
38+
#elif __has_builtin(__integer_pack)
9039
template <size_t _Ep, size_t _Sp>
91-
using __make_indices_imp = typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>;
92-
40+
using __make_indices_imp =
41+
typename __integer_sequence<size_t, __integer_pack(_Ep - _Sp)...>::template __to_tuple_indices<_Sp>;
42+
#else
43+
# error "No known way to get an integer pack from the compiler"
9344
#endif
9445

9546
#if _LIBCPP_STD_VER >= 14
@@ -104,34 +55,20 @@ struct _LIBCPP_TEMPLATE_VIS integer_sequence {
10455
template <size_t... _Ip>
10556
using index_sequence = integer_sequence<size_t, _Ip...>;
10657

107-
# if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
58+
# if __has_builtin(__make_integer_seq)
10859

10960
template <class _Tp, _Tp _Ep>
110-
using __make_integer_sequence _LIBCPP_NODEBUG = __make_integer_seq<integer_sequence, _Tp, _Ep>;
111-
112-
# else
61+
using make_integer_sequence _LIBCPP_NODEBUG = __make_integer_seq<integer_sequence, _Tp, _Ep>;
11362

114-
template <typename _Tp, _Tp _Np>
115-
using __make_integer_sequence_unchecked _LIBCPP_NODEBUG =
116-
typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
63+
# elif __has_builtin(__integer_pack)
11764

118-
template <class _Tp, _Tp _Ep>
119-
struct __make_integer_sequence_checked {
120-
static_assert(is_integral<_Tp>::value, "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;
125-
};
126-
127-
template <class _Tp, _Tp _Ep>
128-
using __make_integer_sequence _LIBCPP_NODEBUG = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
65+
template <class _Tp, _Tp _SequenceSize>
66+
using make_integer_sequence _LIBCPP_NODEBUG = integer_sequence<_Tp, __integer_pack(_SequenceSize)...>;
12967

68+
# else
69+
# error "No known way to get an integer pack from the compiler"
13070
# endif
13171

132-
template <class _Tp, _Tp _Np>
133-
using make_integer_sequence = __make_integer_sequence<_Tp, _Np>;
134-
13572
template <size_t _Np>
13673
using make_index_sequence = make_integer_sequence<size_t, _Np>;
13774

libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp

Lines changed: 0 additions & 19 deletions
This file was deleted.

libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.verify.cpp

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)