[libcxx-commits] [libcxx] [libc++] constexpr deque (PR #129368)

Nhat Nguyen via libcxx-commits libcxx-commits at lists.llvm.org
Sat Mar 1 12:22:25 PST 2025


https://github.com/changkhothuychung updated https://github.com/llvm/llvm-project/pull/129368

>From 171cd5aedbd28a58568ed2735a88d6bdc8a04ea4 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 1 Mar 2025 01:59:41 -0500
Subject: [PATCH 1/5] constexpr deque

---
 libcxx/include/deque | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/deque b/libcxx/include/deque
index 95200b4801d7f..c92b89aa9f1c0 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -2543,7 +2543,8 @@ inline void deque<_Tp, _Allocator>::clear() _NOEXCEPT {
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
+inline _LIBCPP_HIDE_FROM_ABI constexpr bool
+operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
   const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
   return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
 }
@@ -2578,7 +2579,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x,
 #  else // _LIBCPP_STD_VER <= 17
 
 template <class _Tp, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
+_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> constexpr
 operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
   return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
 }
@@ -2586,14 +2587,14 @@ operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y
 #  endif // _LIBCPP_STD_VER <= 17
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
+inline _LIBCPP_HIDE_FROM_ABI constexpr void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
   __x.swap(__y);
 }
 
 #  if _LIBCPP_STD_VER >= 20
 template <class _Tp, class _Allocator, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
+inline _LIBCPP_HIDE_FROM_ABI constexpr typename deque<_Tp, _Allocator>::size_type
 erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
   auto __old_size = __c.size();
   __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end());
@@ -2601,7 +2602,7 @@ erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
 }
 
 template <class _Tp, class _Allocator, class _Predicate>
-inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type
+inline _LIBCPP_HIDE_FROM_ABI constexpr typename deque<_Tp, _Allocator>::size_type
 erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
   auto __old_size = __c.size();
   __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end());

>From caf34bf171925980dce184270b4415d97e10d568 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 1 Mar 2025 14:45:24 -0500
Subject: [PATCH 2/5] use new macros

---
 libcxx/include/deque | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/deque b/libcxx/include/deque
index c92b89aa9f1c0..beea24604d258 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -2543,7 +2543,7 @@ inline void deque<_Tp, _Allocator>::clear() _NOEXCEPT {
 }
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI constexpr bool
+inline _LIBCPP_CONSTEXPR_SINCE_CXX26 constexpr bool
 operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
   const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
   return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
@@ -2579,7 +2579,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x,
 #  else // _LIBCPP_STD_VER <= 17
 
 template <class _Tp, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> constexpr
+_LIBCPP_CONSTEXPR_SINCE_CXX26 __synth_three_way_result<_Tp> constexpr
 operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
   return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
 }
@@ -2587,14 +2587,14 @@ operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y
 #  endif // _LIBCPP_STD_VER <= 17
 
 template <class _Tp, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI constexpr void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
+inline _LIBCPP_CONSTEXPR_SINCE_CXX26 constexpr void swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
   __x.swap(__y);
 }
 
 #  if _LIBCPP_STD_VER >= 20
 template <class _Tp, class _Allocator, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI constexpr typename deque<_Tp, _Allocator>::size_type
+inline _LIBCPP_CONSTEXPR_SINCE_CXX26 constexpr typename deque<_Tp, _Allocator>::size_type
 erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
   auto __old_size = __c.size();
   __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end());
@@ -2602,7 +2602,7 @@ erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
 }
 
 template <class _Tp, class _Allocator, class _Predicate>
-inline _LIBCPP_HIDE_FROM_ABI constexpr typename deque<_Tp, _Allocator>::size_type
+inline _LIBCPP_CONSTEXPR_SINCE_CXX26 constexpr typename deque<_Tp, _Allocator>::size_type
 erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
   auto __old_size = __c.size();
   __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end());

>From 7e8a820d1f61012e089e9436d56582dd0b36e723 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 1 Mar 2025 15:03:32 -0500
Subject: [PATCH 3/5] update test files to reflect constexpr

