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

via libcxx-commits libcxx-commits at lists.llvm.org
Thu May 28 01:02:27 PDT 2026


Author: William Tran-Viet
Date: 2026-05-28T16:02:21+08:00
New Revision: 4306b4ab9c12a8b9bf4314cbaa7400eeaa1e7ddc

URL: https://github.com/llvm/llvm-project/commit/4306b4ab9c12a8b9bf4314cbaa7400eeaa1e7ddc
DIFF: https://github.com/llvm/llvm-project/commit/4306b4ab9c12a8b9bf4314cbaa7400eeaa1e7ddc.diff

LOG: [libc++] Implement P3508R0: Wording for "constexpr for specialized memory algorithms" (#197313)

Resolves #118379

- Add `constexpr` to affected areas
- Add `constexpr` tests
- Update documentation

Tests were created with AI assistance.

Added: 
    

Modified: 
    libcxx/docs/ReleaseNotes/23.rst
    libcxx/docs/Status/Cxx2cPapers.csv
    libcxx/include/__memory/ranges_uninitialized_algorithms.h
    libcxx/include/__memory/uninitialized_algorithms.h
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/ranges_uninitialized_value_construct_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitialized_fill_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/ranges_uninitialized_fill.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp
    libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index 7f5068214ca57..843f25dc7708a 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -49,6 +49,7 @@ Implemented Papers
 - P2322R6: ``ranges::fold`` (`Github <https://llvm.org/PR105208>`__)
 - P4144R1: Remove ``span``'s ``initializer_list`` constructor for C++26 (`Github <https://llvm.org/PR189612>`__)
 - P3383R3: ``mdspan.at()`` (`Github <https://llvm.org/PR175213>`__)
+- P3508R0: Wording for "constexpr for specialized memory algorithms" (`Github <https://llvm.org/PR118379>`__)
 
 Improvements and New Features
 -----------------------------

diff  --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 2eee4321b023a..5b229c75cc8c0 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 0622af8ffd13a..6cfc3924d53b5 100644
--- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h
+++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h
@@ -81,14 +81,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 +104,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_
diff erence_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 +120,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 +143,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_
diff erence_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 +165,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>>;
 
@@ -172,8 +176,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));
   }
@@ -193,7 +198,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_
diff erence_t<_InputIterator> __n,
              _OutputIterator __ofirst,
@@ -219,7 +224,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); };
@@ -230,8 +235,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));
   }
@@ -251,7 +257,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_
diff erence_t<_InputIterator> __n,
              _OutputIterator __ofirst,

diff  --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h
index b14be4338dfee..329b3df45dd70 100644
--- a/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/libcxx/include/__memory/uninitialized_algorithms.h
@@ -57,7 +57,8 @@ struct __always_false {
 // uninitialized_copy
 
 template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _EndPredicate>
-inline _LIBCPP_HIDE_FROM_ABI __in_out_result<_InputIterator, _ForwardIterator> __uninitialized_copy(
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __in_out_result<_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 +70,7 @@ inline _LIBCPP_HIDE_FROM_ABI __in_out_result<_InputIterator, _ForwardIterator> _
 }
 
 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 +81,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 __in_out_result<_InputIterator, _ForwardIterator>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __in_out_result<_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 +93,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 +104,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 +116,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 +125,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 +137,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);
@@ -186,7 +187,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 +199,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 +208,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 +220,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,12 +234,12 @@ template <class _ValueType,
           class _ForwardIterator,
           class _EndPredicate,
           class _IterMove>
