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
> 
> 

Reply via email to