---
 .../std/containers/sequences/deque/compare.pass.cpp   | 10 +++++++++-
 .../sequences/deque/compare.three_way.pass.cpp        | 11 +++++++++--
 .../sequences/deque/deque.capacity/access.pass.cpp    | 10 +++++++++-
 .../sequences/deque/deque.capacity/empty.pass.cpp     |  9 ++++++++-
 .../sequences/deque/deque.capacity/max_size.pass.cpp  | 10 +++++++++-
 .../deque/deque.capacity/resize_size.pass.cpp         | 10 +++++++++-
 .../deque/deque.capacity/resize_size_value.pass.cpp   | 10 +++++++++-
 .../deque/deque.capacity/shrink_to_fit.pass.cpp       | 10 +++++++++-
 .../sequences/deque/deque.capacity/size.pass.cpp      | 10 +++++++++-
 .../containers/sequences/deque/get_allocator.pass.cpp | 10 +++++++++-
 .../std/containers/sequences/deque/iterators.pass.cpp |  9 ++++++++-
 .../std/containers/sequences/deque/types.pass.cpp     | 10 +++++++++-
 12 files changed, 106 insertions(+), 13 deletions(-)

diff --git a/libcxx/test/std/containers/sequences/deque/compare.pass.cpp b/libcxx/test/std/containers/sequences/deque/compare.pass.cpp
index 526e3d38e7dff..25aea88911d82 100644
--- a/libcxx/test/std/containers/sequences/deque/compare.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/compare.pass.cpp
@@ -37,7 +37,7 @@
 
 #include "test_comparisons.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     const std::deque<int> d1, d2;
     assert(testComparisons(d1, d2, true, false));
@@ -113,6 +113,14 @@ int main(int, char**) {
     const std::deque<LessAndEqComp> d2(items2, items2 + 2);
     assert(testComparisons(d1, d2, false, false));
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/compare.three_way.pass.cpp b/libcxx/test/std/containers/sequences/deque/compare.three_way.pass.cpp
index 3d5646a844951..f35ef6081c866 100644
--- a/libcxx/test/std/containers/sequences/deque/compare.three_way.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/compare.three_way.pass.cpp
@@ -18,8 +18,15 @@
 
 #include "test_container_comparisons.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   assert(test_sequence_container_spaceship<std::deque>());
-  // `std::deque` is not constexpr, so no `static_assert` test here.
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp
index 294663c5bd356..fa2ab8c2f45b1 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/access.pass.cpp
@@ -47,7 +47,7 @@ C make(int size, int start = 0) {
   return c;
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     typedef std::deque<int> C;
     C c = make<std::deque<int> >(10);
@@ -118,6 +118,14 @@ int main(int, char**) {
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c));
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/empty.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/empty.pass.cpp
index 5e3a6ec1cea82..cb684a312067b 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/empty.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/empty.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     typedef std::deque<int> C;
     C c;
@@ -46,6 +46,13 @@ int main(int, char**) {
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c));
   }
 #endif
+  return true;
+}
 
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp
index 39feabe3889b3..8043e8e030114 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_allocator.h"
 #include "test_macros.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     typedef limited_allocator<int, 10> A;
     typedef std::deque<int, A> C;
@@ -45,6 +45,14 @@ int main(int, char**) {
     assert(c.max_size() <= alloc_max_size(c.get_allocator()));
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c));
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
index 767fe7ae8864e..8bd735a2cedd5 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
@@ -63,7 +63,7 @@ void testN(int start, int N, int M) {
   test(c1, M);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     int rng[]   = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng) / sizeof(rng[0]);
