[libcxx-commits] [libcxx] [libc++][pstl] Corrected the return types of some parallel algorithms that were returning "void" (PR #230586)
Michael G. Kazakov via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Oct 12 03:54:08 PDT 2026
https://github.com/mikekazakov updated https://github.com/llvm/llvm-project/pull/230586
>From a26bc40c5af0082d48e9bb4d93984edd0c8d2eb9 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Fri, 9 Oct 2026 17:38:10 +0100
Subject: [PATCH] Corrected the return types of some parallel algorithms
---
libcxx/include/__algorithm/pstl.h | 12 +++----
libcxx/include/__memory/pstl.h | 16 +++++-----
libcxx/include/__pstl/backend_fwd.h | 14 ++++----
libcxx/include/__pstl/backends/default.h | 32 ++++++++++---------
.../alg.fill/pstl.fill_n.pass.cpp | 8 ++++-
.../alg.generate/pstl.generate_n.pass.cpp | 8 ++++-
.../alg.foreach/pstl.for_each_n.pass.cpp | 27 ++++++++++------
.../pstl.destroy_n.pass.cpp | 17 ++++++----
...uninitialized_default_construct_n.pass.cpp | 7 ++--
...l.uninitialized_value_construct_n.pass.cpp | 7 ++--
.../pstl.uninitialized_fill_n.pass.cpp | 8 ++---
11 files changed, 92 insertions(+), 64 deletions(-)
diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index 492dd3f3c5d5a..88286df94b0a9 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -486,11 +486,11 @@ template <class _ExecutionPolicy,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill_n requires a ForwardIterator");
using _Implementation = __pstl::__dispatch<__pstl::__fill_n, __pstl::__current_configuration, _RawPolicy>;
- __pstl::__handle_exception<_Implementation>(
+ return __pstl::__handle_exception<_Implementation>(
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), __value);
}
@@ -648,11 +648,11 @@ template <class _ExecutionPolicy,
class _Function,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each_n requires a ForwardIterator");
using _Implementation = __pstl::__dispatch<__pstl::__for_each_n, __pstl::__current_configuration, _RawPolicy>;
- __pstl::__handle_exception<_Implementation>(
+ return __pstl::__handle_exception<_Implementation>(
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__size), std::move(__func));
}
@@ -675,11 +675,11 @@ template <class _ExecutionPolicy,
class _Generator,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate_n requires a ForwardIterator");
using _Implementation = __pstl::__dispatch<__pstl::__generate_n, __pstl::__current_configuration, _RawPolicy>;
- __pstl::__handle_exception<_Implementation>(
+ return __pstl::__handle_exception<_Implementation>(
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__gen));
}
diff --git a/libcxx/include/__memory/pstl.h b/libcxx/include/__memory/pstl.h
index 7dbc9fdcb51d4..4f3024c8b90f6 100644
--- a/libcxx/include/__memory/pstl.h
+++ b/libcxx/include/__memory/pstl.h
@@ -50,10 +50,10 @@ template <class _ExecutionPolicy,
class _Size,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void destroy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n) {
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator destroy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "destroy_n requires ForwardIterators");
using _Implementation = __pstl::__dispatch<__pstl::__destroy_n, __pstl::__current_configuration, _RawPolicy>;
- __pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
+ return __pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
}
template <class _ExecutionPolicy,
@@ -74,13 +74,13 @@ template <class _ExecutionPolicy,
class _Size,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
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);
+ return __pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
}
template <class _ExecutionPolicy,
@@ -131,12 +131,12 @@ template <class _ExecutionPolicy,
class _Size,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
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);
+ return __pstl::__handle_exception<_Implementation>(std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n);
}
template <class _ExecutionPolicy,
@@ -158,12 +158,12 @@ template <class _ExecutionPolicy,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
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>(
+ return __pstl::__handle_exception<_Implementation>(
std::forward<_ExecutionPolicy>(__policy), std::move(__first), __n, __value);
}
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index 2665209887944..e45943954bed9 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -132,7 +132,7 @@ struct __for_each;
template <class _Backend, class _ExecutionPolicy>
struct __for_each_n;
// template <class _Policy, class _ForwardIterator, class _Size, class _Function>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&&, _ForwardIterator __first, _Size __size, _Function __func) const noexcept;
template <class _Backend, class _ExecutionPolicy>
@@ -144,7 +144,7 @@ struct __fill;
template <class _Backend, class _ExecutionPolicy>
struct __fill_n;
// template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&&, _ForwardIterator __first, _Size __n, _Tp const& __value) const noexcept;
template <class _Backend, class _ExecutionPolicy>
@@ -184,7 +184,7 @@ struct __generate;
template <class _Backend, class _ExecutionPolicy>
struct __generate_n;
// template <class _Policy, class _ForwardIterator, class _Size, class _Generator>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&&, _ForwardIterator __first, _Size __n, _Generator __gen) const noexcept;
template <class _Backend, class _ExecutionPolicy>
@@ -434,7 +434,7 @@ struct __destroy;
template <class _Backend, class _ExecutionPolicy>
struct __destroy_n;
// template <class _Policy, class _ForwardIterator, class _Size>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept;
template <class _Backend, class _ExecutionPolicy>
@@ -460,7 +460,7 @@ struct __uninitialized_default_construct;
template <class _Backend, class _ExecutionPolicy>
struct __uninitialized_default_construct_n;
// template <class _Policy, class _ForwardIterator, class _Size>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept;
template <class _Backend, class _ExecutionPolicy>
@@ -486,7 +486,7 @@ struct __uninitialized_value_construct;
template <class _Backend, class _ExecutionPolicy>
struct __uninitialized_value_construct_n;
// template <class _Policy, class _ForwardIterator, class _Size>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept;
template <class _Backend, class _ExecutionPolicy>
@@ -498,7 +498,7 @@ struct __uninitialized_fill;
template <class _Backend, class _ExecutionPolicy>
struct __uninitialized_fill_n;
// template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
-// optional<__empty>
+// optional<_ForwardIterator>
// operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, const _Tp &__value) const noexcept;
} // namespace __pstl
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index 61f5b0c342baa..769344f34249f 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -465,7 +465,7 @@ struct __destroy<__default_backend_tag, _ExecutionPolicy> {
template <class _ExecutionPolicy>
struct __destroy_n<__default_backend_tag, _ExecutionPolicy> {
template <class _Policy, class _ForwardIterator, class _Size>
- optional<__empty> operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept {
+ optional<_ForwardIterator> operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept {
using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
using _Ref = __iterator_reference<_ForwardIterator>;
return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) {
@@ -477,16 +477,19 @@ struct __destroy_n<__default_backend_tag, _ExecutionPolicy> {
template <class _ExecutionPolicy>
struct __for_each_n<__default_backend_tag, _ExecutionPolicy> {
template <class _Policy, class _ForwardIterator, class _Size, class _Function>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
operator()(_Policy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) const noexcept {
if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
_ForwardIterator __last = __first + __size;
- return _ForEach()(__policy, std::move(__first), std::move(__last), std::move(__func));
+ auto __res = _ForEach()(__policy, std::move(__first), __last, std::move(__func));
+ if (!__res) {
+ return nullopt; // Failed to run the algorithm, propagate the error.
+ }
+ return __last;
} else {
// Otherwise, use the serial algorithm to avoid doing two passes over the input
- std::for_each_n(std::move(__first), __size, std::move(__func));
- return __empty{};
+ return std::for_each_n(std::move(__first), __size, std::move(__func));
}
}
};
@@ -505,16 +508,15 @@ struct __fill<__default_backend_tag, _ExecutionPolicy> {
template <class _ExecutionPolicy>
struct __fill_n<__default_backend_tag, _ExecutionPolicy> {
template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Tp const& __value) const noexcept {
if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- using _Fill = __dispatch<__fill, __current_configuration, _ExecutionPolicy>;
- _ForwardIterator __last = __first + __n;
- return _Fill()(__policy, std::move(__first), std::move(__last), __value);
+ using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iterator_reference<_ForwardIterator>;
+ return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) { __element = __value; });
} else {
// Otherwise, use the serial algorithm to avoid doing two passes over the input
- std::fill_n(std::move(__first), __n, __value);
- return optional<__empty>{__empty{}};
+ return std::fill_n(std::move(__first), __n, __value);
}
}
};
@@ -561,7 +563,7 @@ struct __generate<__default_backend_tag, _ExecutionPolicy> {
template <class _ExecutionPolicy>
struct __generate_n<__default_backend_tag, _ExecutionPolicy> {
template <class _Policy, class _ForwardIterator, class _Size, class _Generator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Generator&& __gen) const noexcept {
using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
using _Ref = __iterator_reference<_ForwardIterator>;
@@ -586,7 +588,7 @@ struct __uninitialized_default_construct<__default_backend_tag, _ExecutionPolicy
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>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept {
using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
using _ValueType = __iterator_value_type<_ForwardIterator>;
@@ -614,7 +616,7 @@ struct __uninitialized_value_construct<__default_backend_tag, _ExecutionPolicy>
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>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n) const noexcept {
using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
using _ValueType = __iterator_value_type<_ForwardIterator>;
@@ -642,7 +644,7 @@ struct __uninitialized_fill<__default_backend_tag, _ExecutionPolicy> {
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>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
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>;
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp
index 51232dfef1606..0151177f61759 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp
@@ -34,9 +34,15 @@ template <class Iter>
struct Test {
template <class Policy>
void operator()(Policy&& policy) {
+ { // check the return type
+ int a[] = {0};
+ auto res = std::fill_n(policy, Iter(std::begin(a)), 0, 0);
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ }
{ // simple test
int a[4];
- std::fill_n(policy, Iter(std::begin(a)), std::size(a), 33);
+ auto res = std::fill_n(policy, Iter(std::begin(a)), std::size(a), 33);
+ assert(res == Iter(std::end(a)));
assert(std::all_of(std::begin(a), std::end(a), [](int i) { return i == 33; }));
}
{ // check that an empty range works
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/pstl.generate_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/pstl.generate_n.pass.cpp
index 9506044acdbc0..6001112094059 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/pstl.generate_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.generate/pstl.generate_n.pass.cpp
@@ -26,9 +26,15 @@ template <class Iter>
struct Test {
template <class ExecutionPolicy>
void operator()(ExecutionPolicy&& policy) {
+ { // check the return type
+ int a[] = {0};
+ auto res = std::generate_n(policy, Iter(std::begin(a)), 0, []() { return 1; });
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ }
{ // simple test
int a[10];
- std::generate_n(policy, Iter(std::begin(a)), std::size(a), []() { return 1; });
+ auto res = std::generate_n(policy, Iter(std::begin(a)), std::size(a), []() { return 1; });
+ assert(res == Iter(std::end(a)));
assert(std::all_of(std::begin(a), std::end(a), [](int i) { return i == 1; }));
}
{ // empty range works
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.for_each_n.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.for_each_n.pass.cpp
index 8769d1b4db554..d79a77719f1e9 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.for_each_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/pstl.for_each_n.pass.cpp
@@ -19,6 +19,7 @@
#include <algorithm>
#include <atomic>
#include <cassert>
+#include <type_traits>
#include <vector>
#include "test_macros.h"
@@ -35,15 +36,23 @@ template <class Iter>
struct Test {
template <class Policy>
void operator()(Policy&& policy) {
- int sizes[] = {0, 1, 2, 100};
- for (auto size : sizes) {
- std::vector<int> a(size);
- std::vector<Bool> called(size);
- std::for_each_n(policy, Iter(std::data(a)), std::size(a), [&](int& v) {
- assert(!called[&v - a.data()]);
- called[&v - a.data()] = true;
- });
- assert(std::all_of(std::begin(called), std::end(called), [](bool b) { return b; }));
+ { // Check the return type
+ int a[] = {0};
+ auto res = std::for_each_n(policy, Iter(std::begin(a)), 0, [](int) {});
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ }
+ { // Check that every single element is visited
+ int sizes[] = {0, 1, 2, 100};
+ for (auto size : sizes) {
+ std::vector<int> a(size);
+ std::vector<Bool> called(size);
+ auto res = std::for_each_n(policy, Iter(std::data(a)), std::size(a), [&](int& v) {
+ assert(!called[&v - a.data()]);
+ called[&v - a.data()] = true;
+ });
+ assert(std::all_of(std::begin(called), std::end(called), [](bool b) { return b; }));
+ assert(res == Iter(std::data(a) + std::size(a)));
+ }
}
}
};
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/pstl.destroy_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/pstl.destroy_n.pass.cpp
index bcbdb65bb0e2f..c95caf00394a3 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/pstl.destroy_n.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/pstl.destroy_n.pass.cpp
@@ -13,7 +13,7 @@
// template <class ExecutionPolicy,
// class ForwardIterator,
// class Size>
-// void destroy_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
+// ForwardIterator destroy_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
#include <atomic>
#include <algorithm>
@@ -64,8 +64,9 @@ struct TestCounted {
}
assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 1; }));
- std::destroy_n(policy, Iter(pool), size);
- ASSERT_SAME_TYPE(decltype(std::destroy_n(policy, Iter(pool), size)), void);
+ auto res = std::destroy_n(policy, Iter(pool), size);
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ assert(res == Iter(pool + size));
assert(std::all_of(std::begin(counters), std::begin(counters) + size, [](auto& x) { return x == 0; }));
});
@@ -97,8 +98,9 @@ struct TestArrayCounted3 {
}
assert(counter == 5 * 3);
- std::destroy_n(policy, Iter(pool), 5);
- ASSERT_SAME_TYPE(decltype(std::destroy_n(policy, Iter(pool), 5)), void);
+ auto res = std::destroy_n(policy, Iter(pool), 5);
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ assert(res == Iter(pool + 5));
assert(counter == 0);
std::allocator_traits<Alloc>::deallocate(alloc, pool, 5);
@@ -128,8 +130,9 @@ struct TestArrayCounted3x2 {
}
}
assert(counter == 5 * 3 * 2);
- std::destroy_n(policy, Iter(pool), 5);
- ASSERT_SAME_TYPE(decltype(std::destroy_n(policy, Iter(pool), 5)), void);
+ auto res = std::destroy_n(policy, Iter(pool), 5);
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ assert(res == Iter(pool + 5));
assert(counter == 0);
std::allocator_traits<Alloc>::deallocate(alloc, pool, 5);
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
index a6e9c851f8ed5..0de1dc67affa2 100644
--- 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
@@ -13,7 +13,7 @@
// template <class ExecutionPolicy,
// class ForwardIterator,
// class Size>
-// void uninitialized_default_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
+// ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
#include <atomic>
#include <algorithm>
@@ -67,8 +67,9 @@ struct TestCounted {
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);
+ auto res = std::uninitialized_default_construct_n(policy, Iter(pool), size);
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ assert(res == Iter(pool + size));
// 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; }));
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
index 859e922c4bfa4..b50e631bf0c7a 100644
--- 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
@@ -13,7 +13,7 @@
// template <class ExecutionPolicy,
// class ForwardIterator,
// class Size>
-// void uninitialized_value_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
+// ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n);
#include <atomic>
#include <algorithm>
@@ -67,8 +67,9 @@ struct TestCounted {
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);
+ auto res = std::uninitialized_value_construct_n(policy, Iter(pool), size);
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ assert(res == Iter(pool + size));
// 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; }));
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
index b25d2a7769c5b..6ed8ee303a2f3 100644
--- 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
@@ -14,7 +14,7 @@
// class ForwardIterator,
// class Size,
// class T>
-// void uninitialized_fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value);
+// ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value);
#include <atomic>
#include <algorithm>
@@ -69,9 +69,9 @@ struct TestCounted {
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);
+ auto res = std::uninitialized_fill_n(policy, Iter(pool), size, CountedInit{pool, counters});
+ static_assert(std::is_same_v<decltype(res), Iter>);
+ assert(res == Iter(pool + size));
// 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; }));
More information about the libcxx-commits
mailing list