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>();
_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; } + }; + + 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; }; +#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
