[libcxx-commits] [libcxx] 9410fc6 - [libc++][pstl] Implementation of parallel uninitialized_default_construct, uninitialized_value_construct and uninitialized_fill (#214580)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 13 04:13:57 PDT 2026
Author: Michael G. Kazakov
Date: 2026-08-13T12:13:52+01:00
New Revision: 9410fc68c61057a493abd33c43fbcb8bae1f98e0
URL: https://github.com/llvm/llvm-project/commit/9410fc68c61057a493abd33c43fbcb8bae1f98e0
DIFF: https://github.com/llvm/llvm-project/commit/9410fc68c61057a493abd33c43fbcb8bae1f98e0.diff
LOG: [libc++][pstl] Implementation of parallel uninitialized_default_construct, uninitialized_value_construct and uninitialized_fill (#214580)
This PR adds parallel versions of these functions:
- `std::uninitialized_default_construct`
- `std::uninitialized_default_construct_n`
- `std::uninitialized_value_construct`
- `std::uninitialized_value_construct_n`
- `std::uninitialized_fill`
- `std::uninitialized_fill_n`
They use parallel `for_each` under the hood and are effectively
one-liners, e.g.:
```c++
return ForEach()(policy, std::move(first), std::move(last), [&value](Ref element) {
::new (static_cast<void*>(std::addressof(element))) ValueType(value);
});
```
Fixes #134590.
Fixes #134591.
Fixes #134594.
Fixes #134595.
Part of #99938.
Added:
libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct.pass.cpp
libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct_n.pass.cpp
libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct.pass.cpp
libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct_n.pass.cpp
libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/pstl.uninitialized_fill_n.pass.cpp
libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/pstl.uninitialized_fill.pass.cpp
Modified:
libcxx/include/__memory/pstl.h
libcxx/include/__pstl/backend_fwd.h
libcxx/include/__pstl/backends/default.h
libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__memory/pstl.h b/libcxx/include/__memory/pstl.h
index a4fc727f3bf72..c06f53bed7206 100644
--- a/libcxx/include/__memory/pstl.h
+++ b/libcxx/include/__memory/pstl.h
@@ -55,6 +55,87 @@ _LIBCPP_HIDE_FROM_ABI void destroy_n(_ExecutionPolicy&& __policy, _ForwardIterat
__pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
}
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+uninitialized_default_construct(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "uninitialized_default_construct requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__uninitialized_default_construct, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Size,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+uninitialized_default_construct_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
+ _ForwardIterator, "uninitialized_default_construct_n requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__uninitialized_default_construct_n, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+uninitialized_value_construct(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "uninitialized_value_construct requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__uninitialized_value_construct, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Size,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+uninitialized_value_construct_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "uninitialized_value_construct_n requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__uninitialized_value_construct_n, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Tp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+uninitialized_fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "uninitialized_fill requires ForwardIterators");
+ using _Implementation = __pstl::__dispatch<__pstl::__uninitialized_fill, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Size,
+ class _Tp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+uninitialized_fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "uninitialized_fill_n requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__uninitialized_fill_n, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n, __value);
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index eb0c8123507d8..221b1b8cb7316 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -384,6 +384,42 @@ struct __destroy_n;
// optional<__empty>
// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept;
+template <class _Backend, class _ExecutionPolicy>
+struct __uninitialized_default_construct;
+// template <class _Policy, class _ForwardIterator>
+// optional<__empty>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __uninitialized_default_construct_n;
+// template <class _Policy, class _ForwardIterator, class _Size>
+// optional<__empty>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __uninitialized_value_construct;
+// template <class _Policy, class _ForwardIterator>
+// optional<__empty>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __uninitialized_value_construct_n;
+// template <class _Policy, class _ForwardIterator, class _Size>
+// optional<__empty>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __uninitialized_fill;
+// template <class _Policy, class _ForwardIterator, class _Tp>
+// optional<__empty>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp &__value) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __uninitialized_fill_n;
+// template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
+// optional<__empty>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, const _Tp &__value) const noexcept;
+
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index 443fd5a35eb02..f9a2da0a8f826 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -89,6 +89,12 @@ namespace __pstl {
// - replace_if
// - generate
// - generate_n
+// - uninitialized_default_construct
+// - uninitialized_default_construct_n
+// - uninitialized_value_construct
+// - uninitialized_value_construct_n
+// - uninitialized_fill
+// - uninitialized_fill_n
//
// merge family
// ------------
@@ -496,6 +502,90 @@ struct __generate_n<__default_backend_tag, _ExecutionPolicy> {
}
};
+template <class _ExecutionPolicy>
+struct __uninitialized_default_construct<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last) const noexcept {
+ using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
+ using _ValueType = __iterator_value_type<_ForwardIterator>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [](_Ref __element) {
+ ::new (static_cast<void*>(std::addressof(__element))) _ValueType;
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __uninitialized_default_construct_n<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Size>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept {
+ using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
+ using _ValueType = __iterator_value_type<_ForwardIterator>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEachN()(__policy, std::move(__first), __n, [](_Ref __element) {
+ ::new (static_cast<void*>(std::addressof(__element))) _ValueType;
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __uninitialized_value_construct<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last) const noexcept {
+ using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
+ using _ValueType = __iterator_value_type<_ForwardIterator>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [](_Ref __element) {
+ ::new (static_cast<void*>(std::addressof(__element))) _ValueType();
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __uninitialized_value_construct_n<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Size>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept {
+ using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
+ using _ValueType = __iterator_value_type<_ForwardIterator>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEachN()(__policy, std::move(__first), __n, [](_Ref __element) {
+ ::new (static_cast<void*>(std::addressof(__element))) _ValueType();
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __uninitialized_fill<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
+ using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
+ using _ValueType = __iterator_value_type<_ForwardIterator>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&__value](_Ref __element) {
+ ::new (static_cast<void*>(std::addressof(__element))) _ValueType(__value);
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __uninitialized_fill_n<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) const noexcept {
+ using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
+ using _ValueType = __iterator_value_type<_ForwardIterator>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEachN()(__policy, std::move(__first), __n, [&__value](_Ref __element) {
+ ::new (static_cast<void*>(std::addressof(__element))) _ValueType(__value);
+ });
+ }
+};
+
//////////////////////////////////////////////////////////////
// stable_sort family
//////////////////////////////////////////////////////////////
diff --git a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
index 84996de9d9298..89dfbea3a0365 100644
--- a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
@@ -282,4 +282,19 @@ void f(non_forward_iterator non_fwd,
(void)std::adjacent_
diff erence(
pol, non_fwd, non_fwd, it, func); // expected-error@*:* {{static assertion failed: adjacent_
diff erence}}
}
+
+ {
+ std::uninitialized_default_construct(
+ pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: uninitialized_default_construct}}
+ std::uninitialized_default_construct_n(
+ pol, non_fwd, n); // expected-error@*:* {{static assertion failed: uninitialized_default_construct_n}}
+ std::uninitialized_value_construct(
+ pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: uninitialized_value_construct}}
+ std::uninitialized_value_construct_n(
+ pol, non_fwd, n); // expected-error@*:* {{static assertion failed: uninitialized_value_construct_n}}
+ std::uninitialized_fill(
+ pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: uninitialized_fill}}
+ std::uninitialized_fill_n(
+ pol, non_fwd, n, val); // expected-error@*:* {{static assertion failed: uninitialized_fill_n}}
+ }
}
diff --git a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
index c63f65572832f..c7e6148ed4822 100644
--- a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
@@ -466,6 +466,32 @@ int main(int, char**) {
(void)std::adjacent_
diff erence(policy, std::move(first1), std::move(last1), std::move(dest), op);
});
}
+
+ {
+ // uninitialized_default_construct(first, last)
+ assert_non_throwing([=, &policy] {
+ std::uninitialized_default_construct(policy, std::move(first1), std::move(last1));
+ });
+
+ // uninitialized_default_construct_n(first, n)
+ assert_non_throwing([=, &policy] { std::uninitialized_default_construct_n(policy, std::move(first1), n); });
+
+ // uninitialized_value_construct(first, last)
+ assert_non_throwing([=, &policy] {
+ std::uninitialized_value_construct(policy, std::move(first1), std::move(last1));
+ });
+
+ // uninitialized_value_construct_n(first, n)
+ assert_non_throwing([=, &policy] { std::uninitialized_value_construct_n(policy, std::move(first1), n); });
+
+ // uninitialized_fill(first, last, val)
+ assert_non_throwing([=, &policy] {
+ std::uninitialized_fill(policy, std::move(first1), std::move(last1), val);
+ });
+
+ // uninitialized_fill_n(first, n, val)
+ assert_non_throwing([=, &policy] { std::uninitialized_fill_n(policy, std::move(first1), n, val); });
+ }
}
});
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct.pass.cpp
new file mode 100644
index 0000000000000..3d91cd13f1fc7
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct.pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator>
+// void uninitialized_default_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(uninitialized_default_construct);
+
+static_assert(sfinae_test_uninitialized_default_construct<int, int*, int*>);
+static_assert(!sfinae_test_uninitialized_default_construct<std::execution::parallel_policy, int*, int*>);
+
+// Each Counted object has a dedicated external atomic counter.
+// To be able to connect with that counter, each Counted object knows that it is located inside a single pool.
+struct Counted {
+ static std::atomic_int counters[1073];
+ static Counted* pool;
+ std::atomic_int* counter;
+ Counted() : counter(counters + (this - pool)) { counter->fetch_add(1); }
+ Counted(Counted const& other) : counter(other.counter) { counter->fetch_add(1); }
+ ~Counted() { counter->fetch_sub(1); }
+ friend void operator&(Counted) = delete;
+};
+std::atomic_int Counted::counters[1073];
+Counted* Counted::pool = nullptr;
+
+template <class Iter>
+struct TestCounted {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ // Alias the static member variables
+ auto& counters = Counted::counters;
+ Counted*& pool = Counted::pool;
+
+ // Initialize all Counted counters to 0
+ std::fill_n(std::begin(counters), std::size(counters), 0);
+
+ // Allocate memory for the Counted objects
+ using Alloc = std::allocator<Counted>;
+ Alloc alloc;
+ pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+ runway_sample(std::size(counters) + 1, [&](size_t size) {
+ // Default-construct the Counted objects in range [0, size).
+ std::uninitialized_default_construct(policy, Iter(pool), Iter(pool + size));
+ ASSERT_SAME_TYPE(decltype(std::uninitialized_default_construct(policy, Iter(pool), Iter(pool + size))), void);
+
+ // Verify that inside this range the counters are all 1 and outside the range they are all 0.
+ assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+ assert(std::all_of(std::begin(counters) + size, std::end(counters), [](auto& x) { return x == 0; }));
+
+ // Destroy the constructed objects and verify that all counters are 0.
+ std::destroy(pool, pool + size);
+ assert(std::all_of(std::begin(counters), std::end(counters), [](auto& x) { return x == 0; }));
+ });
+
+ std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+ }
+ }
+};
+
+template <class Iter>
+struct TestInt {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ constexpr int n = 1073;
+ std::allocator<int> alloc;
+ int* data = alloc.allocate(n);
+ int* last = data + n;
+
+ std::uninitialized_default_construct(policy, Iter(data), Iter(last));
+ // There's nothing we can meaningfully test here, since default-constructing an int is only observable in constexpr contexts,
+ // but still run the algorithm to excercise the runtime.
+
+ std::destroy(data, last);
+ alloc.deallocate(data, n);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<Counted*>{}, TestIteratorWithPolicies<TestCounted>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestInt>{});
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct_n.pass.cpp
new file mode 100644
index 0000000000000..a6e9c851f8ed5
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/pstl.uninitialized_default_construct_n.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator,
+// class Size>
+// void uninitialized_default_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(uninitialized_default_construct_n);
+
+static_assert(sfinae_test_uninitialized_default_construct_n<int, int*, int>);
+static_assert(!sfinae_test_uninitialized_default_construct_n<std::execution::parallel_policy, int*, int>);
+
+// Each Counted object has a dedicated external atomic counter.
+// To be able to connect with that counter, each Counted object knows that it is located inside a single pool.
+struct Counted {
+ static std::atomic_int counters[1073];
+ static Counted* pool;
+ std::atomic_int* counter;
+ Counted() : counter(counters + (this - pool)) { counter->fetch_add(1); }
+ Counted(Counted const& other) : counter(other.counter) { counter->fetch_add(1); }
+ ~Counted() { counter->fetch_sub(1); }
+ friend void operator&(Counted) = delete;
+};
+std::atomic_int Counted::counters[1073];
+Counted* Counted::pool = nullptr;
+
+template <class Iter>
+struct TestCounted {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ // Alias the static member variables
+ auto& counters = Counted::counters;
+ Counted*& pool = Counted::pool;
+
+ // Initialize all Counted counters to 0
+ std::fill_n(std::begin(counters), std::size(counters), 0);
+
+ // Allocate memory for the Counted objects
+ using Alloc = std::allocator<Counted>;
+ Alloc alloc;
+ pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+ runway_sample(std::size(counters) + 1, [&](size_t size) {
+ // Default-construct the Counted objects in range [0, size).
+ std::uninitialized_default_construct_n(policy, Iter(pool), size);
+ ASSERT_SAME_TYPE(decltype(std::uninitialized_default_construct_n(policy, Iter(pool), size)), void);
+
+ // Verify that inside this range the counters are all 1 and outside the range they are all 0.
+ assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+ assert(std::all_of(std::begin(counters) + size, std::end(counters), [](auto& x) { return x == 0; }));
+
+ // Destroy the constructed objects and verify that all counters are 0.
+ std::destroy(pool, pool + size);
+ assert(std::all_of(std::begin(counters), std::end(counters), [](auto& x) { return x == 0; }));
+ });
+
+ std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+ }
+ }
+};
+
+template <class Iter>
+struct TestInt {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ constexpr int n = 1073;
+ std::allocator<int> alloc;
+ int* data = alloc.allocate(n);
+ int* last = data + n;
+
+ std::uninitialized_default_construct_n(policy, Iter(data), n);
+ // There's nothing we can meaningfully test here, since default-constructing an int is only observable in constexpr contexts,
+ // but still run the algorithm to excercise the runtime.
+
+ std::destroy(data, last);
+ alloc.deallocate(data, n);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<Counted*>{}, TestIteratorWithPolicies<TestCounted>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestInt>{});
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct.pass.cpp
new file mode 100644
index 0000000000000..b8390e6884a92
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct.pass.cpp
@@ -0,0 +1,112 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator>
+// void uninitialized_value_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(uninitialized_value_construct);
+
+static_assert(sfinae_test_uninitialized_value_construct<int, int*, int*>);
+static_assert(!sfinae_test_uninitialized_value_construct<std::execution::parallel_policy, int*, int*>);
+
+// Each Counted object has a dedicated external atomic counter.
+// To be able to connect with that counter, each Counted object knows that it is located inside a single pool.
+struct Counted {
+ static std::atomic_int counters[1073];
+ static Counted* pool;
+ std::atomic_int* counter;
+ Counted() : counter(counters + (this - pool)) { counter->fetch_add(1); }
+ Counted(Counted const& other) : counter(other.counter) { counter->fetch_add(1); }
+ ~Counted() { counter->fetch_sub(1); }
+ friend void operator&(Counted) = delete;
+};
+std::atomic_int Counted::counters[1073];
+Counted* Counted::pool = nullptr;
+
+template <class Iter>
+struct TestCounted {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ std::atomic_int(&counters)[1073] = Counted::counters;
+ Counted*& pool = Counted::pool;
+
+ // initialize all Counted counters to 0
+ std::fill_n(std::begin(counters), std::size(counters), 0);
+
+ // Allocate memory for the Counted objects
+ using Alloc = std::allocator<Counted>;
+ Alloc alloc;
+ pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+ runway_sample(std::size(counters) + 1, [&](size_t size) {
+ // Default-construct the Counted objects in range [0, size).
+ std::uninitialized_value_construct(policy, Iter(pool), Iter(pool + size));
+ ASSERT_SAME_TYPE(decltype(std::uninitialized_value_construct(policy, Iter(pool), Iter(pool + size))), void);
+
+ // Verify that inside this range the counters are all 1 and outside the range they are all 0.
+ assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+ assert(std::all_of(std::begin(counters) + size, std::end(counters), [](auto& x) { return x == 0; }));
+
+ // Destroy the constructed objects and verify that all counters are 0.
+ std::destroy(pool, pool + size);
+ assert(std::all_of(std::begin(counters), std::end(counters), [](auto& x) { return x == 0; }));
+ });
+
+ std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+ }
+ }
+};
+
+template <class Iter>
+struct TestInt {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ constexpr int n = 1073;
+ std::allocator<int> alloc;
+ int* data = alloc.allocate(n);
+ int* last = data + n;
+ std::memset(data, 0xFF, n * sizeof(int));
+
+ std::uninitialized_value_construct(policy, Iter(data), Iter(last));
+ for (int i = 0; i != n; ++i) {
+ assert(data[i] == 0);
+ }
+
+ std::destroy(data, last);
+ alloc.deallocate(data, n);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<Counted*>{}, TestIteratorWithPolicies<TestCounted>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestInt>{});
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct_n.pass.cpp
new file mode 100644
index 0000000000000..859e922c4bfa4
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/pstl.uninitialized_value_construct_n.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator,
+// class Size>
+// void uninitialized_value_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(uninitialized_value_construct_n);
+
+static_assert(sfinae_test_uninitialized_value_construct_n<int, int*, int>);
+static_assert(!sfinae_test_uninitialized_value_construct_n<std::execution::parallel_policy, int*, int>);
+
+// Each Counted object has a dedicated external atomic counter.
+// To be able to connect with that counter, each Counted object knows that it is located inside a single pool.
+struct Counted {
+ static std::atomic_int counters[1073];
+ static Counted* pool;
+ std::atomic_int* counter;
+ Counted() : counter(counters + (this - pool)) { counter->fetch_add(1); }
+ Counted(Counted const& other) : counter(other.counter) { counter->fetch_add(1); }
+ ~Counted() { counter->fetch_sub(1); }
+ friend void operator&(Counted) = delete;
+};
+std::atomic_int Counted::counters[1073];
+Counted* Counted::pool = nullptr;
+
+template <class Iter>
+struct TestCounted {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ std::atomic_int(&counters)[1073] = Counted::counters;
+ Counted*& pool = Counted::pool;
+
+ // initialize all Counted counters to 0
+ std::fill_n(std::begin(counters), std::size(counters), 0);
+
+ // Allocate memory for the Counted objects
+ using Alloc = std::allocator<Counted>;
+ Alloc alloc;
+ pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+ runway_sample(std::size(counters) + 1, [&](size_t size) {
+ // Default-construct the Counted objects in range [0, size).
+ std::uninitialized_value_construct_n(policy, Iter(pool), size);
+ ASSERT_SAME_TYPE(decltype(std::uninitialized_value_construct_n(policy, Iter(pool), size)), void);
+
+ // Verify that inside this range the counters are all 1 and outside the range they are all 0.
+ assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+ assert(std::all_of(std::begin(counters) + size, std::end(counters), [](auto& x) { return x == 0; }));
+
+ // Destroy the constructed objects and verify that all counters are 0.
+ std::destroy(pool, pool + size);
+ assert(std::all_of(std::begin(counters), std::end(counters), [](auto& x) { return x == 0; }));
+ });
+
+ std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+ }
+ }
+};
+
+template <class Iter>
+struct TestInt {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ constexpr int n = 1073;
+ std::allocator<int> alloc;
+ int* data = alloc.allocate(n);
+ int* last = data + n;
+ std::memset(data, 0xFF, n * sizeof(int));
+
+ std::uninitialized_value_construct_n(policy, Iter(data), n);
+ for (int i = 0; i != n; ++i) {
+ assert(data[i] == 0);
+ }
+
+ std::destroy(data, last);
+ alloc.deallocate(data, n);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<Counted*>{}, TestIteratorWithPolicies<TestCounted>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestInt>{});
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/pstl.uninitialized_fill_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/pstl.uninitialized_fill_n.pass.cpp
new file mode 100644
index 0000000000000..b25d2a7769c5b
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/pstl.uninitialized_fill_n.pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator,
+// class Size,
+// class T>
+// void uninitialized_fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(uninitialized_fill_n);
+
+static_assert(sfinae_test_uninitialized_fill_n<int, int*, int, int>);
+static_assert(!sfinae_test_uninitialized_fill_n<std::execution::parallel_policy, int*, int, int>);
+
+// Init payload to initialize each Counted object with a pointer to its dedicated counter
+struct CountedInit {
+ struct Counted* first_;
+ std::atomic_int* counters_;
+};
+
+// Each Counted object has a dedicated external atomic counter
+struct Counted {
+ std::atomic_int* counter_;
+ explicit Counted(CountedInit init) : counter_(init.counters_ + (this - init.first_)) { counter_->fetch_add(1); }
+ Counted(Counted const& other) : counter_(other.counter_) { counter_->fetch_add(1); }
+ ~Counted() { counter_->fetch_sub(1); }
+ friend void operator&(Counted) = delete;
+};
+
+template <class Iter>
+struct TestCounted {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ // Test uninitialized_fill_n() with a range of Counted objects.
+ // Ranges vary in size from 0 to 1073.
+ // Each object has its own counter.
+ std::atomic_int counters[1073];
+ std::fill_n(std::begin(counters), std::size(counters), 0); // initialize all counters to 0
+
+ // Allocate memory for the Counted objects
+ using Alloc = std::allocator<Counted>;
+ Alloc alloc;
+ Counted* pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+ runway_sample(std::size(counters) + 1, [&](size_t size) {
+ // Construct the Counted object in range [0, size).
+ std::uninitialized_fill_n(policy, Iter(pool), size, CountedInit{pool, counters});
+ ASSERT_SAME_TYPE(
+ decltype(std::uninitialized_fill_n(policy, Iter(pool), size, CountedInit{pool, counters})), void);
+
+ // Verify that inside this range the counters are all 1 and outside the range they are all 0.
+ assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+ assert(std::all_of(std::begin(counters) + size, std::end(counters), [](auto& x) { return x == 0; }));
+
+ // Destroy the constructed objects and verify that all counters are 0.
+ std::destroy(Iter(pool), Iter(pool + size));
+ assert(std::all_of(std::begin(counters), std::end(counters), [](auto& x) { return x == 0; }));
+ });
+
+ std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+ }
+ }
+};
+
+template <class Iter>
+struct TestInt {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ constexpr int n = 1073;
+ std::allocator<int> alloc;
+ int* data = alloc.allocate(n);
+ int* last = data + n;
+
+ std::uninitialized_fill_n(policy, Iter(data), n, 42);
+ for (int i = 0; i != n; ++i) {
+ assert(data[i] == 42);
+ }
+
+ std::destroy(data, last);
+ alloc.deallocate(data, n);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<Counted*>{}, TestIteratorWithPolicies<TestCounted>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestInt>{});
+ return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/pstl.uninitialized_fill.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/pstl.uninitialized_fill.pass.cpp
new file mode 100644
index 0000000000000..ce20e02dc3e5f
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/pstl.uninitialized_fill.pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator,
+// class T>
+// void uninitialized_fill(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value);
+
+#include <atomic>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(uninitialized_fill);
+
+static_assert(sfinae_test_uninitialized_fill<int, int*, int*, int>);
+static_assert(!sfinae_test_uninitialized_fill<std::execution::parallel_policy, int*, int*, int>);
+
+// Init payload to initialize each Counted object with a pointer to its dedicated counter
+struct CountedInit {
+ struct Counted* first_;
+ std::atomic_int* counters_;
+};
+
+// Each Counted object has a dedicated external atomic counter
+struct Counted {
+ std::atomic_int* counter_;
+ explicit Counted(CountedInit init) : counter_(init.counters_ + (this - init.first_)) { counter_->fetch_add(1); }
+ Counted(Counted const& other) : counter_(other.counter_) { counter_->fetch_add(1); }
+ ~Counted() { counter_->fetch_sub(1); }
+ friend void operator&(Counted) = delete;
+};
+
+template <class Iter>
+struct TestCounted {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ // Test uninitialized_fill() with a range of Counted objects.
+ // Ranges vary in size from 0 to 1073.
+ // Each object has its own counter.
+ std::atomic_int counters[1073];
+ std::fill_n(std::begin(counters), std::size(counters), 0); // initialize all counters to 0
+
+ // Allocate memory for the Counted objects
+ using Alloc = std::allocator<Counted>;
+ Alloc alloc;
+ Counted* pool = std::allocator_traits<Alloc>::allocate(alloc, std::size(counters));
+
+ runway_sample(std::size(counters) + 1, [&](size_t size) {
+ // Construct the Counted object in range [0, size).
+ std::uninitialized_fill(policy, Iter(pool), Iter(pool + size), CountedInit{pool, counters});
+ ASSERT_SAME_TYPE(
+ decltype(std::uninitialized_fill(policy, Iter(pool), Iter(pool + size), CountedInit{pool, counters})),
+ void);
+
+ // Verify that inside this range the counters are all 1 and outside the range they are all 0.
+ assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
+ assert(std::all_of(std::begin(counters) + size, std::end(counters), [](auto& x) { return x == 0; }));
+
+ // Destroy the constructed objects and verify that all counters are 0.
+ std::destroy(Iter(pool), Iter(pool + size));
+ assert(std::all_of(std::begin(counters), std::end(counters), [](auto& x) { return x == 0; }));
+ });
+
+ std::allocator_traits<Alloc>::deallocate(alloc, pool, std::size(counters));
+ }
+ }
+};
+
+template <class Iter>
+struct TestInt {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ constexpr int n = 1073;
+ std::allocator<int> alloc;
+ int* data = alloc.allocate(n);
+ int* last = data + n;
+
+ std::uninitialized_fill(policy, Iter(data), Iter(last), 42);
+ for (int i = 0; i != n; ++i) {
+ assert(data[i] == 42);
+ }
+
+ std::destroy(data, last);
+ alloc.deallocate(data, n);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<Counted*>{}, TestIteratorWithPolicies<TestCounted>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestInt>{});
+ return 0;
+}
More information about the libcxx-commits
mailing list