[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