Tested on x86_64-linux. (Not tested with Clang yet.) OK for trunk?
--------------------- 8< --------------------
This patch introduces the internal helper type _IndexPack to simplify
defining a pack of indices via a structured binding declaration:
constexpr auto [...__is] = _IndexPack<N>;
_IndexPack is a distinct object to enable the 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 (_IndexPack): Define.
* testsuite/ext/indexpack.cc: New test.
Signed-off-by: Matthias Kretz <[email protected]>
---
libstdc++-v3/include/bits/utility.h | 14 ++++++++++++++
libstdc++-v3/testsuite/ext/indexpack.cc | 20 ++++++++++++++++++++
2 files changed, 34 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..6ebcdbe08ef 100644
--- a/libstdc++-v3/include/bits/utility.h
+++ b/libstdc++-v3/include/bits/utility.h
@@ -170,6 +170,20 @@ struct integer_sequence
/// Alias template index_sequence_for
template<typename... _Types>
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
+
+#if __has_builtin(__integer_pack)
+ template <auto _Num, typename _Tp = decltype(_Num)>
+ inline constexpr _Tp
+ _IndexPack[_Num] = {__integer_pack(_Tp(_Num))...};
+#else
+ template <auto _Num, typename _Tp = decltype(_Num), typename =
make_integer_sequence<_Tp, _Num>>
+ inline constexpr _Tp
+ _IndexPack[_Num];
+
+ template <auto _Num, typename _Tp, _Tp... _Is>
+ inline constexpr _Tp
+ _IndexPack<_Num, _Tp, integer_sequence<_Tp, _Is...>>[_Num] = {_Is...};
+#endif // __integer_pack
#endif // __glibcxx_integer_sequence
#if __cplusplus >= 201703L
diff --git a/libstdc++-v3/testsuite/ext/indexpack.cc b/libstdc++-v3/testsuite/
ext/indexpack.cc
new file mode 100644
index 00000000000..bd835fdbc4b
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/indexpack.cc
@@ -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::_IndexPack<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>();
+}
--
──────────────────────────────────────────────────────────────────────────
Dr. Matthias Kretz https://mattkretz.github.io
GSI Helmholtz Center for Heavy Ion Research https://gsi.de
std::simd
──────────────────────────────────────────────────────────────────────────