@@ -90,6 +90,14 @@ int main(int, char**) {
           testN<std::deque<int, safe_allocator<int>>>(rng[i], rng[j], rng[k]);
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
index 0abd94759a50f..9e1d3ff39e18f 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
@@ -63,7 +63,7 @@ void testN(int start, int N, int M) {
   test(c1, M, -10);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     int rng[]   = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng) / sizeof(rng[0]);
@@ -91,5 +91,13 @@ int main(int, char**) {
   }
 #endif
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
index 34eedf8d050b7..fed42d2b691c9 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
@@ -50,7 +50,7 @@ void testN(int start, int N) {
   test(c1);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     int rng[]   = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng) / sizeof(rng[0]);
@@ -74,6 +74,14 @@ int main(int, char**) {
         testN<std::deque<int, safe_allocator<int>> >(rng[i], rng[j]);
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.capacity/size.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.capacity/size.pass.cpp
index 5c6a34867b39a..97219518ab4c5 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.capacity/size.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.capacity/size.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     typedef std::deque<int> C;
     C c;
@@ -72,6 +72,14 @@ int main(int, char**) {
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c));
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/get_allocator.pass.cpp b/libcxx/test/std/containers/sequences/deque/get_allocator.pass.cpp
index 6b8bc6c555bcd..38cb73cfe5e28 100644
--- a/libcxx/test/std/containers/sequences/deque/get_allocator.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/get_allocator.pass.cpp
@@ -18,7 +18,7 @@
 #include "test_allocator.h"
 #include "test_macros.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     std::allocator<int> alloc;
     const std::deque<int> d(alloc);
@@ -29,6 +29,14 @@ int main(int, char**) {
     const std::deque<int, other_allocator<int> > d(alloc);
     assert(d.get_allocator() == alloc);
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp b/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp
index 337fd688ebcdb..604a5a79d9671 100644
--- a/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp
@@ -22,7 +22,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     typedef std::deque<int> C;
     C c;
@@ -104,6 +104,13 @@ int main(int, char**) {
 #  endif // TEST_STD_VER > 20
   }
 #endif
+  return true;
+}
 
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/types.pass.cpp b/libcxx/test/std/containers/sequences/deque/types.pass.cpp
index 8184d55873d20..da12694aa14c0 100644
--- a/libcxx/test/std/containers/sequences/deque/types.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/types.pass.cpp
@@ -77,7 +77,7 @@ void test() {
                 "");
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool tests() {
   test<int, test_allocator<int> >();
   test<int*, std::allocator<int*> >();
   test<Copyable, test_allocator<Copyable> >();
@@ -106,6 +106,14 @@ int main(int, char**) {
                   "");
   }
 #endif
+  return false;
+}
+
+int main(int, char**) {
+  tests();
+#if TEST_STD_VER >= 26
+  static_assert(tests());
+#endif
 
   return 0;
 }

>From 28f98a858b1e5a4e5243b108e8422278d938a9bb Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 1 Mar 2025 15:17:17 -0500
Subject: [PATCH 4/5] more files updated

---
 .../sequences/deque/deque.cons/alloc.pass.cpp | 28 ++++++++++++-------
 .../assign_initializer_list.pass.cpp          |  9 +++++-
 .../deque.cons/assign_iter_iter.pass.cpp      |  4 ++-
 .../deque.cons/assign_size_value.pass.cpp     | 10 ++++++-
 .../sequences/deque/deque.cons/copy.pass.cpp  | 10 ++++++-
 .../deque/deque.cons/copy_alloc.pass.cpp      | 10 ++++++-
 .../deque/deque.cons/deduct.pass.cpp          | 10 ++++++-
 .../deque/deque.cons/default.pass.cpp         | 10 ++++++-
 .../deque.cons/default_noexcept.pass.cpp      | 10 ++++++-
 .../deque/deque.cons/dtor_noexcept.pass.cpp   | 10 ++++++-
 .../deque/deque.cons/from_range.pass.cpp      | 10 ++++++-
 .../deque.cons/initializer_list.pass.cpp      | 10 ++++++-
 .../initializer_list_alloc.pass.cpp           | 10 ++++++-
 .../deque/deque.cons/iter_iter.pass.cpp       |  5 +++-
 .../deque/deque.cons/iter_iter_alloc.pass.cpp |  4 +++
 .../deque/deque.cons/move_alloc.pass.cpp      | 10 ++++++-
 16 files changed, 136 insertions(+), 24 deletions(-)

diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp
index 4b19ef3e22173..55bbc0652737c 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp
@@ -20,23 +20,31 @@
 #include "min_allocator.h"
 
 template <class T, class Allocator>
-void test(const Allocator& a) {
+void test_util(const Allocator& a) {
   std::deque<T, Allocator> d(a);
   assert(d.size() == 0);
   assert(d.get_allocator() == a);
   LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(d));
 }
 
-int main(int, char**) {
-  test<int>(std::allocator<int>());
-  test<NotConstructible>(test_allocator<NotConstructible>(3));
+TEST_CONSTEXPR_CXX26 bool test() {
+  test_util<int>(std::allocator<int>());
+  test_util<NotConstructible>(test_allocator<NotConstructible>(3));
 #if TEST_STD_VER >= 11
-  test<int>(min_allocator<int>());
-  test<int>(safe_allocator<int>());
-  test<NotConstructible>(min_allocator<NotConstructible>{});
-  test<NotConstructible>(safe_allocator<NotConstructible>{});
-  test<int>(explicit_allocator<int>());
-  test<NotConstructible>(explicit_allocator<NotConstructible>{});
+  test_util<int>(min_allocator<int>());
+  test_util<int>(safe_allocator<int>());
+  test_util<NotConstructible>(min_allocator<NotConstructible>{});
+  test_util<NotConstructible>(safe_allocator<NotConstructible>{});
+  test_util<int>(explicit_allocator<int>());
+  test_util<NotConstructible>(explicit_allocator<NotConstructible>{});
+#endif
+  return false;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp
index bc57098463eaa..6e2a5b1369e70 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     std::deque<int> d;
     d.assign({3, 4, 5, 6});
@@ -40,6 +40,13 @@ int main(int, char**) {
     assert(d[3] == 6);
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(d));
   }
+  return true;
+}
 
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
index c57eb9d08cabe..5a1b29c02ca2e 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
@@ -144,6 +144,8 @@ void test_iterators() {
 
 int main(int, char**) {
   basic_test();
-
+#if TEST_STD_VER >= 26
+  static_assert(basic_test());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
index 30277125e46e1..97857088a77e4 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
@@ -55,7 +55,7 @@ void testN(int start, int N, int M) {
   test(c1, M, -10);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     int rng[]   = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng) / sizeof(rng[0]);
@@ -74,6 +74,14 @@ int main(int, char**) {
           testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp
index 9f7a429d122a3..4de61a8445f1c 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/copy.pass.cpp
@@ -26,7 +26,7 @@ void test(const C& x) {
   LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(x));
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool tests() {
   {
     int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
     int* an  = ab + sizeof(ab) / sizeof(ab[0]);
@@ -63,6 +63,14 @@ int main(int, char**) {
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(v2));
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+#if TEST_STD_VER >= 26
+  static_assert(tests());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp
index fb3ad3c25a8f1..a93a28204abab 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp
@@ -26,7 +26,7 @@ void test(const C& x, const typename C::allocator_type& a) {
   LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c));
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool tests() {
   {
     int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
     int* an  = ab + sizeof(ab) / sizeof(ab[0]);
@@ -49,6 +49,14 @@ int main(int, char**) {
     test(std::deque<int, safe_allocator<int> >(ab, an, safe_allocator<int>()), safe_allocator<int>());
   }
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+#if TEST_STD_VER >= 26
+  static_assert(tests());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.pass.cpp
index c481ac59ab411..995eeb578f7b2 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.pass.cpp
@@ -32,7 +32,7 @@
 
 struct A {};
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   //  Test the explicit deduction guides
   {
     const int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -156,6 +156,14 @@ int main(int, char**) {
 #endif
 
   SequenceContainerDeductionGuidesSfinaeAway<std::deque, std::deque<int>>();
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/default.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/default.pass.cpp
index 6bfd4857f9b0a..f6fa7c642ff6c 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/default.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/default.pass.cpp
@@ -31,13 +31,21 @@ void test() {
 #endif
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool tests() {
   test<int, std::allocator<int> >();
   test<NotConstructible, limited_allocator<NotConstructible, 1> >();
 #if TEST_STD_VER >= 11
   test<int, min_allocator<int> >();
   test<NotConstructible, min_allocator<NotConstructible> >();
 #endif
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp
index 244fef829f521..a37504dcb5568 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/default_noexcept.pass.cpp
@@ -29,7 +29,7 @@ struct some_alloc {
   void allocate(std::size_t);
 };
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
 #if defined(_LIBCPP_VERSION)
   {
     typedef std::deque<MoveOnly> C;
@@ -48,6 +48,14 @@ int main(int, char**) {
     typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C;
     static_assert(!std::is_nothrow_default_constructible<C>::value, "");
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp
index f0a839484f9dc..8aa967ebe0885 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/dtor_noexcept.pass.cpp
@@ -27,7 +27,7 @@ struct some_alloc {
   void allocate(std::size_t);
 };
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     typedef std::deque<MoveOnly> C;
     static_assert(std::is_nothrow_destructible<C>::value, "");
@@ -46,6 +46,14 @@ int main(int, char**) {
     static_assert(!std::is_nothrow_destructible<C>::value, "");
   }
 #endif // _LIBCPP_VERSION
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/from_range.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/from_range.pass.cpp
index cfc07ab7bc797..251d6dc18d51d 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/from_range.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/from_range.pass.cpp
@@ -17,7 +17,7 @@
 // template<container-compatible-range<T> R>
 //   deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   for_all_iterators_and_allocators<int>([]<class Iter, class Sent, class Alloc>() {
     test_sequence_container<std::deque, int, Iter, Sent, Alloc>([]([[maybe_unused]] const auto& c) {
       LIBCPP_ASSERT(c.__invariants());
@@ -31,6 +31,14 @@ int main(int, char**) {
   // See https://github.com/llvm/llvm-project/issues/62056.
   //test_exception_safety_throwing_copy<std::deque>();
   //test_exception_safety_throwing_allocator<std::deque, int>();
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp
index d7df936f9413d..4c41ca54aafdd 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     std::deque<int> d = {3, 4, 5, 6};
     assert(d.size() == 4);
@@ -38,6 +38,14 @@ int main(int, char**) {
     assert(d[3] == 6);
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(d));
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp
index f5f1a23243002..3dd1d0c4dfc6a 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp
@@ -20,7 +20,7 @@
 #include "test_allocator.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     std::deque<int, test_allocator<int>> d({3, 4, 5, 6}, test_allocator<int>(3));
     assert(d.get_allocator() == test_allocator<int>(3));
@@ -41,6 +41,14 @@ int main(int, char**) {
     assert(d[3] == 6);
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(d));
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp
index 1f8a044d0b602..379c8a88b1d7d 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp
@@ -105,6 +105,9 @@ void test_emplacable_concept() {
 int main(int, char**) {
   basic_test();
   test_emplacable_concept();
-
+#if TEST_STD_VER >= 26
+  static_assert(basic_test());
+  static_assert(test_emplacable_concept());
+#endif
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp
index 61318c3d0f2d3..ec95a9ff7e6d1 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp
@@ -101,6 +101,10 @@ void test_emplacable_concept() {
 int main(int, char**) {
   basic_test();
   test_emplacable_concept();
+#if TEST_STD_VER >= 26
+  static_assert(basic_test());
+  static_assert(test_emplacable_concept());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp
index 985d8ad9db67f..5940e05c56fd6 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/move_alloc.pass.cpp
@@ -21,7 +21,7 @@
 #include "test_allocator.h"
 #include "min_allocator.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
   {
     int ab[]      = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
     const int* an = ab + sizeof(ab) / sizeof(ab[0]);
@@ -94,6 +94,14 @@ int main(int, char**) {
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c2));
     LIBCPP_ASSERT(is_double_ended_contiguous_container_asan_correct(c3));
   }
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
 
   return 0;
 }

>From 00e3607e5fd649f813e30fe85332693eb07e6201 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sat, 1 Mar 2025 15:21:40 -0500
Subject: [PATCH 5/5] feature test macros

---
 libcxx/docs/FeatureTestMacroTable.rst         |  4 +-
 libcxx/include/version                        |  6 ++-
 .../complex.version.compile.pass.cpp          | 42 +++++++--------
 .../deque.version.compile.pass.cpp            | 28 ++++++++++
 .../version.version.compile.pass.cpp          | 52 ++++++++++++++-----
 .../generate_feature_test_macro_components.py |  7 ++-
 6 files changed, 102 insertions(+), 37 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index dcf9838edd74b..f53ac166cffce 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -202,7 +202,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_algorithms``                         ``201806L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_constexpr_complex``                            ``201711L``
+    ``__cpp_lib_constexpr_deque``                              ``202502L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_dynamic_alloc``                      ``201907L``
     ---------------------------------------------------------- -----------------
@@ -416,6 +416,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bitset``                                       ``202306L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_complex``                            ``201711L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_new``                                ``202406L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_constrained_equality``                         *unimplemented*
diff --git a/libcxx/include/version b/libcxx/include/version
index 63ead9fd5d29d..c783da85fb7ea 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -64,7 +64,8 @@ __cpp_lib_constexpr_algorithms                          201806L <algorithm> <uti
 __cpp_lib_constexpr_bitset                              202207L <bitset>
 __cpp_lib_constexpr_charconv                            202207L <charconv>
 __cpp_lib_constexpr_cmath                               202202L <cmath> <cstdlib>
-__cpp_lib_constexpr_complex                             201711L <complex>
+__cpp_lib_constexpr_complex                             201711L <deque>
+__cpp_lib_constexpr_deque                               202502L <complex>
 __cpp_lib_constexpr_dynamic_alloc                       201907L <memory>
 __cpp_lib_constexpr_functional                          201907L <functional>
 __cpp_lib_constexpr_iterator                            201811L <iterator>
@@ -398,7 +399,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # endif
 # define __cpp_lib_concepts                             202002L
 # define __cpp_lib_constexpr_algorithms                 201806L
-# define __cpp_lib_constexpr_complex                    201711L
+# define __cpp_lib_constexpr_deque                      202502L
 # define __cpp_lib_constexpr_dynamic_alloc              201907L
 # define __cpp_lib_constexpr_functional                 201907L
 # define __cpp_lib_constexpr_iterator                   201811L
@@ -536,6 +537,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_bind_front
 # define __cpp_lib_bind_front                           202306L
 # define __cpp_lib_bitset                               202306L
+# define __cpp_lib_constexpr_complex                    201711L
 # if !defined(_LIBCPP_ABI_VCRUNTIME)
 #   define __cpp_lib_constexpr_new                      202406L
 # endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.compile.pass.cpp
index 3718a9e222f98..6fd155f7b4216 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.compile.pass.cpp
@@ -15,9 +15,9 @@
 
 // Test the feature test macros defined by <complex>
 
-/*  Constant                       Value
-    __cpp_lib_complex_udls         201309L [C++14]
-    __cpp_lib_constexpr_complex    201711L [C++20]
+/*  Constant                     Value
+    __cpp_lib_complex_udls       201309L [C++14]
+    __cpp_lib_constexpr_deque    202502L [C++20]
 */
 
 #include <complex>
@@ -29,8 +29,8 @@
 #   error "__cpp_lib_complex_udls should not be defined before c++14"
 # endif
 
-# ifdef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should not be defined before c++20"
+# ifdef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should not be defined before c++20"
 # endif
 
 #elif TEST_STD_VER == 14
@@ -42,8 +42,8 @@
 #   error "__cpp_lib_complex_udls should have the value 201309L in c++14"
 # endif
 
-# ifdef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should not be defined before c++20"
+# ifdef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should not be defined before c++20"
 # endif
 
 #elif TEST_STD_VER == 17
@@ -55,8 +55,8 @@
 #   error "__cpp_lib_complex_udls should have the value 201309L in c++17"
 # endif
 
-# ifdef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should not be defined before c++20"
+# ifdef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should not be defined before c++20"
 # endif
 
 #elif TEST_STD_VER == 20
@@ -68,11 +68,11 @@
 #   error "__cpp_lib_complex_udls should have the value 201309L in c++20"
 # endif
 
-# ifndef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should be defined in c++20"
+# ifndef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should be defined in c++20"
 # endif
-# if __cpp_lib_constexpr_complex != 201711L
-#   error "__cpp_lib_constexpr_complex should have the value 201711L in c++20"
+# if __cpp_lib_constexpr_deque != 202502L
+#   error "__cpp_lib_constexpr_deque should have the value 202502L in c++20"
 # endif
 
 #elif TEST_STD_VER == 23
@@ -84,11 +84,11 @@
 #   error "__cpp_lib_complex_udls should have the value 201309L in c++23"
 # endif
 
-# ifndef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should be defined in c++23"
+# ifndef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should be defined in c++23"
 # endif
-# if __cpp_lib_constexpr_complex != 201711L
-#   error "__cpp_lib_constexpr_complex should have the value 201711L in c++23"
+# if __cpp_lib_constexpr_deque != 202502L
+#   error "__cpp_lib_constexpr_deque should have the value 202502L in c++23"
 # endif
 
 #elif TEST_STD_VER > 23
@@ -100,11 +100,11 @@
 #   error "__cpp_lib_complex_udls should have the value 201309L in c++26"
 # endif
 
-# ifndef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should be defined in c++26"
+# ifndef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should be defined in c++26"
 # endif
-# if __cpp_lib_constexpr_complex != 201711L
-#   error "__cpp_lib_constexpr_complex should have the value 201711L in c++26"
+# if __cpp_lib_constexpr_deque != 202502L
+#   error "__cpp_lib_constexpr_deque should have the value 202502L in c++26"
 # endif
 
 #endif // TEST_STD_VER > 23
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.compile.pass.cpp
index d0e4ac130c60e..6f716eeefdeef 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/deque.version.compile.pass.cpp
@@ -17,6 +17,7 @@
 
 /*  Constant                                                Value
     __cpp_lib_allocator_traits_is_always_equal              201411L [C++17]
+    __cpp_lib_constexpr_complex                             201711L [C++26]
     __cpp_lib_containers_ranges                             202202L [C++23]
     __cpp_lib_default_template_type_for_algorithm_values    202403L [C++26]
     __cpp_lib_erase_if                                      202002L [C++20]
@@ -32,6 +33,10 @@
 #   error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_containers_ranges
 #   error "__cpp_lib_containers_ranges should not be defined before c++23"
 # endif
@@ -54,6 +59,10 @@
 #   error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_containers_ranges
 #   error "__cpp_lib_containers_ranges should not be defined before c++23"
 # endif
@@ -79,6 +88,10 @@
 #   error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
 # endif
 
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_containers_ranges
 #   error "__cpp_lib_containers_ranges should not be defined before c++23"
 # endif
@@ -107,6 +120,10 @@
 #   error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++20"
 # endif
 
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_containers_ranges
 #   error "__cpp_lib_containers_ranges should not be defined before c++23"
 # endif
@@ -138,6 +155,10 @@
 #   error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++23"
 # endif
 
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_containers_ranges
 #   error "__cpp_lib_containers_ranges should be defined in c++23"
 # endif
@@ -172,6 +193,13 @@
 #   error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++26"
 # endif
 
+# ifndef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should be defined in c++26"
+# endif
+# if __cpp_lib_constexpr_complex != 201711L
+#   error "__cpp_lib_constexpr_complex should have the value 201711L in c++26"
+# endif
+
 # ifndef __cpp_lib_containers_ranges
 #   error "__cpp_lib_containers_ranges should be defined in c++26"
 # endif
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 1e4465d515e6b..8214c757f0576 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
@@ -59,7 +59,8 @@
     __cpp_lib_constexpr_bitset                              202207L [C++23]
     __cpp_lib_constexpr_charconv                            202207L [C++23]
     __cpp_lib_constexpr_cmath                               202202L [C++23]
-    __cpp_lib_constexpr_complex                             201711L [C++20]
+    __cpp_lib_constexpr_complex                             201711L [C++26]
+    __cpp_lib_constexpr_deque                               202502L [C++20]
     __cpp_lib_constexpr_dynamic_alloc                       201907L [C++20]
     __cpp_lib_constexpr_functional                          201907L [C++20]
     __cpp_lib_constexpr_iterator                            201811L [C++20]
@@ -423,7 +424,11 @@
 # endif
 
 # ifdef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should not be defined before c++20"
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
+# ifdef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should not be defined before c++20"
 # endif
 
 # ifdef __cpp_lib_constexpr_dynamic_alloc
@@ -1299,7 +1304,11 @@
 # endif
 
 # ifdef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should not be defined before c++20"
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
+# ifdef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should not be defined before c++20"
 # endif
 
 # ifdef __cpp_lib_constexpr_dynamic_alloc
@@ -2277,7 +2286,11 @@
 # endif
 
 # ifdef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should not be defined before c++20"
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
+# endif
+
+# ifdef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should not be defined before c++20"
 # endif
 
 # ifdef __cpp_lib_constexpr_dynamic_alloc
@@ -3488,11 +3501,15 @@
 #   error "__cpp_lib_constexpr_cmath should not be defined before c++23"
 # endif
 
-# ifndef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should be defined in c++20"
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
 # endif
-# if __cpp_lib_constexpr_complex != 201711L
-#   error "__cpp_lib_constexpr_complex should have the value 201711L in c++20"
+
+# ifndef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_deque != 202502L
+#   error "__cpp_lib_constexpr_deque should have the value 202502L in c++20"
 # endif
 
 # ifndef __cpp_lib_constexpr_dynamic_alloc
@@ -4928,11 +4945,15 @@
 #   endif
 # endif
 
-# ifndef __cpp_lib_constexpr_complex
-#   error "__cpp_lib_constexpr_complex should be defined in c++23"
+# ifdef __cpp_lib_constexpr_complex
+#   error "__cpp_lib_constexpr_complex should not be defined before c++26"
 # endif
-# if __cpp_lib_constexpr_complex != 201711L
-#   error "__cpp_lib_constexpr_complex should have the value 201711L in c++23"
+
+# ifndef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should be defined in c++23"
+# endif
+# if __cpp_lib_constexpr_deque != 202502L
+#   error "__cpp_lib_constexpr_deque should have the value 202502L in c++23"
 # endif
 
 # ifndef __cpp_lib_constexpr_dynamic_alloc
@@ -6603,6 +6624,13 @@
 #   error "__cpp_lib_constexpr_complex should have the value 201711L in c++26"
 # endif
 
+# ifndef __cpp_lib_constexpr_deque
+#   error "__cpp_lib_constexpr_deque should be defined in c++26"
+# endif
+# if __cpp_lib_constexpr_deque != 202502L
+#   error "__cpp_lib_constexpr_deque should have the value 202502L in c++26"
+# endif
+
 # ifndef __cpp_lib_constexpr_dynamic_alloc
 #   error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++26"
 # endif
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 8bf7633e985d5..41627efa51ad5 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -342,7 +342,12 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_constexpr_complex",
-            "values": {"c++20": 201711},
+            "values": {"c++26": 201711},
+            "headers": ["deque"],
+        },
+        {
+            "name": "__cpp_lib_constexpr_deque",
+            "values": {"c++20": 202502},
             "headers": ["complex"],
         },
         {



More information about the libcxx-commits mailing list