[PATCH] libstdc++: Implement P1789R3: structured bindings for std::integer_sequence
Ivan Lazaric
ivan.lazaric1@gmail.com
Sat Apr 4 17:01:23 GMT 2026
P1789 enables accessing the sequence values through structured bindings.
```
auto [...values] = std::make_index_sequence<10>{};
// values is a pack of size 10, and elements 0, 1, 2, ..., 9
```
Corresponding C++ draft commit: 3d71a838ed2a1689dd329f964ec4d58152487151
Feature-test macro integer_sequence has been bumped to 202511L.
libstdc++-v3/ChangeLog:
* include/bits/utility.h:
Implement structured bindings protocol for std::integer_sequence.
* include/bits/version.def: Bump integer_sequence feature-test macro.
* include/bits/version.h: Regenerate.
* testsuite/20_util/integer_sequence/structured_binding.cc: New test.
Signed-off-by: Ivan Lazaric <ivan.lazaric1@gmail.com>
---
Tested everything under 20_util, including the new test.
libstdc++-v3/include/bits/utility.h | 28 ++++++++++++++++++
libstdc++-v3/include/bits/version.def | 5 ++++
libstdc++-v3/include/bits/version.h | 7 ++++-
.../integer_sequence/structured_binding.cc | 29 +++++++++++++++++++
4 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 libstdc++-v3/testsuite/20_util/integer_sequence/structured_binding.cc
diff --git a/libstdc++-v3/include/bits/utility.h b/libstdc++-v3/include/bits/utility.h
index bd6b18d54dd..159884dd814 100644
--- a/libstdc++-v3/include/bits/utility.h
+++ b/libstdc++-v3/include/bits/utility.h
@@ -150,6 +150,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr size_t size() noexcept { return sizeof...(_Idx); }
};
+#if __glibcxx_integer_sequence >= 202511L // C++ >= 26
+ template<typename _Tp, _Tp... _Idx>
+ struct tuple_size<integer_sequence<_Tp, _Idx...>>
+ : integral_constant<size_t, sizeof...(_Idx)> { };
+
+ template<size_t __i, class _Tp, _Tp... _Idx>
+ struct tuple_element<__i, integer_sequence<_Tp, _Idx...>>
+ {
+ static_assert(__i < sizeof...(_Idx));
+ using type = _Tp;
+ };
+
+ template<size_t __i, class _Tp, _Tp... _Idx>
+ struct tuple_element<__i, const integer_sequence<_Tp, _Idx...>>
+ {
+ static_assert(__i < sizeof...(_Idx));
+ using type = _Tp;
+ };
+
+ template<size_t __i, class _Tp, _Tp... _Idx>
+ constexpr _Tp
+ get (integer_sequence<_Tp, _Idx...>) noexcept
+ {
+ static_assert(__i < sizeof...(_Idx));
+ return _Idx...[__i];
+ }
+#endif // __glibcxx_integer_sequence >= 202511L
+
/// Alias template make_integer_sequence
template<typename _Tp, _Tp _Num>
using make_integer_sequence
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index b89e60d156d..6103f6a41d1 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -184,6 +184,11 @@ ftms = {
ftms = {
name = integer_sequence;
+ values = {
+ v = 202511;
+ cxxmin = 26;
+ extra_cond = "__cpp_pack_indexing";
+ };
values = {
v = 201304;
cxxmin = 14;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index d73b547e1b0..0de2ad9e5f3 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -186,7 +186,12 @@
#undef __glibcxx_want_exchange_function
#if !defined(__cpp_lib_integer_sequence)
-# if (__cplusplus >= 201402L)
+# if (__cplusplus > 202302L) && (__cpp_pack_indexing)
+# define __glibcxx_integer_sequence 202511L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_integer_sequence)
+# define __cpp_lib_integer_sequence 202511L
+# endif
+# elif (__cplusplus >= 201402L)
# define __glibcxx_integer_sequence 201304L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_integer_sequence)
# define __cpp_lib_integer_sequence 201304L
diff --git a/libstdc++-v3/testsuite/20_util/integer_sequence/structured_binding.cc b/libstdc++-v3/testsuite/20_util/integer_sequence/structured_binding.cc
new file mode 100644
index 00000000000..b8e9fa1caa1
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/integer_sequence/structured_binding.cc
@@ -0,0 +1,29 @@
+// { dg-do compile { target c++26 } }
+
+#include <utility>
+
+#if __cpp_lib_integer_sequence < 202511L
+# error "Feature-test macro __cpp_lib_integer_sequence is incorrect"
+#endif
+
+constexpr auto
+destructure_sum(auto seq)
+{
+ auto [...elems] = seq;
+ return (0 + ... + elems);
+}
+
+using IS1 = std::make_index_sequence<10>;
+static_assert(std::tuple_size_v<IS1> == 10);
+static_assert(std::is_same_v<std::tuple_element_t<3, IS1>, size_t>);
+static_assert(std::get<7>(IS1{}) == 7);
+static_assert(destructure_sum(IS1{}) == 45);
+
+using IS2 = std::integer_sequence<int, 42, 101, -13>;
+static_assert(std::tuple_size_v<IS2> == 3);
+static_assert(std::is_same_v<std::tuple_element_t<1, IS2>, int>);
+static_assert(std::get<2>(IS2{}) == -13);
+static_assert(destructure_sum(IS2{}) == 130);
+
+using IS3 = std::integer_sequence<char>;
+static_assert(std::tuple_size_v<IS3> == 0);
--
2.43.0
More information about the Libstdc++
mailing list