]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: New _IotaArray utility to simplify index pack creation
authorMatthias Kretz <m.kretz@gsi.de>
Fri, 24 Oct 2025 11:28:29 +0000 (13:28 +0200)
committerMatthias Kretz <m.kretz@gsi.de>
Mon, 27 Oct 2025 10:48:49 +0000 (11:48 +0100)
This patch introduces the internal helper type _IotaArray to simplify
defining a pack of indices via a structured binding declaration:
constexpr auto [...__is] = _IotaArray<N>;

_IotaArray is a C-array for lowest overhead in terms of template
instantiations. Non-GCC compilers that do not implement
__integer_pack have a slightly higher overhead.

libstdc++-v3/ChangeLog:

* include/bits/utility.h (_IotaArray): Define.
* testsuite/ext/iotaarray.cc: New test.

Signed-off-by: Matthias Kretz <m.kretz@gsi.de>
libstdc++-v3/include/bits/utility.h
libstdc++-v3/testsuite/ext/iotaarray.cc [new file with mode: 0644]

index 4e574658eba598d6e55f016d5e5ba34f09db6bd2..96ac69883f16c3bd39dc876dbac290d9601f45ee 100644 (file)
@@ -172,6 +172,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
 #endif // __glibcxx_integer_sequence
 
+#if __cpp_structured_bindings >= 202411L
+#if __has_builtin(__integer_pack)
+  template <auto _Num, typename _Tp = decltype(_Num)>
+    inline constexpr _Tp
+    _IotaArray[_Num] = {__integer_pack(_Tp(_Num))...};
+#elif defined __glibcxx_integer_sequence
+  template <auto _Num, typename _Tp = decltype(_Num), typename = make_integer_sequence<_Tp, _Num>>
+    inline constexpr _Tp
+    _IotaArray[_Num];
+
+  template <auto _Num, typename _Tp, _Tp... _Is>
+    inline constexpr _Tp
+    _IotaArray<_Num, _Tp, integer_sequence<_Tp, _Is...>>[_Num] = {_Is...};
+#endif // __integer_pack
+#endif // __cpp_structured_bindings >= 202411L
+
 #if __cplusplus >= 201703L
 
   struct in_place_t {
diff --git a/libstdc++-v3/testsuite/ext/iotaarray.cc b/libstdc++-v3/testsuite/ext/iotaarray.cc
new file mode 100644 (file)
index 0000000..b259602
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++26 } }
+
+#include <utility>
+#include <type_traits>
+
+template<auto N>
+void test()
+{
+  constexpr auto [id0, ...ids] = std::_IotaArray<N>;
+  static_assert( std::is_same_v<decltype(id0), const decltype(N)> );
+  static_assert( sizeof...(ids) == N - 1 );
+  static_assert( (id0 + ... + ids) == N*(N-1)/2 );
+}
+
+int main()
+{
+  test<1>();
+  test<4u>();
+  test<8ull>();
+}