[libcxx-commits] [libcxx] [libc++] Implement P3508R0: Wording for "constexpr for specialized memory algorithms" (PR #197313)

William Tran-Viet via libcxx-commits libcxx-commits at lists.llvm.org
Sun May 24 13:08:29 PDT 2026


https://github.com/smallp-o-p updated https://github.com/llvm/llvm-project/pull/197313

>From 69ac5b66dcf6336b2e0317536ef104afa68dc1c5 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 17:14:34 -0400
Subject: [PATCH 01/18] Implement P3508R0

---
 libcxx/docs/FeatureTestMacroTable.rst         |  3 +-
 libcxx/docs/Status/Cxx2cPapers.csv            |  2 +-
 .../ranges_uninitialized_algorithms.h         | 42 ++++++++++-------
 .../__memory/uninitialized_algorithms.h       | 47 +++++++++++--------
 4 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index ae48eaed1f46b..0d455beacd6df 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -138,7 +138,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_parallel_algorithm``                           *unimplemented*
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_raw_memory_algorithms``                        ``201606L``
+    ``__cpp_lib_raw_memory_algorithms``                        ``202406L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_sample``                                       ``201603L``
     ---------------------------------------------------------- -----------------
@@ -542,4 +542,3 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_variant``                                      ``202306L``
     ========================================================== =================
-
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index eb15fac940f5c..8f8ca6825c246 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -87,7 +87,7 @@
 "`P3396R1 <https://wg21.link/P3396R1>`__","``std::execution`` wording fixes","2024-11 (Wrocław)","","","`#118376 <https://github.com/llvm/llvm-project/issues/118376>`__",""
 "`P2835R7 <https://wg21.link/P2835R7>`__","Expose ``std::atomic_ref``'s object address","2024-11 (Wrocław)","|Complete|","22","`#118377 <https://github.com/llvm/llvm-project/issues/118377>`__",""
 "`P3323R1 <https://wg21.link/P3323R1>`__","cv-qualified types in ``atomic`` and ``atomic_ref``","2024-11 (Wrocław)","","","`#118378 <https://github.com/llvm/llvm-project/issues/118378>`__",""
-"`P3508R0 <https://wg21.link/P3508R0>`__","Wording for ""constexpr for specialized memory algorithms""","2024-11 (Wrocław)","","","`#118379 <https://github.com/llvm/llvm-project/issues/118379>`__",""
+"`P3508R0 <https://wg21.link/P3508R0>`__","Wording for ""constexpr for specialized memory algorithms""","2024-11 (Wrocław)","|Complete|","23","`#118379 <https://github.com/llvm/llvm-project/issues/118379>`__",""
 "`P3369R0 <https://wg21.link/P3369R0>`__","constexpr for ``uninitialized_default_construct``","2024-11 (Wrocław)","","","`#118380 <https://github.com/llvm/llvm-project/issues/118380>`__",""
 "`P3370R1 <https://wg21.link/P3370R1>`__","Add new library headers from C23","2024-11 (Wrocław)","","","`#118381 <https://github.com/llvm/llvm-project/issues/118381>`__",""
 "`P3309R3 <https://wg21.link/P3309R3>`__","constexpr ``atomic`` and ``atomic_ref``","2024-11 (Wrocław)","","","`#118382 <https://github.com/llvm/llvm-project/issues/118382>`__",""
diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
index 57a7a4616826e..83e33527f35d3 100644
--- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h
+++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
@@ -44,14 +44,16 @@ namespace ranges {
 struct __uninitialized_default_construct {
   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+  operator()(_ForwardIterator __first, _Sentinel __last) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_default_construct<_ValueType>(std::move(__first), std::move(__last));
   }
 
   template <__nothrow_forward_range _ForwardRange>
     requires default_initializable<range_value_t<_ForwardRange>>
-  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 borrowed_iterator_t<_ForwardRange>
+  operator()(_ForwardRange&& __range) const {
     return (*this)(ranges::begin(__range), ranges::end(__range));
   }
 };
@@ -65,7 +67,7 @@ inline constexpr auto uninitialized_default_construct = __uninitialized_default_
 struct __uninitialized_default_construct_n {
   template <__nothrow_forward_iterator _ForwardIterator>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_default_construct_n<_ValueType>(std::move(__first), __n);
@@ -81,14 +83,16 @@ inline constexpr auto uninitialized_default_construct_n = __uninitialized_defaul
 struct __uninitialized_value_construct {
   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+  operator()(_ForwardIterator __first, _Sentinel __last) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_value_construct<_ValueType>(std::move(__first), std::move(__last));
   }
 
   template <__nothrow_forward_range _ForwardRange>
     requires default_initializable<range_value_t<_ForwardRange>>
-  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 borrowed_iterator_t<_ForwardRange>
+  operator()(_ForwardRange&& __range) const {
     return (*this)(ranges::begin(__range), ranges::end(__range));
   }
 };
@@ -102,7 +106,7 @@ inline constexpr auto uninitialized_value_construct = __uninitialized_value_cons
 struct __uninitialized_value_construct_n {
   template <__nothrow_forward_iterator _ForwardIterator>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_value_construct_n<_ValueType>(std::move(__first), __n);
@@ -118,14 +122,16 @@ inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_co
 struct __uninitialized_fill {
   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel, class _Tp>
     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
-  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+  operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_fill<_ValueType>(std::move(__first), std::move(__last), __x);
   }
 
   template <__nothrow_forward_range _ForwardRange, class _Tp>
     requires constructible_from<range_value_t<_ForwardRange>, const _Tp&>
-  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 borrowed_iterator_t<_ForwardRange>
+  operator()(_ForwardRange&& __range, const _Tp& __x) const {
     return (*this)(ranges::begin(__range), ranges::end(__range), __x);
   }
 };
@@ -139,7 +145,7 @@ inline constexpr auto uninitialized_fill = __uninitialized_fill{};
 struct __uninitialized_fill_n {
   template <__nothrow_forward_iterator _ForwardIterator, class _Tp>
     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
-  _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n, const _Tp& __x) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_fill_n<_ValueType>(std::move(__first), __n, __x);
@@ -161,7 +167,7 @@ struct __uninitialized_copy {
             __nothrow_forward_iterator _OutputIterator,
             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
-  _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 uninitialized_copy_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
 
@@ -173,8 +179,9 @@ struct __uninitialized_copy {
 
   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
-  _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
-  operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+      uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
+      operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
     return (*this)(
         ranges::begin(__in_range), ranges::end(__in_range), ranges::begin(__out_range), ranges::end(__out_range));
   }
@@ -194,7 +201,7 @@ struct __uninitialized_copy_n {
             __nothrow_forward_iterator _OutputIterator,
             __nothrow_sentinel_for<_OutputIterator> _Sentinel>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
-  _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 uninitialized_copy_n_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst,
              iter_difference_t<_InputIterator> __n,
              _OutputIterator __ofirst,
@@ -222,7 +229,7 @@ struct __uninitialized_move {
             __nothrow_forward_iterator _OutputIterator,
             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
-  _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 uninitialized_move_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
     using _ValueType   = remove_reference_t<iter_reference_t<_OutputIterator>>;
     auto __iter_move   = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
@@ -234,8 +241,9 @@ struct __uninitialized_move {
 
   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
     requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>>
-  _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
-  operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+      uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
+      operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
     return (*this)(
         ranges::begin(__in_range), ranges::end(__in_range), ranges::begin(__out_range), ranges::end(__out_range));
   }
@@ -255,7 +263,7 @@ struct __uninitialized_move_n {
             __nothrow_forward_iterator _OutputIterator,
             __nothrow_sentinel_for<_OutputIterator> _Sentinel>
     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
-  _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result<_InputIterator, _OutputIterator>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 uninitialized_move_n_result<_InputIterator, _OutputIterator>
   operator()(_InputIterator __ifirst,
              iter_difference_t<_InputIterator> __n,
              _OutputIterator __ofirst,
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index 9182db4b412e3..eded04eb06be0 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -57,7 +57,7 @@ struct __always_false {
 // uninitialized_copy
 
 template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _EndPredicate>
-inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitialized_copy(
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<_InputIterator, _ForwardIterator> __uninitialized_copy(
     _InputIterator __ifirst, _Sentinel1 __ilast, _ForwardIterator __ofirst, _EndPredicate __stop_copying) {
   _ForwardIterator __idx = __ofirst;
   auto __guard           = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
@@ -69,7 +69,7 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitiali
 }
 
 template <class _InputIterator, class _ForwardIterator>
-_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 uninitialized_copy(_InputIterator __ifirst, _InputIterator __ilast, _ForwardIterator __ofirst) {
   typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
   auto __result = std::__uninitialized_copy<_ValueType>(
@@ -80,7 +80,7 @@ uninitialized_copy(_InputIterator __ifirst, _InputIterator __ilast, _ForwardIter
 // uninitialized_copy_n
 
 template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _EndPredicate>
-inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<_InputIterator, _ForwardIterator>
 __uninitialized_copy_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst, _EndPredicate __stop_copying) {
   _ForwardIterator __idx = __ofirst;
   auto __guard           = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
@@ -92,7 +92,7 @@ __uninitialized_copy_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __of
 }
 
 template <class _InputIterator, class _Size, class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 uninitialized_copy_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst) {
   typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
   auto __result =
@@ -103,7 +103,7 @@ uninitialized_copy_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofir
 // uninitialized_fill
 
 template <class _ValueType, class _ForwardIterator, class _Sentinel, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 __uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) {
   _ForwardIterator __idx = __first;
   auto __guard           = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
@@ -115,7 +115,7 @@ __uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x)
 }
 
 template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI void
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x) {
   typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
   (void)std::__uninitialized_fill<_ValueType>(__first, __last, __x);
@@ -124,7 +124,7 @@ uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp&
 // uninitialized_fill_n
 
 template <class _ValueType, class _ForwardIterator, class _Size, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 __uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
   _ForwardIterator __idx = __first;
   auto __guard           = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
@@ -136,7 +136,7 @@ __uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
 }
 
 template <class _ForwardIterator, class _Size, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
   typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
   return std::__uninitialized_fill_n<_ValueType>(__first, __n, __x);
@@ -147,7 +147,7 @@ uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
 // uninitialized_default_construct
 
 template <class _ValueType, class _ForwardIterator, class _Sentinel>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
   auto __idx   = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
@@ -159,7 +159,8 @@ __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
 }
 
 template <class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   (void)std::__uninitialized_default_construct<_ValueType>(std::move(__first), std::move(__last));
 }
@@ -167,7 +168,8 @@ inline _LIBCPP_HIDE_FROM_ABI void uninitialized_default_construct(_ForwardIterat
 // uninitialized_default_construct_n
 
 template <class _ValueType, class _ForwardIterator, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+__uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
   auto __idx = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
   for (; __n > 0; ++__idx, (void)--__n)
@@ -178,7 +180,8 @@ inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_default_construct_
 }
 
 template <class _ForwardIterator, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   return std::__uninitialized_default_construct_n<_ValueType>(std::move(__first), __n);
 }
@@ -186,7 +189,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_default_construct_n(
 // uninitialized_value_construct
 
 template <class _ValueType, class _ForwardIterator, class _Sentinel>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) {
   auto __idx   = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
@@ -198,7 +201,8 @@ __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) {
 }
 
 template <class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   (void)std::__uninitialized_value_construct<_ValueType>(std::move(__first), std::move(__last));
 }
@@ -206,7 +210,8 @@ inline _LIBCPP_HIDE_FROM_ABI void uninitialized_value_construct(_ForwardIterator
 // uninitialized_value_construct_n
 
 template <class _ValueType, class _ForwardIterator, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+__uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
   auto __idx = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
   for (; __n > 0; ++__idx, (void)--__n)
@@ -217,7 +222,8 @@ inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_value_construct_n(
 }
 
 template <class _ForwardIterator, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   return std::__uninitialized_value_construct_n<_ValueType>(std::move(__first), __n);
 }
@@ -230,7 +236,7 @@ template <class _ValueType,
           class _ForwardIterator,
           class _EndPredicate,
           class _IterMove>
-inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitialized_move(
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<_InputIterator, _ForwardIterator> __uninitialized_move(
     _InputIterator __ifirst,
     _Sentinel1 __ilast,
     _ForwardIterator __ofirst,
@@ -247,7 +253,7 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitiali
 }
 
 template <class _InputIterator, class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
 uninitialized_move(_InputIterator __ifirst, _InputIterator __ilast, _ForwardIterator __ofirst) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   auto __iter_move = [](auto&& __iter) -> decltype(auto) { return std::move(*__iter); };
@@ -265,7 +271,8 @@ template <class _ValueType,
           class _ForwardIterator,
           class _EndPredicate,
           class _IterMove>
-inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitialized_move_n(
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<_InputIterator, _ForwardIterator>
+__uninitialized_move_n(
     _InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst, _EndPredicate __stop_moving, _IterMove __iter_move) {
   auto __idx   = __ofirst;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
@@ -277,7 +284,7 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitiali
 }
 
 template <class _InputIterator, class _Size, class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<_InputIterator, _ForwardIterator>
 uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   auto __iter_move = [](auto&& __iter) -> decltype(auto) { return std::move(*__iter); };

>From 05f35e36d53ceaf30f51bf468f1d13b0bf57a0b7 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 17:43:22 -0400
Subject: [PATCH 02/18] Add constexpr tests

---
 .../ranges_uninitialized_copy.pass.cpp        | 55 ++++++++++++++++++
 .../ranges_uninitialized_copy_n.pass.cpp      | 40 +++++++++++++
 .../uninitialized_copy.pass.cpp               | 27 +++++++++
 .../uninitialized_copy_n.pass.cpp             | 29 +++++++++-
 .../ranges_uninitialized_fill_n.pass.cpp      | 23 ++++++++
 .../uninitialized_fill_n.pass.cpp             | 27 +++++++++
 .../ranges_uninitialized_fill.pass.cpp        | 39 +++++++++++++
 .../uninitialized_fill.pass.cpp               | 26 +++++++++
 .../ranges_uninitialized_move.pass.cpp        | 57 +++++++++++++++++++
 .../ranges_uninitialized_move_n.pass.cpp      | 41 +++++++++++++
 .../uninitialized_move.pass.cpp               | 29 +++++++++-
 .../uninitialized_move_n.pass.cpp             | 28 +++++++++
 12 files changed, 419 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp
index 52ba70b009bab..51cef5033a307 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp
@@ -28,6 +28,7 @@
 #include "../buffer.h"
 #include "../counted.h"
 #include "../overload_compare_iterator.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 
@@ -42,6 +43,55 @@ struct NotConvertibleFromInt {};
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_copy), int*, int*, NotConvertibleFromInt*,
                                    NotConvertibleFromInt*>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n       = 3;
+  const ConstCopy in[n] = {ConstCopy(1), ConstCopy(2), ConstCopy(3)};
+  std::allocator<ConstCopy> alloc;
+
+  // (iter, sentinel) overload.
+  {
+    ConstCopy* out = alloc.allocate(n);
+    auto result    = std::ranges::uninitialized_copy(in, in + n, out, out + n);
+    assert(result.in == in + n);
+    assert(result.out == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == in[i].val);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // (range) overload.
+  {
+    ConstCopy* out = alloc.allocate(n);
+    auto out_range = std::ranges::subrange(out, out + n);
+    auto result    = std::ranges::uninitialized_copy(in, out_range);
+    assert(result.in == in + n);
+    assert(result.out == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == in[i].val);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // Destination range is shorter than the source range.
+  {
+    constexpr int m = 2;
+    ConstCopy* out  = alloc.allocate(m);
+    auto result     = std::ranges::uninitialized_copy(in, in + n, out, out + m);
+    assert(result.in == in + m);
+    assert(result.out == out + m);
+    for (int i = 0; i != m; ++i)
+      assert(out[i].val == in[i].val);
+
+    std::destroy(out, out + m);
+    alloc.deallocate(out, m);
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -395,5 +445,10 @@ int main(int, char**) {
     }
   }
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy_n.pass.cpp
index 84fba1aa79293..afb565c258715 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy_n.pass.cpp
@@ -25,6 +25,7 @@
 #include "../buffer.h"
 #include "../counted.h"
 #include "../overload_compare_iterator.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 
@@ -39,6 +40,40 @@ struct NotConvertibleFromInt {};
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_copy_n), int*, std::size_t, NotConvertibleFromInt*,
                                    NotConvertibleFromInt*>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n       = 3;
+  const ConstCopy in[n] = {ConstCopy(1), ConstCopy(2), ConstCopy(3)};
+  std::allocator<ConstCopy> alloc;
+
+  {
+    ConstCopy* out = alloc.allocate(n);
+    auto result    = std::ranges::uninitialized_copy_n(in, n, out, out + n);
+    assert(result.in == in + n);
+    assert(result.out == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == in[i].val);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // Destination range is shorter than the source range.
+  {
+    constexpr int m = 2;
+    ConstCopy* out  = alloc.allocate(m);
+    auto result     = std::ranges::uninitialized_copy_n(in, n, out, out + m);
+    assert(result.in == in + m);
+    assert(result.out == out + m);
+    for (int i = 0; i != m; ++i)
+      assert(out[i].val == in[i].val);
+
+    std::destroy(out, out + m);
+    alloc.deallocate(out, m);
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -177,5 +212,10 @@ int main(int, char**) {
     }
   }
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif // TEST_STD_VER >= 26
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
index dddc550e0ef12..4a25d4c1025d5 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
@@ -17,6 +17,9 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 26
+#  include "copy_move_types.h"
+#endif
 #include "../overload_compare_iterator.h"
 
 struct B
@@ -48,6 +51,25 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+#if TEST_STD_VER >= 26
+TEST_CONSTEXPR_CXX26 bool test() {
+  const int n           = 3;
+  const ConstCopy in[n] = {ConstCopy(1), ConstCopy(2), ConstCopy(3)};
+  std::allocator<ConstCopy> alloc;
+  ConstCopy* out = alloc.allocate(n);
+
+  ConstCopy* result = std::uninitialized_copy(in, in + n, out);
+  assert(result == out + n);
+  for (int i = 0; i != n; ++i)
+    assert(out[i].val == in[i].val);
+
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+#endif // TEST_STD_VER >= 26
+
 int main(int, char**)
 {
     {
@@ -115,5 +137,10 @@ int main(int, char**)
         }
     }
 
+#if TEST_STD_VER >= 26
+    test();
+    static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
index ddaf02c184bd4..e725c42a14733 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
@@ -17,6 +17,9 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 26
+#  include "copy_move_types.h"
+#endif
 #include "../overload_compare_iterator.h"
 
 struct B
@@ -48,6 +51,25 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+#if TEST_STD_VER >= 26
+TEST_CONSTEXPR_CXX26 bool test() {
+  const int n           = 3;
+  const ConstCopy in[n] = {ConstCopy(1), ConstCopy(2), ConstCopy(3)};
+  std::allocator<ConstCopy> alloc;
+  ConstCopy* out = alloc.allocate(n);
+
+  ConstCopy* result = std::uninitialized_copy_n(in, n, out);
+  assert(result == out + n);
+  for (int i = 0; i != n; ++i)
+    assert(out[i].val == in[i].val);
+
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+#endif // TEST_STD_VER >= 26
+
 int main(int, char**)
 {
     {
@@ -115,5 +137,10 @@ int main(int, char**)
         }
     }
 
-  return 0;
+#if TEST_STD_VER >= 26
+    test();
+    static_assert(test());
+#endif // TEST_STD_VER >= 26
+
+    return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitialized_fill_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitialized_fill_n.pass.cpp
index 0b35c1114d87c..4420cde5587e8 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitialized_fill_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitialized_fill_n.pass.cpp
@@ -23,6 +23,7 @@
 
 #include "../buffer.h"
 #include "../counted.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 
@@ -35,6 +36,23 @@ LIBCPP_STATIC_ASSERT(std::is_class_v<decltype(std::ranges::uninitialized_fill_n)
 struct NotConvertibleFromInt {};
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_fill_n), NotConvertibleFromInt*, std::size_t, int>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n = 3;
+  ConstCopy value(42);
+  std::allocator<ConstCopy> alloc;
+
+  ConstCopy* out = alloc.allocate(n);
+  auto result    = std::ranges::uninitialized_fill_n(out, n, value);
+  assert(result == out + n);
+  for (int i = 0; i != n; ++i)
+    assert(out[i].val == value.val);
+
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+
 int main(int, char**) {
   constexpr int value = 42;
   Counted x(value);
@@ -101,5 +119,10 @@ int main(int, char**) {
   }
 #endif // TEST_HAS_NO_EXCEPTIONS
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
index 8b46f1ba67aa3..09fd8a78332f2 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
@@ -16,6 +16,9 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 26
+#  include "copy_move_types.h"
+#endif
 
 struct B
 {
@@ -46,6 +49,25 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+#if TEST_STD_VER >= 26
+TEST_CONSTEXPR_CXX26 bool test() {
+  const int n = 3;
+  ConstCopy value(42);
+  std::allocator<ConstCopy> alloc;
+  ConstCopy* out = alloc.allocate(n);
+
+  ConstCopy* result = std::uninitialized_fill_n(out, n, value);
+  assert(result == out + n);
+  for (int i = 0; i != n; ++i)
+    assert(out[i].val == value.val);
+
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+#endif // TEST_STD_VER >= 26
+
 int main(int, char**)
 {
     {
@@ -85,5 +107,10 @@ int main(int, char**)
 
     }
 
+#if TEST_STD_VER >= 26
+    test();
+    static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/ranges_uninitialized_fill.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/ranges_uninitialized_fill.pass.cpp
index 6f75fc13a1c39..3cbdf58cc2281 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/ranges_uninitialized_fill.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/ranges_uninitialized_fill.pass.cpp
@@ -27,6 +27,7 @@
 
 #include "../buffer.h"
 #include "../counted.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 
@@ -40,6 +41,39 @@ struct NotConvertibleFromInt {};
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_fill), NotConvertibleFromInt*,
                                    NotConvertibleFromInt*, int>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n = 3;
+  ConstCopy value(42);
+  std::allocator<ConstCopy> alloc;
+
+  // (iter, sentinel) overload.
+  {
+    ConstCopy* out = alloc.allocate(n);
+    auto result    = std::ranges::uninitialized_fill(out, out + n, value);
+    assert(result == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == value.val);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // (range) overload.
+  {
+    ConstCopy* out = alloc.allocate(n);
+    auto out_range = std::ranges::subrange(out, out + n);
+    auto result    = std::ranges::uninitialized_fill(out_range, value);
+    assert(result == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == value.val);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   constexpr int value = 42;
   Counted x(value);
@@ -198,5 +232,10 @@ int main(int, char**) {
   }
 #endif // TEST_HAS_NO_EXCEPTIONS
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
index fd6576d79ad1a..5e5633b0106d6 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
@@ -17,6 +17,9 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 26
+#  include "copy_move_types.h"
+#endif
 
 struct B
 {
@@ -47,6 +50,24 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+#if TEST_STD_VER >= 26
+TEST_CONSTEXPR_CXX26 bool test() {
+  int n = 3;
+  ConstCopy value(42);
+  std::allocator<ConstCopy> alloc;
+  ConstCopy* out = alloc.allocate(n);
+
+  std::uninitialized_fill(out, out + n, value);
+  for (int i = 0; i != n; ++i)
+    assert(out[i].val == value.val);
+
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+#endif // TEST_STD_VER >= 26
+
 int main(int, char**)
 {
     {
@@ -82,5 +103,10 @@ int main(int, char**)
         assert(bp[i].i_ == 23);
     }
 
+#if TEST_STD_VER >= 26
+    test();
+    static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
index c6b38b4fea864..d37d49918ac05 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
@@ -29,6 +29,7 @@
 #include "../counted.h"
 #include "../overload_compare_iterator.h"
 #include "MoveOnly.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 
@@ -43,6 +44,57 @@ struct NotConvertibleFromInt {};
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_move), int*, int*, NotConvertibleFromInt*,
                                    NotConvertibleFromInt*>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n = 3;
+  std::allocator<MutableMove> alloc;
+
+  // (iter, sentinel) overload.
+  {
+    MutableMove in[n] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+    MutableMove* out  = alloc.allocate(n);
+    auto result       = std::ranges::uninitialized_move(in, in + n, out, out + n);
+    assert(result.in == in + n);
+    assert(result.out == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == i + 1);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // (range) overload.
+  {
+    MutableMove in[n] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+    MutableMove* out  = alloc.allocate(n);
+    auto out_range    = std::ranges::subrange(out, out + n);
+    auto result       = std::ranges::uninitialized_move(in, out_range);
+    assert(result.in == in + n);
+    assert(result.out == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == i + 1);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // Destination range is shorter than the source range.
+  {
+    constexpr int m   = 2;
+    MutableMove in[n] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+    MutableMove* out  = alloc.allocate(m);
+    auto result       = std::ranges::uninitialized_move(in, in + n, out, out + m);
+    assert(result.in == in + m);
+    assert(result.out == out + m);
+    for (int i = 0; i != m; ++i)
+      assert(out[i].val == i + 1);
+
+    std::destroy(out, out + m);
+    alloc.deallocate(out, m);
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -434,5 +486,10 @@ int main(int, char**) {
     }
   }
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp
index cac2acc5932b3..5168a7aa7b733 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp
@@ -26,6 +26,7 @@
 #include "../counted.h"
 #include "../overload_compare_iterator.h"
 #include "MoveOnly.h"
+#include "copy_move_types.h"
 #include "test_iterators.h"
 #include "test_macros.h"
 
@@ -40,6 +41,41 @@ struct NotConvertibleFromInt {};
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_move_n), int*, std::size_t, NotConvertibleFromInt*,
                                    NotConvertibleFromInt*>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n = 3;
+  std::allocator<MutableMove> alloc;
+
+  {
+    MutableMove in[n] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+    MutableMove* out  = alloc.allocate(n);
+    auto result       = std::ranges::uninitialized_move_n(in, n, out, out + n);
+    assert(result.in == in + n);
+    assert(result.out == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i].val == i + 1);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // Destination range is shorter than the source range.
+  {
+    constexpr int m   = 2;
+    MutableMove in[n] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+    MutableMove* out  = alloc.allocate(m);
+    auto result       = std::ranges::uninitialized_move_n(in, n, out, out + m);
+    assert(result.in == in + m);
+    assert(result.out == out + m);
+    for (int i = 0; i != m; ++i)
+      assert(out[i].val == i + 1);
+
+    std::destroy(out, out + m);
+    alloc.deallocate(out, m);
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -207,5 +243,10 @@ int main(int, char**) {
     }
   }
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
index f77cbea19bd4d..c0716a69a24d7 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
@@ -18,6 +18,9 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 26
+#  include "copy_move_types.h"
+#endif
 #include "test_iterators.h"
 #include "../overload_compare_iterator.h"
 
@@ -55,6 +58,25 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
+#if TEST_STD_VER >= 26
+TEST_CONSTEXPR_CXX26 bool test() {
+  const int N       = 3;
+  MutableMove in[N] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+  std::allocator<MutableMove> alloc;
+  MutableMove* out = alloc.allocate(N);
+
+  MutableMove* result = std::uninitialized_move(in, in + N, out);
+  assert(result == out + N);
+  for (int i = 0; i != N; ++i)
+    assert(out[i].val == i + 1);
+
+  std::destroy(out, out + N);
+  alloc.deallocate(out, N);
+
+  return true;
+}
+#endif // TEST_STD_VER >= 26
+
 void test_ctor_throws()
 {
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -141,5 +163,10 @@ int main(int, char**) {
         }
     }
 
-  return 0;
+#if TEST_STD_VER >= 26
+    test();
+    static_assert(test());
+#endif
+
+    return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
index 7cdfb4da08e4d..0731beb07f0d5 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
@@ -18,6 +18,9 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 26
+#  include "copy_move_types.h"
+#endif
 #include "test_iterators.h"
 #include "../overload_compare_iterator.h"
 
@@ -55,6 +58,26 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
+#if TEST_STD_VER >= 26
+TEST_CONSTEXPR_CXX26 bool test() {
+  const int N       = 3;
+  MutableMove in[N] = {MutableMove(1), MutableMove(2), MutableMove(3)};
+  std::allocator<MutableMove> alloc;
+  MutableMove* out = alloc.allocate(N);
+
+  auto result = std::uninitialized_move_n(in, N, out);
+  assert(result.first == in + N);
+  assert(result.second == out + N);
+  for (int i = 0; i != N; ++i)
+    assert(out[i].val == i + 1);
+
+  std::destroy(out, out + N);
+  alloc.deallocate(out, N);
+
+  return true;
+}
+#endif // TEST_STD_VER >= 26
+
 void test_ctor_throws()
 {
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -144,5 +167,10 @@ int main(int, char**)
         }
     }
 
+#if TEST_STD_VER >= 26
+    test();
+    static_assert(test());
+#endif
+
   return 0;
 }

>From 9ba0967c57c9e41e5e60b29a7bc7494c994cf690 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 17:55:42 -0400
Subject: [PATCH 03/18] release note

---
 libcxx/docs/ReleaseNotes/23.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index a55869a8bf783..e7c78fb88f91b 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -48,6 +48,7 @@ Implemented Papers
 - P2164R9: ``views::enumerate`` (`Github <https://llvm.org/PR105251>`__)
 - P2322R6: ``ranges::fold`` (`Github <https://llvm.org/PR105208>`__)
 - P4144R1: Remove ``span``'s ``initializer_list`` constructor for C++26 (`Github <https://llvm.org/PR189612>`__)
+- P3508R0: Wording for "constexpr for specialized memory algorithms" (`Github <https://llvm.org/PR118379>`__)
 
 Improvements and New Features
 -----------------------------

>From 2d096c6b759fd7005ab54c9aea26606079beafd4 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 18:02:45 -0400
Subject: [PATCH 04/18] feature macro

---
 libcxx/include/version | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libcxx/include/version b/libcxx/include/version
index 1c683b67e5700..24ba697eac061 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -369,7 +369,11 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_not_fn                               201603L
 # define __cpp_lib_optional                             201606L
 // # define __cpp_lib_parallel_algorithm                   201603L
+#if _LIBCPP_STD_VER >= 26
+# define __cpp_lib_raw_memory_algorithms                202406L
+#else
 # define __cpp_lib_raw_memory_algorithms                201606L
+#endif
 # define __cpp_lib_sample                               201603L
 # if _LIBCPP_HAS_THREADS
 #   define __cpp_lib_scoped_lock                        201703L

>From 1ea959b9c889f4cfcbce13b9b3d88e284f6109f0 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 18:03:27 -0400
Subject: [PATCH 05/18] format

---
 .../uninitialized.copy/uninitialized_copy.pass.cpp              | 2 +-
 .../uninitialized.fill.n/uninitialized_fill_n.pass.cpp          | 2 +-
 .../uninitialized.fill/uninitialized_fill.pass.cpp              | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
index 4a25d4c1025d5..a11dc4fa882df 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
@@ -142,5 +142,5 @@ int main(int, char**)
     static_assert(test());
 #endif
 
-  return 0;
+    return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
index 09fd8a78332f2..3e182fe2ec877 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
@@ -112,5 +112,5 @@ int main(int, char**)
     static_assert(test());
 #endif
 
-  return 0;
+    return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
index 5e5633b0106d6..d655a3fc0bb25 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
@@ -108,5 +108,5 @@ int main(int, char**)
     static_assert(test());
 #endif
 
-  return 0;
+    return 0;
 }

>From dae7110e6029ae86d02ccf908ea536de36d657c7 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 18:03:36 -0400
Subject: [PATCH 06/18] ditto

---
 .../uninitialized.move/uninitialized_move_n.pass.cpp            | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
index 0731beb07f0d5..429d01c8e79cf 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
@@ -172,5 +172,5 @@ int main(int, char**)
     static_assert(test());
 #endif
 
-  return 0;
+    return 0;
 }

>From 0f66c317413d7c5ce38e7eea962b4c03c5db6d50 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 18:05:22 -0400
Subject: [PATCH 07/18] feature macro

---
 libcxx/include/version | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libcxx/include/version b/libcxx/include/version
index 24ba697eac061..99f87f7bd5c6f 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -223,7 +223,7 @@ __cpp_lib_ranges_stride                                 202207L <ranges>
 __cpp_lib_ranges_to_container                           202202L <ranges>
 __cpp_lib_ranges_zip                                    202110L <ranges> <tuple> <utility>
 __cpp_lib_ratio                                         202306L <ratio>
-__cpp_lib_raw_memory_algorithms                         201606L <memory>
+__cpp_lib_raw_memory_algorithms                         202406L <memory>
 __cpp_lib_rcu                                           202306L <rcu>
 __cpp_lib_reference_from_temporary                      202202L <type_traits>
 __cpp_lib_reference_wrapper                             202403L <functional>
@@ -369,11 +369,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_not_fn                               201603L
 # define __cpp_lib_optional                             201606L
 // # define __cpp_lib_parallel_algorithm                   201603L
-#if _LIBCPP_STD_VER >= 26
 # define __cpp_lib_raw_memory_algorithms                202406L
-#else
-# define __cpp_lib_raw_memory_algorithms                201606L
-#endif
 # define __cpp_lib_sample                               201603L
 # if _LIBCPP_HAS_THREADS
 #   define __cpp_lib_scoped_lock                        201703L

>From b97ef4163b28fec2332e44aa6e296ed6cd3017fd Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 18:15:02 -0400
Subject: [PATCH 08/18] feature macro again

---
 libcxx/include/version                                 | 4 +++-
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/version b/libcxx/include/version
index 99f87f7bd5c6f..2853f66d1e145 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -369,7 +369,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_not_fn                               201603L
 # define __cpp_lib_optional                             201606L
 // # define __cpp_lib_parallel_algorithm                   201603L
-# define __cpp_lib_raw_memory_algorithms                202406L
+# define __cpp_lib_raw_memory_algorithms                201606L
 # define __cpp_lib_sample                               201603L
 # if _LIBCPP_HAS_THREADS
 #   define __cpp_lib_scoped_lock                        201703L
@@ -636,6 +636,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_tuple_like                           202311L
 # undef  __cpp_lib_variant
 # define __cpp_lib_variant                              202306L
+# undef __cpp_lib_raw_memory_algorithms
+# define __cpp_lib_raw_memory_algorithms                202406L
 #endif
 
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 2c1f92992bf1a..603cc1512b0f2 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1200,7 +1200,7 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_raw_memory_algorithms",
-            "values": {"c++17": 201606},
+            "values": {"c++17": 201606, "c++26": 202406},
             "headers": ["memory"],
         },
         {

>From c664c40d34ee442873848bcb1e26e1b8c8264a36 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 18:21:25 -0400
Subject: [PATCH 09/18] feature macros x3

---
 libcxx/docs/FeatureTestMacroTable.rst                        | 5 ++++-
 libcxx/include/version                                       | 5 +++--
 .../support.limits.general/memory.version.compile.pass.cpp   | 4 ++--
 .../support.limits.general/version.version.compile.pass.cpp  | 4 ++--
 4 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 0d455beacd6df..4160bfc53162f 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -138,7 +138,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_parallel_algorithm``                           *unimplemented*
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_raw_memory_algorithms``                        ``202406L``
+    ``__cpp_lib_raw_memory_algorithms``                        ``201606L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_sample``                                       ``201603L``
     ---------------------------------------------------------- -----------------
@@ -512,6 +512,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ratio``                                        ``202306L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_raw_memory_algorithms``                        ``202406L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_rcu``                                          *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_reference_wrapper``                            ``202403L``
@@ -542,3 +544,4 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_variant``                                      ``202306L``
     ========================================================== =================
+
diff --git a/libcxx/include/version b/libcxx/include/version
index 2853f66d1e145..5da68a0317b90 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -224,6 +224,7 @@ __cpp_lib_ranges_to_container                           202202L <ranges>
 __cpp_lib_ranges_zip                                    202110L <ranges> <tuple> <utility>
 __cpp_lib_ratio                                         202306L <ratio>
 __cpp_lib_raw_memory_algorithms                         202406L <memory>
+                                                        201606L // C++17
 __cpp_lib_rcu                                           202306L <rcu>
 __cpp_lib_reference_from_temporary                      202202L <type_traits>
 __cpp_lib_reference_wrapper                             202403L <functional>
@@ -617,6 +618,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_ranges_concat                        202403L
 # define __cpp_lib_ranges_indices                       202506L
 # define __cpp_lib_ratio                                202306L
+# undef  __cpp_lib_raw_memory_algorithms
+# define __cpp_lib_raw_memory_algorithms                202406L
 // # define __cpp_lib_rcu                                  202306L
 # define __cpp_lib_reference_wrapper                    202403L
 # define __cpp_lib_saturation_arithmetic                202603L
@@ -636,8 +639,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_tuple_like                           202311L
 # undef  __cpp_lib_variant
 # define __cpp_lib_variant                              202306L
-# undef __cpp_lib_raw_memory_algorithms
-# define __cpp_lib_raw_memory_algorithms                202406L
 #endif
 
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index f287e1ad9b3ad..69a51441d82db 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -623,8 +623,8 @@
 #  ifndef __cpp_lib_raw_memory_algorithms
 #    error "__cpp_lib_raw_memory_algorithms should be defined in c++26"
 #  endif
-#  if __cpp_lib_raw_memory_algorithms != 201606L
-#    error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26"
+#  if __cpp_lib_raw_memory_algorithms != 202406L
+#    error "__cpp_lib_raw_memory_algorithms should have the value 202406L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_shared_ptr_arrays
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 dfee4b6d458db..615eb6b71dccd 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
@@ -7811,8 +7811,8 @@
 #  ifndef __cpp_lib_raw_memory_algorithms
 #    error "__cpp_lib_raw_memory_algorithms should be defined in c++26"
 #  endif
-#  if __cpp_lib_raw_memory_algorithms != 201606L
-#    error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26"
+#  if __cpp_lib_raw_memory_algorithms != 202406L
+#    error "__cpp_lib_raw_memory_algorithms should have the value 202406L in c++26"
 #  endif
 
 #  if !defined(_LIBCPP_VERSION)

>From fdbb4533ae4ada24d49cd30f95b202041bcd54b5 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 12 May 2026 21:26:20 -0400
Subject: [PATCH 10/18] Don't constexpr uninitialized_default_construct

---
 .../include/__memory/ranges_uninitialized_algorithms.h   | 8 +++-----
 libcxx/include/__memory/uninitialized_algorithms.h       | 9 +++------
 2 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
index 83e33527f35d3..703d3d92ff82c 100644
--- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h
+++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
@@ -44,16 +44,14 @@ namespace ranges {
 struct __uninitialized_default_construct {
   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
-  operator()(_ForwardIterator __first, _Sentinel __last) const {
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_default_construct<_ValueType>(std::move(__first), std::move(__last));
   }
 
   template <__nothrow_forward_range _ForwardRange>
     requires default_initializable<range_value_t<_ForwardRange>>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 borrowed_iterator_t<_ForwardRange>
-  operator()(_ForwardRange&& __range) const {
+  _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
     return (*this)(ranges::begin(__range), ranges::end(__range));
   }
 };
@@ -67,7 +65,7 @@ inline constexpr auto uninitialized_default_construct = __uninitialized_default_
 struct __uninitialized_default_construct_n {
   template <__nothrow_forward_iterator _ForwardIterator>
     requires default_initializable<iter_value_t<_ForwardIterator>>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+  _LIBCPP_HIDE_FROM_ABI _ForwardIterator
   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n) const {
     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
     return std::__uninitialized_default_construct_n<_ValueType>(std::move(__first), __n);
diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index eded04eb06be0..70bf01846b35b 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -159,8 +159,7 @@ __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
 }
 
 template <class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
-uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
+inline _LIBCPP_HIDE_FROM_ABI void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   (void)std::__uninitialized_default_construct<_ValueType>(std::move(__first), std::move(__last));
 }
@@ -168,8 +167,7 @@ uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __las
 // uninitialized_default_construct_n
 
 template <class _ValueType, class _ForwardIterator, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
-__uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
+inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
   auto __idx = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
   for (; __n > 0; ++__idx, (void)--__n)
@@ -180,8 +178,7 @@ __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
 }
 
 template <class _ForwardIterator, class _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
-uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
+inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
   using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
   return std::__uninitialized_default_construct_n<_ValueType>(std::move(__first), __n);
 }

>From 99b8202b4a91de4dc2ffb587371feb2f325f0176 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Fri, 15 May 2026 19:22:09 -0400
Subject: [PATCH 11/18] Undo feature macro bump

---
 libcxx/docs/FeatureTestMacroTable.rst                  | 3 ---
 libcxx/include/version                                 | 5 +----
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 3 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 4160bfc53162f..609bb42889827 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -512,8 +512,6 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ratio``                                        ``202306L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_raw_memory_algorithms``                        ``202406L``
-    ---------------------------------------------------------- -----------------
     ``__cpp_lib_rcu``                                          *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_reference_wrapper``                            ``202403L``
@@ -544,4 +542,3 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_variant``                                      ``202306L``
     ========================================================== =================
-
diff --git a/libcxx/include/version b/libcxx/include/version
index 5da68a0317b90..1c683b67e5700 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -223,8 +223,7 @@ __cpp_lib_ranges_stride                                 202207L <ranges>
 __cpp_lib_ranges_to_container                           202202L <ranges>
 __cpp_lib_ranges_zip                                    202110L <ranges> <tuple> <utility>
 __cpp_lib_ratio                                         202306L <ratio>
-__cpp_lib_raw_memory_algorithms                         202406L <memory>
-                                                        201606L // C++17
+__cpp_lib_raw_memory_algorithms                         201606L <memory>
 __cpp_lib_rcu                                           202306L <rcu>
 __cpp_lib_reference_from_temporary                      202202L <type_traits>
 __cpp_lib_reference_wrapper                             202403L <functional>
@@ -618,8 +617,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_ranges_concat                        202403L
 # define __cpp_lib_ranges_indices                       202506L
 # define __cpp_lib_ratio                                202306L
-# undef  __cpp_lib_raw_memory_algorithms
-# define __cpp_lib_raw_memory_algorithms                202406L
 // # define __cpp_lib_rcu                                  202306L
 # define __cpp_lib_reference_wrapper                    202403L
 # define __cpp_lib_saturation_arithmetic                202603L
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 603cc1512b0f2..2c1f92992bf1a 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1200,7 +1200,7 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_raw_memory_algorithms",
-            "values": {"c++17": 201606, "c++26": 202406},
+            "values": {"c++17": 201606},
             "headers": ["memory"],
         },
         {

>From f0562a1f3d91ec09c8a4d127a7ef61bc3bb17b02 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Fri, 15 May 2026 19:30:30 -0400
Subject: [PATCH 12/18] Remove constexpr from __uninitialized_default_construct

---
 libcxx/include/__memory/uninitialized_algorithms.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index 70bf01846b35b..fa21f9e033374 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -147,7 +147,7 @@ uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
 // uninitialized_default_construct
 
 template <class _ValueType, class _ForwardIterator, class _Sentinel>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _ForwardIterator
+inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
 __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) {
   auto __idx   = __first;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });

>From 9977ba24c3ce29c08d1390e43e33c9e0c2552e8f Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Fri, 15 May 2026 19:38:26 -0400
Subject: [PATCH 13/18] Add tests for value_construct_n, sweep in existing
 tests that are constexpr friendly

---
 ...ges_uninitialized_value_construct.pass.cpp | 70 ++++++++++++++-----
 ...s_uninitialized_value_construct_n.pass.cpp | 57 ++++++++++-----
 .../uninitialized_value_construct.pass.cpp    | 58 ++++++++++-----
 .../uninitialized_value_construct_n.pass.cpp  | 61 ++++++++++------
 4 files changed, 173 insertions(+), 73 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct.pass.cpp
index 6bab25ca38475..e577baaf27082 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct.pass.cpp
@@ -41,6 +41,54 @@ struct NotDefaultCtrable {
 static_assert(
     !std::is_invocable_v<decltype(std::ranges::uninitialized_value_construct), NotDefaultCtrable*, NotDefaultCtrable*>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  constexpr int n = 3;
+  std::allocator<int> alloc;
+
+  // (iter, sentinel) overload.
+  {
+    int* out    = alloc.allocate(n);
+    auto result = std::ranges::uninitialized_value_construct(out, out + n);
+    assert(result == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i] == 0);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // (range) overload.
+  {
+    int* out       = alloc.allocate(n);
+    auto out_range = std::ranges::subrange(out, out + n);
+    auto result    = std::ranges::uninitialized_value_construct(out_range);
+    assert(result == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i] == 0);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // Any existing values should be overwritten by value constructors.
+  {
+    constexpr int N = 5;
+    int buffer[N]   = {42, 42, 42, 42, 42};
+
+    std::ranges::uninitialized_value_construct(buffer, buffer + 1);
+    assert(buffer[0] == 0);
+    assert(buffer[1] == 42);
+
+    std::ranges::uninitialized_value_construct(buffer, buffer + N);
+    assert(buffer[0] == 0);
+    assert(buffer[1] == 0);
+    assert(buffer[2] == 0);
+    assert(buffer[3] == 0);
+    assert(buffer[4] == 0);
+  }
+  return true;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -132,23 +180,6 @@ int main(int, char**) {
     Counted::reset();
   }
 
-  // Any existing values should be overwritten by value constructors.
-  {
-    constexpr int N = 5;
-    int buffer[N] = {42, 42, 42, 42, 42};
-
-    std::ranges::uninitialized_value_construct(buffer, buffer + 1);
-    assert(buffer[0] == 0);
-    assert(buffer[1] == 42);
-
-    std::ranges::uninitialized_value_construct(buffer, buffer + N);
-    assert(buffer[0] == 0);
-    assert(buffer[1] == 0);
-    assert(buffer[2] == 0);
-    assert(buffer[3] == 0);
-    assert(buffer[4] == 0);
-  }
-
   // An exception is thrown while objects are being created -- the existing objects should stay
   // valid. (iterator, sentinel) overload.
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -183,5 +214,10 @@ int main(int, char**) {
   }
 #endif // TEST_HAS_NO_EXCEPTIONS
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif // TEST_STD_VER >= 26
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct_n.pass.cpp
index ac8f8f1173fd1..d240072b8259f 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct_n.pass.cpp
@@ -36,6 +36,41 @@ struct NotDefaultCtrable {
 };
 static_assert(!std::is_invocable_v<decltype(std::ranges::uninitialized_value_construct_n), NotDefaultCtrable*, int>);
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  {
+    constexpr int n = 3;
+    std::allocator<int> alloc;
+    int* out = alloc.allocate(n);
+
+    auto result = std::ranges::uninitialized_value_construct_n(out, n);
+    assert(result == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i] == 0);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  // Any existing values should be overwritten by value constructors.
+  {
+    constexpr int N = 5;
+    int buffer[N]   = {42, 42, 42, 42, 42};
+
+    std::ranges::uninitialized_value_construct_n(buffer, 1);
+    assert(buffer[0] == 0);
+    assert(buffer[1] == 42);
+
+    std::ranges::uninitialized_value_construct_n(buffer, N);
+    assert(buffer[0] == 0);
+    assert(buffer[1] == 0);
+    assert(buffer[2] == 0);
+    assert(buffer[3] == 0);
+    assert(buffer[4] == 0);
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -59,23 +94,6 @@ int main(int, char**) {
     Counted::reset();
   }
 
-  // Any existing values should be overwritten by value constructors.
-  {
-    constexpr int N = 5;
-    int buffer[N] = {42, 42, 42, 42, 42};
-
-    std::ranges::uninitialized_value_construct_n(buffer, 1);
-    assert(buffer[0] == 0);
-    assert(buffer[1] == 42);
-
-    std::ranges::uninitialized_value_construct_n(buffer, N);
-    assert(buffer[0] == 0);
-    assert(buffer[1] == 0);
-    assert(buffer[2] == 0);
-    assert(buffer[3] == 0);
-    assert(buffer[4] == 0);
-  }
-
   // An exception is thrown while objects are being created -- the existing objects should stay
   // valid.
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -95,5 +113,10 @@ int main(int, char**) {
   }
 #endif // TEST_HAS_NO_EXCEPTIONS
 
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
index e24b693c0ab0e..daf16ce3d0e5c 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
@@ -53,6 +53,38 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  {
+    const int n = 3;
+    std::allocator<int> alloc;
+    int* out = alloc.allocate(n);
+
+    std::uninitialized_value_construct(out, out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i] == 0);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  {
+    using It    = forward_iterator<int*>;
+    const int N = 5;
+    int pool[N] = {-1, -1, -1, -1, -1};
+    int* p      = pool;
+    std::uninitialized_value_construct(It(p), It(p + 1));
+    assert(pool[0] == 0);
+    assert(pool[1] == -1);
+    std::uninitialized_value_construct(It(p + 1), It(p + N));
+    assert(pool[1] == 0);
+    assert(pool[2] == 0);
+    assert(pool[3] == 0);
+    assert(pool[4] == 0);
+  }
+
+  return true;
+}
+
 void test_ctor_throws()
 {
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -86,27 +118,15 @@ void test_counted()
     assert(Counted::count == 0);
 }
 
-void test_value_initialized()
-{
-    using It = forward_iterator<int*>;
-    const int N = 5;
-    int pool[N] = {-1, -1, -1, -1, -1};
-    int* p = pool;
-    std::uninitialized_value_construct(It(p), It(p+1));
-    assert(pool[0] == 0);
-    assert(pool[1] == -1);
-    std::uninitialized_value_construct(It(p+1), It(p+N));
-    assert(pool[1] == 0);
-    assert(pool[2] == 0);
-    assert(pool[3] == 0);
-    assert(pool[4] == 0);
-}
-
 int main(int, char**)
 {
-    test_counted();
-    test_value_initialized();
-    test_ctor_throws();
+  test_counted();
+  test_ctor_throws();
+
+  test();
+#if TEST_STD_VER >= 26
+  static_assert(test());
+#endif // TEST_STD_VER >= 26
 
   return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
index cc7638d60abe5..e0759bba885a9 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
@@ -52,6 +52,41 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  {
+    const int n = 3;
+    std::allocator<int> alloc;
+    int* out = alloc.allocate(n);
+
+    int* result = std::uninitialized_value_construct_n(out, n);
+    assert(result == out + n);
+    for (int i = 0; i != n; ++i)
+      assert(out[i] == 0);
+
+    std::destroy(out, out + n);
+    alloc.deallocate(out, n);
+  }
+
+  {
+    using It    = forward_iterator<int*>;
+    const int N = 5;
+    int pool[N] = {-1, -1, -1, -1, -1};
+    int* p      = pool;
+    It e        = std::uninitialized_value_construct_n(It(p), 1);
+    assert(e == It(p + 1));
+    assert(pool[0] == 0);
+    assert(pool[1] == -1);
+    e = std::uninitialized_value_construct_n(It(p + 1), 4);
+    assert(e == It(p + N));
+    assert(pool[1] == 0);
+    assert(pool[2] == 0);
+    assert(pool[3] == 0);
+    assert(pool[4] == 0);
+  }
+
+  return true;
+}
+
 void test_ctor_throws()
 {
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -89,28 +124,14 @@ void test_counted()
     assert(Counted::count == 0);
 }
 
-void test_value_initialized()
-{
-    using It = forward_iterator<int*>;
-    const int N = 5;
-    int pool[N] = {-1, -1, -1, -1, -1};
-    int* p = pool;
-    It e = std::uninitialized_value_construct_n(It(p), 1);
-    assert(e == It(p+1));
-    assert(pool[0] == 0);
-    assert(pool[1] == -1);
-    e = std::uninitialized_value_construct_n(It(p+1), 4);
-    assert(e == It(p+N));
-    assert(pool[1] == 0);
-    assert(pool[2] == 0);
-    assert(pool[3] == 0);
-    assert(pool[4] == 0);
-}
-
 int main(int, char**)
 {
     test_counted();
-    test_value_initialized();
 
-  return 0;
+    test();
+#if TEST_STD_VER >= 26
+    static_assert(test());
+#endif // TEST_STD_VER >= 26
+
+    return 0;
 }

>From 17d14b8caa212b5bb5d072e4a043b400dc3bbde3 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Fri, 15 May 2026 19:49:39 -0400
Subject: [PATCH 14/18] generate files, undo stray removed newline

---
 libcxx/docs/FeatureTestMacroTable.rst                         | 1 +
 .../support.limits.general/memory.version.compile.pass.cpp    | 4 ++--
 .../support.limits.general/version.version.compile.pass.cpp   | 4 ++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 609bb42889827..ae48eaed1f46b 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -542,3 +542,4 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_variant``                                      ``202306L``
     ========================================================== =================
+
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index 69a51441d82db..f287e1ad9b3ad 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -623,8 +623,8 @@
 #  ifndef __cpp_lib_raw_memory_algorithms
 #    error "__cpp_lib_raw_memory_algorithms should be defined in c++26"
 #  endif
-#  if __cpp_lib_raw_memory_algorithms != 202406L
-#    error "__cpp_lib_raw_memory_algorithms should have the value 202406L in c++26"
+#  if __cpp_lib_raw_memory_algorithms != 201606L
+#    error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26"
 #  endif
 
 #  ifndef __cpp_lib_shared_ptr_arrays
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 615eb6b71dccd..dfee4b6d458db 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
@@ -7811,8 +7811,8 @@
 #  ifndef __cpp_lib_raw_memory_algorithms
 #    error "__cpp_lib_raw_memory_algorithms should be defined in c++26"
 #  endif
-#  if __cpp_lib_raw_memory_algorithms != 202406L
-#    error "__cpp_lib_raw_memory_algorithms should have the value 202406L in c++26"
+#  if __cpp_lib_raw_memory_algorithms != 201606L
+#    error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26"
 #  endif
 
 #  if !defined(_LIBCPP_VERSION)

>From 96be5890c84844aef0f8dd08d87c8920cb5cdfe6 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Fri, 15 May 2026 19:53:19 -0400
Subject: [PATCH 15/18] Formatting

---
 .../uninitialized_value_construct_n.pass.cpp              | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
index e0759bba885a9..f7a88dd971df0 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
@@ -126,12 +126,12 @@ void test_counted()
 
 int main(int, char**)
 {
-    test_counted();
+  test_counted();
 
-    test();
+  test();
 #if TEST_STD_VER >= 26
-    static_assert(test());
+  static_assert(test());
 #endif // TEST_STD_VER >= 26
 
-    return 0;
+  return 0;
 }

>From e3d4801ac1db18f8c4e2e8e0f1a1baa16d612462 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Tue, 19 May 2026 21:37:17 -0400
Subject: [PATCH 16/18] Use existing MoveOnly helper, move another range move
 test to constexpr

---
 .../ranges_uninitialized_move.pass.cpp        | 30 ++++++++--------
 .../uninitialized_move.pass.cpp               | 32 ++++++++---------
 .../uninitialized_move_n.pass.cpp             | 34 +++++++++----------
 3 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
index d37d49918ac05..85259cc20998a 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
@@ -92,6 +92,21 @@ TEST_CONSTEXPR_CXX26 bool test() {
     alloc.deallocate(out, m);
   }
 
+  // Any existing values should be overwritten by move constructors.
+  {
+    constexpr int N = 5;
+    int in[N]       = {1, 2, 3, 4, 5};
+    int out[N]      = {6, 7, 8, 9, 10};
+    assert(!std::equal(in, in + N, out, out + N));
+
+    std::ranges::uninitialized_move(in, in + 1, out, out + N);
+    assert(out[0] == 1);
+    assert(out[1] == 7);
+
+    std::ranges::uninitialized_move(in, in + N, out, out + N);
+    assert(std::equal(in, in + N, out, out + N));
+  }
+
   return true;
 }
 
@@ -265,21 +280,6 @@ int main(int, char**) {
   }
   Counted::reset();
 
-  // Any existing values should be overwritten by move constructors.
-  {
-    constexpr int N = 5;
-    int in[N] = {1, 2, 3, 4, 5};
-    int out[N] = {6, 7, 8, 9, 10};
-    assert(!std::equal(in, in + N, out, out + N));
-
-    std::ranges::uninitialized_move(in, in + 1, out, out + N);
-    assert(out[0] == 1);
-    assert(out[1] == 7);
-
-    std::ranges::uninitialized_move(in, in + N, out, out + N);
-    assert(std::equal(in, in + N, out, out + N));
-  }
-
   // An exception is thrown while objects are being created -- check that the objects in the source
   // range have been moved from. (iterator, sentinel) overload.
 #ifndef TEST_HAS_NO_EXCEPTIONS
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
index c0716a69a24d7..13fef7a972e95 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
@@ -17,10 +17,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "MoveOnly.h"
 #include "test_macros.h"
-#if TEST_STD_VER >= 26
-#  include "copy_move_types.h"
-#endif
 #include "test_iterators.h"
 #include "../overload_compare_iterator.h"
 
@@ -58,24 +56,24 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
-#if TEST_STD_VER >= 26
 TEST_CONSTEXPR_CXX26 bool test() {
-  const int N       = 3;
-  MutableMove in[N] = {MutableMove(1), MutableMove(2), MutableMove(3)};
-  std::allocator<MutableMove> alloc;
-  MutableMove* out = alloc.allocate(N);
-
-  MutableMove* result = std::uninitialized_move(in, in + N, out);
-  assert(result == out + N);
-  for (int i = 0; i != N; ++i)
-    assert(out[i].val == i + 1);
+  const int n    = 3;
+  MoveOnly in[n] = {1, 2, 3};
+  std::allocator<MoveOnly> alloc;
+  MoveOnly* out = alloc.allocate(n);
+
+  MoveOnly* result = std::uninitialized_move(in, in + n, out);
+  assert(result == out + n);
+  for (int i = 0; i < n; ++i) {
+    assert(in[i] == 0);
+    assert(out[i] == i + 1);
+  }
 
-  std::destroy(out, out + N);
-  alloc.deallocate(out, N);
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
 
   return true;
 }
-#endif // TEST_STD_VER >= 26
 
 void test_ctor_throws()
 {
@@ -163,8 +161,8 @@ int main(int, char**) {
         }
     }
 
-#if TEST_STD_VER >= 26
     test();
+#if TEST_STD_VER >= 26
     static_assert(test());
 #endif
 
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
index 429d01c8e79cf..785cfb406efd9 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
@@ -17,10 +17,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "MoveOnly.h"
 #include "test_macros.h"
-#if TEST_STD_VER >= 26
-#  include "copy_move_types.h"
-#endif
 #include "test_iterators.h"
 #include "../overload_compare_iterator.h"
 
@@ -58,25 +56,25 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
-#if TEST_STD_VER >= 26
 TEST_CONSTEXPR_CXX26 bool test() {
-  const int N       = 3;
-  MutableMove in[N] = {MutableMove(1), MutableMove(2), MutableMove(3)};
-  std::allocator<MutableMove> alloc;
-  MutableMove* out = alloc.allocate(N);
-
-  auto result = std::uninitialized_move_n(in, N, out);
-  assert(result.first == in + N);
-  assert(result.second == out + N);
-  for (int i = 0; i != N; ++i)
-    assert(out[i].val == i + 1);
+  const int n    = 3;
+  MoveOnly in[n] = {1, 2, 3};
+  std::allocator<MoveOnly> alloc;
+  MoveOnly* out = alloc.allocate(n);
+
+  auto result = std::uninitialized_move_n(in, n, out);
+  assert(result.first == in + n);
+  assert(result.second == out + n);
+  for (int i = 0; i < n; ++i) {
+    assert(in[i] == 0);
+    assert(out[i] == i + 1);
+  }
 
-  std::destroy(out, out + N);
-  alloc.deallocate(out, N);
+  std::destroy(out, out + n);
+  alloc.deallocate(out, n);
 
   return true;
 }
-#endif // TEST_STD_VER >= 26
 
 void test_ctor_throws()
 {
@@ -167,8 +165,8 @@ int main(int, char**)
         }
     }
 
-#if TEST_STD_VER >= 26
     test();
+#if TEST_STD_VER >= 26
     static_assert(test());
 #endif
 

>From 812c9c7b3ef9d694e89c83037e40894a1e80ce47 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 24 May 2026 15:58:39 -0400
Subject: [PATCH 17/18] Include copy_move_types unconditionally, use backported
 destroy algo

---
 .../uninitialized.copy/uninitialized_copy.pass.cpp  | 11 ++++-------
 .../uninitialized_copy_n.pass.cpp                   | 13 +++++--------
 .../uninitialized.fill/uninitialized_fill.pass.cpp  | 11 ++++-------
 3 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
index a11dc4fa882df..7f9706edc2ce0 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
@@ -16,10 +16,9 @@
 #include <memory>
 #include <cassert>
 
+#include "copy_move_types.h"
+#include "../destroy.h"
 #include "test_macros.h"
-#if TEST_STD_VER >= 26
-#  include "copy_move_types.h"
-#endif
 #include "../overload_compare_iterator.h"
 
 struct B
@@ -51,7 +50,6 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
-#if TEST_STD_VER >= 26
 TEST_CONSTEXPR_CXX26 bool test() {
   const int n           = 3;
   const ConstCopy in[n] = {ConstCopy(1), ConstCopy(2), ConstCopy(3)};
@@ -63,12 +61,11 @@ TEST_CONSTEXPR_CXX26 bool test() {
   for (int i = 0; i != n; ++i)
     assert(out[i].val == in[i].val);
 
-  std::destroy(out, out + n);
+  backport::destroy(out, out + n);
   alloc.deallocate(out, n);
 
   return true;
 }
-#endif // TEST_STD_VER >= 26
 
 int main(int, char**)
 {
@@ -137,8 +134,8 @@ int main(int, char**)
         }
     }
 
-#if TEST_STD_VER >= 26
     test();
+#if TEST_STD_VER >= 26
     static_assert(test());
 #endif
 
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
index e725c42a14733..f42efecfaf8af 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
@@ -16,10 +16,9 @@
 #include <memory>
 #include <cassert>
 
+#include "copy_move_types.h"
+#include "../destroy.h"
 #include "test_macros.h"
-#if TEST_STD_VER >= 26
-#  include "copy_move_types.h"
-#endif
 #include "../overload_compare_iterator.h"
 
 struct B
@@ -51,7 +50,6 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
-#if TEST_STD_VER >= 26
 TEST_CONSTEXPR_CXX26 bool test() {
   const int n           = 3;
   const ConstCopy in[n] = {ConstCopy(1), ConstCopy(2), ConstCopy(3)};
@@ -63,12 +61,11 @@ TEST_CONSTEXPR_CXX26 bool test() {
   for (int i = 0; i != n; ++i)
     assert(out[i].val == in[i].val);
 
-  std::destroy(out, out + n);
+  backport::destroy(out, out + n);
   alloc.deallocate(out, n);
 
   return true;
 }
-#endif // TEST_STD_VER >= 26
 
 int main(int, char**)
 {
@@ -137,10 +134,10 @@ int main(int, char**)
         }
     }
 
-#if TEST_STD_VER >= 26
     test();
+#if TEST_STD_VER >= 26
     static_assert(test());
-#endif // TEST_STD_VER >= 26
+#endif
 
     return 0;
 }
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
index d655a3fc0bb25..1ae1c7e1b0bd4 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
@@ -16,10 +16,9 @@
 #include <memory>
 #include <cassert>
 
+#include "copy_move_types.h"
+#include "../destroy.h"
 #include "test_macros.h"
-#if TEST_STD_VER >= 26
-#  include "copy_move_types.h"
-#endif
 
 struct B
 {
@@ -50,7 +49,6 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
-#if TEST_STD_VER >= 26
 TEST_CONSTEXPR_CXX26 bool test() {
   int n = 3;
   ConstCopy value(42);
@@ -61,12 +59,11 @@ TEST_CONSTEXPR_CXX26 bool test() {
   for (int i = 0; i != n; ++i)
     assert(out[i].val == value.val);
 
-  std::destroy(out, out + n);
+  backport::destroy(out, out + n);
   alloc.deallocate(out, n);
 
   return true;
 }
-#endif // TEST_STD_VER >= 26
 
 int main(int, char**)
 {
@@ -103,8 +100,8 @@ int main(int, char**)
         assert(bp[i].i_ == 23);
     }
 
-#if TEST_STD_VER >= 26
     test();
+#if TEST_STD_VER >= 26
     static_assert(test());
 #endif
 

>From 4e1f25af2e34a8ef30325938917b193ff842c2ec Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 24 May 2026 16:08:08 -0400
Subject: [PATCH 18/18] Ditto

---
 .../uninitialized_fill_n.pass.cpp                     | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
index 3e182fe2ec877..e837da88114c2 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
@@ -15,10 +15,9 @@
 #include <memory>
 #include <cassert>
 
+#include "copy_move_types.h"
+#include "../destroy.h"
 #include "test_macros.h"
-#if TEST_STD_VER >= 26
-#  include "copy_move_types.h"
-#endif
 
 struct B
 {
@@ -49,7 +48,6 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
-#if TEST_STD_VER >= 26
 TEST_CONSTEXPR_CXX26 bool test() {
   const int n = 3;
   ConstCopy value(42);
@@ -61,12 +59,11 @@ TEST_CONSTEXPR_CXX26 bool test() {
   for (int i = 0; i != n; ++i)
     assert(out[i].val == value.val);
 
-  std::destroy(out, out + n);
+  backport::destroy(out, out + n);
   alloc.deallocate(out, n);
 
   return true;
 }
-#endif // TEST_STD_VER >= 26
 
 int main(int, char**)
 {
@@ -107,8 +104,8 @@ int main(int, char**)
 
     }
 
-#if TEST_STD_VER >= 26
     test();
+#if TEST_STD_VER >= 26
     static_assert(test());
 #endif
 



More information about the libcxx-commits mailing list