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

Reply via email to