-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[libc++] P1789R3: Library Support for Expansion Statements #167184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-libcxx Author: None (Tsche) ChangesP1789R3 was accepted for C++26 through LWG motion 14 at the 2025 Kona meeting. This patch implements it, along with tests and documentation changes. Full diff: https://github.com/llvm/llvm-project/pull/167184.diff 10 Files Affected:
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index d5ed9188b1b23..349164a96de87 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -474,6 +474,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_inplace_vector`` *unimplemented*
---------------------------------------------------------- -----------------
+ ``__cpp_lib_integer_sequence`` ``202511L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_is_sufficiently_aligned`` ``202411L``
---------------------------------------------------------- -----------------
``__cpp_lib_is_virtual_base_of`` ``202406L``
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index a6a0ac8670fb5..685e7a22be28a 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -48,6 +48,7 @@ Implemented Papers
- P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__)
- P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://llvm.org/PR105424>`__)
- P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
+- P1789R3: Library Support for Expansion Statements
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index e0e47b864d38f..7347408fbb3c1 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -157,3 +157,5 @@
"`P3552R3 <https://wg21.link/P3552R3>`__","Add a Coroutine Task Type","2025-06 (Sofia)","","","`#148182 <https://github.com/llvm/llvm-project/issues/148182>`__",""
"`P1317R2 <https://wg21.link/P1317R2>`__","Remove return type deduction in ``std::apply``","2025-06 (Sofia)","","","`#148183 <https://github.com/llvm/llvm-project/issues/148183>`__",""
"","","","","","",""
+"`P1789R3 <https://wg21.link/P1789R3>`__","Library Support for Expansion Statements`","2025-11 (Kona)","|Complete|","22","",""
+"","","","","","",""
diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h
index 329826ae5eda2..8889c1196a450 100644
--- a/libcxx/include/__utility/integer_sequence.h
+++ b/libcxx/include/__utility/integer_sequence.h
@@ -13,6 +13,11 @@
#include <__cstddef/size_t.h>
#include <__type_traits/is_integral.h>
+#if _LIBCPP_STD_VER >= 26
+# include <__tuple/tuple_element.h>
+# include <__tuple/tuple_size.h>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -67,6 +72,30 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_I
}
# endif // _LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 26
+// structured binding support for integer_sequence
+template <typename _Tp, _Tp... _Indices>
+struct tuple_size<integer_sequence<_Tp, _Indices...>> : public integral_constant<size_t, sizeof...(_Indices)> {};
+
+template <size_t _Ip, typename _Tp, _Tp... _Indices>
+struct tuple_element<_Ip, integer_sequence<_Tp, _Indices...>> {
+ static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (std::integer_sequence)");
+ using type _LIBCPP_NODEBUG = _Tp;
+};
+
+template <size_t _Ip, typename _Tp, _Tp... _Indices>
+struct tuple_element<_Ip, const integer_sequence<_Tp, _Indices...>> {
+ static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (const std::integer_sequence)");
+ using type _LIBCPP_NODEBUG = _Tp;
+};
+
+template <size_t _Ip, typename _Tp, _Tp... _Indices>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp get(integer_sequence<_Tp, _Indices...>) _NOEXCEPT {
+ static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::get<> (std::integer_sequence)");
+ return _Indices...[_Ip];
+}
+# endif // _LIBCPP_STD_VER >= 20
+
# endif // _LIBCPP_STD_VER >= 14
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/version b/libcxx/include/version
index b0030602f854a..c9a4c58a9a289 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -141,7 +141,7 @@ __cpp_lib_incomplete_container_elements 201505L <forward_list> <
__cpp_lib_inplace_vector 202406L <inplace_vector>
__cpp_lib_int_pow2 202002L <bit>
__cpp_lib_integer_comparison_functions 202002L <utility>
-__cpp_lib_integer_sequence 201304L <utility>
+__cpp_lib_integer_sequence 202511L <utility>
__cpp_lib_integral_constant_callable 201304L <type_traits>
__cpp_lib_interpolate 201902L <cmath> <numeric>
__cpp_lib_invoke 201411L <functional>
@@ -582,6 +582,8 @@ __cpp_lib_void_t 201411L <type_traits>
// # define __cpp_lib_generate_random 202403L
// # define __cpp_lib_hazard_pointer 202306L
// # define __cpp_lib_inplace_vector 202406L
+# undef __cpp_lib_integer_sequence
+# define __cpp_lib_integer_sequence 202511L
# define __cpp_lib_is_sufficiently_aligned 202411L
# if __has_builtin(__builtin_is_virtual_base_of)
# define __cpp_lib_is_virtual_base_of 202406L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
index b882a5df04ae3..1d82ef9ec0e86 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
@@ -432,8 +432,8 @@
# ifndef __cpp_lib_integer_sequence
# error "__cpp_lib_integer_sequence should be defined in c++26"
# endif
-# if __cpp_lib_integer_sequence != 201304L
-# error "__cpp_lib_integer_sequence should have the value 201304L in c++26"
+# if __cpp_lib_integer_sequence != 202511L
+# error "__cpp_lib_integer_sequence should have the value 202511L in c++26"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 8189c5c4e5985..355ca57bac64c 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -7156,8 +7156,8 @@
# ifndef __cpp_lib_integer_sequence
# error "__cpp_lib_integer_sequence should be defined in c++26"
# endif
-# if __cpp_lib_integer_sequence != 201304L
-# error "__cpp_lib_integer_sequence should have the value 201304L in c++26"
+# if __cpp_lib_integer_sequence != 202511L
+# error "__cpp_lib_integer_sequence should have the value 202511L in c++26"
# endif
# ifndef __cpp_lib_integral_constant_callable
diff --git a/libcxx/test/std/utilities/intseq/intseq.binding/integer_seq.pass.cpp b/libcxx/test/std/utilities/intseq/intseq.binding/integer_seq.pass.cpp
new file mode 100644
index 0000000000000..8deda77419e66
--- /dev/null
+++ b/libcxx/test/std/utilities/intseq/intseq.binding/integer_seq.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// <utility>
+
+// structured binding support for integer_sequence
+
+#include <tuple>
+#include <utility>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ using empty = std::integer_sequence<int>;
+ using size4 = std::integer_sequence<int, 9, 8, 7, 2>;
+
+ static_assert ( std::tuple_size_v<empty> == 0, "empty size wrong" );
+ static_assert ( std::tuple_size_v<const empty> == 0, "empty size wrong" );
+
+ static_assert ( std::tuple_size_v<size4> == 4, "size4 size wrong" );
+ static_assert ( std::tuple_size_v<const size4> == 4, "size4 size wrong" );
+
+ static_assert ( std::is_same_v<std::tuple_element_t<0, size4>, int>, "size4 type wrong" );
+ static_assert ( std::is_same_v<std::tuple_element_t<1, size4>, int>, "size4 type wrong" );
+ static_assert ( std::is_same_v<std::tuple_element_t<2, size4>, int>, "size4 type wrong" );
+ static_assert ( std::is_same_v<std::tuple_element_t<3, size4>, int>, "size4 type wrong" );
+
+ static_assert ( std::is_same_v<std::tuple_element_t<0, const size4>, int>, "const4 type wrong" );
+ static_assert ( std::is_same_v<std::tuple_element_t<1, const size4>, int>, "const4 type wrong" );
+ static_assert ( std::is_same_v<std::tuple_element_t<2, const size4>, int>, "const4 type wrong" );
+ static_assert ( std::is_same_v<std::tuple_element_t<3, const size4>, int>, "const4 type wrong" );
+
+ constexpr static size4 seq4{};
+ static_assert ( get<0> (seq4) == 9, "size4 element 0 wrong" );
+ static_assert ( get<1> (seq4) == 8, "size4 element 1 wrong" );
+ static_assert ( get<2> (seq4) == 7, "size4 element 2 wrong" );
+ static_assert ( get<3> (seq4) == 2, "size4 element 3 wrong" );
+
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/intseq/intseq.binding/integer_seq.verify.cpp b/libcxx/test/std/utilities/intseq/intseq.binding/integer_seq.verify.cpp
new file mode 100644
index 0000000000000..9c93d11b28ceb
--- /dev/null
+++ b/libcxx/test/std/utilities/intseq/intseq.binding/integer_seq.verify.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+// <utility>
+
+// Expect failures for tuple_element and get with empty integer_sequence
+
+#include <utility>
+
+void f() {
+ using test1 = typename std::tuple_element<0, std::integer_sequence<int>>::type; // expected-error-re@*:* {{static assertion failed{{.*}}Index out of bounds in std::tuple_element<> (std::integer_sequence)}}
+ using test2 = typename std::tuple_element<0, const std::integer_sequence<int>>::type; // expected-error-re@*:* {{static assertion failed{{.*}}Index out of bounds in std::tuple_element<> (const std::integer_sequence)}}
+
+ auto empty = std::integer_sequence<int>();
+ // expected-error-re@*:* {{static assertion failed{{.*}}Index out of bounds in std::get<> (std::integer_sequence)}}
+ // expected-error-re@*:* {{invalid index 0 for pack '{{.*}}' of size 0}}
+ (void)std::get<0>(empty);
+}
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 22209f53d50d7..914172410e332 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -764,7 +764,10 @@ def add_version_header(tc):
},
{
"name": "__cpp_lib_integer_sequence",
- "values": {"c++14": 201304},
+ "values": {
+ "c++14": 201304,
+ "c++26": 202511, # P1789R3 Library Support for Expansion Statements
+ },
"headers": ["utility"],
},
{
|
|
✅ With the latest revision this PR passed the Python code formatter. |
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
P1789R3 was accepted for C++26 through LWG motion 14 at the 2025 Kona meeting. This patch implements it, along with tests and documentation changes.