From 21c7bc51e9ed2402a3a2f7a88d63cc8f5c2e303c Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Wed, 28 Feb 2024 20:33:20 +0100 Subject: [PATCH] [libc++] Use __integer_pack to implement integer_sequence on GCC (#82983) This significantly simplifies the implementation. --- libcxx/include/__utility/integer_sequence.h | 87 +++---------------- .../make_integer_seq_fallback.pass.cpp | 19 ---- .../make_integer_seq_fallback.verify.cpp | 24 ----- 3 files changed, 12 insertions(+), 118 deletions(-) delete mode 100644 libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp delete mode 100644 libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.verify.cpp diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h index e63f3f265b7d5e..ccce9433e7a801 100644 --- a/libcxx/include/__utility/integer_sequence.h +++ b/libcxx/include/__utility/integer_sequence.h @@ -31,65 +31,16 @@ struct __integer_sequence { using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; }; -#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) - -namespace __detail { - -template -struct __repeat; -template -struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { - typedef _LIBCPP_NODEBUG __integer_sequence< - _Tp, - _Np..., - sizeof...(_Np) + _Np..., - 2 * sizeof...(_Np) + _Np..., - 3 * sizeof...(_Np) + _Np..., - 4 * sizeof...(_Np) + _Np..., - 5 * sizeof...(_Np) + _Np..., - 6 * sizeof...(_Np) + _Np..., - 7 * sizeof...(_Np) + _Np..., - _Extra...> - type; -}; - -template -struct __parity; -template -struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; - -// clang-format off -template<> struct __make<0> { typedef __integer_sequence type; }; -template<> struct __make<1> { typedef __integer_sequence type; }; -template<> struct __make<2> { typedef __integer_sequence type; }; -template<> struct __make<3> { typedef __integer_sequence type; }; -template<> struct __make<4> { typedef __integer_sequence type; }; -template<> struct __make<5> { typedef __integer_sequence type; }; -template<> struct __make<6> { typedef __integer_sequence type; }; -template<> struct __make<7> { typedef __integer_sequence type; }; - -template<> struct __parity<0> { template struct __pmake : __repeat::type> {}; }; -template<> struct __parity<1> { template struct __pmake : __repeat::type, _Np - 1> {}; }; -template<> struct __parity<2> { template struct __pmake : __repeat::type, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<3> { template struct __pmake : __repeat::type, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<4> { template struct __pmake : __repeat::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<5> { template struct __pmake : __repeat::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<6> { template struct __pmake : __repeat::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<7> { template struct __pmake : __repeat::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -// clang-format on - -} // namespace __detail - -#endif - #if __has_builtin(__make_integer_seq) template using __make_indices_imp = typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>; -#else +#elif __has_builtin(__integer_pack) template -using __make_indices_imp = typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; - +using __make_indices_imp = + typename __integer_sequence::template __to_tuple_indices<_Sp>; +#else +# error "No known way to get an integer pack from the compiler" #endif #if _LIBCPP_STD_VER >= 14 @@ -104,34 +55,20 @@ struct _LIBCPP_TEMPLATE_VIS integer_sequence { template using index_sequence = integer_sequence; -# if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) +# if __has_builtin(__make_integer_seq) template -using __make_integer_sequence _LIBCPP_NODEBUG = __make_integer_seq; - -# else +using make_integer_sequence _LIBCPP_NODEBUG = __make_integer_seq; -template -using __make_integer_sequence_unchecked _LIBCPP_NODEBUG = - typename __detail::__make<_Np>::type::template __convert; +# elif __has_builtin(__integer_pack) -template -struct __make_integer_sequence_checked { - static_assert(is_integral<_Tp>::value, "std::make_integer_sequence can only be instantiated with an integral type"); - static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length"); - // Workaround GCC bug by preventing bad installations when 0 <= _Ep - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929 - typedef _LIBCPP_NODEBUG __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type; -}; - -template -using __make_integer_sequence _LIBCPP_NODEBUG = typename __make_integer_sequence_checked<_Tp, _Ep>::type; +template +using make_integer_sequence _LIBCPP_NODEBUG = integer_sequence<_Tp, __integer_pack(_SequenceSize)...>; +# else +# error "No known way to get an integer pack from the compiler" # endif -template -using make_integer_sequence = __make_integer_sequence<_Tp, _Np>; - template using make_index_sequence = make_integer_sequence; diff --git a/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp b/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp deleted file mode 100644 index ceeb4dd3eeec41..00000000000000 --- a/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.pass.cpp +++ /dev/null @@ -1,19 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// - -// template -// using make_integer_sequence = integer_sequence; - -// UNSUPPORTED: c++03, c++11 - -#define _LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE -#include "make_integer_seq.pass.cpp" - -#include "test_macros.h" diff --git a/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.verify.cpp b/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.verify.cpp deleted file mode 100644 index 32a4a5431333e2..00000000000000 --- a/libcxx/test/std/utilities/intseq/intseq.make/make_integer_seq_fallback.verify.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// - -// template -// using make_integer_sequence = integer_sequence; - -// UNSUPPORTED: c++03, c++11 - -// This test hangs during recursive template instantiation with libstdc++ -// UNSUPPORTED: stdlib=libstdc++ - -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE - -#include - -typedef std::make_integer_sequence MakeSeqT; -MakeSeqT i; // expected-error-re@*:* {{static assertion failed{{.*}}std::make_integer_sequence must have a non-negative sequence length}}