On Fri, 5 Nov 2021 at 21:19, Patrick Palka wrote: > On Thu, Nov 4, 2021 at 2:34 PM Jonathan Wakely via Libstdc++ > wrote: > > > > Tested powerpc64le-linux, committed to trunk. > > > > > > This reduces the number of class template instantiations needed for code > > using tuples, by reusing _Nth_type in tuple_element and specializing > > tuple_size_v for tuple, pair and array (and const-qualified versions of > > them). > > > > Also define the _Nth_type primary template as a complete type (but with > > no nested 'type' member). This avoids "invalid use of incomplete type" > > errors for out-of-range specializations of tuple_element. Those errors > > would probably be confusing and unhelpful for users. We already have > > a user-friendly static assert in tuple_element itself. > > > > Also ensure that tuple_size_v is available whenever tuple_size is (as > > proposed by LWG 3387). We already do that for tuple_element_t. > > > > libstdc++-v3/ChangeLog: > > > > * include/bits/stl_pair.h (tuple_size_v): Define partial > > specializations for std::pair. > > * include/bits/utility.h (_Nth_type): Move definition here > > and define primary template. > > (tuple_size_v): Move definition here. > > * include/std/array (tuple_size_v): Define partial > > specializations for std::array. > > * include/std/tuple (tuple_size_v): Move primary template to > > . Define partial specializations for > > std::tuple. > > (tuple_element): Change definition to use _Nth_type. > > * include/std/variant (_Nth_type): Move to . > > (variant_alternative, variant): Adjust qualification of > > _Nth_type. > > * testsuite/20_util/tuple/element_access/get_neg.cc: Prune > > additional errors from _Nth_type. > > --- > > libstdc++-v3/include/bits/stl_pair.h | 8 +++ > > libstdc++-v3/include/bits/utility.h | 51 +++++++++++++++- > > libstdc++-v3/include/std/array | 8 +++ > > libstdc++-v3/include/std/tuple | 39 +++++-------- > > libstdc++-v3/include/std/variant | 58 ++----------------- > > .../20_util/tuple/element_access/get_neg.cc | 1 + > > 6 files changed, 84 insertions(+), 81 deletions(-) > > > > diff --git a/libstdc++-v3/include/bits/stl_pair.h > b/libstdc++-v3/include/bits/stl_pair.h > > index 5b400daf97f..6081e0c7fe9 100644 > > --- a/libstdc++-v3/include/bits/stl_pair.h > > +++ b/libstdc++-v3/include/bits/stl_pair.h > > @@ -771,6 +771,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > struct tuple_element<1, pair<_Tp1, _Tp2>> > > { typedef _Tp2 type; }; > > > > +#if __cplusplus >= 201703L > > + template > > + inline constexpr size_t tuple_size_v> = 2; > > + > > + template > > + inline constexpr size_t tuple_size_v> = 2; > > +#endif > > + > > /// @cond undocumented > > template > > struct __pair_get; > > diff --git a/libstdc++-v3/include/bits/utility.h > b/libstdc++-v3/include/bits/utility.h > > index fce52a4530d..c9ffa008217 100644 > > --- a/libstdc++-v3/include/bits/utility.h > > +++ b/libstdc++-v3/include/bits/utility.h > > @@ -70,6 +70,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > struct tuple_size> > > : public tuple_size<_Tp> { }; > > > > +#if __cplusplus >= 201703L > > + template > > + inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; > > +#endif > > + > > /// Gives the type of the ith element of a given tuple type. > > template > > struct tuple_element; > > @@ -97,8 +102,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > }; > > > > #if __cplusplus >= 201402L > > -// The standard says this macro and alias template should be in > > -// but we define them here, to be available in and > too. > > +// The standard says this macro and alias template should be in > but we > > +// we define them here, to be available in , and > too. > > +// _GLIBCXX_RESOLVE_LIB_DEFECTS > > +// 3378. tuple_size_v/tuple_element_t should be available when > > +// tuple_size/tuple_element are > > #define __cpp_lib_tuple_element_t 201402L > > > > template > > @@ -195,6 +203,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > #endif // C++17 > > #endif // C++14 > > > > + template > > + struct _Nth_type > > + { }; > > + > > + template > > + struct _Nth_type<0, _Tp0, _Rest...> > > + { using type = _Tp0; }; > > + > > + template > > + struct _Nth_type<1, _Tp0, _Tp1, _Rest...> > > + { using type = _Tp1; }; > > + > > + template _Rest> > > + struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...> > > + { using type = _Tp2; }; > > + > > + template > + typename... _Rest> > > +#if __cpp_concepts > > + requires (_Np >= 3) > > +#endif > > + struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...> > > + : _Nth_type<_Np - 3, _Rest...> > > + { }; > > + > > +#if ! __cpp_concepts // Need additional specializations to avoid > ambiguities. > > + template > > + struct _Nth_type<0, _Tp0, _Tp1, _Rest...> > > + { using type = _Tp0; }; > > + > > + template _Rest> > > + struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...> > > + { using type = _Tp0; }; > > + > > + template _Rest> > > + struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...> > > + { using type = _Tp1; }; > > +#endif > > + > > _GLIBCXX_END_NAMESPACE_VERSION > > } // namespace > > > > diff --git a/libstdc++-v3/include/std/array > b/libstdc++-v3/include/std/array > > index 3e12d35157c..413f8e2be01 100644 > > --- a/libstdc++-v3/include/std/array > > +++ b/libstdc++-v3/include/std/array > > @@ -481,6 +481,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > using type = _Tp; > > }; > > > > +#if __cplusplus >= 201703L > > + template > > + inline constexpr size_t tuple_size_v> = _Nm; > > + > > + template > > + inline constexpr size_t tuple_size_v> = _Nm; > > +#endif > > + > > template > > struct __is_tuple_like_impl> : true_type > > { }; > > diff --git a/libstdc++-v3/include/std/tuple > b/libstdc++-v3/include/std/tuple > > index aaee0b8826a..b82cdf12569 100644 > > --- a/libstdc++-v3/include/std/tuple > > +++ b/libstdc++-v3/include/std/tuple > > @@ -1344,36 +1344,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > struct tuple_size> > > : public integral_constant { }; > > > > -#if __cplusplus > 201402L > > - template > > - inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; > > +#if __cplusplus >= 201703L > > + template > > + inline constexpr size_t tuple_size_v> > > Missing ... after _Types? > > > + = sizeof...(_Types); > > + > > + template > > + inline constexpr size_t tuple_size_v> > > Same here. (I guess now's a good time to fix PR100652!) > > > Oops! Fixed by the attached patch, pushed to trunk. Thanks.