-inline _LIBCPP_HIDE_FROM_ABI __in_out_result<_InputIterator, _ForwardIterator> __uninitialized_move(
-    _InputIterator __ifirst,
-    _Sentinel1 __ilast,
-    _ForwardIterator __ofirst,
-    _EndPredicate __stop_moving,
-    _IterMove __iter_move) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __in_out_result<_InputIterator, _ForwardIterator>
+__uninitialized_move(_InputIterator __ifirst,
+                     _Sentinel1 __ilast,
+                     _ForwardIterator __ofirst,
+                     _EndPredicate __stop_moving,
+                     _IterMove __iter_move) {
   auto __idx   = __ofirst;
   auto __guard = std::__make_exception_guard([&] { std::__destroy(__ofirst, __idx); });
   for (; __ifirst != __ilast && !__stop_moving(__idx); ++__idx, (void)++__ifirst) {
@@ -247,7 +251,7 @@ inline _LIBCPP_HIDE_FROM_ABI __in_out_result<_InputIterator, _ForwardIterator> _
 }
 
 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 +269,8 @@ template <class _ValueType,
           class _ForwardIterator,
           class _EndPredicate,
           class _IterMove>
-inline _LIBCPP_HIDE_FROM_ABI __in_out_result<_InputIterator, _ForwardIterator> __uninitialized_move_n(
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __in_out_result<_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 +282,7 @@ inline _LIBCPP_HIDE_FROM_ABI __in_out_result<_InputIterator, _ForwardIterator> _
 }
 
 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); };

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..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
@@ -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();
+  test_counted();
+
+  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/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..950501ffb0483 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,6 +16,8 @@
 #include <memory>
 #include <cassert>
 
+#include "algorithms.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "../overload_compare_iterator.h"
 
@@ -48,6 +50,23 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+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);
+
+  util::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+
 int main(int, char**)
 {
     {
@@ -115,5 +134,10 @@ int main(int, char**)
         }
     }
 
-  return 0;
+    test();
+#if TEST_STD_VER >= 26
+    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..2daa7b49e07d9 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,6 +16,8 @@
 #include <memory>
 #include <cassert>
 
+#include "algorithms.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 #include "../overload_compare_iterator.h"
 
@@ -48,6 +50,23 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+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);
+
+  util::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+
 int main(int, char**)
 {
     {
@@ -115,5 +134,10 @@ int main(int, char**)
         }
     }
 
-  return 0;
+    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/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..94c89643fb989 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,6 +15,8 @@
 #include <memory>
 #include <cassert>
 
+#include "algorithms.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 
 struct B
@@ -46,6 +48,23 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+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);
+
+  util::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+
 int main(int, char**)
 {
     {
@@ -85,5 +104,10 @@ int main(int, char**)
 
     }
 
-  return 0;
+    test();
+#if TEST_STD_VER >= 26
+    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..f7a45448fcc41 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,6 +16,8 @@
 #include <memory>
 #include <cassert>
 
+#include "algorithms.h"
+#include "copy_move_types.h"
 #include "test_macros.h"
 
 struct B
@@ -47,6 +49,22 @@ struct Nasty
 
 int Nasty::counter_ = 0;
 
+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);
+
+  util::destroy(out, out + n);
+  alloc.deallocate(out, n);
+
+  return true;
+}
+
 int main(int, char**)
 {
     {
@@ -82,5 +100,10 @@ int main(int, char**)
         assert(bp[i].i_ == 23);
     }
 
-  return 0;
+    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.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp
index c6b38b4fea864..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
@@ -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,72 @@ 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);
+  }
+
+  // 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;
+}
+
 int main(int, char**) {
   // An empty range -- no default constructors should be invoked.
   {
@@ -213,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
@@ -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..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,6 +17,7 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "MoveOnly.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "../overload_compare_iterator.h"
@@ -55,6 +56,25 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  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);
+
+  return true;
+}
+
 void test_ctor_throws()
 {
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -141,5 +161,10 @@ int main(int, char**) {
         }
     }
 
-  return 0;
+    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_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
index 7cdfb4da08e4d..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,6 +17,7 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "MoveOnly.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "../overload_compare_iterator.h"
@@ -55,6 +56,26 @@ int ThrowsCounted::count = 0;
 int ThrowsCounted::constructed = 0;
 int ThrowsCounted::throw_after = 0;
 
+TEST_CONSTEXPR_CXX26 bool test() {
+  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);
+
+  return true;
+}
+
 void test_ctor_throws()
 {
 #ifndef TEST_HAS_NO_EXCEPTIONS
@@ -144,5 +165,10 @@ int main(int, char**)
         }
     }
 
-  return 0;
+    test();
+#if TEST_STD_VER >= 26
+    static_assert(test());
+#endif
+
+    return 0;
 }


        


More information about the libcxx-commits mailing list