I forgot to commit this patch at the start of stage 1 when Jason added the __integer_pack builtin.
This patch uses __has_builtin to detect Clang's __make_integer_seq builtin and uses that instead when available. This means it works with either __integer_pack or __make_integer_seq. whichever is available. We _could_ keep the old implementation, for compilers that don't support either builtin (I'm not sure if Intel icc supports either) but I haven't done that here. * include/std/utility (_Itup_cat, _Make_integer_sequence): Remove. (_Build_index_tuple, make_integer_sequence): Use built-in to generate pack expansion. Tested powerpc64le-linux, committed to trunk.
commit d208208c187b810b68cee66730866eb862aed09d Author: Jonathan Wakely <jwak...@redhat.com> Date: Mon Sep 18 12:44:00 2017 +0100 Use built-in for std::make_integer_sequnce * include/std/utility (_Itup_cat, _Make_integer_sequence): Remove. (_Build_index_tuple, make_integer_sequence): Use built-in to generate pack expansion. diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index c18bcb6f72d..29a626004f9 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -267,32 +267,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // extract the elements in a tuple. template<size_t... _Indexes> struct _Index_tuple { }; - // Concatenates two _Index_tuples. - template<typename _Itup1, typename _Itup2> struct _Itup_cat; - - template<size_t... _Ind1, size_t... _Ind2> - struct _Itup_cat<_Index_tuple<_Ind1...>, _Index_tuple<_Ind2...>> - { - using __type = _Index_tuple<_Ind1..., (_Ind2 + sizeof...(_Ind1))...>; - }; +#ifdef __has_builtin +# if __has_builtin(__make_integer_seq) +# define _GLIBCXX_USE_MAKE_INTEGER_SEQ 1 +# endif +#endif // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. template<size_t _Num> struct _Build_index_tuple - : _Itup_cat<typename _Build_index_tuple<_Num / 2>::__type, - typename _Build_index_tuple<_Num - _Num / 2>::__type> - { }; - - template<> - struct _Build_index_tuple<1> { - typedef _Index_tuple<0> __type; - }; +#if _GLIBCXX_USE_MAKE_INTEGER_SEQ + template<typename, size_t... _Indices> + using _IdxTuple = _Index_tuple<_Indices...>; - template<> - struct _Build_index_tuple<0> - { - typedef _Index_tuple<> __type; + using __type = __make_integer_seq<_IdxTuple, size_t, _Num>; +#else + using __type = _Index_tuple<__integer_pack(_Num)...>; +#endif }; #if __cplusplus > 201103L @@ -307,23 +299,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr size_t size() { return sizeof...(_Idx); } }; - template<typename _Tp, _Tp _Num, - typename _ISeq = typename _Build_index_tuple<_Num>::__type> - struct _Make_integer_sequence; - - template<typename _Tp, _Tp _Num, size_t... _Idx> - struct _Make_integer_sequence<_Tp, _Num, _Index_tuple<_Idx...>> - { - static_assert( _Num >= 0, - "Cannot make integer sequence of negative length" ); - - typedef integer_sequence<_Tp, static_cast<_Tp>(_Idx)...> __type; - }; - /// Alias template make_integer_sequence template<typename _Tp, _Tp _Num> using make_integer_sequence - = typename _Make_integer_sequence<_Tp, _Num>::__type; +#if _GLIBCXX_USE_MAKE_INTEGER_SEQ + = __make_integer_seq<integer_sequence, _Tp, _Num>; +#else + = integer_sequence<_Tp, __integer_pack(_Num)...>; +#endif + +#undef _GLIBCXX_USE_MAKE_INTEGER_SEQ /// Alias template index_sequence template<size_t... _Idx>