On Mon, 13 Oct 2025, Tomasz Kamiński wrote: > This patch introduces the internal helper type _IndexPack to support > introducing a pack of indices via a structured binding declaration: > static constexpr auto [...__is] = _IndexPack<N>();
Nice! This'll prove helpful. > > _IndexPack is a distinct type from _Index_tuple and index_sequence to > enable a simpler implementation: it requires only a single template > parameter, and get<I> performs returns I. Implementing get as a > static member avoids making it visible for ADL overload resolution. > > The use of static on the structured binding is required to work around > PR122269 [1]. > > [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122269 > > libstdc++-v3/ChangeLog: > > * include/bits/utility.h (_IndexPack, tuple_size<_IndexPack<_Num>>) > (tuple_element<_Idx, _IndexPack<_Num>>): Define. > * testsuite/ext/indexpack.cc: New test. > --- > Tested on x86_64-linux locally. OK for trunk? > > libstdc++-v3/include/bits/utility.h | 19 +++++++++++++++++++ > libstdc++-v3/testsuite/ext/indexpack.cc | 19 +++++++++++++++++++ > 2 files changed, 38 insertions(+) > create mode 100644 libstdc++-v3/testsuite/ext/indexpack.cc > > diff --git a/libstdc++-v3/include/bits/utility.h > b/libstdc++-v3/include/bits/utility.h > index 4e574658eba..2bc8629cb92 100644 > --- a/libstdc++-v3/include/bits/utility.h > +++ b/libstdc++-v3/include/bits/utility.h > @@ -313,6 +313,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > inline constexpr bool __is_nontype_v<nontype_t<__val>> = true; > #endif > > +#if __cpp_structured_bindings >= 202411L > + template<size_t _Num> > + struct _IndexPack > + { > + template<size_t _Idx> > + static consteval size_t > + get() noexcept > + { return _Idx; } It seems we can work around PR122269 for now by making get() return a reference to local static: template<size_t _Idx> static consteval const size_t& get() noexcept { static constexpr size_t _S_val = _Idx; return _S_val; } LGTM either way > + }; > + > + template<size_t _Num> > + struct tuple_size<_IndexPack<_Num>> > + { static constexpr size_t value = _Num; }; > + > + template<size_t _Idx, size_t _Num> > + struct tuple_element<_Idx, _IndexPack<_Num>> > + { using type = size_t; }; I guess given the intended use case of this helper, we don't need to care about making this partial spec SFINAE-friendly for when _Idx >= _Num. > +#endif > + > _GLIBCXX_END_NAMESPACE_VERSION > } // namespace > > diff --git a/libstdc++-v3/testsuite/ext/indexpack.cc > b/libstdc++-v3/testsuite/ext/indexpack.cc > new file mode 100644 > index 00000000000..929d77e6bf1 > --- /dev/null > +++ b/libstdc++-v3/testsuite/ext/indexpack.cc > @@ -0,0 +1,19 @@ > +// { dg-do compile { target c++26 } } > + > +#include <utility> > + > +template<std::size_t N> > +void test() > +{ > + // PR122269 static should not be necessary > + static constexpr auto [...ids] = std::_IndexPack<N>(); > + static_assert( sizeof...(ids) == N ); > + static_assert( (ids + ... + 0) == N*(N-1)/2 ); > +} > + > +int main() > +{ > + test<0>(); > + test<4>(); > + test<8>(); > +} > -- > 2.51.0 > >
