[libcxx-commits] [libcxx] [libc++] Overhaul the PSTL dispatching mechanism (PR #88131)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Apr 12 14:29:19 PDT 2024
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/88131
>From b0d7fcad8998d7018da428bfb01cb16df0bcb3a2 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 5 Apr 2024 15:11:35 -0400
Subject: [PATCH 1/8] WIP: introduce CPU traits
---
libcxx/include/CMakeLists.txt | 1 +
.../__algorithm/pstl_backends/cpu_backend.h | 45 --
.../pstl_backends/cpu_backends/any_of.h | 9 +-
.../pstl_backends/cpu_backends/backend.h | 10 +-
.../pstl_backends/cpu_backends/fill.h | 3 +-
.../pstl_backends/cpu_backends/find_if.h | 22 +-
.../pstl_backends/cpu_backends/for_each.h | 3 +-
.../pstl_backends/cpu_backends/libdispatch.h | 459 +++++++++---------
.../pstl_backends/cpu_backends/merge.h | 3 +-
.../pstl_backends/cpu_backends/serial.h | 98 ++--
.../pstl_backends/cpu_backends/stable_sort.h | 3 +-
.../pstl_backends/cpu_backends/thread.h | 96 ++--
.../pstl_backends/cpu_backends/transform.h | 5 +-
.../cpu_backends/transform_reduce.h | 18 +-
libcxx/include/__pstl/cpu_algos/cpu_traits.h | 84 ++++
libcxx/src/pstl/libdispatch.cpp | 7 +-
libcxx/utils/generate_iwyu_mapping.py | 1 +
17 files changed, 465 insertions(+), 402 deletions(-)
create mode 100644 libcxx/include/__pstl/cpu_algos/cpu_traits.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 097a41d4c41740..1f90dd6db5b158 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -591,6 +591,7 @@ set(files
__numeric/transform_exclusive_scan.h
__numeric/transform_inclusive_scan.h
__numeric/transform_reduce.h
+ __pstl/cpu_algos/cpu_traits.h
__random/bernoulli_distribution.h
__random/binomial_distribution.h
__random/cauchy_distribution.h
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backend.h b/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
index 6980ded189ea2a..c93139243af459 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
@@ -10,51 +10,6 @@
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
#include <__config>
-
-/*
-
- // _Functor takes a subrange for [__first, __last) that should be executed in serial
- template <class _RandomAccessIterator, class _Functor>
- optional<__empty> __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func);
-
- template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction>
- optional<_Tp>
- __parallel_transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction);
-
- // Cancel the execution of other jobs - they aren't needed anymore
- void __cancel_execution();
-
- template <class _RandomAccessIterator1,
- class _RandomAccessIterator2,
- class _RandomAccessIterator3,
- class _Compare,
- class _LeafMerge>
- optional<void> __parallel_merge(
- _RandomAccessIterator1 __first1,
- _RandomAccessIterator1 __last1,
- _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2,
- _RandomAccessIterator3 __outit,
- _Compare __comp,
- _LeafMerge __leaf_merge);
-
- template <class _RandomAccessIterator, class _Comp, class _LeafSort>
- void __parallel_stable_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Comp __comp,
- _LeafSort __leaf_sort);
-
- TODO: Document the parallel backend
-
-Exception handling
-==================
-
-CPU backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their
-implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are turned
-into a program termination at the front-end level. When a backend returns a disengaged `optional` to the frontend, the
-frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to the user.
-*/
-
#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__algorithm/pstl_backends/cpu_backends/fill.h>
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h
index 13dff80086e72b..3755d288047e0b 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h
@@ -17,6 +17,7 @@
#include <__config>
#include <__functional/operations.h>
#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -30,13 +31,13 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Index, class _Brick>
+template <class _Backend, class _Index, class _Brick>
_LIBCPP_HIDE_FROM_ABI optional<bool> __parallel_or(_Index __first, _Index __last, _Brick __f) {
std::atomic<bool> __found(false);
- auto __ret = __par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) {
+ auto __ret = __pstl::__cpu_traits<_Backend>::__for_each(__first, __last, [__f, &__found](_Index __i, _Index __j) {
if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) {
__found.store(true, std::memory_order_relaxed);
- __par_backend::__cancel_execution();
+ __pstl::__cpu_traits<_Backend>::__cancel_execution();
}
});
if (!__ret)
@@ -74,7 +75,7 @@ _LIBCPP_HIDE_FROM_ABI optional<bool>
__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__parallel_or(
+ return std::__parallel_or<__cpu_backend_tag>(
__first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
auto __res = std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __pred);
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
index ea2210a4a7adbd..0641a51e6823e3 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
@@ -30,9 +30,13 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-struct __cpu_backend_tag {};
-
-inline constexpr size_t __lane_size = 64;
+# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
+using __cpu_backend_tag = __pstl::__serial_backend_tag;
+# elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
+using __cpu_backend_tag = __pstl::__std_thread_backend_tag;
+# elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
+using __cpu_backend_tag = __pstl::__libdispatch_backend_tag;
+# endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
index 64babe9fd2bdae..0c20bdff62675a 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
@@ -13,6 +13,7 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/empty.h>
#include <optional>
@@ -39,7 +40,7 @@ _LIBCPP_HIDE_FROM_ABI optional<__empty>
__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return __par_backend::__parallel_for(
+ return __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
__first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
[[maybe_unused]] auto __res = std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __value);
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h
index 170470e4fb7edd..626293faef6921 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h
@@ -16,6 +16,7 @@
#include <__functional/operations.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -33,7 +34,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Index, class _Brick, class _Compare>
+template <class _Backend, class _Index, class _Brick, class _Compare>
_LIBCPP_HIDE_FROM_ABI optional<_Index>
__parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) {
typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
@@ -41,8 +42,8 @@ __parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool
_DifferenceType __initial_dist = __b_first ? __n : -1;
std::atomic<_DifferenceType> __extremum(__initial_dist);
// TODO: find out what is better here: parallel_for or parallel_reduce
- auto __res =
- __par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
+ auto __res = __pstl::__cpu_traits<_Backend>::__for_each(
+ __first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
// See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
// why using a shared variable scales fairly well in this situation.
if (__comp(__i - __first, __extremum)) {
@@ -61,12 +62,12 @@ __parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool
return __extremum.load() != __initial_dist ? __first + __extremum.load() : __last;
}
-template <class _Index, class _DifferenceType, class _Compare>
+template <class _Backend, class _Index, class _DifferenceType, class _Compare>
_LIBCPP_HIDE_FROM_ABI _Index
__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept {
// Experiments show good block sizes like this
- const _DifferenceType __block_size = 8;
- alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
+ const _DifferenceType __block_size = 8;
+ alignas(__pstl::__cpu_traits<_Backend>::__lane_size) _DifferenceType __lane[__block_size] = {0};
while (__end - __begin >= __block_size) {
_DifferenceType __found = 0;
_PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) {
@@ -102,7 +103,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__parallel_find(
+ return std::__parallel_find<__cpu_backend_tag>(
__first,
__last,
[&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
@@ -116,9 +117,10 @@ __pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __l
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
using __diff_t = __iter_diff_t<_ForwardIterator>;
- return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
- return __pred(__iter[__i]);
- });
+ return std::__simd_first<__cpu_backend_tag>(
+ __first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
+ return __pred(__iter[__i]);
+ });
} else {
return std::find_if(__first, __last, __pred);
}
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
index 81fd4526b8dbf1..d637084e151d81 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
@@ -13,6 +13,7 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/empty.h>
#include <optional>
@@ -39,7 +40,7 @@ _LIBCPP_HIDE_FROM_ABI optional<__empty>
__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__par_backend::__parallel_for(
+ return __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
__first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
[[maybe_unused]] auto __res = std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __func);
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h
index e885e7f225172c..7353c4222a06e1 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h
@@ -23,6 +23,7 @@
#include <__memory/construct_at.h>
#include <__memory/unique_ptr.h>
#include <__numeric/reduce.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__utility/empty.h>
#include <__utility/exception_guard.h>
#include <__utility/move.h>
@@ -37,9 +38,9 @@ _LIBCPP_PUSH_MACROS
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
-namespace __par_backend {
-inline namespace __libdispatch {
+struct __libdispatch_backend_tag {};
// ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do
// we.
@@ -49,7 +50,7 @@ __dispatch_apply(size_t __chunk_count, void* __context, void (*__func)(void* __c
template <class _Func>
_LIBCPP_HIDE_FROM_ABI void __dispatch_apply(size_t __chunk_count, _Func __func) noexcept {
- __libdispatch::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) {
+ __pstl::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) {
(*static_cast<_Func*>(__context))(__chunk);
});
}
@@ -66,7 +67,7 @@ template <class _RandomAccessIterator, class _Functor>
_LIBCPP_HIDE_FROM_ABI optional<__empty>
__dispatch_parallel_for(__chunk_partitions __partitions, _RandomAccessIterator __first, _Functor __func) {
// Perform the chunked execution.
- __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
+ __pstl::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
auto __index =
__chunk == 0
@@ -78,266 +79,268 @@ __dispatch_parallel_for(__chunk_partitions __partitions, _RandomAccessIterator _
return __empty{};
}
-template <class _RandomAccessIterator, class _Functor>
-_LIBCPP_HIDE_FROM_ABI optional<__empty>
-__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) {
- return __libdispatch::__dispatch_parallel_for(
- __libdispatch::__partition_chunks(__last - __first), std::move(__first), std::move(__func));
-}
-
-template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
-struct __merge_range {
- __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
- : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
+template <>
+struct __cpu_traits<__libdispatch_backend_tag> {
+ template <class _RandomAccessIterator, class _Functor>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) {
+ return __pstl::__dispatch_parallel_for(
+ __pstl::__partition_chunks(__last - __first), std::move(__first), std::move(__func));
+ }
- _RandomAccessIterator1 __mid1_;
- _RandomAccessIterator2 __mid2_;
- _RandomAccessIteratorOut __result_;
-};
+ template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
+ struct __merge_range {
+ __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
+ : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
-template <typename _RandomAccessIterator1,
- typename _RandomAccessIterator2,
- typename _RandomAccessIterator3,
- typename _Compare,
- typename _LeafMerge>
-_LIBCPP_HIDE_FROM_ABI optional<__empty> __parallel_merge(
- _RandomAccessIterator1 __first1,
- _RandomAccessIterator1 __last1,
- _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2,
- _RandomAccessIterator3 __result,
- _Compare __comp,
- _LeafMerge __leaf_merge) noexcept {
- __chunk_partitions __partitions =
- __libdispatch::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2));
-
- if (__partitions.__chunk_count_ == 0)
- return __empty{};
+ _RandomAccessIterator1 __mid1_;
+ _RandomAccessIterator2 __mid2_;
+ _RandomAccessIteratorOut __result_;
+ };
- if (__partitions.__chunk_count_ == 1) {
- __leaf_merge(__first1, __last1, __first2, __last2, __result, __comp);
- return __empty{};
- }
+ template <typename _RandomAccessIterator1,
+ typename _RandomAccessIterator2,
+ typename _RandomAccessIterator3,
+ typename _Compare,
+ typename _LeafMerge>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __merge(_RandomAccessIterator1 __first1,
+ _RandomAccessIterator1 __last1,
+ _RandomAccessIterator2 __first2,
+ _RandomAccessIterator2 __last2,
+ _RandomAccessIterator3 __result,
+ _Compare __comp,
+ _LeafMerge __leaf_merge) noexcept {
+ __chunk_partitions __partitions =
+ __pstl::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2));
+
+ if (__partitions.__chunk_count_ == 0)
+ return __empty{};
+
+ if (__partitions.__chunk_count_ == 1) {
+ __leaf_merge(__first1, __last1, __first2, __last2, __result, __comp);
+ return __empty{};
+ }
- using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>;
- auto const __n_ranges = __partitions.__chunk_count_ + 1;
+ using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>;
+ auto const __n_ranges = __partitions.__chunk_count_ + 1;
- // TODO: use __uninitialized_buffer
- auto __destroy = [=](__merge_range_t* __ptr) {
- std::destroy_n(__ptr, __n_ranges);
- std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges);
- };
+ // TODO: use __uninitialized_buffer
+ auto __destroy = [=](__merge_range_t* __ptr) {
+ std::destroy_n(__ptr, __n_ranges);
+ std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges);
+ };
- unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
- [&]() -> __merge_range_t* {
+ unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
+ [&]() -> __merge_range_t* {
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- try {
+ try {
# endif
- return std::allocator<__merge_range_t>().allocate(__n_ranges);
+ return std::allocator<__merge_range_t>().allocate(__n_ranges);
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
- } catch (const std::bad_alloc&) {
- return nullptr;
- }
+ } catch (const std::bad_alloc&) {
+ return nullptr;
+ }
# endif
- }(),
- __destroy);
-
- if (!__ranges)
- return nullopt;
+ }(),
+ __destroy);
+
+ if (!__ranges)
+ return nullopt;
+
+ // TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case
+ __merge_range_t* __r = __ranges.get();
+ std::__construct_at(__r++, __first1, __first2, __result);
+
+ bool __iterate_first_range = __last1 - __first1 > __last2 - __first2;
+
+ auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t {
+ auto [__mid1, __mid2] = [&] {
+ if (__iterate_first_range) {
+ auto __m1 = __first1 + __chunk_size;
+ auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp);
+ return std::make_pair(__m1, __m2);
+ } else {
+ auto __m2 = __first2 + __chunk_size;
+ auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp);
+ return std::make_pair(__m1, __m2);
+ }
+ }();
- // TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case
- __merge_range_t* __r = __ranges.get();
- std::__construct_at(__r++, __first1, __first2, __result);
+ __result += (__mid1 - __first1) + (__mid2 - __first2);
+ __first1 = __mid1;
+ __first2 = __mid2;
+ return {std::move(__mid1), std::move(__mid2), __result};
+ };
- bool __iterate_first_range = __last1 - __first1 > __last2 - __first2;
+ // handle first chunk
+ std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_));
- auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t {
- auto [__mid1, __mid2] = [&] {
- if (__iterate_first_range) {
- auto __m1 = __first1 + __chunk_size;
- auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp);
- return std::make_pair(__m1, __m2);
- } else {
- auto __m2 = __first2 + __chunk_size;
- auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp);
- return std::make_pair(__m1, __m2);
- }
- }();
+ // handle 2 -> N - 1 chunks
+ for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i)
+ std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_));
- __result += (__mid1 - __first1) + (__mid2 - __first2);
- __first1 = __mid1;
- __first2 = __mid2;
- return {std::move(__mid1), std::move(__mid2), __result};
- };
+ // handle last chunk
+ std::__construct_at(__r, __last1, __last2, __result);
- // handle first chunk
- std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_));
-
- // handle 2 -> N - 1 chunks
- for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i)
- std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_));
-
- // handle last chunk
- std::__construct_at(__r, __last1, __last2, __result);
-
- __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) {
- auto __first_iters = __ranges[__index];
- auto __last_iters = __ranges[__index + 1];
- __leaf_merge(
- __first_iters.__mid1_,
- __last_iters.__mid1_,
- __first_iters.__mid2_,
- __last_iters.__mid2_,
- __first_iters.__result_,
- __comp);
- });
+ __pstl::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) {
+ auto __first_iters = __ranges[__index];
+ auto __last_iters = __ranges[__index + 1];
+ __leaf_merge(
+ __first_iters.__mid1_,
+ __last_iters.__mid1_,
+ __first_iters.__mid2_,
+ __last_iters.__mid2_,
+ __first_iters.__result_,
+ __comp);
+ });
- return __empty{};
-}
+ return __empty{};
+ }
-template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction>
-_LIBCPP_HIDE_FROM_ABI optional<_Value> __parallel_transform_reduce(
- _RandomAccessIterator __first,
- _RandomAccessIterator __last,
- _Transform __transform,
- _Value __init,
- _Combiner __combiner,
- _Reduction __reduction) {
- if (__first == __last)
- return __init;
-
- auto __partitions = __libdispatch::__partition_chunks(__last - __first);
-
- auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) {
- std::destroy_n(__ptr, __count);
- std::allocator<_Value>().deallocate(__ptr, __count);
- };
+ template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction>
+ _LIBCPP_HIDE_FROM_ABI static optional<_Value> __transform_reduce(
+ _RandomAccessIterator __first,
+ _RandomAccessIterator __last,
+ _Transform __transform,
+ _Value __init,
+ _Combiner __combiner,
+ _Reduction __reduction) {
+ if (__first == __last)
+ return __init;
+
+ auto __partitions = __pstl::__partition_chunks(__last - __first);
+
+ auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) {
+ std::destroy_n(__ptr, __count);
+ std::allocator<_Value>().deallocate(__ptr, __count);
+ };
- // TODO: use __uninitialized_buffer
- // TODO: allocate one element per worker instead of one element per chunk
- unique_ptr<_Value[], decltype(__destroy)> __values(
- std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy);
+ // TODO: use __uninitialized_buffer
+ // TODO: allocate one element per worker instead of one element per chunk
+ unique_ptr<_Value[], decltype(__destroy)> __values(
+ std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy);
+
+ // __dispatch_apply is noexcept
+ __pstl::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
+ auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
+ auto __index = __chunk == 0 ? 0
+ : (__chunk * __partitions.__chunk_size_) +
+ (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
+ if (__this_chunk_size != 1) {
+ std::__construct_at(
+ __values.get() + __chunk,
+ __reduction(__first + __index + 2,
+ __first + __index + __this_chunk_size,
+ __combiner(__transform(__first + __index), __transform(__first + __index + 1))));
+ } else {
+ std::__construct_at(__values.get() + __chunk, __transform(__first + __index));
+ }
+ });
- // __dispatch_apply is noexcept
- __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
- auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
- auto __index =
- __chunk == 0
- ? 0
- : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
- if (__this_chunk_size != 1) {
- std::__construct_at(
- __values.get() + __chunk,
- __reduction(__first + __index + 2,
- __first + __index + __this_chunk_size,
- __combiner(__transform(__first + __index), __transform(__first + __index + 1))));
- } else {
- std::__construct_at(__values.get() + __chunk, __transform(__first + __index));
- }
- });
+ return std::reduce(
+ std::make_move_iterator(__values.get()),
+ std::make_move_iterator(__values.get() + __partitions.__chunk_count_),
+ std::move(__init),
+ __combiner);
+ }
- return std::reduce(
- std::make_move_iterator(__values.get()),
- std::make_move_iterator(__values.get() + __partitions.__chunk_count_),
- std::move(__init),
- __combiner);
-}
+ template <class _RandomAccessIterator, class _Comp, class _LeafSort>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) {
+ const auto __size = __last - __first;
+ auto __partitions = __pstl::__partition_chunks(__size);
-template <class _RandomAccessIterator, class _Comp, class _LeafSort>
-_LIBCPP_HIDE_FROM_ABI optional<__empty> __parallel_stable_sort(
- _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) {
- const auto __size = __last - __first;
- auto __partitions = __libdispatch::__partition_chunks(__size);
+ if (__partitions.__chunk_count_ == 0)
+ return __empty{};
- if (__partitions.__chunk_count_ == 0)
- return __empty{};
+ if (__partitions.__chunk_count_ == 1) {
+ __leaf_sort(__first, __last, __comp);
+ return __empty{};
+ }
- if (__partitions.__chunk_count_ == 1) {
- __leaf_sort(__first, __last, __comp);
- return __empty{};
- }
+ using _Value = __iter_value_type<_RandomAccessIterator>;
- using _Value = __iter_value_type<_RandomAccessIterator>;
+ auto __destroy = [__size](_Value* __ptr) {
+ std::destroy_n(__ptr, __size);
+ std::allocator<_Value>().deallocate(__ptr, __size);
+ };
- auto __destroy = [__size](_Value* __ptr) {
- std::destroy_n(__ptr, __size);
- std::allocator<_Value>().deallocate(__ptr, __size);
- };
+ // TODO: use __uninitialized_buffer
+ unique_ptr<_Value[], decltype(__destroy)> __values(std::allocator<_Value>().allocate(__size), __destroy);
- // TODO: use __uninitialized_buffer
- unique_ptr<_Value[], decltype(__destroy)> __values(std::allocator<_Value>().allocate(__size), __destroy);
+ // Initialize all elements to a moved-from state
+ // TODO: Don't do this - this can be done in the first merge - see https://llvm.org/PR63928
+ std::__construct_at(__values.get(), std::move(*__first));
+ for (__iter_diff_t<_RandomAccessIterator> __i = 1; __i != __size; ++__i) {
+ std::__construct_at(__values.get() + __i, std::move(__values.get()[__i - 1]));
+ }
+ *__first = std::move(__values.get()[__size - 1]);
+
+ __pstl::__dispatch_parallel_for(
+ __partitions,
+ __first,
+ [&__leaf_sort, &__comp](_RandomAccessIterator __chunk_first, _RandomAccessIterator __chunk_last) {
+ __leaf_sort(std::move(__chunk_first), std::move(__chunk_last), __comp);
+ });
+
+ bool __objects_are_in_buffer = false;
+ do {
+ const auto __old_chunk_size = __partitions.__chunk_size_;
+ if (__partitions.__chunk_count_ % 2 == 1) {
+ auto __inplace_merge_chunks = [&__comp, &__partitions](auto __first_chunk_begin) {
+ std::inplace_merge(
+ __first_chunk_begin,
+ __first_chunk_begin + __partitions.__first_chunk_size_,
+ __first_chunk_begin + __partitions.__first_chunk_size_ + __partitions.__chunk_size_,
+ __comp);
+ };
+ if (__objects_are_in_buffer)
+ __inplace_merge_chunks(__values.get());
+ else
+ __inplace_merge_chunks(__first);
+ __partitions.__first_chunk_size_ += 2 * __partitions.__chunk_size_;
+ } else {
+ __partitions.__first_chunk_size_ += __partitions.__chunk_size_;
+ }
- // Initialize all elements to a moved-from state
- // TODO: Don't do this - this can be done in the first merge - see https://llvm.org/PR63928
- std::__construct_at(__values.get(), std::move(*__first));
- for (__iter_diff_t<_RandomAccessIterator> __i = 1; __i != __size; ++__i) {
- std::__construct_at(__values.get() + __i, std::move(__values.get()[__i - 1]));
- }
- *__first = std::move(__values.get()[__size - 1]);
-
- __libdispatch::__dispatch_parallel_for(
- __partitions,
- __first,
- [&__leaf_sort, &__comp](_RandomAccessIterator __chunk_first, _RandomAccessIterator __chunk_last) {
- __leaf_sort(std::move(__chunk_first), std::move(__chunk_last), __comp);
- });
-
- bool __objects_are_in_buffer = false;
- do {
- const auto __old_chunk_size = __partitions.__chunk_size_;
- if (__partitions.__chunk_count_ % 2 == 1) {
- auto __inplace_merge_chunks = [&__comp, &__partitions](auto __first_chunk_begin) {
- std::inplace_merge(
- __first_chunk_begin,
- __first_chunk_begin + __partitions.__first_chunk_size_,
- __first_chunk_begin + __partitions.__first_chunk_size_ + __partitions.__chunk_size_,
- __comp);
+ __partitions.__chunk_size_ *= 2;
+ __partitions.__chunk_count_ /= 2;
+
+ auto __merge_chunks = [__partitions, __old_chunk_size, &__comp](auto __from_first, auto __to_first) {
+ __pstl::__dispatch_parallel_for(
+ __partitions,
+ __from_first,
+ [__old_chunk_size, &__from_first, &__to_first, &__comp](auto __chunk_first, auto __chunk_last) {
+ std::merge(std::make_move_iterator(__chunk_first),
+ std::make_move_iterator(__chunk_last - __old_chunk_size),
+ std::make_move_iterator(__chunk_last - __old_chunk_size),
+ std::make_move_iterator(__chunk_last),
+ __to_first + (__chunk_first - __from_first),
+ __comp);
+ });
};
+
if (__objects_are_in_buffer)
- __inplace_merge_chunks(__values.get());
+ __merge_chunks(__values.get(), __first);
else
- __inplace_merge_chunks(__first);
- __partitions.__first_chunk_size_ += 2 * __partitions.__chunk_size_;
- } else {
- __partitions.__first_chunk_size_ += __partitions.__chunk_size_;
- }
-
- __partitions.__chunk_size_ *= 2;
- __partitions.__chunk_count_ /= 2;
-
- auto __merge_chunks = [__partitions, __old_chunk_size, &__comp](auto __from_first, auto __to_first) {
- __libdispatch::__dispatch_parallel_for(
- __partitions,
- __from_first,
- [__old_chunk_size, &__from_first, &__to_first, &__comp](auto __chunk_first, auto __chunk_last) {
- std::merge(std::make_move_iterator(__chunk_first),
- std::make_move_iterator(__chunk_last - __old_chunk_size),
- std::make_move_iterator(__chunk_last - __old_chunk_size),
- std::make_move_iterator(__chunk_last),
- __to_first + (__chunk_first - __from_first),
- __comp);
- });
- };
+ __merge_chunks(__first, __values.get());
+ __objects_are_in_buffer = !__objects_are_in_buffer;
+ } while (__partitions.__chunk_count_ > 1);
- if (__objects_are_in_buffer)
- __merge_chunks(__values.get(), __first);
- else
- __merge_chunks(__first, __values.get());
- __objects_are_in_buffer = !__objects_are_in_buffer;
- } while (__partitions.__chunk_count_ > 1);
+ if (__objects_are_in_buffer) {
+ std::move(__values.get(), __values.get() + __size, __first);
+ }
- if (__objects_are_in_buffer) {
- std::move(__values.get(), __values.get() + __size, __first);
+ return __empty{};
}
- return __empty{};
-}
-
-_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
+ _LIBCPP_HIDE_FROM_ABI static void __cancel_execution() {}
-} // namespace __libdispatch
-} // namespace __par_backend
+ static constexpr size_t __lane_size = 64;
+};
+} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
index b0db70f58b2ef4..c93f4051c9d094 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
@@ -13,6 +13,7 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/move.h>
#include <optional>
@@ -45,7 +46,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __pstl_merge(
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- auto __res = __par_backend::__parallel_merge(
+ auto __res = __pstl::__cpu_traits<__cpu_backend_tag>::__merge(
__first1,
__last1,
__first2,
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
index afcc7ffb266130..7544619a8eefd8 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
@@ -11,6 +11,7 @@
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
#include <__config>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__utility/empty.h>
#include <__utility/move.h>
#include <cstddef>
@@ -26,54 +27,55 @@ _LIBCPP_PUSH_MACROS
# include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
-
-namespace __par_backend {
-inline namespace __serial_cpu_backend {
-
-template <class _RandomAccessIterator, class _Fp>
-_LIBCPP_HIDE_FROM_ABI optional<__empty>
-__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
- __f(__first, __last);
- return __empty{};
-}
-
-template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
-_LIBCPP_HIDE_FROM_ABI optional<_Tp>
-__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
- return __reduce(std::move(__first), std::move(__last), std::move(__init));
-}
-
-template <class _RandomAccessIterator, class _Compare, class _LeafSort>
-_LIBCPP_HIDE_FROM_ABI optional<__empty> __parallel_stable_sort(
- _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
- __leaf_sort(__first, __last, __comp);
- return __empty{};
-}
-
-_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
-
-template <class _RandomAccessIterator1,
- class _RandomAccessIterator2,
- class _RandomAccessIterator3,
- class _Compare,
- class _LeafMerge>
-_LIBCPP_HIDE_FROM_ABI optional<__empty> __parallel_merge(
- _RandomAccessIterator1 __first1,
- _RandomAccessIterator1 __last1,
- _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2,
- _RandomAccessIterator3 __outit,
- _Compare __comp,
- _LeafMerge __leaf_merge) {
- __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
- return __empty{};
-}
-
-// TODO: Complete this list
-
-} // namespace __serial_cpu_backend
-} // namespace __par_backend
-
+namespace __pstl {
+
+struct __serial_backend_tag {};
+
+template <>
+struct __cpu_traits<__serial_backend_tag> {
+ template <class _RandomAccessIterator, class _Fp>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
+ __f(__first, __last);
+ return __empty{};
+ }
+
+ template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
+ _LIBCPP_HIDE_FROM_ABI static optional<_Tp>
+ __transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
+ return __reduce(std::move(__first), std::move(__last), std::move(__init));
+ }
+
+ template <class _RandomAccessIterator, class _Compare, class _LeafSort>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
+ __leaf_sort(__first, __last, __comp);
+ return __empty{};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static void __cancel_execution() {}
+
+ template <class _RandomAccessIterator1,
+ class _RandomAccessIterator2,
+ class _RandomAccessIterator3,
+ class _Compare,
+ class _LeafMerge>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __merge(_RandomAccessIterator1 __first1,
+ _RandomAccessIterator1 __last1,
+ _RandomAccessIterator2 __first2,
+ _RandomAccessIterator2 __last2,
+ _RandomAccessIterator3 __outit,
+ _Compare __comp,
+ _LeafMerge __leaf_merge) {
+ __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
+ return __empty{};
+ }
+
+ static constexpr size_t __lane_size = 64;
+};
+
+} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
index 34c423586c4b74..8c60cf897ff860 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
@@ -12,6 +12,7 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__algorithm/stable_sort.h>
#include <__config>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/empty.h>
#include <optional>
@@ -28,7 +29,7 @@ template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
_LIBCPP_HIDE_FROM_ABI optional<__empty>
__pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) {
- return __par_backend::__parallel_stable_sort(
+ return __pstl::__cpu_traits<__cpu_backend_tag>::__stable_sort(
__first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
std::stable_sort(__g_first, __g_last, __g_comp);
});
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h
index eb11a961b760c3..2acf912264a001 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h
@@ -11,6 +11,7 @@
#include <__assert>
#include <__config>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__utility/empty.h>
#include <__utility/move.h>
#include <cstddef>
@@ -29,52 +30,55 @@ _LIBCPP_PUSH_MACROS
// by a proper implementation once the PSTL implementation is somewhat stable.
_LIBCPP_BEGIN_NAMESPACE_STD
-
-namespace __par_backend {
-inline namespace __thread_cpu_backend {
-
-template <class _RandomAccessIterator, class _Fp>
-_LIBCPP_HIDE_FROM_ABI optional<__empty>
-__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
- __f(__first, __last);
- return __empty{};
-}
-
-template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
-_LIBCPP_HIDE_FROM_ABI optional<_Tp>
-__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
- return __reduce(std::move(__first), std::move(__last), std::move(__init));
-}
-
-template <class _RandomAccessIterator, class _Compare, class _LeafSort>
-_LIBCPP_HIDE_FROM_ABI optional<__empty> __parallel_stable_sort(
- _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
- __leaf_sort(__first, __last, __comp);
- return __empty{};
-}
-
-_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
-
-template <class _RandomAccessIterator1,
- class _RandomAccessIterator2,
- class _RandomAccessIterator3,
- class _Compare,
- class _LeafMerge>
-_LIBCPP_HIDE_FROM_ABI optional<__empty> __parallel_merge(
- _RandomAccessIterator1 __first1,
- _RandomAccessIterator1 __last1,
- _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2,
- _RandomAccessIterator3 __outit,
- _Compare __comp,
- _LeafMerge __leaf_merge) {
- __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
- return __empty{};
-}
-
-} // namespace __thread_cpu_backend
-} // namespace __par_backend
-
+namespace __pstl {
+
+struct __std_thread_backend_tag {};
+
+template <>
+struct __cpu_traits<__std_thread_backend_tag> {
+ template <class _RandomAccessIterator, class _Fp>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
+ __f(__first, __last);
+ return __empty{};
+ }
+
+ template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
+ _LIBCPP_HIDE_FROM_ABI static optional<_Tp>
+ __transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
+ return __reduce(std::move(__first), std::move(__last), std::move(__init));
+ }
+
+ template <class _RandomAccessIterator, class _Compare, class _LeafSort>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
+ __leaf_sort(__first, __last, __comp);
+ return __empty{};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static void __cancel_execution() {}
+
+ template <class _RandomAccessIterator1,
+ class _RandomAccessIterator2,
+ class _RandomAccessIterator3,
+ class _Compare,
+ class _LeafMerge>
+ _LIBCPP_HIDE_FROM_ABI static optional<__empty>
+ __merge(_RandomAccessIterator1 __first1,
+ _RandomAccessIterator1 __last1,
+ _RandomAccessIterator2 __first2,
+ _RandomAccessIterator2 __last2,
+ _RandomAccessIterator3 __outit,
+ _Compare __comp,
+ _LeafMerge __leaf_merge) {
+ __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
+ return __empty{};
+ }
+
+ static constexpr size_t __lane_size = 64;
+};
+
+} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
index fdf1a2e78dad90..4b9b2968668327 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
@@ -14,6 +14,7 @@
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
@@ -49,7 +50,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __pstl_transform(
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- std::__par_backend::__parallel_for(
+ __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
__first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
auto __res = std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op);
@@ -97,7 +98,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __pstl_transform(
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- auto __res = std::__par_backend::__parallel_for(
+ auto __res = __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
__first1,
__last1,
[__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
index 376abd39fa36e0..c074eea9861c1b 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
@@ -14,6 +14,7 @@
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/transform_reduce.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/desugars_to.h>
#include <__type_traits/is_arithmetic.h>
#include <__type_traits/is_execution_policy.h>
@@ -32,7 +33,8 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <typename _DifferenceType,
+template <typename _Backend,
+ typename _DifferenceType,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
@@ -48,7 +50,8 @@ __simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _Unar
return __init;
}
-template <typename _Size,
+template <typename _Backend,
+ typename _Size,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
@@ -58,7 +61,8 @@ template <typename _Size,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
- const _Size __block_size = __lane_size / sizeof(_Tp);
+ constexpr size_t __lane_size = __pstl::__cpu_traits<_Backend>::__lane_size;
+ const _Size __block_size = __lane_size / sizeof(_Tp);
if (__n > 2 * __block_size && __block_size > 1) {
alignas(__lane_size) char __lane_buffer[__lane_size];
_Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
@@ -116,7 +120,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_Tp> __pstl_transform_reduce(
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
- return __par_backend::__parallel_transform_reduce(
+ return __pstl::__cpu_traits<__cpu_backend_tag>::__transform_reduce(
__first1,
std::move(__last1),
[__first1, __first2, __transform](_ForwardIterator1 __iter) {
@@ -138,7 +142,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_Tp> __pstl_transform_reduce(
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
- return std::__simd_transform_reduce(
+ return std::__simd_transform_reduce<__cpu_backend_tag>(
__last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
return __transform(__first1[__i], __first2[__i]);
});
@@ -163,7 +167,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_Tp> __pstl_transform_reduce(
_UnaryOperation __transform) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return __par_backend::__parallel_transform_reduce(
+ return __pstl::__cpu_traits<__cpu_backend_tag>::__transform_reduce(
std::move(__first),
std::move(__last),
[__transform](_ForwardIterator __iter) { return __transform(*__iter); },
@@ -182,7 +186,7 @@ _LIBCPP_HIDE_FROM_ABI optional<_Tp> __pstl_transform_reduce(
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__simd_transform_reduce(
+ return std::__simd_transform_reduce<__cpu_backend_tag>(
__last - __first,
std::move(__init),
std::move(__reduce),
diff --git a/libcxx/include/__pstl/cpu_algos/cpu_traits.h b/libcxx/include/__pstl/cpu_algos/cpu_traits.h
new file mode 100644
index 00000000000000..b24f0973d8e5ba
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/cpu_traits.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H
+#define _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// __cpu_traits
+//
+// This traits class encapsulates the basis operations for a CPU-based implementation of the PSTL.
+// All the operations in the PSTL can be implemented from these basis operations, so a pure CPU backend
+// only needs to customize these traits in order to get an implementation of the whole PSTL.
+//
+// Basis operations
+// ================
+//
+// template <class _RandomAccessIterator, class _Functor>
+// optional<__empty> __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func);
+// - __func must take a subrange of [__first, __last) that should be executed in serial
+//
+// template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction>
+// optional<_Tp> __transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction);
+//
+// template <class _RandomAccessIterator1,
+// class _RandomAccessIterator2,
+// class _RandomAccessIterator3,
+// class _Compare,
+// class _LeafMerge>
+// optional<_RandomAccessIterator3> __merge(_RandomAccessIterator1 __first1,
+// _RandomAccessIterator1 __last1,
+// _RandomAccessIterator2 __first2,
+// _RandomAccessIterator2 __last2,
+// _RandomAccessIterator3 __outit,
+// _Compare __comp,
+// _LeafMerge __leaf_merge);
+//
+// template <class _RandomAccessIterator, class _Comp, class _LeafSort>
+// optional<__empty> __stable_sort(_RandomAccessIterator __first,
+// _RandomAccessIterator __last,
+// _Comp __comp,
+// _LeafSort __leaf_sort);
+//
+// void __cancel_execution();
+// Cancel the execution of other jobs - they aren't needed anymore. This is not a binding request,
+// some backends may not actually be able to cancel jobs.
+//
+// constexpr size_t __lane_size;
+// Size of SIMD lanes.
+//
+//
+// Exception handling
+// ==================
+//
+// CPU backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their
+// implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are turned
+// into a program termination at the front-end level. When a backend returns a disengaged `optional` to the frontend, the
+// frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to the user.
+
+template <class _Backend>
+struct __cpu_traits;
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H
diff --git a/libcxx/src/pstl/libdispatch.cpp b/libcxx/src/pstl/libdispatch.cpp
index 52d4afbcce6e00..71d07fa88634a1 100644
--- a/libcxx/src/pstl/libdispatch.cpp
+++ b/libcxx/src/pstl/libdispatch.cpp
@@ -12,8 +12,7 @@
#include <dispatch/dispatch.h>
_LIBCPP_BEGIN_NAMESPACE_STD
-
-namespace __par_backend::inline __libdispatch {
+namespace __pstl {
void __dispatch_apply(size_t chunk_count, void* context, void (*func)(void* context, size_t chunk)) noexcept {
::dispatch_apply_f(chunk_count, DISPATCH_APPLY_AUTO, context, func);
@@ -29,7 +28,5 @@ __chunk_partitions __partition_chunks(ptrdiff_t element_count) noexcept {
return partitions;
}
-// NOLINTNEXTLINE(llvm-namespace-comment) // This is https://llvm.org/PR56804
-} // namespace __par_backend::inline __libdispatch
-
+} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/utils/generate_iwyu_mapping.py b/libcxx/utils/generate_iwyu_mapping.py
index 8ab7b86299edca..b8a8580ea30f34 100644
--- a/libcxx/utils/generate_iwyu_mapping.py
+++ b/libcxx/utils/generate_iwyu_mapping.py
@@ -10,6 +10,7 @@ def IWYU_mapping(header: str) -> typing.Optional[typing.List[str]]:
ignore = [
"__debug_utils/.+",
"__fwd/get[.]h",
+ "__pstl/.+",
"__support/.+",
]
if any(re.match(pattern, header) for pattern in ignore):
>From 1a5e402ecd540de449e37fd60e561dce58d31bc4 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 5 Apr 2024 10:28:11 -0400
Subject: [PATCH 2/8] WIP: Add missing requirements for random access
iterators
In this patch, also add all the missing checks in existing algorithms
and add tests for those.
This can be done before the large refactoring
---
libcxx/test/support/test_iterators.h | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index 7ffb74990fa4dd..e2a3c2cdae41ec 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -1484,9 +1484,14 @@ class iterator_wrapper {
return tmp;
}
- iterator_wrapper& operator+=(difference_type i) {
+ Derived& operator+=(difference_type i) {
iter_ += i;
- return *this;
+ return static_cast<Derived&>(*this);
+ }
+
+ Derived& operator-=(difference_type i) {
+ iter_ -= i;
+ return static_cast<Derived&>(*this);
}
friend decltype(iter_ - iter_) operator-(const iterator_wrapper& lhs, const iterator_wrapper& rhs) {
@@ -1503,8 +1508,17 @@ class iterator_wrapper {
return iter;
}
+ friend Derived operator+(difference_type i, Derived iter) {
+ return iter + i;
+ }
+
friend bool operator==(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ == rhs.iter_; }
friend bool operator!=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ != rhs.iter_; }
+
+ friend bool operator>(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ > rhs.iter_; }
+ friend bool operator<(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ < rhs.iter_; }
+ friend bool operator<=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ <= rhs.iter_; }
+ friend bool operator>=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ >= rhs.iter_; }
};
class iterator_error : std::runtime_error {
>From 0c64ca6263ed5c64c50fcecd237605270d3019a3 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 5 Apr 2024 14:44:56 -0400
Subject: [PATCH 3/8] WIP: Improve testing of exception handling.
Move elision was happening and could render the tests useless.
Also take the occasion in this patch to handle all algorithms.
Can easily(?) be landed before the rest.
---
.../reduce/pstl.exception_handling.pass.cpp | 1 +
.../pstl.exception_handling.pass.cpp | 38 ++++++++++++-------
2 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp
index d52889b1be1479..1688fe3d8f0d9b 100644
--- a/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp
@@ -38,6 +38,7 @@ int main(int, char**) {
int a[2]{};
(void)std::reduce(policy, std::begin(a), std::end(a), 1, [](int, int) -> int { throw 1; });
});
+
EXPECT_STD_TERMINATE([&] {
try {
int a[] = {1, 2};
diff --git a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp
index 5ac04334f00053..78751bc3c92a10 100644
--- a/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp
@@ -26,12 +26,10 @@ int main(int, char**) {
EXPECT_STD_TERMINATE([&] {
try {
int a[] = {1, 2};
- (void)std::transform_reduce(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- util::throw_on_move_iterator(std::begin(a), 1),
- 1);
+ util::throw_on_move_iterator first1(std::begin(a), 1);
+ util::throw_on_move_iterator last1(std::end(a), 1);
+ util::throw_on_move_iterator first2(std::begin(a), 1);
+ (void)std::transform_reduce(policy, std::move(first1), std::move(last1), std::move(first2), 1);
} catch (const util::iterator_error&) {
assert(false);
}
@@ -39,20 +37,32 @@ int main(int, char**) {
});
EXPECT_STD_TERMINATE([&] {
- int a[2]{};
+ int a[] = {1, 2};
(void)std::transform_reduce(
policy, std::begin(a), std::end(a), 1, [](int, int) -> int { throw 1; }, [](int) -> int { return 0; });
});
+
+ EXPECT_STD_TERMINATE([&] {
+ try {
+ int a[] = {1, 2};
+ util::throw_on_move_iterator first1(std::begin(a), 1);
+ util::throw_on_move_iterator last1(std::end(a), 1);
+ (void)std::transform_reduce(policy, std::move(first1), std::move(last1), 1, std::plus{}, [](int) -> int {
+ return 0;
+ });
+ } catch (const util::iterator_error&) {
+ assert(false);
+ }
+ std::terminate(); // make the test pass in case the algorithm didn't move the iterator
+ });
+
EXPECT_STD_TERMINATE([&] {
try {
int a[] = {1, 2};
- (void)std::transform_reduce(
- policy,
- util::throw_on_move_iterator(std::begin(a), 1),
- util::throw_on_move_iterator(std::end(a), 1),
- 1,
- std::plus{},
- [](int) -> int { return 0; });
+ util::throw_on_move_iterator first1(std::begin(a), 1);
+ util::throw_on_move_iterator last1(std::end(a), 1);
+ util::throw_on_move_iterator first2(std::begin(a), 1);
+ (void)std::transform_reduce(policy, std::move(first1), std::move(last1), std::move(first2), 1);
} catch (const util::iterator_error&) {
assert(false);
}
>From 5adc2cff69d077b6171000a54f9e9bc4387553ce Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 5 Apr 2024 14:46:00 -0400
Subject: [PATCH 4/8] [WIP][libc++] PSTL dispatching mechanism overhaul
The experimental PSTL's current dispatching mechanism was designed with
flexibility in mind. However, while reviewing the in-progress OpenMP
backend, I realized that the dispatching mechanism based on ADL and
default definitions in the frontend had several downsides. To name a
few:
1. The dispatching of an algorithm to the back-end and its default
implementation is bundled together via `_LIBCPP_PSTL_CUSTOMIZATION_POINT`.
This makes the dispatching really confusing and leads to annoyances
such as variable shadowing and weird lambda captures in the front-end.
2. The distinction between back-end functions and front-end algorithms
is not as clear as it could be, which led us to call one where we meant
the other in a few cases. This is bad due to the exception requirements
of the PSTL.
3. There are two levels of back-end dispatching in the PSTL, which treat
CPU backends as a special case. This was confusing and not as flexible
as we'd like. For example, there was no straightforward way to dispatch
all uses of `unseq` to a specific back-end from the OpenMP backend,
or for CPU backends to fall back on each other.
This patch rewrites the backend dispatching mechanism to solve these
problems, but doesn't touch any of the actual implementation of
algorithms. Specifically, this rewrite has the following characteristics:
- All back-ends are full top-level backends defining all the basis operations
required by the PSTL. This is made realistic for CPU backends by providing
the CPU-based basis operations as simple helpers that can easily be reused
when defining the PSTL basis operations.
- The default definitions for algorithms are separated from their dispatching
logic and grouped in families instead, based on the basis operation they
require for their default implementation.
- The front-end is thus simplified a whole lot and made very consistent
for all algorithms, which makes it easier to audit the front-end for
things like exception-correctness.
Fixes #70718
---
libcxx/CMakeLists.txt | 18 +-
libcxx/cmake/caches/Apple.cmake | 2 +-
libcxx/include/CMakeLists.txt | 36 +--
.../__algorithm/pstl_any_all_none_of.h | 98 +-------
libcxx/include/__algorithm/pstl_backend.h | 232 ------------------
.../__algorithm/pstl_backends/cpu_backend.h | 23 --
.../pstl_backends/cpu_backends/backend.h | 45 ----
.../pstl_backends/cpu_backends/fill.h | 63 -----
.../pstl_backends/cpu_backends/for_each.h | 63 -----
.../pstl_backends/cpu_backends/merge.h | 86 -------
.../pstl_backends/cpu_backends/serial.h | 85 -------
.../pstl_backends/cpu_backends/stable_sort.h | 46 ----
.../pstl_backends/cpu_backends/transform.h | 139 -----------
.../cpu_backends/transform_reduce.h | 206 ----------------
libcxx/include/__algorithm/pstl_copy.h | 87 ++-----
libcxx/include/__algorithm/pstl_count.h | 80 +-----
libcxx/include/__algorithm/pstl_equal.h | 130 +++-------
libcxx/include/__algorithm/pstl_fill.h | 72 +-----
libcxx/include/__algorithm/pstl_find.h | 84 +------
libcxx/include/__algorithm/pstl_for_each.h | 60 +----
.../__algorithm/pstl_frontend_dispatch.h | 44 ----
libcxx/include/__algorithm/pstl_generate.h | 66 +----
.../include/__algorithm/pstl_is_partitioned.h | 41 +---
libcxx/include/__algorithm/pstl_merge.h | 55 +++--
libcxx/include/__algorithm/pstl_move.h | 54 +---
libcxx/include/__algorithm/pstl_replace.h | 188 +++-----------
libcxx/include/__algorithm/pstl_rotate_copy.h | 60 ++---
libcxx/include/__algorithm/pstl_sort.h | 37 +--
libcxx/include/__algorithm/pstl_stable_sort.h | 28 ++-
libcxx/include/__algorithm/pstl_transform.h | 69 ++----
libcxx/include/__config_site.in | 6 +-
libcxx/include/__numeric/pstl_reduce.h | 78 +++---
.../include/__numeric/pstl_transform_reduce.h | 99 +++-----
libcxx/include/__pstl/README.md | 171 +++++++++++++
libcxx/include/__pstl/backend_fwd.h | 125 ++++++++++
.../backends}/libdispatch.h | 97 +++++---
libcxx/include/__pstl/backends/serial.h | 162 ++++++++++++
.../thread.h => __pstl/backends/std_thread.h} | 80 ++++--
libcxx/include/__pstl/configuration.h | 41 ++++
.../cpu_algos}/any_of.h | 62 +++--
libcxx/include/__pstl/cpu_algos/cpu_traits.h | 7 +-
libcxx/include/__pstl/cpu_algos/fill.h | 65 +++++
.../cpu_algos}/find_if.h | 71 +++---
libcxx/include/__pstl/cpu_algos/for_each.h | 65 +++++
libcxx/include/__pstl/cpu_algos/merge.h | 79 ++++++
libcxx/include/__pstl/cpu_algos/stable_sort.h | 46 ++++
libcxx/include/__pstl/cpu_algos/transform.h | 152 ++++++++++++
.../__pstl/cpu_algos/transform_reduce.h | 214 ++++++++++++++++
libcxx/include/__pstl/defaults.h | 20 ++
.../include/__pstl/defaults/find_if_family.h | 134 ++++++++++
.../include/__pstl/defaults/for_each_family.h | 153 ++++++++++++
libcxx/include/__pstl/defaults/merge_family.h | 50 ++++
.../__pstl/defaults/stable_sort_family.h | 58 +++++
.../__pstl/defaults/transform_family.h | 176 +++++++++++++
.../__pstl/defaults/transform_reduce_family.h | 175 +++++++++++++
libcxx/include/__pstl/run_backend.h | 48 ++++
libcxx/include/libcxx.imp | 15 --
libcxx/include/module.modulemap | 4 -
libcxx/src/CMakeLists.txt | 2 +-
libcxx/src/pstl/libdispatch.cpp | 2 +-
60 files changed, 2488 insertions(+), 2266 deletions(-)
delete mode 100644 libcxx/include/__algorithm/pstl_backend.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backend.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
delete mode 100644 libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
delete mode 100644 libcxx/include/__algorithm/pstl_frontend_dispatch.h
create mode 100644 libcxx/include/__pstl/README.md
create mode 100644 libcxx/include/__pstl/backend_fwd.h
rename libcxx/include/{__algorithm/pstl_backends/cpu_backends => __pstl/backends}/libdispatch.h (80%)
create mode 100644 libcxx/include/__pstl/backends/serial.h
rename libcxx/include/{__algorithm/pstl_backends/cpu_backends/thread.h => __pstl/backends/std_thread.h} (50%)
create mode 100644 libcxx/include/__pstl/configuration.h
rename libcxx/include/{__algorithm/pstl_backends/cpu_backends => __pstl/cpu_algos}/any_of.h (56%)
create mode 100644 libcxx/include/__pstl/cpu_algos/fill.h
rename libcxx/include/{__algorithm/pstl_backends/cpu_backends => __pstl/cpu_algos}/find_if.h (66%)
create mode 100644 libcxx/include/__pstl/cpu_algos/for_each.h
create mode 100644 libcxx/include/__pstl/cpu_algos/merge.h
create mode 100644 libcxx/include/__pstl/cpu_algos/stable_sort.h
create mode 100644 libcxx/include/__pstl/cpu_algos/transform.h
create mode 100644 libcxx/include/__pstl/cpu_algos/transform_reduce.h
create mode 100644 libcxx/include/__pstl/defaults.h
create mode 100644 libcxx/include/__pstl/defaults/find_if_family.h
create mode 100644 libcxx/include/__pstl/defaults/for_each_family.h
create mode 100644 libcxx/include/__pstl/defaults/merge_family.h
create mode 100644 libcxx/include/__pstl/defaults/stable_sort_family.h
create mode 100644 libcxx/include/__pstl/defaults/transform_family.h
create mode 100644 libcxx/include/__pstl/defaults/transform_reduce_family.h
create mode 100644 libcxx/include/__pstl/run_backend.h
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index e565c47c76687a..36232a814bfdff 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -301,9 +301,9 @@ option(LIBCXX_HAS_EXTERNAL_THREAD_API
This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF)
if (LIBCXX_ENABLE_THREADS)
- set(LIBCXX_PSTL_CPU_BACKEND "std_thread" CACHE STRING "Which PSTL CPU backend to use")
+ set(LIBCXX_PSTL_BACKEND "std_thread" CACHE STRING "Which PSTL backend to use")
else()
- set(LIBCXX_PSTL_CPU_BACKEND "serial" CACHE STRING "Which PSTL CPU backend to use")
+ set(LIBCXX_PSTL_BACKEND "serial" CACHE STRING "Which PSTL backend to use")
endif()
# Misc options ----------------------------------------------------------------
@@ -793,14 +793,14 @@ elseif (LIBCXX_HARDENING_MODE STREQUAL "debug")
config_define(8 _LIBCPP_HARDENING_MODE_DEFAULT)
endif()
-if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "serial")
- config_define(1 _LIBCPP_PSTL_CPU_BACKEND_SERIAL)
-elseif(LIBCXX_PSTL_CPU_BACKEND STREQUAL "std_thread")
- config_define(1 _LIBCPP_PSTL_CPU_BACKEND_THREAD)
-elseif(LIBCXX_PSTL_CPU_BACKEND STREQUAL "libdispatch")
- config_define(1 _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
+if (LIBCXX_PSTL_BACKEND STREQUAL "serial")
+ config_define(1 _LIBCPP_PSTL_BACKEND_SERIAL)
+elseif(LIBCXX_PSTL_BACKEND STREQUAL "std_thread")
+ config_define(1 _LIBCPP_PSTL_BACKEND_STD_THREAD)
+elseif(LIBCXX_PSTL_BACKEND STREQUAL "libdispatch")
+ config_define(1 _LIBCPP_PSTL_BACKEND_LIBDISPATCH)
else()
- message(FATAL_ERROR "LIBCXX_PSTL_CPU_BACKEND is set to ${LIBCXX_PSTL_CPU_BACKEND}, which is not a valid backend.
+ message(FATAL_ERROR "LIBCXX_PSTL_BACKEND is set to ${LIBCXX_PSTL_BACKEND}, which is not a valid backend.
Valid backends are: serial, std_thread and libdispatch")
endif()
diff --git a/libcxx/cmake/caches/Apple.cmake b/libcxx/cmake/caches/Apple.cmake
index cec13c08acf107..8768653e620add 100644
--- a/libcxx/cmake/caches/Apple.cmake
+++ b/libcxx/cmake/caches/Apple.cmake
@@ -7,7 +7,7 @@ set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
set(LIBCXX_ENABLE_SHARED ON CACHE BOOL "")
set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "")
set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "")
-set(LIBCXX_PSTL_CPU_BACKEND libdispatch CACHE STRING "")
+set(LIBCXX_PSTL_BACKEND libdispatch CACHE STRING "")
set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 1f90dd6db5b158..4208b07e6b33bb 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -73,27 +73,12 @@ set(files
__algorithm/pop_heap.h
__algorithm/prev_permutation.h
__algorithm/pstl_any_all_none_of.h
- __algorithm/pstl_backend.h
- __algorithm/pstl_backends/cpu_backend.h
- __algorithm/pstl_backends/cpu_backends/any_of.h
- __algorithm/pstl_backends/cpu_backends/backend.h
- __algorithm/pstl_backends/cpu_backends/fill.h
- __algorithm/pstl_backends/cpu_backends/find_if.h
- __algorithm/pstl_backends/cpu_backends/for_each.h
- __algorithm/pstl_backends/cpu_backends/libdispatch.h
- __algorithm/pstl_backends/cpu_backends/merge.h
- __algorithm/pstl_backends/cpu_backends/serial.h
- __algorithm/pstl_backends/cpu_backends/stable_sort.h
- __algorithm/pstl_backends/cpu_backends/thread.h
- __algorithm/pstl_backends/cpu_backends/transform.h
- __algorithm/pstl_backends/cpu_backends/transform_reduce.h
__algorithm/pstl_copy.h
__algorithm/pstl_count.h
__algorithm/pstl_equal.h
__algorithm/pstl_fill.h
__algorithm/pstl_find.h
__algorithm/pstl_for_each.h
- __algorithm/pstl_frontend_dispatch.h
__algorithm/pstl_generate.h
__algorithm/pstl_is_partitioned.h
__algorithm/pstl_merge.h
@@ -591,7 +576,28 @@ set(files
__numeric/transform_exclusive_scan.h
__numeric/transform_inclusive_scan.h
__numeric/transform_reduce.h
+ __pstl/backend_fwd.h
+ __pstl/backends/libdispatch.h
+ __pstl/backends/serial.h
+ __pstl/backends/std_thread.h
+ __pstl/configuration.h
+ __pstl/cpu_algos/any_of.h
__pstl/cpu_algos/cpu_traits.h
+ __pstl/cpu_algos/fill.h
+ __pstl/cpu_algos/find_if.h
+ __pstl/cpu_algos/for_each.h
+ __pstl/cpu_algos/merge.h
+ __pstl/cpu_algos/stable_sort.h
+ __pstl/cpu_algos/transform_reduce.h
+ __pstl/cpu_algos/transform.h
+ __pstl/defaults.h
+ __pstl/defaults/find_if_family.h
+ __pstl/defaults/for_each_family.h
+ __pstl/defaults/merge_family.h
+ __pstl/defaults/stable_sort_family.h
+ __pstl/defaults/transform_family.h
+ __pstl/defaults/transform_reduce_family.h
+ __pstl/run_backend.h
__random/bernoulli_distribution.h
__random/binomial_distribution.h
__random/cauchy_distribution.h
diff --git a/libcxx/include/__algorithm/pstl_any_all_none_of.h b/libcxx/include/__algorithm/pstl_any_all_none_of.h
index 4b1e0e61b54218..ecc05c74db8c04 100644
--- a/libcxx/include/__algorithm/pstl_any_all_none_of.h
+++ b/libcxx/include/__algorithm/pstl_any_all_none_of.h
@@ -9,15 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
-#include <__algorithm/pstl_find.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -30,29 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_any_of(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool> __any_of(
- _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) -> optional<bool> {
- auto __res = std::__find_if(__policy, __g_first, __g_last, __g_pred);
- if (!__res)
- return nullopt;
- return *__res != __g_last;
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
@@ -61,35 +38,9 @@ template <class _ExecutionPolicy,
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__any_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class>
-void __pstl_all_of(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
-__all_of(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Pred&& __pred) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) -> optional<bool> {
- auto __res = std::__any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
- return !__g_pred(__value);
- });
- if (!__res)
- return nullopt;
- return !*__res;
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred));
+ using _Implementation = __pstl::__any_of<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
template <class _ExecutionPolicy,
@@ -100,33 +51,9 @@ template <class _ExecutionPolicy,
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__all_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class>
-void __pstl_none_of(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
-__none_of(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Pred&& __pred) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) -> optional<bool> {
- auto __res = std::__any_of(__policy, __g_first, __g_last, __g_pred);
- if (!__res)
- return nullopt;
- return !*__res;
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred));
+ using _Implementation = __pstl::__all_of<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
template <class _ExecutionPolicy,
@@ -137,10 +64,9 @@ template <class _ExecutionPolicy,
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__none_of(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ using _Implementation = __pstl::__none_of<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_backend.h b/libcxx/include/__algorithm/pstl_backend.h
deleted file mode 100644
index 3af03ce2fbc8ee..00000000000000
--- a/libcxx/include/__algorithm/pstl_backend.h
+++ /dev/null
@@ -1,232 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKEND_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKEND_H
-
-#include <__algorithm/pstl_backends/cpu_backend.h>
-#include <__config>
-#include <execution>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-/*
-TODO: Documentation of how backends work
-
-A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
-
- template <class _ExecutionPolicy, class _Iterator, class _Func>
- optional<__empty> __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<_Iterator> __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
- optional<__empty>
- __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
-
- template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _Comp>
- optional<_ForwardOutIterator> __pstl_merge(_Backend,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __result,
- _Comp __comp);
-
- template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
- optional<_OutIterator>
- __pstl_transform(_Backend, _InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
-
- template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
- optional<_OutIterator> __pstl_transform(_InIterator1 __first1,
- _InIterator2 __first2,
- _InIterator1 __last1,
- _OutIterator __result,
- _BinaryOperation __op);
-
- template <class _ExecutionPolicy,
- class _Iterator1,
- class _Iterator2,
- class _Tp,
- class _BinaryOperation1,
- class _BinaryOperation2>
- optional<_Tp> __pstl_transform_reduce(_Backend,
- _Iterator1 __first1,
- _Iterator1 __last1,
- _Iterator2 __first2,
- _Iterator2 __last2,
- _Tp __init,
- _BinaryOperation1 __reduce,
- _BinaryOperation2 __transform);
-
- template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
- optional<_Tp> __pstl_transform_reduce(_Backend,
- _Iterator __first,
- _Iterator __last,
- _Tp __init,
- _BinaryOperation __reduce,
- _UnaryOperation __transform);
-
-// TODO: Complete this list
-
-The following functions are optional but can be provided. If provided, they are used by the corresponding
-algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are
-implemented, all the algorithms will eventually forward to the basis algorithms listed above:
-
- template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
- optional<__empty> __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<bool> __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<bool> __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<bool> __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _Iterator, class _Tp>
- optional<_Iterator> __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<_Iterator> __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _Iterator, class _Tp>
- optional<__empty> __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
-
- template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
- optional<__empty> __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
-
- template <class _ExecutionPolicy, class _Iterator, class _Generator>
- optional<__empty> __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<__empty> __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
- optional<__empty> __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
-
- template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
- optional<_OutIterator> __pstl_merge(_Backend,
- _Iterator1 __first1,
- _Iterator1 __last1,
- _Iterator2 __first2,
- _Iterator2 __last2,
- _OutIterator __result,
- _Comp __comp);
-
- template <class _ExecutionPolicy, class _Iterator, class _OutIterator>
- optional<_OutIterator> __pstl_move(_Backend, _Iterator __first, _Iterator __last, _OutIterator __result);
-
- template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
- optional<_Tp> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
-
- temlate <class _ExecutionPolicy, class _Iterator>
- optional<__iter_value_type<_Iterator>> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
-
- template <class _ExecutionPolicy, class _Iterator, class _Tp>
- optional<__iter_diff_t<_Iterator>> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
-
- template <class _ExecutionPolicy, class _Iterator, class _Predicate>
- optional<__iter_diff_t<_Iterator>> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
-
- template <class _ExecutionPolicy, class _Iterator, class _Tp>
- optional<__empty>
- __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
-
- template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
- optional<__empty>
- __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
-
- template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
- optional<__empty> __pstl_replace_copy(_Backend,
- _Iterator __first,
- _Iterator __last,
- _OutIterator __result,
- const _Tp& __old_value,
- const _Tp& __new_value);
-
- template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
- optional<__empty> __pstl_replace_copy_if(_Backend,
- _Iterator __first,
- _Iterator __last,
- _OutIterator __result,
- _Pred __pred,
- const _Tp& __new_value);
-
- template <class _ExecutionPolicy, class _Iterator, class _OutIterator>
- optional<_Iterator> __pstl_rotate_copy(
- _Backend, _Iterator __first, _Iterator __middle, _Iterator __last, _OutIterator __result);
-
- template <class _ExecutionPolicy, class _Iterator, class _Comp>
- optional<__empty> __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
-
- template <class _ExecutionPolicy, class _Iterator1, class _Iterator2, class _Comp>
- optional<bool> __pstl_equal(_Backend, _Iterator1 first1, _Iterator1 last1, _Iterator2 first2, _Comp __comp);
-
-// TODO: Complete this list
-
-Exception handling
-==================
-
-PSTL backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their
-implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are turned
-into a program termination at the front-end level. When a backend returns a disengaged `optional` to the frontend, the
-frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to the user.
-*/
-
-template <class _ExecutionPolicy>
-struct __select_backend;
-
-template <>
-struct __select_backend<std::execution::sequenced_policy> {
- using type = __cpu_backend_tag;
-};
-
-# if _LIBCPP_STD_VER >= 20
-template <>
-struct __select_backend<std::execution::unsequenced_policy> {
- using type = __cpu_backend_tag;
-};
-# endif
-
-# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) || \
- defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
-template <>
-struct __select_backend<std::execution::parallel_policy> {
- using type = __cpu_backend_tag;
-};
-
-template <>
-struct __select_backend<std::execution::parallel_unsequenced_policy> {
- using type = __cpu_backend_tag;
-};
-
-# else
-
-// ...New vendors can add parallel backends here...
-
-# error "Invalid choice of a PSTL parallel backend"
-# endif
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backend.h b/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
deleted file mode 100644
index c93139243af459..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backend.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
-
-#include <__config>
-#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__algorithm/pstl_backends/cpu_backends/fill.h>
-#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
-#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
-#include <__algorithm/pstl_backends/cpu_backends/merge.h>
-#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
-#include <__algorithm/pstl_backends/cpu_backends/transform.h>
-#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
deleted file mode 100644
index 0641a51e6823e3..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
-
-#include <__config>
-#include <cstddef>
-
-#if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
-# include <__algorithm/pstl_backends/cpu_backends/serial.h>
-#elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
-# include <__algorithm/pstl_backends/cpu_backends/thread.h>
-#elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
-# include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
-#else
-# error "Invalid CPU backend choice"
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
-using __cpu_backend_tag = __pstl::__serial_backend_tag;
-# elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
-using __cpu_backend_tag = __pstl::__std_thread_backend_tag;
-# elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
-using __cpu_backend_tag = __pstl::__libdispatch_backend_tag;
-# endif
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
deleted file mode 100644
index 0c20bdff62675a..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
-
-#include <__algorithm/fill.h>
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__utility/empty.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Index, class _DifferenceType, class _Tp>
-_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept {
- _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
- _PSTL_PRAGMA_SIMD
- for (_DifferenceType __i = 0; __i < __n; ++__i)
- __first[__i] = __value;
- return __first + __n;
-}
-
-template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
-_LIBCPP_HIDE_FROM_ABI optional<__empty>
-__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
- __first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
- [[maybe_unused]] auto __res = std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{}, __brick_first, __brick_last, __value);
- _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
- });
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- std::__simd_fill_n(__first, __last - __first, __value);
- return __empty{};
- } else {
- std::fill(__first, __last, __value);
- return __empty{};
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
deleted file mode 100644
index d637084e151d81..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
-
-#include <__algorithm/for_each.h>
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__utility/empty.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Iterator, class _DifferenceType, class _Function>
-_LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk(_Iterator __first, _DifferenceType __n, _Function __f) noexcept {
- _PSTL_PRAGMA_SIMD
- for (_DifferenceType __i = 0; __i < __n; ++__i)
- __f(__first[__i]);
-
- return __first + __n;
-}
-
-template <class _ExecutionPolicy, class _ForwardIterator, class _Functor>
-_LIBCPP_HIDE_FROM_ABI optional<__empty>
-__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
- __first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
- [[maybe_unused]] auto __res = std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{}, __brick_first, __brick_last, __func);
- _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
- });
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- std::__simd_walk(__first, __last - __first, __func);
- return __empty{};
- } else {
- std::for_each(__first, __last, __func);
- return __empty{};
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
deleted file mode 100644
index c93f4051c9d094..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
-
-#include <__algorithm/merge.h>
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__utility/move.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_PUSH_MACROS
-# include <__undef_macros>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _Comp>
-_LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __pstl_merge(
- __cpu_backend_tag,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __result,
- _Comp __comp) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- auto __res = __pstl::__cpu_traits<__cpu_backend_tag>::__merge(
- __first1,
- __last1,
- __first2,
- __last2,
- __result,
- __comp,
- [](_ForwardIterator1 __g_first1,
- _ForwardIterator1 __g_last1,
- _ForwardIterator2 __g_first2,
- _ForwardIterator2 __g_last2,
- _ForwardOutIterator __g_result,
- _Comp __g_comp) {
- [[maybe_unused]] auto __g_res = std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{},
- std::move(__g_first1),
- std::move(__g_last1),
- std::move(__g_first2),
- std::move(__g_last2),
- std::move(__g_result),
- std::move(__g_comp));
- _LIBCPP_ASSERT_INTERNAL(__g_res, "unsed/sed should never try to allocate!");
- });
- if (!__res)
- return nullopt;
- return __result + (__last1 - __first1) + (__last2 - __first2);
- } else {
- return std::merge(__first1, __last1, __first2, __last2, __result, __comp);
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
deleted file mode 100644
index 7544619a8eefd8..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
-
-#include <__config>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__utility/empty.h>
-#include <__utility/move.h>
-#include <cstddef>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_PUSH_MACROS
-# include <__undef_macros>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-struct __serial_backend_tag {};
-
-template <>
-struct __cpu_traits<__serial_backend_tag> {
- template <class _RandomAccessIterator, class _Fp>
- _LIBCPP_HIDE_FROM_ABI static optional<__empty>
- __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
- __f(__first, __last);
- return __empty{};
- }
-
- template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
- _LIBCPP_HIDE_FROM_ABI static optional<_Tp>
- __transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
- return __reduce(std::move(__first), std::move(__last), std::move(__init));
- }
-
- template <class _RandomAccessIterator, class _Compare, class _LeafSort>
- _LIBCPP_HIDE_FROM_ABI static optional<__empty>
- __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
- __leaf_sort(__first, __last, __comp);
- return __empty{};
- }
-
- _LIBCPP_HIDE_FROM_ABI static void __cancel_execution() {}
-
- template <class _RandomAccessIterator1,
- class _RandomAccessIterator2,
- class _RandomAccessIterator3,
- class _Compare,
- class _LeafMerge>
- _LIBCPP_HIDE_FROM_ABI static optional<__empty>
- __merge(_RandomAccessIterator1 __first1,
- _RandomAccessIterator1 __last1,
- _RandomAccessIterator2 __first2,
- _RandomAccessIterator2 __last2,
- _RandomAccessIterator3 __outit,
- _Compare __comp,
- _LeafMerge __leaf_merge) {
- __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
- return __empty{};
- }
-
- static constexpr size_t __lane_size = 64;
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
deleted file mode 100644
index 8c60cf897ff860..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
-
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__algorithm/stable_sort.h>
-#include <__config>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__utility/empty.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
-_LIBCPP_HIDE_FROM_ABI optional<__empty>
-__pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) {
- return __pstl::__cpu_traits<__cpu_backend_tag>::__stable_sort(
- __first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
- std::stable_sort(__g_first, __g_last, __g_comp);
- });
- } else {
- std::stable_sort(__first, __last, __comp);
- return __empty{};
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
deleted file mode 100644
index 4b9b2968668327..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
-
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__algorithm/transform.h>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__iterator/iterator_traits.h>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_PUSH_MACROS
-# include <__undef_macros>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
-_LIBCPP_HIDE_FROM_ABI _Iterator2
-__simd_walk(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept {
- _PSTL_PRAGMA_SIMD
- for (_DifferenceType __i = 0; __i < __n; ++__i)
- __f(__first1[__i], __first2[__i]);
- return __first2 + __n;
-}
-
-template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
-_LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __pstl_transform(
- __cpu_backend_tag,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __result,
- _UnaryOperation __op) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
- __first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
- auto __res = std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op);
- _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
- return *std::move(__res);
- });
- return __result + (__last - __first);
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- return std::__simd_walk(
- __first,
- __last - __first,
- __result,
- [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
- __out_value = __op(__in_value);
- });
- } else {
- return std::transform(__first, __last, __result, __op);
- }
-}
-
-template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
-_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk(
- _Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept {
- _PSTL_PRAGMA_SIMD
- for (_DifferenceType __i = 0; __i < __n; ++__i)
- __f(__first1[__i], __first2[__i], __first3[__i]);
- return __first3 + __n;
-}
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _BinaryOperation,
- enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __pstl_transform(
- __cpu_backend_tag,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardOutIterator __result,
- _BinaryOperation __op) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- auto __res = __pstl::__cpu_traits<__cpu_backend_tag>::__for_each(
- __first1,
- __last1,
- [__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
- return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{},
- __brick_first,
- __brick_last,
- __first2 + (__brick_first - __first1),
- __result + (__brick_first - __first1),
- __op);
- });
- if (!__res)
- return nullopt;
- return __result + (__last1 - __first1);
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
- return std::__simd_walk(
- __first1,
- __last1 - __first1,
- __first2,
- __result,
- [&](__iter_reference<_ForwardIterator1> __in1,
- __iter_reference<_ForwardIterator2> __in2,
- __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
- } else {
- return std::transform(__first1, __last1, __first2, __result, __op);
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h b/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
deleted file mode 100644
index c074eea9861c1b..00000000000000
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h
+++ /dev/null
@@ -1,206 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
-
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__iterator/iterator_traits.h>
-#include <__numeric/transform_reduce.h>
-#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__type_traits/desugars_to.h>
-#include <__type_traits/is_arithmetic.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__utility/move.h>
-#include <new>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <typename _Backend,
- typename _DifferenceType,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- typename _UnaryResult = invoke_result_t<_UnaryOperation, _DifferenceType>,
- __enable_if_t<__desugars_to_v<__plus_tag, _BinaryOperation, _Tp, _UnaryResult> && is_arithmetic_v<_Tp> &&
- is_arithmetic_v<_UnaryResult>,
- int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Tp
-__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
- _PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
- for (_DifferenceType __i = 0; __i < __n; ++__i)
- __init += __f(__i);
- return __init;
-}
-
-template <typename _Backend,
- typename _Size,
- typename _Tp,
- typename _BinaryOperation,
- typename _UnaryOperation,
- typename _UnaryResult = invoke_result_t<_UnaryOperation, _Size>,
- __enable_if_t<!(__desugars_to_v<__plus_tag, _BinaryOperation, _Tp, _UnaryResult> && is_arithmetic_v<_Tp> &&
- is_arithmetic_v<_UnaryResult>),
- int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Tp
-__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
- constexpr size_t __lane_size = __pstl::__cpu_traits<_Backend>::__lane_size;
- const _Size __block_size = __lane_size / sizeof(_Tp);
- if (__n > 2 * __block_size && __block_size > 1) {
- alignas(__lane_size) char __lane_buffer[__lane_size];
- _Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
-
- // initializer
- _PSTL_PRAGMA_SIMD
- for (_Size __i = 0; __i < __block_size; ++__i) {
- ::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i)));
- }
- // main loop
- _Size __i = 2 * __block_size;
- const _Size __last_iteration = __block_size * (__n / __block_size);
- for (; __i < __last_iteration; __i += __block_size) {
- _PSTL_PRAGMA_SIMD
- for (_Size __j = 0; __j < __block_size; ++__j) {
- __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j));
- }
- }
- // remainder
- _PSTL_PRAGMA_SIMD
- for (_Size __j = 0; __j < __n - __last_iteration; ++__j) {
- __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j));
- }
- // combiner
- for (_Size __j = 0; __j < __block_size; ++__j) {
- __init = __binary_op(std::move(__init), std::move(__lane[__j]));
- }
- // destroyer
- _PSTL_PRAGMA_SIMD
- for (_Size __j = 0; __j < __block_size; ++__j) {
- __lane[__j].~_Tp();
- }
- } else {
- for (_Size __i = 0; __i < __n; ++__i) {
- __init = __binary_op(std::move(__init), __f(__i));
- }
- }
- return __init;
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _Tp,
- class _BinaryOperation1,
- class _BinaryOperation2>
-_LIBCPP_HIDE_FROM_ABI optional<_Tp> __pstl_transform_reduce(
- __cpu_backend_tag,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _Tp __init,
- _BinaryOperation1 __reduce,
- _BinaryOperation2 __transform) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
- return __pstl::__cpu_traits<__cpu_backend_tag>::__transform_reduce(
- __first1,
- std::move(__last1),
- [__first1, __first2, __transform](_ForwardIterator1 __iter) {
- return __transform(*__iter, *(__first2 + (__iter - __first1)));
- },
- std::move(__init),
- std::move(__reduce),
- [__first1, __first2, __reduce, __transform](
- _ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) {
- return *std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{},
- __brick_first,
- std::move(__brick_last),
- __first2 + (__brick_first - __first1),
- std::move(__brick_init),
- std::move(__reduce),
- std::move(__transform));
- });
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
- return std::__simd_transform_reduce<__cpu_backend_tag>(
- __last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
- return __transform(__first1[__i], __first2[__i]);
- });
- } else {
- return std::transform_reduce(
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__init),
- std::move(__reduce),
- std::move(__transform));
- }
-}
-
-template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
-_LIBCPP_HIDE_FROM_ABI optional<_Tp> __pstl_transform_reduce(
- __cpu_backend_tag,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _Tp __init,
- _BinaryOperation __reduce,
- _UnaryOperation __transform) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return __pstl::__cpu_traits<__cpu_backend_tag>::__transform_reduce(
- std::move(__first),
- std::move(__last),
- [__transform](_ForwardIterator __iter) { return __transform(*__iter); },
- std::move(__init),
- __reduce,
- [__transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) {
- auto __res = std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{},
- std::move(__brick_first),
- std::move(__brick_last),
- std::move(__brick_init),
- std::move(__reduce),
- std::move(__transform));
- _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
- return *std::move(__res);
- });
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__simd_transform_reduce<__cpu_backend_tag>(
- __last - __first,
- std::move(__init),
- std::move(__reduce),
- [=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
- } else {
- return std::transform_reduce(
- std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
diff --git a/libcxx/include/__algorithm/pstl_copy.h b/libcxx/include/__algorithm/pstl_copy.h
index 1069dcec0e117a..de9cab902654c8 100644
--- a/libcxx/include/__algorithm/pstl_copy.h
+++ b/libcxx/include/__algorithm/pstl_copy.h
@@ -9,20 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H
#define _LIBCPP___ALGORITHM_PSTL_COPY_H
-#include <__algorithm/copy_n.h>
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
-#include <__algorithm/pstl_transform.h>
#include <__config>
-#include <__functional/identity.h>
-#include <__iterator/concepts.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
-#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/is_trivially_copyable.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -35,67 +30,19 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-// TODO: Use the std::copy/move shenanigans to forward to std::memmove
-
-template <class>
-void __pstl_copy();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
-__copy(_ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _ForwardOutIterator&& __result) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_copy, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result) {
- return std::__transform(__policy, __g_first, __g_last, __g_result, __identity());
- },
- std::move(__first),
- std::move(__last),
- std::move(__result));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
- auto __res = std::__copy(__policy, std::move(__first), std::move(__last), std::move(__result));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class>
-void __pstl_copy_n();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _Size,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __copy_n(
- _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __n, _ForwardOutIterator&& __result) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_copy_n, _RawPolicy),
- [&__policy](
- _ForwardIterator __g_first, _Size __g_n, _ForwardOutIterator __g_result) -> optional<_ForwardIterator> {
- if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value)
- return std::__copy(__policy, std::move(__g_first), std::move(__g_first + __g_n), std::move(__g_result));
- else
- return std::copy_n(__g_first, __g_n, __g_result);
- },
- std::move(__first),
- std::move(__n),
- std::move(__result));
+copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__copy<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__out));
}
template <class _ExecutionPolicy,
@@ -105,11 +52,13 @@ template <class _ExecutionPolicy,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
- auto __res = std::__copy_n(__policy, std::move(__first), std::move(__n), std::move(__result));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__copy_n<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__out));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_count.h b/libcxx/include/__algorithm/pstl_count.h
index 2781f6bfd3c9e0..b5f018adbd57fc 100644
--- a/libcxx/include/__algorithm/pstl_count.h
+++ b/libcxx/include/__algorithm/pstl_count.h
@@ -9,21 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_COUNT_H
#define _LIBCPP___ALGORITHM_PSTL_COUNT_H
-#include <__algorithm/count.h>
-#include <__algorithm/for_each.h>
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_for_each.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
-#include <__atomic/atomic.h>
#include <__config>
-#include <__functional/operations.h>
-#include <__iterator/iterator_traits.h>
-#include <__numeric/pstl_transform_reduce.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -36,33 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_count_if(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> __count_if(
- _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept {
- using __diff_t = __iter_diff_t<_ForwardIterator>;
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) -> optional<__diff_t> {
- return std::__transform_reduce(
- __policy,
- std::move(__g_first),
- std::move(__g_last),
- __diff_t(),
- std::plus{},
- [&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); });
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
@@ -70,33 +37,10 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- auto __res = std::__count_if(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class>
-void __pstl_count(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>>
-__count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value)
- -> optional<__iter_diff_t<_ForwardIterator>> {
- return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) {
- return __v == __g_value;
- });
- },
- std::move(__first),
- std::move(__last),
- __value);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__count_if<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
template <class _ExecutionPolicy,
@@ -106,10 +50,10 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- auto __res = std::__count(__policy, std::move(__first), std::move(__last), __value);
- if (!__res)
- std::__throw_bad_alloc();
- return *__res;
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__count<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_equal.h b/libcxx/include/__algorithm/pstl_equal.h
index d235c0f4f41972..88e3db0ac3960f 100644
--- a/libcxx/include/__algorithm/pstl_equal.h
+++ b/libcxx/include/__algorithm/pstl_equal.h
@@ -9,12 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_EQUAL_H
#define _LIBCPP___ALGORITHM_PSTL_EQUAL_H
-#include <__algorithm/equal.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__functional/operations.h>
-#include <__iterator/iterator_traits.h>
-#include <__numeric/pstl_transform_reduce.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -28,40 +31,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_equal();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
-__equal(_ExecutionPolicy&& __policy,
- _ForwardIterator1&& __first1,
- _ForwardIterator1&& __last1,
- _ForwardIterator2&& __first2,
- _Pred&& __pred) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_equal, _RawPolicy),
- [&__policy](
- _ForwardIterator1 __g_first1, _ForwardIterator1 __g_last1, _ForwardIterator2 __g_first2, _Pred __g_pred) {
- return std::__transform_reduce(
- __policy,
- std::move(__g_first1),
- std::move(__g_last1),
- std::move(__g_first2),
- true,
- std::logical_and{},
- std::move(__g_pred));
- },
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__pred));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
@@ -74,62 +43,27 @@ equal(_ExecutionPolicy&& __policy,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_Pred __pred) {
- auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *__res;
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI bool
-equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
- return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::equal_to{});
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ using _Implementation = __pstl::__equal_3leg<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__pred));
}
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
- class _Pred,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
-__equal(_ExecutionPolicy&& __policy,
- _ForwardIterator1&& __first1,
- _ForwardIterator1&& __last1,
- _ForwardIterator2&& __first2,
- _ForwardIterator2&& __last2,
- _Pred&& __pred) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_equal, _RawPolicy),
- [&__policy](_ForwardIterator1 __g_first1,
- _ForwardIterator1 __g_last1,
- _ForwardIterator2 __g_first2,
- _ForwardIterator2 __g_last2,
- _Pred __g_pred) -> optional<bool> {
- if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value &&
- __has_random_access_iterator_category<_ForwardIterator2>::value) {
- if (__g_last1 - __g_first1 != __g_last2 - __g_first2)
- return false;
- return std::__equal(
- __policy, std::move(__g_first1), std::move(__g_last1), std::move(__g_first2), std::move(__g_pred));
- } else {
- (void)__policy; // Avoid unused lambda capture warning
- return std::equal(
- std::move(__g_first1),
- std::move(__g_last1),
- std::move(__g_first2),
- std::move(__g_last2),
- std::move(__g_pred));
- }
- },
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- std::move(__pred));
+_LIBCPP_HIDE_FROM_ABI bool
+equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), equal_to{});
}
template <class _ExecutionPolicy,
@@ -145,25 +79,33 @@ equal(_ExecutionPolicy&& __policy,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_Pred __pred) {
- auto __res = std::__equal(
- __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *__res;
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ using _Implementation = __pstl::__equal<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__pred));
}
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
- enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI bool
equal(_ExecutionPolicy&& __policy,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
return std::equal(
- __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::equal_to{});
+ __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), equal_to{});
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_fill.h b/libcxx/include/__algorithm/pstl_fill.h
index 488b49a0feec96..eb4a6e7fe4696f 100644
--- a/libcxx/include/__algorithm/pstl_fill.h
+++ b/libcxx/include/__algorithm/pstl_fill.h
@@ -9,18 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H
#define _LIBCPP___ALGORITHM_PSTL_FILL_H
-#include <__algorithm/fill_n.h>
-#include <__algorithm/pstl_for_each.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
-#include <__iterator/concepts.h>
#include <__iterator/cpp17_iterator_concepts.h>
-#include <__iterator/iterator_traits.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -33,29 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_fill(); // declaration needed for the frontend dispatch below
-
-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 optional<__empty>
-__fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
- return std::__for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
- __element = __g_value;
- });
- },
- std::move(__first),
- std::move(__last),
- __value);
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
@@ -64,47 +38,23 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI void
fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- if (!std::__fill(__policy, std::move(__first), std::move(__last), __value))
- std::__throw_bad_alloc();
-}
-
-template <class>
-void __pstl_fill_n(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _SizeT,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__fill_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _SizeT&& __n, const _Tp& __value) noexcept {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n, _RawPolicy),
- [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
- if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value)
- std::fill(__policy, __g_first, __g_first + __g_n, __g_value);
- else
- std::fill_n(__g_first, __g_n, __g_value);
- return optional<__empty>{__empty{}};
- },
- std::move(__first),
- std::move(__n),
- __value);
+ using _Implementation = __pstl::__fill<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
}
template <class _ExecutionPolicy,
class _ForwardIterator,
- class _SizeT,
+ 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
-fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
+fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- if (!std::__fill_n(__policy, std::move(__first), std::move(__n), __value))
- std::__throw_bad_alloc();
+ using _Implementation = __pstl::__fill_n<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), __value);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_find.h b/libcxx/include/__algorithm/pstl_find.h
index 5b694db68aead4..f72d3244995480 100644
--- a/libcxx/include/__algorithm/pstl_find.h
+++ b/libcxx/include/__algorithm/pstl_find.h
@@ -9,17 +9,13 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H
#define _LIBCPP___ALGORITHM_PSTL_FIND_H
-#include <__algorithm/comp.h>
-#include <__algorithm/find.h>
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -32,17 +28,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>>
-__find_if(_ExecutionPolicy&&, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
@@ -51,34 +36,8 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__find_if(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class>
-void __pstl_find_if_not();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>>
-__find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not, _RawPolicy),
- [&](_ForwardIterator&& __g_first, _ForwardIterator&& __g_last, _Predicate&& __g_pred)
- -> optional<__remove_cvref_t<_ForwardIterator>> {
- return std::__find_if(
- __policy, __g_first, __g_last, [&](__iter_reference<__remove_cvref_t<_ForwardIterator>> __value) {
- return !__g_pred(__value);
- });
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred));
+ using _Implementation = __pstl::__find_if<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(__policy, std::move(__first), std::move(__last), std::move(__pred));
}
template <class _ExecutionPolicy,
@@ -89,33 +48,9 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__find_if_not(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class>
-void __pstl_find();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>>
-__find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find, _RawPolicy),
- [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) -> optional<_ForwardIterator> {
- return std::find_if(
- __policy, __g_first, __g_last, [&](__iter_reference<__remove_cvref_t<_ForwardIterator>> __element) {
- return __element == __g_value;
- });
- },
- std::move(__first),
- std::move(__last),
- __value);
+ using _Implementation = __pstl::__find_if_not<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
template <class _ExecutionPolicy,
@@ -126,10 +61,9 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__find(__policy, std::move(__first), std::move(__last), __value);
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ using _Implementation = __pstl::__find<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_for_each.h b/libcxx/include/__algorithm/pstl_for_each.h
index bb7b5a61a6dc0d..29d856c4a5e6a9 100644
--- a/libcxx/include/__algorithm/pstl_for_each.h
+++ b/libcxx/include/__algorithm/pstl_for_each.h
@@ -9,20 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
-#include <__algorithm/for_each.h>
-#include <__algorithm/for_each_n.h>
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
-#include <__iterator/concepts.h>
#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
-#include <__type_traits/void_t.h>
-#include <__utility/empty.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -35,17 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Function,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__for_each(_ExecutionPolicy&&, _ForwardIterator&& __first, _ForwardIterator&& __last, _Function&& __func) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Function,
@@ -54,35 +38,9 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI void
for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- if (!std::__for_each(__policy, std::move(__first), std::move(__last), std::move(__func)))
- std::__throw_bad_alloc();
-}
-
-template <class>
-void __pstl_for_each_n(); // declaration needed for the frontend dispatch below
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Size,
- class _Function,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __size, _Function&& __func) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n, _RawPolicy),
- [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) -> optional<__empty> {
- if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func));
- return __empty{};
- } else {
- std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func));
- return __empty{};
- }
- },
- std::move(__first),
- std::move(__size),
- std::move(__func));
+ using _Implementation = __pstl::__for_each<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__func));
}
template <class _ExecutionPolicy,
@@ -94,9 +52,9 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI void
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- auto __res = std::__for_each_n(__policy, std::move(__first), std::move(__size), std::move(__func));
- if (!__res)
- std::__throw_bad_alloc();
+ using _Implementation = __pstl::__for_each_n<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__size), std::move(__func));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_frontend_dispatch.h b/libcxx/include/__algorithm/pstl_frontend_dispatch.h
deleted file mode 100644
index 6fa11074911547..00000000000000
--- a/libcxx/include/__algorithm/pstl_frontend_dispatch.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
-#define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
-
-#include <__config>
-#include <__type_traits/is_callable.h>
-#include <__utility/forward.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-#if _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-# define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name, policy) \
- [](auto&&... __args) -> decltype(std::name<policy>( \
- typename __select_backend<policy>::type{}, std::forward<decltype(__args)>(__args)...)) { \
- return std::name<policy>(typename __select_backend<policy>::type{}, std::forward<decltype(__args)>(__args)...); \
- }
-
-template <class _SpecializedImpl, class _GenericImpl, class... _Args>
-_LIBCPP_HIDE_FROM_ABI decltype(auto)
-__pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) {
- if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) {
- return __specialized_impl(std::forward<_Args>(__args)...);
- } else {
- return __generic_impl(std::forward<_Args>(__args)...);
- }
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
diff --git a/libcxx/include/__algorithm/pstl_generate.h b/libcxx/include/__algorithm/pstl_generate.h
index 7133c6f4f4c621..fbf1fc0bf22889 100644
--- a/libcxx/include/__algorithm/pstl_generate.h
+++ b/libcxx/include/__algorithm/pstl_generate.h
@@ -9,17 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_GENERATE_H
#define _LIBCPP___ALGORITHM_PSTL_GENERATE_H
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_for_each.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
-#include <__iterator/iterator_traits.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -32,30 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_generate();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Generator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__generate(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Generator&& __gen) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
- return std::__for_each(
- __policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) {
- __element = __g_gen();
- });
- },
- std::move(__first),
- std::move(__last),
- std::move(__gen));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Generator,
@@ -64,32 +38,9 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI void
generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- if (!std::__generate(__policy, std::move(__first), std::move(__last), std::move(__gen)))
- std::__throw_bad_alloc();
-}
-
-template <class>
-void __pstl_generate_n();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Size,
- class _Generator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__generate_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __n, _Generator&& __gen) {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) {
- return std::__for_each_n(
- __policy, std::move(__g_first), std::move(__g_n), [&](__iter_reference<_ForwardIterator> __element) {
- __element = __g_gen();
- });
- },
- std::move(__first),
- __n,
- std::move(__gen));
+ using _Implementation = __pstl::__generate<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__gen));
}
template <class _ExecutionPolicy,
@@ -101,8 +52,9 @@ template <class _ExecutionPolicy,
_LIBCPP_HIDE_FROM_ABI void
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- if (!std::__generate_n(__policy, std::move(__first), std::move(__n), std::move(__gen)))
- std::__throw_bad_alloc();
+ using _Implementation = __pstl::__generate_n<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__gen));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_is_partitioned.h b/libcxx/include/__algorithm/pstl_is_partitioned.h
index b6543021220727..6360245c50e65d 100644
--- a/libcxx/include/__algorithm/pstl_is_partitioned.h
+++ b/libcxx/include/__algorithm/pstl_is_partitioned.h
@@ -9,16 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
#define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
-#include <__algorithm/pstl_any_all_none_of.h>
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_find.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -31,30 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_is_partitioned();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool> __is_partitioned(
- _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
- __g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred);
- if (__g_first == __g_last)
- return true;
- ++__g_first;
- return std::none_of(__policy, __g_first, __g_last, __g_pred);
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
@@ -62,10 +37,10 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- auto __res = std::__is_partitioned(__policy, std::move(__first), std::move(__last), std::move(__pred));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__is_partitioned<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_merge.h b/libcxx/include/__algorithm/pstl_merge.h
index 3d262db6bc0c15..68747449f74bc0 100644
--- a/libcxx/include/__algorithm/pstl_merge.h
+++ b/libcxx/include/__algorithm/pstl_merge.h
@@ -9,14 +9,16 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H
#define _LIBCPP___ALGORITHM_PSTL_MERGE_H
-#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -33,25 +35,29 @@ template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
- class _Comp = std::less<>,
+ class _Comp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
-__merge(_ExecutionPolicy&&,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __result,
- _Comp __comp = {}) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_merge<_RawPolicy>(
- _Backend{},
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+merge(_ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __out,
+ _Comp __comp) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1));
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2));
+ using _Implementation = __pstl::__merge<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
std::move(__first1),
std::move(__last1),
std::move(__first2),
std::move(__last2),
- std::move(__result),
+ std::move(__out),
std::move(__comp));
}
@@ -59,7 +65,6 @@ template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
- class _Comp = std::less<>,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
@@ -68,19 +73,19 @@ merge(_ExecutionPolicy&& __policy,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
- _ForwardOutIterator __result,
- _Comp __comp = {}) {
- auto __res = std::__merge(
- __policy,
+ _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1));
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2));
+ return std::merge(
+ std::forward<_ExecutionPolicy>(__policy),
std::move(__first1),
std::move(__last1),
std::move(__first2),
std::move(__last2),
- std::move(__result),
- std::move(__comp));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ std::move(__out),
+ less{});
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_move.h b/libcxx/include/__algorithm/pstl_move.h
index d8441f1a6c2e16..998da5e15c100f 100644
--- a/libcxx/include/__algorithm/pstl_move.h
+++ b/libcxx/include/__algorithm/pstl_move.h
@@ -9,19 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_MOVE_H
#define _LIBCPP___ALGORITHM_PSTL_MOVE_H
-#include <__algorithm/copy_n.h>
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
-#include <__algorithm/pstl_transform.h>
#include <__config>
-#include <__functional/identity.h>
-#include <__iterator/iterator_traits.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
-#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/is_trivially_copyable.h>
#include <__type_traits/remove_cvref.h>
-#include <optional>
+#include <__utility/forward.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -34,45 +30,19 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-// TODO: Use the std::copy/move shenanigans to forward to std::memmove
-// Investigate whether we want to still forward to std::transform(policy)
-// in that case for the execution::par part, or whether we actually want
-// to run everything serially in that case.
-
-template <class>
-void __pstl_move();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
-__move(_ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _ForwardOutIterator&& __result) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_move, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result) {
- return std::__transform(__policy, __g_first, __g_last, __g_result, [](auto&& __v) { return std::move(__v); });
- },
- std::move(__first),
- std::move(__last),
- std::move(__result));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
- auto __res = std::__move(__policy, std::move(__first), std::move(__last), std::move(__result));
- if (!__res)
- std::__throw_bad_alloc();
- return *__res;
+move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(std::move(*__first)));
+ using _Implementation = __pstl::__move<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__out));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_replace.h b/libcxx/include/__algorithm/pstl_replace.h
index b1caf3fd4ac0a1..7204301f3e5965 100644
--- a/libcxx/include/__algorithm/pstl_replace.h
+++ b/libcxx/include/__algorithm/pstl_replace.h
@@ -9,16 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H
#define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_for_each.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
-#include <__algorithm/pstl_transform.h>
#include <__config>
-#include <__iterator/iterator_traits.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -31,37 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_replace_if();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Pred,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__replace_if(_ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _Pred&& __pred,
- const _Tp& __new_value) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if, _RawPolicy),
- [&__policy](
- _ForwardIterator&& __g_first, _ForwardIterator&& __g_last, _Pred&& __g_pred, const _Tp& __g_new_value) {
- std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
- if (__g_pred(__element))
- __element = __g_new_value;
- });
- return optional<__empty>{__empty{}};
- },
- std::move(__first),
- std::move(__last),
- std::move(__pred),
- __new_value);
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Pred,
@@ -74,40 +42,10 @@ replace_if(_ExecutionPolicy&& __policy,
_ForwardIterator __last,
_Pred __pred,
const _Tp& __new_value) {
- auto __res = std::__replace_if(__policy, std::move(__first), std::move(__last), std::move(__pred), __new_value);
- if (!__res)
- std::__throw_bad_alloc();
-}
-
-template <class>
-void __pstl_replace();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
-__replace(_ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- const _Tp& __old_value,
- const _Tp& __new_value) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace, _RawPolicy),
- [&__policy](
- _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) {
- return std::__replace_if(
- __policy,
- std::move(__g_first),
- std::move(__g_last),
- [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
- __g_new_value);
- },
- std::move(__first),
- std::move(__last),
- __old_value,
- __new_value);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__replace_if<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred), __new_value);
}
template <class _ExecutionPolicy,
@@ -121,46 +59,10 @@ replace(_ExecutionPolicy&& __policy,
_ForwardIterator __last,
const _Tp& __old_value,
const _Tp& __new_value) {
- if (!std::__replace(__policy, std::move(__first), std::move(__last), __old_value, __new_value))
- std::__throw_bad_alloc();
-}
-
-template <class>
-void __pstl_replace_copy_if();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _Pred,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_copy_if(
- _ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _ForwardOutIterator&& __result,
- _Pred&& __pred,
- const _Tp& __new_value) {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if, _RawPolicy),
- [&__policy](_ForwardIterator __g_first,
- _ForwardIterator __g_last,
- _ForwardOutIterator __g_result,
- _Pred __g_pred,
- const _Tp& __g_new_value) -> optional<__empty> {
- if (!std::__transform(
- __policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) {
- return __g_pred(__element) ? __g_new_value : __element;
- }))
- return nullopt;
- return __empty{};
- },
- std::move(__first),
- std::move(__last),
- std::move(__result),
- std::move(__pred),
- __new_value);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__replace<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __old_value, __new_value);
}
template <class _ExecutionPolicy,
@@ -174,49 +76,19 @@ _LIBCPP_HIDE_FROM_ABI void replace_copy_if(
_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
- _ForwardOutIterator __result,
+ _ForwardOutIterator __out,
_Pred __pred,
const _Tp& __new_value) {
- if (!std::__replace_copy_if(
- __policy, std::move(__first), std::move(__last), std::move(__result), std::move(__pred), __new_value))
- std::__throw_bad_alloc();
-}
-
-template <class>
-void __pstl_replace_copy();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_copy(
- _ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _ForwardOutIterator&& __result,
- const _Tp& __old_value,
- const _Tp& __new_value) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy, _RawPolicy),
- [&__policy](_ForwardIterator __g_first,
- _ForwardIterator __g_last,
- _ForwardOutIterator __g_result,
- const _Tp& __g_old_value,
- const _Tp& __g_new_value) {
- return std::__replace_copy_if(
- __policy,
- std::move(__g_first),
- std::move(__g_last),
- std::move(__g_result),
- [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
- __g_new_value);
- },
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__replace_copy_if<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
std::move(__first),
std::move(__last),
- std::move(__result),
- __old_value,
+ std::move(__out),
+ std::move(__pred),
__new_value);
}
@@ -230,12 +102,20 @@ _LIBCPP_HIDE_FROM_ABI void replace_copy(
_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
- _ForwardOutIterator __result,
+ _ForwardOutIterator __out,
const _Tp& __old_value,
const _Tp& __new_value) {
- if (!std::__replace_copy(
- __policy, std::move(__first), std::move(__last), std::move(__result), __old_value, __new_value))
- std::__throw_bad_alloc();
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__replace_copy<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ __old_value,
+ __new_value);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_rotate_copy.h b/libcxx/include/__algorithm/pstl_rotate_copy.h
index 346aab1d4a55c0..660684163667a3 100644
--- a/libcxx/include/__algorithm/pstl_rotate_copy.h
+++ b/libcxx/include/__algorithm/pstl_rotate_copy.h
@@ -9,11 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
#define _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_copy.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
+#include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
+#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
-#include <optional>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -26,38 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_rotate_copy();
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
-__rotate_copy(_ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __middle,
- _ForwardIterator&& __last,
- _ForwardOutIterator&& __result) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_rotate_copy, _RawPolicy),
- [&__policy](_ForwardIterator __g_first,
- _ForwardIterator __g_middle,
- _ForwardIterator __g_last,
- _ForwardOutIterator __g_result) -> optional<_ForwardOutIterator> {
- auto __result_mid =
- std::__copy(__policy, _ForwardIterator(__g_middle), std::move(__g_last), std::move(__g_result));
- if (!__result_mid)
- return nullopt;
- return std::__copy(__policy, std::move(__g_first), std::move(__g_middle), *std::move(__result_mid));
- },
- std::move(__first),
- std::move(__middle),
- std::move(__last),
- std::move(__result));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
@@ -68,12 +40,16 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy(
_ForwardIterator __first,
_ForwardIterator __middle,
_ForwardIterator __last,
- _ForwardOutIterator __result) {
- auto __res =
- std::__rotate_copy(__policy, std::move(__first), std::move(__middle), std::move(__last), std::move(__result));
- if (!__res)
- std::__throw_bad_alloc();
- return *__res;
+ _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__rotate_copy<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__middle),
+ std::move(__last),
+ std::move(__out));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_sort.h b/libcxx/include/__algorithm/pstl_sort.h
index a931f768111a23..446daa1ae930e5 100644
--- a/libcxx/include/__algorithm/pstl_sort.h
+++ b/libcxx/include/__algorithm/pstl_sort.h
@@ -9,17 +9,16 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_SORT_H
#define _LIBCPP___ALGORITHM_PSTL_SORT_H
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
-#include <__algorithm/pstl_stable_sort.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
+#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
-#include <__utility/empty.h>
#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -32,27 +31,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_sort();
-
-template <class _ExecutionPolicy,
- class _RandomAccessIterator,
- class _Comp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __sort(
- _ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort, _RawPolicy),
- [&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
- std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp));
- return optional<__empty>{__empty{}};
- },
- std::move(__first),
- std::move(__last),
- std::move(__comp));
-}
-
template <class _ExecutionPolicy,
class _RandomAccessIterator,
class _Comp,
@@ -60,8 +38,10 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
- if (!std::__sort(__policy, std::move(__first), std::move(__last), std::move(__comp)))
- std::__throw_bad_alloc();
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ using _Implementation = __pstl::__sort<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
}
template <class _ExecutionPolicy,
@@ -70,6 +50,7 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
}
diff --git a/libcxx/include/__algorithm/pstl_stable_sort.h b/libcxx/include/__algorithm/pstl_stable_sort.h
index 8ea0bb3f9a8d59..b761a80d106884 100644
--- a/libcxx/include/__algorithm/pstl_stable_sort.h
+++ b/libcxx/include/__algorithm/pstl_stable_sort.h
@@ -9,15 +9,16 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
#define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
-#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
-#include <__utility/empty.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -32,24 +33,25 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _RandomAccessIterator,
- class _Comp = less<>,
+ class _Comp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __stable_sort(
- _ExecutionPolicy&&, _RandomAccessIterator&& __first, _RandomAccessIterator&& __last, _Comp&& __comp = {}) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp));
+_LIBCPP_HIDE_FROM_ABI void
+stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ using _Implementation = __pstl::__stable_sort<__pstl::__configured_backend, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
}
template <class _ExecutionPolicy,
class _RandomAccessIterator,
- class _Comp = less<>,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void stable_sort(
- _ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) {
- if (!std::__stable_sort(__policy, std::move(__first), std::move(__last), std::move(__comp)))
- std::__throw_bad_alloc();
+_LIBCPP_HIDE_FROM_ABI void
+stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ std::stable_sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pstl_transform.h b/libcxx/include/__algorithm/pstl_transform.h
index f95938782fc3bd..ab4e0b1f9f29fb 100644
--- a/libcxx/include/__algorithm/pstl_transform.h
+++ b/libcxx/include/__algorithm/pstl_transform.h
@@ -9,14 +9,15 @@
#ifndef _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
#define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
-#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -29,23 +30,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _UnaryOperation,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardOutIterator>>
-__transform(_ExecutionPolicy&&,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _ForwardOutIterator&& __result,
- _UnaryOperation&& __op) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_transform<_RawPolicy>(
- _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
@@ -56,34 +40,18 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
- _ForwardOutIterator __result,
+ _ForwardOutIterator __out,
_UnaryOperation __op) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
- auto __res = std::__transform(__policy, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _BinaryOperation,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardOutIterator>>
-__transform(_ExecutionPolicy&&,
- _ForwardIterator1&& __first1,
- _ForwardIterator1&& __last1,
- _ForwardIterator2&& __first2,
- _ForwardOutIterator&& __result,
- _BinaryOperation&& __op) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_transform<_RawPolicy>(
- _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));
+ using _Implementation = __pstl::__transform<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ std::move(__op));
}
template <class _ExecutionPolicy,
@@ -98,17 +66,20 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
- _ForwardOutIterator __result,
+ _ForwardOutIterator __out,
_BinaryOperation __op) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
- auto __res = std::__transform(
- __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ using _Implementation = __pstl::__transform_binary<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__out),
+ std::move(__op));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index 7c002c5bfcf8e7..89a14609ee3f92 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -32,9 +32,9 @@
#cmakedefine _LIBCPP_INSTRUMENTED_WITH_ASAN
// PSTL backends
-#cmakedefine _LIBCPP_PSTL_CPU_BACKEND_SERIAL
-#cmakedefine _LIBCPP_PSTL_CPU_BACKEND_THREAD
-#cmakedefine _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH
+#cmakedefine _LIBCPP_PSTL_BACKEND_SERIAL
+#cmakedefine _LIBCPP_PSTL_BACKEND_STD_THREAD
+#cmakedefine _LIBCPP_PSTL_BACKEND_LIBDISPATCH
// Hardening.
#cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@
diff --git a/libcxx/include/__numeric/pstl_reduce.h b/libcxx/include/__numeric/pstl_reduce.h
index f9f666c2bb38b8..fd5f82690cf5f0 100644
--- a/libcxx/include/__numeric/pstl_reduce.h
+++ b/libcxx/include/__numeric/pstl_reduce.h
@@ -9,12 +9,16 @@
#ifndef _LIBCPP___NUMERIC_PSTL_REDUCE_H
#define _LIBCPP___NUMERIC_PSTL_REDUCE_H
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
-#include <__functional/identity.h>
-#include <__iterator/iterator_traits.h>
-#include <__numeric/pstl_transform_reduce.h>
+#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
+#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -27,27 +31,18 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class>
-void __pstl_reduce();
-
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
- class _BinaryOperation = plus<>,
+ class _BinaryOperation,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_Tp>
-__reduce(_ExecutionPolicy&& __policy,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _Tp&& __init,
- _BinaryOperation&& __op = {}) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Tp __g_init, _BinaryOperation __g_op) {
- return std::__transform_reduce(
- __policy, std::move(__g_first), std::move(__g_last), std::move(__g_init), std::move(__g_op), __identity{});
- },
+_LIBCPP_HIDE_FROM_ABI _Tp reduce(
+ _ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__reduce<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
std::move(__first),
std::move(__last),
std::move(__init),
@@ -57,35 +52,14 @@ __reduce(_ExecutionPolicy&& __policy,
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
- class _BinaryOperation = plus<>,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
-reduce(_ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _Tp __init,
- _BinaryOperation __op = {}) {
- auto __res = std::__reduce(__policy, std::move(__first), std::move(__last), std::move(__init), std::move(__op));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_value_type<_ForwardIterator>>
-__reduce(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last) noexcept {
- return std::__pstl_frontend_dispatch(
- _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce, _RawPolicy),
- [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last) {
- return std::__reduce(
- __policy, std::move(__g_first), std::move(__g_last), __iter_value_type<_ForwardIterator>());
- },
- std::move(__first),
- std::move(__last));
+reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__reduce<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__init), plus{});
}
template <class _ExecutionPolicy,
@@ -94,10 +68,14 @@ template <class _ExecutionPolicy,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator>
reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
- auto __res = std::__reduce(__policy, std::move(__first), std::move(__last));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__reduce<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ __iter_value_type<_ForwardIterator>(),
+ plus{});
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__numeric/pstl_transform_reduce.h b/libcxx/include/__numeric/pstl_transform_reduce.h
index 07ecf0d9956bb0..4c4044791fda0d 100644
--- a/libcxx/include/__numeric/pstl_transform_reduce.h
+++ b/libcxx/include/__numeric/pstl_transform_reduce.h
@@ -9,14 +9,16 @@
#ifndef _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
#define _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
-#include <__algorithm/pstl_backend.h>
-#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__functional/operations.h>
-#include <__numeric/transform_reduce.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/configuration.h>
+#include <__pstl/run_backend.h>
+#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
#include <__utility/move.h>
-#include <optional>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -29,33 +31,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _Tp,
- class _BinaryOperation1,
- class _BinaryOperation2,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI optional<_Tp> __transform_reduce(
- _ExecutionPolicy&&,
- _ForwardIterator1&& __first1,
- _ForwardIterator1&& __last1,
- _ForwardIterator2&& __first2,
- _Tp&& __init,
- _BinaryOperation1&& __reduce,
- _BinaryOperation2&& __transform) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_transform_reduce<_RawPolicy>(
- _Backend{},
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__init),
- std::move(__reduce),
- std::move(__transform));
-}
-
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
@@ -72,18 +47,17 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_Tp __init,
_BinaryOperation1 __reduce,
_BinaryOperation2 __transform) {
- auto __res = std::__transform_reduce(
- __policy,
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ using _Implementation = __pstl::__transform_reduce_binary<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
std::move(__first1),
std::move(__last1),
std::move(__first2),
std::move(__init),
std::move(__reduce),
std::move(__transform));
-
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
}
// This overload doesn't get a customization point because it's trivial to detect (through e.g.
@@ -92,38 +66,25 @@ template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _Tp,
- enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_ExecutionPolicy&& __policy,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_Tp __init) {
- return std::transform_reduce(__policy, __first1, __last1, __first2, __init, plus{}, multiplies{});
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Tp,
- class _BinaryOperation,
- class _UnaryOperation,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_Tp>> __transform_reduce(
- _ExecutionPolicy&&,
- _ForwardIterator&& __first,
- _ForwardIterator&& __last,
- _Tp&& __init,
- _BinaryOperation&& __reduce,
- _UnaryOperation&& __transform) noexcept {
- using _Backend = typename __select_backend<_RawPolicy>::type;
- return std::__pstl_transform_reduce<_RawPolicy>(
- _Backend{},
- std::move(__first),
- std::move(__last),
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ using _Implementation = __pstl::__transform_reduce_binary<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
std::move(__init),
- std::move(__reduce),
- std::move(__transform));
+ plus{},
+ multiplies{});
}
template <class _ExecutionPolicy,
@@ -140,11 +101,15 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_Tp __init,
_BinaryOperation __reduce,
_UnaryOperation __transform) {
- auto __res = std::__transform_reduce(
- __policy, std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
- if (!__res)
- std::__throw_bad_alloc();
- return *std::move(__res);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__transform_reduce<__pstl::__configured_backend, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__init),
+ std::move(__reduce),
+ std::move(__transform));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__pstl/README.md b/libcxx/include/__pstl/README.md
new file mode 100644
index 00000000000000..9fa5223d03e109
--- /dev/null
+++ b/libcxx/include/__pstl/README.md
@@ -0,0 +1,171 @@
+TODO: Documentation of how backends work
+
+A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
+
+```c++
+template <class _ExecutionPolicy, class _Iterator, class _Func>
+optional<__empty> __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<_Iterator> __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
+optional<__empty>
+__pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _Comp>
+optional<_ForwardOutIterator> __pstl_merge(_Backend,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __result,
+ _Comp __comp);
+
+template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
+optional<_OutIterator>
+__pstl_transform(_Backend, _InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
+
+template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
+optional<_OutIterator> __pstl_transform(_InIterator1 __first1,
+ _InIterator2 __first2,
+ _InIterator1 __last1,
+ _OutIterator __result,
+ _BinaryOperation __op);
+
+template <class _ExecutionPolicy,
+ class _Iterator1,
+ class _Iterator2,
+ class _Tp,
+ class _BinaryOperation1,
+ class _BinaryOperation2>
+optional<_Tp> __pstl_transform_reduce(_Backend,
+ _Iterator1 __first1,
+ _Iterator1 __last1,
+ _Iterator2 __first2,
+ _Iterator2 __last2,
+ _Tp __init,
+ _BinaryOperation1 __reduce,
+ _BinaryOperation2 __transform);
+
+template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
+optional<_Tp> __pstl_transform_reduce(_Backend,
+ _Iterator __first,
+ _Iterator __last,
+ _Tp __init,
+ _BinaryOperation __reduce,
+ _UnaryOperation __transform);
+
+// TODO: Complete this list
+```
+
+The following functions are optional but can be provided. If provided, they are used by the corresponding
+algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are
+implemented, all the algorithms will eventually forward to the basis algorithms listed above:
+
+```c++
+template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
+optional<__empty> __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<bool> __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<bool> __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<bool> __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _Iterator, class _Tp>
+optional<_Iterator> __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<_Iterator> __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _Iterator, class _Tp>
+optional<__empty> __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
+
+template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
+optional<__empty> __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
+
+template <class _ExecutionPolicy, class _Iterator, class _Generator>
+optional<__empty> __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<__empty> __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
+optional<__empty> __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
+
+template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
+optional<_OutIterator> __pstl_merge(_Backend,
+ _Iterator1 __first1,
+ _Iterator1 __last1,
+ _Iterator2 __first2,
+ _Iterator2 __last2,
+ _OutIterator __result,
+ _Comp __comp);
+
+template <class _ExecutionPolicy, class _Iterator, class _OutIterator>
+optional<_OutIterator> __pstl_move(_Backend, _Iterator __first, _Iterator __last, _OutIterator __result);
+
+template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
+optional<_Tp> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
+
+temlate <class _ExecutionPolicy, class _Iterator>
+optional<__iter_value_type<_Iterator>> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
+
+template <class _ExecutionPolicy, class _Iterator, class _Tp>
+optional<__iter_diff_t<_Iterator>> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
+
+template <class _ExecutionPolicy, class _Iterator, class _Predicate>
+optional<__iter_diff_t<_Iterator>> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
+
+template <class _ExecutionPolicy, class _Iterator, class _Tp>
+optional<__empty>
+__pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
+optional<__empty>
+__pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
+optional<__empty> __pstl_replace_copy(_Backend,
+ _Iterator __first,
+ _Iterator __last,
+ _OutIterator __result,
+ const _Tp& __old_value,
+ const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
+optional<__empty> __pstl_replace_copy_if(_Backend,
+ _Iterator __first,
+ _Iterator __last,
+ _OutIterator __result,
+ _Pred __pred,
+ const _Tp& __new_value);
+
+template <class _ExecutionPolicy, class _Iterator, class _OutIterator>
+optional<_Iterator> __pstl_rotate_copy(
+ _Backend, _Iterator __first, _Iterator __middle, _Iterator __last, _OutIterator __result);
+
+template <class _ExecutionPolicy, class _Iterator, class _Comp>
+optional<__empty> __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
+
+template <class _ExecutionPolicy, class _Iterator1, class _Iterator2, class _Comp>
+optional<bool> __pstl_equal(_Backend, _Iterator1 first1, _Iterator1 last1, _Iterator2 first2, _Comp __comp);
+
+// TODO: Complete this list
+```
+
+Exception handling
+==================
+
+PSTL backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their
+implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are turned
+into a program termination at the front-end level. When a backend returns a disengaged `optional` to the frontend, the
+frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to the user.
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
new file mode 100644
index 00000000000000..8c2545ed49b478
--- /dev/null
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_BACKEND_FWD_H
+#define _LIBCPP___PSTL_BACKEND_FWD_H
+
+#include <__config>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// find_if family
+template <class _Backend, class _RawExecutionPolicy>
+struct __find_if;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __find;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __find_if_not;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __any_of;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __all_of;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __none_of;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __is_partitioned;
+
+// for_each family
+template <class _Backend, class _RawExecutionPolicy>
+struct __for_each;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __for_each_n;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __fill;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __fill_n;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace_if;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __generate;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __generate_n;
+
+// merge family
+template <class _Backend, class _RawExecutionPolicy>
+struct __merge;
+
+// stable_sort family
+template <class _Backend, class _RawExecutionPolicy>
+struct __stable_sort;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __sort;
+
+// transform family
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform_binary;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace_copy_if;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace_copy;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __move;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __copy;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __copy_n;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __rotate_copy;
+
+// transform_reduce family
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform_reduce;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform_reduce_binary;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __count_if;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __count;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __equal_3leg;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __equal;
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __reduce;
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_BACKEND_FWD_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
similarity index 80%
rename from libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h
rename to libcxx/include/__pstl/backends/libdispatch.h
index 7353c4222a06e1..e723e39c802c23 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
+#ifndef _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H
+#define _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H
#include <__algorithm/inplace_merge.h>
#include <__algorithm/lower_bound.h>
@@ -23,7 +23,17 @@
#include <__memory/construct_at.h>
#include <__memory/unique_ptr.h>
#include <__numeric/reduce.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/cpu_algos/any_of.h>
#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__pstl/cpu_algos/fill.h>
+#include <__pstl/cpu_algos/find_if.h>
+#include <__pstl/cpu_algos/for_each.h>
+#include <__pstl/cpu_algos/merge.h>
+#include <__pstl/cpu_algos/stable_sort.h>
+#include <__pstl/cpu_algos/transform.h>
+#include <__pstl/cpu_algos/transform_reduce.h>
+#include <__pstl/defaults.h>
#include <__utility/empty.h>
#include <__utility/exception_guard.h>
#include <__utility/move.h>
@@ -32,11 +42,6 @@
#include <new>
#include <optional>
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __pstl {
@@ -79,6 +84,16 @@ __dispatch_parallel_for(__chunk_partitions __partitions, _RandomAccessIterator _
return __empty{};
}
+template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
+struct __merge_range {
+ __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
+ : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
+
+ _RandomAccessIterator1 __mid1_;
+ _RandomAccessIterator2 __mid2_;
+ _RandomAccessIteratorOut __result_;
+};
+
template <>
struct __cpu_traits<__libdispatch_backend_tag> {
template <class _RandomAccessIterator, class _Functor>
@@ -88,16 +103,6 @@ struct __cpu_traits<__libdispatch_backend_tag> {
__pstl::__partition_chunks(__last - __first), std::move(__first), std::move(__func));
}
- template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
- struct __merge_range {
- __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
- : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
-
- _RandomAccessIterator1 __mid1_;
- _RandomAccessIterator2 __mid2_;
- _RandomAccessIteratorOut __result_;
- };
-
template <typename _RandomAccessIterator1,
typename _RandomAccessIterator2,
typename _RandomAccessIterator3,
@@ -133,15 +138,15 @@ struct __cpu_traits<__libdispatch_backend_tag> {
unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
[&]() -> __merge_range_t* {
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try {
-# endif
+#endif
return std::allocator<__merge_range_t>().allocate(__n_ranges);
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
} catch (const std::bad_alloc&) {
return nullptr;
}
-# endif
+#endif
}(),
__destroy);
@@ -336,15 +341,51 @@ struct __cpu_traits<__libdispatch_backend_tag> {
}
_LIBCPP_HIDE_FROM_ABI static void __cancel_execution() {}
-
- static constexpr size_t __lane_size = 64;
};
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
+// Mandatory implementations of the computational basis
+template <class _ExecutionPolicy>
+struct __find_if<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_find_if<__libdispatch_backend_tag, _ExecutionPolicy> {};
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+template <class _ExecutionPolicy>
+struct __for_each<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_for_each<__libdispatch_backend_tag, _ExecutionPolicy> {};
-_LIBCPP_POP_MACROS
+template <class _ExecutionPolicy>
+struct __merge<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_merge<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __stable_sort<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_stable_sort<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_binary<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform_binary<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_reduce<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform_reduce<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_reduce_binary<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform_reduce_binary<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+// Not mandatory, but better optimized
+template <class _ExecutionPolicy>
+struct __any_of<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_any_of<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __fill<__libdispatch_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_fill<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
+#endif // _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H
diff --git a/libcxx/include/__pstl/backends/serial.h b/libcxx/include/__pstl/backends/serial.h
new file mode 100644
index 00000000000000..2d67bc381783b5
--- /dev/null
+++ b/libcxx/include/__pstl/backends/serial.h
@@ -0,0 +1,162 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_BACKENDS_SERIAL_H
+#define _LIBCPP___PSTL_BACKENDS_SERIAL_H
+
+#include <__algorithm/find_if.h>
+#include <__algorithm/for_each.h>
+#include <__algorithm/merge.h>
+#include <__algorithm/stable_sort.h>
+#include <__algorithm/transform.h>
+#include <__config>
+#include <__numeric/transform_reduce.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/defaults.h>
+#include <__utility/empty.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+struct __serial_backend_tag {};
+
+// Mandatory implementations of the computational basis
+template <class _ExecutionPolicy>
+struct __find_if<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ return std::find_if(std::move(__first), std::move(__last), std::forward<_Pred>(__pred));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __for_each<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Function>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Function&& __func) const noexcept {
+ std::for_each(std::move(__first), std::move(__last), std::forward<_Function>(__func));
+ return __empty{};
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __merge<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardOutIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&&,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __out,
+ _Comp&& __comp) const noexcept {
+ return std::merge(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__out),
+ std::forward<_Comp>(__comp));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __stable_sort<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _RandomAccessIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) const noexcept {
+ std::stable_sort(std::move(__first), std::move(__last), std::forward<_Comp>(__comp));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __transform<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&&, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out, _UnaryOperation&& __op)
+ const noexcept {
+ return std::transform(std::move(__first), std::move(__last), std::move(__out), std::forward<_UnaryOperation>(__op));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __transform_binary<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _BinaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&&,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardOutIterator __out,
+ _BinaryOperation&& __op) const noexcept {
+ return std::transform(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__out),
+ std::forward<_BinaryOperation>(__op));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __transform_reduce<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_Tp>
+ operator()(_Policy&&,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _Tp const& __init,
+ _BinaryOperation&& __reduce,
+ _UnaryOperation&& __transform) const noexcept {
+ return std::transform_reduce(
+ std::move(__first),
+ std::move(__last),
+ __init,
+ std::forward<_BinaryOperation>(__reduce),
+ std::forward<_UnaryOperation>(__transform));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __transform_reduce_binary<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation1,
+ class _BinaryOperation2>
+ _LIBCPP_HIDE_FROM_ABI optional<_Tp> operator()(
+ _Policy&&,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _Tp const& __init,
+ _BinaryOperation1&& __reduce,
+ _BinaryOperation2&& __transform) const noexcept {
+ return std::transform_reduce(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ __init,
+ std::forward<_BinaryOperation1>(__reduce),
+ std::forward<_BinaryOperation2>(__transform));
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_BACKENDS_SERIAL_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h b/libcxx/include/__pstl/backends/std_thread.h
similarity index 50%
rename from libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h
rename to libcxx/include/__pstl/backends/std_thread.h
index 2acf912264a001..0795f0555277e5 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h
+++ b/libcxx/include/__pstl/backends/std_thread.h
@@ -6,32 +6,28 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
+#ifndef _LIBCPP___PSTL_BACKENDS_STD_THREAD_H
+#define _LIBCPP___PSTL_BACKENDS_STD_THREAD_H
-#include <__assert>
#include <__config>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/cpu_algos/any_of.h>
#include <__pstl/cpu_algos/cpu_traits.h>
-#include <__utility/empty.h>
-#include <__utility/move.h>
-#include <cstddef>
-#include <optional>
+#include <__pstl/cpu_algos/fill.h>
+#include <__pstl/cpu_algos/find_if.h>
+#include <__pstl/cpu_algos/for_each.h>
+#include <__pstl/cpu_algos/merge.h>
+#include <__pstl/cpu_algos/stable_sort.h>
+#include <__pstl/cpu_algos/transform.h>
+#include <__pstl/cpu_algos/transform_reduce.h>
+#include <__pstl/defaults.h>
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
// This backend implementation is for testing purposes only and not meant for production use. This will be replaced
// by a proper implementation once the PSTL implementation is somewhat stable.
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
struct __std_thread_backend_tag {};
template <>
@@ -78,11 +74,49 @@ struct __cpu_traits<__std_thread_backend_tag> {
static constexpr size_t __lane_size = 64;
};
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
+// Mandatory implementations of the computational basis
+template <class _ExecutionPolicy>
+struct __find_if<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_find_if<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __for_each<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_for_each<__std_thread_backend_tag, _ExecutionPolicy> {};
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
+template <class _ExecutionPolicy>
+struct __merge<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_merge<__std_thread_backend_tag, _ExecutionPolicy> {};
-_LIBCPP_POP_MACROS
+template <class _ExecutionPolicy>
+struct __stable_sort<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_stable_sort<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_binary<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform_binary<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_reduce<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform_reduce<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_reduce_binary<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_transform_reduce_binary<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+// Not mandatory, but better optimized
+template <class _ExecutionPolicy>
+struct __any_of<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_any_of<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __fill<__std_thread_backend_tag, _ExecutionPolicy>
+ : __cpu_parallel_fill<__std_thread_backend_tag, _ExecutionPolicy> {};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
+#endif // _LIBCPP___PSTL_BACKENDS_STD_THREAD_H
diff --git a/libcxx/include/__pstl/configuration.h b/libcxx/include/__pstl/configuration.h
new file mode 100644
index 00000000000000..89a45d6a111cd5
--- /dev/null
+++ b/libcxx/include/__pstl/configuration.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CONFIGURATION_H
+#define _LIBCPP___PSTL_CONFIGURATION_H
+
+#include <__config>
+
+#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
+# include <__pstl/backends/serial.h>
+#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
+# include <__pstl/backends/std_thread.h>
+#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+# include <__pstl/backends/libdispatch.h>
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
+using __configured_backend = __serial_backend_tag;
+#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
+using __configured_backend = __std_thread_backend_tag;
+#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+using __configured_backend = __libdispatch_backend_tag;
+#else
+
+// ...New vendors can add parallel backends here...
+
+# error "Invalid choice of a PSTL parallel backend"
+#endif
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_CONFIGURATION_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h b/libcxx/include/__pstl/cpu_algos/any_of.h
similarity index 56%
rename from libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h
rename to libcxx/include/__pstl/cpu_algos/any_of.h
index 3755d288047e0b..39a9dbf1f197d1 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h
+++ b/libcxx/include/__pstl/cpu_algos/any_of.h
@@ -6,16 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H
+#define _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H
#include <__algorithm/any_of.h>
-#include <__algorithm/find_if.h>
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__assert>
#include <__atomic/atomic.h>
#include <__atomic/memory_order.h>
#include <__config>
-#include <__functional/operations.h>
#include <__iterator/concepts.h>
#include <__pstl/cpu_algos/cpu_traits.h>
#include <__type_traits/is_execution_policy.h>
@@ -24,12 +22,12 @@
#include <cstdint>
#include <optional>
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_PUSH_MACROS
-# include <__undef_macros>
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
template <class _Backend, class _Index, class _Brick>
_LIBCPP_HIDE_FROM_ABI optional<bool> __parallel_or(_Index __first, _Index __last, _Brick __f) {
@@ -70,30 +68,30 @@ _LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred
return false;
}
-template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
-_LIBCPP_HIDE_FROM_ABI optional<bool>
-__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__parallel_or<__cpu_backend_tag>(
- __first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
- auto __res = std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{}, __brick_first, __brick_last, __pred);
- _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
- return *std::move(__res);
- });
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__simd_or(__first, __last - __first, __pred);
- } else {
- return std::any_of(__first, __last, __pred);
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_any_of {
+ template <class _Policy, class _ForwardIterator, class _Predicate>
+ _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __pstl::__parallel_or<_Backend>(
+ __first, __last, [&__policy, &__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+ using _AnyOfUnseq = __pstl::__any_of<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ auto __res = _AnyOfUnseq()(std::__remove_parallel_policy(__policy), __brick_first, __brick_last, __pred);
+ _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
+ return *std::move(__res);
+ });
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __pstl::__simd_or(__first, __last - __first, __pred);
+ } else {
+ return std::any_of(__first, __last, __pred);
+ }
}
-}
+};
+} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
-_LIBCPP_POP_MACROS
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
+#endif // _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H
diff --git a/libcxx/include/__pstl/cpu_algos/cpu_traits.h b/libcxx/include/__pstl/cpu_algos/cpu_traits.h
index b24f0973d8e5ba..15bfadb037d69c 100644
--- a/libcxx/include/__pstl/cpu_algos/cpu_traits.h
+++ b/libcxx/include/__pstl/cpu_algos/cpu_traits.h
@@ -69,9 +69,10 @@ namespace __pstl {
// ==================
//
// CPU backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their
-// implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are turned
-// into a program termination at the front-end level. When a backend returns a disengaged `optional` to the frontend, the
-// frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to the user.
+// implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are
+// turned into a program termination at the front-end level. When a backend returns a disengaged `optional` to the
+// frontend, the frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to
+// the user.
template <class _Backend>
struct __cpu_traits;
diff --git a/libcxx/include/__pstl/cpu_algos/fill.h b/libcxx/include/__pstl/cpu_algos/fill.h
new file mode 100644
index 00000000000000..954069cef67b24
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/fill.h
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_FILL_H
+#define _LIBCPP___PSTL_CPU_ALGOS_FILL_H
+
+#include <__algorithm/fill.h>
+#include <__assert>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/empty.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Index, class _DifferenceType, class _Tp>
+_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept {
+ _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
+ _PSTL_PRAGMA_SIMD
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ __first[__i] = __value;
+ return __first + __n;
+}
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_fill {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __cpu_traits<_Backend>::__for_each(
+ __first, __last, [&__policy, &__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+ using _FillUnseq = __pstl::__fill<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ [[maybe_unused]] auto __res =
+ _FillUnseq()(std::__remove_parallel_policy(__policy), __brick_first, __brick_last, __value);
+ _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
+ });
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ __pstl::__simd_fill_n(__first, __last - __first, __value);
+ return __empty{};
+ } else {
+ std::fill(__first, __last, __value);
+ return __empty{};
+ }
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_FILL_H
diff --git a/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h b/libcxx/include/__pstl/cpu_algos/find_if.h
similarity index 66%
rename from libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h
rename to libcxx/include/__pstl/cpu_algos/find_if.h
index 626293faef6921..4e58e63e62bc4c 100644
--- a/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h
+++ b/libcxx/include/__pstl/cpu_algos/find_if.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
-#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H
+#define _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H
#include <__algorithm/find_if.h>
-#include <__algorithm/pstl_backends/cpu_backends/backend.h>
+#include <__assert>
#include <__atomic/atomic.h>
#include <__config>
#include <__functional/operations.h>
@@ -27,12 +27,11 @@
# pragma GCC system_header
#endif
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
_LIBCPP_PUSH_MACROS
-# include <__undef_macros>
+#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
template <class _Backend, class _Index, class _Brick, class _Compare>
_LIBCPP_HIDE_FROM_ABI optional<_Index>
@@ -98,38 +97,40 @@ __simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Co
return __first + __end;
}
-template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
-_LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
-__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- return std::__parallel_find<__cpu_backend_tag>(
- __first,
- __last,
- [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
- auto __res = std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>(
- __cpu_backend_tag{}, __brick_first, __brick_last, __pred);
- _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
- return *std::move(__res);
- },
- less<>{},
- true);
- } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
- __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- using __diff_t = __iter_diff_t<_ForwardIterator>;
- return std::__simd_first<__cpu_backend_tag>(
- __first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
- return __pred(__iter[__i]);
- });
- } else {
- return std::find_if(__first, __last, __pred);
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_find_if {
+ template <class _Policy, class _ForwardIterator, class _Predicate>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __pstl::__parallel_find<_Backend>(
+ __first,
+ __last,
+ [&__policy, &__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+ using _FindIfUnseq = __pstl::__find_if<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ auto __res = _FindIfUnseq()(std::__remove_parallel_policy(__policy), __brick_first, __brick_last, __pred);
+ _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
+ return *std::move(__res);
+ },
+ less<>{},
+ true);
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ using __diff_t = __iter_diff_t<_ForwardIterator>;
+ return __pstl::__simd_first<_Backend>(
+ __first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
+ return __pred(__iter[__i]);
+ });
+ } else {
+ return std::find_if(__first, __last, __pred);
+ }
}
-}
+};
+} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
+#endif // _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H
diff --git a/libcxx/include/__pstl/cpu_algos/for_each.h b/libcxx/include/__pstl/cpu_algos/for_each.h
new file mode 100644
index 00000000000000..b64a8942783989
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/for_each.h
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H
+#define _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H
+
+#include <__algorithm/for_each.h>
+#include <__assert>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/empty.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Iterator, class _DifferenceType, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator __simd_for_each(_Iterator __first, _DifferenceType __n, _Function __f) noexcept {
+ _PSTL_PRAGMA_SIMD
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ __f(__first[__i]);
+
+ return __first + __n;
+}
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_for_each {
+ template <class _Policy, class _ForwardIterator, class _Functor>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __cpu_traits<_Backend>::__for_each(
+ __first, __last, [&__policy, __func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+ using _ForEachUnseq = __pstl::__for_each<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ [[maybe_unused]] auto __res =
+ _ForEachUnseq()(std::__remove_parallel_policy(__policy), __brick_first, __brick_last, __func);
+ _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
+ });
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ __pstl::__simd_for_each(__first, __last - __first, __func);
+ return __empty{};
+ } else {
+ std::for_each(__first, __last, __func);
+ return __empty{};
+ }
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H
diff --git a/libcxx/include/__pstl/cpu_algos/merge.h b/libcxx/include/__pstl/cpu_algos/merge.h
new file mode 100644
index 00000000000000..1fa2d7d26f6d0e
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/merge.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_MERGE_H
+#define _LIBCPP___PSTL_CPU_ALGOS_MERGE_H
+
+#include <__algorithm/merge.h>
+#include <__assert>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_merge {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardOutIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __result,
+ _Comp __comp) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
+ auto __res = __cpu_traits<_Backend>::__merge(
+ __first1,
+ __last1,
+ __first2,
+ __last2,
+ __result,
+ __comp,
+ [&__policy](_ForwardIterator1 __g_first1,
+ _ForwardIterator1 __g_last1,
+ _ForwardIterator2 __g_first2,
+ _ForwardIterator2 __g_last2,
+ _ForwardOutIterator __g_result,
+ _Comp __g_comp) {
+ using _MergeUnseq = __pstl::__merge<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ [[maybe_unused]] auto __g_res = _MergeUnseq()(
+ std::__remove_parallel_policy(__policy),
+ std::move(__g_first1),
+ std::move(__g_last1),
+ std::move(__g_first2),
+ std::move(__g_last2),
+ std::move(__g_result),
+ std::move(__g_comp));
+ _LIBCPP_ASSERT_INTERNAL(__g_res, "unsed/sed should never try to allocate!");
+ });
+ if (!__res)
+ return nullopt;
+ return __result + (__last1 - __first1) + (__last2 - __first2);
+ } else {
+ return std::merge(__first1, __last1, __first2, __last2, __result, __comp);
+ }
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_MERGE_H
diff --git a/libcxx/include/__pstl/cpu_algos/stable_sort.h b/libcxx/include/__pstl/cpu_algos/stable_sort.h
new file mode 100644
index 00000000000000..edfec68d175879
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/stable_sort.h
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H
+#define _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H
+
+#include <__algorithm/stable_sort.h>
+#include <__config>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/empty.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_stable_sort {
+ template <class _Policy, class _RandomAccessIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy>) {
+ return __cpu_traits<_Backend>::__stable_sort(
+ __first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
+ std::stable_sort(__g_first, __g_last, __g_comp);
+ });
+ } else {
+ std::stable_sort(__first, __last, __comp);
+ return __empty{};
+ }
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H
diff --git a/libcxx/include/__pstl/cpu_algos/transform.h b/libcxx/include/__pstl/cpu_algos/transform.h
new file mode 100644
index 00000000000000..ba8e578958cd90
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/transform.h
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H
+#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H
+
+#include <__algorithm/transform.h>
+#include <__assert>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator2
+__simd_transform(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept {
+ _PSTL_PRAGMA_SIMD
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ __f(__first1[__i], __first2[__i]);
+ return __first2 + __n;
+}
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_transform {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __result,
+ _UnaryOperation __op) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
+ __cpu_traits<_Backend>::__for_each(
+ __first,
+ __last,
+ [&__policy, __op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
+ using _TransformUnseq = __pstl::__transform<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ auto __res = _TransformUnseq()(
+ std::__remove_parallel_policy(__policy),
+ __brick_first,
+ __brick_last,
+ __result + (__brick_first - __first),
+ __op);
+ _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
+ return *std::move(__res);
+ });
+ return __result + (__last - __first);
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
+ return __pstl::__simd_transform(
+ __first,
+ __last - __first,
+ __result,
+ [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
+ __out_value = __op(__in_value);
+ });
+ } else {
+ return std::transform(__first, __last, __result, __op);
+ }
+ }
+};
+
+template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_transform_binary(
+ _Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept {
+ _PSTL_PRAGMA_SIMD
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ __f(__first1[__i], __first2[__i], __first3[__i]);
+ return __first3 + __n;
+}
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_transform_binary {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _BinaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardOutIterator __result,
+ _BinaryOperation __op) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
+ auto __res = __cpu_traits<_Backend>::__for_each(
+ __first1,
+ __last1,
+ [&__policy, __op, __first1, __first2, __result](
+ _ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
+ using _TransformBinaryUnseq =
+ __pstl::__transform_binary<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ return _TransformBinaryUnseq()(
+ std::__remove_parallel_policy(__policy),
+ __brick_first,
+ __brick_last,
+ __first2 + (__brick_first - __first1),
+ __result + (__brick_first - __first1),
+ __op);
+ });
+ if (!__res)
+ return nullopt;
+ return __result + (__last1 - __first1);
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
+ return __pstl::__simd_transform_binary(
+ __first1,
+ __last1 - __first1,
+ __first2,
+ __result,
+ [&](__iter_reference<_ForwardIterator1> __in1,
+ __iter_reference<_ForwardIterator2> __in2,
+ __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
+ } else {
+ return std::transform(__first1, __last1, __first2, __result, __op);
+ }
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H
diff --git a/libcxx/include/__pstl/cpu_algos/transform_reduce.h b/libcxx/include/__pstl/cpu_algos/transform_reduce.h
new file mode 100644
index 00000000000000..12c991ed281b28
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/transform_reduce.h
@@ -0,0 +1,214 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H
+#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H
+
+#include <__assert>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__numeric/transform_reduce.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/desugars_to.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+#include <new>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <typename _Backend,
+ typename _DifferenceType,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ typename _UnaryResult = invoke_result_t<_UnaryOperation, _DifferenceType>,
+ __enable_if_t<__desugars_to_v<__plus_tag, _BinaryOperation, _Tp, _UnaryResult> && is_arithmetic_v<_Tp> &&
+ is_arithmetic_v<_UnaryResult>,
+ int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
+ _PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ __init += __f(__i);
+ return __init;
+}
+
+template <typename _Backend,
+ typename _Size,
+ typename _Tp,
+ typename _BinaryOperation,
+ typename _UnaryOperation,
+ typename _UnaryResult = invoke_result_t<_UnaryOperation, _Size>,
+ __enable_if_t<!(__desugars_to_v<__plus_tag, _BinaryOperation, _Tp, _UnaryResult> && is_arithmetic_v<_Tp> &&
+ is_arithmetic_v<_UnaryResult>),
+ int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
+ static constexpr auto __lane_size = __cpu_traits<_Backend>::__lane_size;
+ const _Size __block_size = __lane_size / sizeof(_Tp);
+ if (__n > 2 * __block_size && __block_size > 1) {
+ alignas(__lane_size) char __lane_buffer[__lane_size];
+ _Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
+
+ // initializer
+ _PSTL_PRAGMA_SIMD
+ for (_Size __i = 0; __i < __block_size; ++__i) {
+ ::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i)));
+ }
+ // main loop
+ _Size __i = 2 * __block_size;
+ const _Size __last_iteration = __block_size * (__n / __block_size);
+ for (; __i < __last_iteration; __i += __block_size) {
+ _PSTL_PRAGMA_SIMD
+ for (_Size __j = 0; __j < __block_size; ++__j) {
+ __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j));
+ }
+ }
+ // remainder
+ _PSTL_PRAGMA_SIMD
+ for (_Size __j = 0; __j < __n - __last_iteration; ++__j) {
+ __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j));
+ }
+ // combiner
+ for (_Size __j = 0; __j < __block_size; ++__j) {
+ __init = __binary_op(std::move(__init), std::move(__lane[__j]));
+ }
+ // destroyer
+ _PSTL_PRAGMA_SIMD
+ for (_Size __j = 0; __j < __block_size; ++__j) {
+ __lane[__j].~_Tp();
+ }
+ } else {
+ for (_Size __i = 0; __i < __n; ++__i) {
+ __init = __binary_op(std::move(__init), __f(__i));
+ }
+ }
+ return __init;
+}
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_transform_reduce_binary {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation1,
+ class _BinaryOperation2>
+ _LIBCPP_HIDE_FROM_ABI optional<_Tp> operator()(
+ _Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _Tp __init,
+ _BinaryOperation1 __reduce,
+ _BinaryOperation2 __transform) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
+ return __cpu_traits<_Backend>::__transform_reduce(
+ __first1,
+ std::move(__last1),
+ [__first1, __first2, __transform](_ForwardIterator1 __iter) {
+ return __transform(*__iter, *(__first2 + (__iter - __first1)));
+ },
+ std::move(__init),
+ std::move(__reduce),
+ [&__policy, __first1, __first2, __reduce, __transform](
+ _ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) {
+ using _TransformReduceBinaryUnseq =
+ __pstl::__transform_reduce_binary<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ return *_TransformReduceBinaryUnseq()(
+ std::__remove_parallel_policy(__policy),
+ __brick_first,
+ std::move(__brick_last),
+ __first2 + (__brick_first - __first1),
+ std::move(__brick_init),
+ std::move(__reduce),
+ std::move(__transform));
+ });
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
+ return __pstl::__simd_transform_reduce<_Backend>(
+ __last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
+ return __transform(__first1[__i], __first2[__i]);
+ });
+ } else {
+ return std::transform_reduce(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__init),
+ std::move(__reduce),
+ std::move(__transform));
+ }
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_transform_reduce {
+ template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_Tp>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _Tp __init,
+ _BinaryOperation __reduce,
+ _UnaryOperation __transform) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __cpu_traits<_Backend>::__transform_reduce(
+ std::move(__first),
+ std::move(__last),
+ [__transform](_ForwardIterator __iter) { return __transform(*__iter); },
+ std::move(__init),
+ __reduce,
+ [&__policy, __transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) {
+ using _TransformReduceUnseq =
+ __pstl::__transform_reduce<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>;
+ auto __res = _TransformReduceUnseq()(
+ std::__remove_parallel_policy(__policy),
+ std::move(__brick_first),
+ std::move(__brick_last),
+ std::move(__brick_init),
+ std::move(__reduce),
+ std::move(__transform));
+ _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!");
+ return *std::move(__res);
+ });
+ } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ return __pstl::__simd_transform_reduce<_Backend>(
+ __last - __first,
+ std::move(__init),
+ std::move(__reduce),
+ [=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
+ } else {
+ return std::transform_reduce(
+ std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
+ }
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H
diff --git a/libcxx/include/__pstl/defaults.h b/libcxx/include/__pstl/defaults.h
new file mode 100644
index 00000000000000..27b2c7b5e88e08
--- /dev/null
+++ b/libcxx/include/__pstl/defaults.h
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_DEFAULTS_H
+#define _LIBCPP___PSTL_DEFAULTS_H
+
+#include <__config>
+#include <__pstl/defaults/find_if_family.h>
+#include <__pstl/defaults/for_each_family.h>
+#include <__pstl/defaults/merge_family.h>
+#include <__pstl/defaults/stable_sort_family.h>
+#include <__pstl/defaults/transform_family.h>
+#include <__pstl/defaults/transform_reduce_family.h>
+
+#endif // _LIBCPP___PSTL_DEFAULTS_H
diff --git a/libcxx/include/__pstl/defaults/find_if_family.h b/libcxx/include/__pstl/defaults/find_if_family.h
new file mode 100644
index 00000000000000..4f7b2df8beac51
--- /dev/null
+++ b/libcxx/include/__pstl/defaults/find_if_family.h
@@ -0,0 +1,134 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FIND_IF_FAMILY_H
+#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FIND_IF_FAMILY_H
+
+#include <__config>
+#include <__functional/not_fn.h>
+#include <__pstl/backend_fwd.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// This header defines the default implementation for the find_if family of algorithms:
+// - find
+// - find_if_not
+// - any_of
+// - all_of
+// - none_of
+// - is_partitioned
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __find_if {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept = delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __find {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
+ using _FindIf = __pstl::__find_if<_Backend, _RawExecutionPolicy>;
+ return _FindIf()(
+ __policy, std::move(__first), std::move(__last), [&](__iter_reference<_ForwardIterator> __element) {
+ return __element == __value;
+ });
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __find_if_not {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _FindIf = __pstl::__find_if<_Backend, _RawExecutionPolicy>;
+ return _FindIf()(__policy, __first, __last, std::not_fn(__pred));
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __any_of {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _FindIf = __pstl::__find_if<_Backend, _RawExecutionPolicy>;
+ auto __res = _FindIf()(__policy, __first, __last, __pred);
+ if (!__res)
+ return nullopt;
+ return *__res != __last;
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __all_of {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _AnyOf = __pstl::__any_of<_Backend, _RawExecutionPolicy>;
+ auto __res = _AnyOf()(__policy, __first, __last, [&](__iter_reference<_ForwardIterator> __value) {
+ return !__pred(__value);
+ });
+ if (!__res)
+ return nullopt;
+ return !*__res;
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __none_of {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _AnyOf = __pstl::__any_of<_Backend, _RawExecutionPolicy>;
+ auto __res = _AnyOf()(__policy, __first, __last, __pred);
+ if (!__res)
+ return nullopt;
+ return !*__res;
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __is_partitioned {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _FindIfNot = __pstl::__find_if_not<_Backend, _RawExecutionPolicy>;
+ auto __maybe_first = _FindIfNot()(__policy, std::move(__first), std::move(__last), __pred);
+ if (__maybe_first == nullopt)
+ return nullopt;
+
+ __first = *__maybe_first;
+ if (__first == __last)
+ return true;
+ ++__first;
+ using _NoneOf = __pstl::__none_of<_Backend, _RawExecutionPolicy>;
+ return _NoneOf()(__policy, std::move(__first), std::move(__last), __pred);
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FIND_IF_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/for_each_family.h b/libcxx/include/__pstl/defaults/for_each_family.h
new file mode 100644
index 00000000000000..227709e8458a1a
--- /dev/null
+++ b/libcxx/include/__pstl/defaults/for_each_family.h
@@ -0,0 +1,153 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FOR_EACH_FAMILY_H
+#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FOR_EACH_FAMILY_H
+
+#include <__algorithm/fill_n.h>
+#include <__algorithm/for_each_n.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__pstl/backend_fwd.h>
+#include <__utility/empty.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// This header defines the default implementation for the for_each family of algorithms:
+// - for_each_n
+// - fill
+// - fill_n
+// - replace
+// - replace_if
+// - generate
+// - generate_n
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __for_each {
+ template <class _Policy, class _ForwardIterator, class _Function>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function&& __func) const noexcept =
+ delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __for_each_n {
+ template <class _Policy, class _ForwardIterator, class _Size, class _Function>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) const noexcept {
+ if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
+ _ForwardIterator __last = __first + __size;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), std::move(__func));
+ } 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{};
+ }
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __fill {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
+ using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __value; });
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __fill_n {
+ template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ 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 = __pstl::__fill<_Backend, _RawExecutionPolicy>;
+ _ForwardIterator __last = __first + __n;
+ return _Fill()(__policy, std::move(__first), std::move(__last), __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{}};
+ }
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __old, _Tp const& __new)
+ const noexcept {
+ using _ReplaceIf = __pstl::__replace_if<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ReplaceIf()(
+ __policy, std::move(__first), std::move(__last), [&](_Ref __element) { return __element == __old; }, __new);
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace_if {
+ template <class _Policy, class _ForwardIterator, class _Pred, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred, _Tp const& __new_value)
+ const noexcept {
+ using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) {
+ if (__pred(__element))
+ __element = __new_value;
+ });
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __generate {
+ template <class _Policy, class _ForwardIterator, class _Generator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator&& __gen) const noexcept {
+ using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __gen(); });
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __generate_n {
+ template <class _Policy, class _ForwardIterator, class _Size, class _Generator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Generator&& __gen) const noexcept {
+ using _ForEachN = __pstl::__for_each_n<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) { __element = __gen(); });
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FOR_EACH_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/merge_family.h b/libcxx/include/__pstl/defaults/merge_family.h
new file mode 100644
index 00000000000000..67e937d45bcc0f
--- /dev/null
+++ b/libcxx/include/__pstl/defaults/merge_family.h
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_MERGE_FAMILY_H
+#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_MERGE_FAMILY_H
+
+#include <__config>
+#include <__pstl/backend_fwd.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// This header defines the default implementation for the merge family of algorithms.
+// For now, there are no other algorithms in that family.
+template <class _Backend, class _RawExecutionPolicy>
+struct __merge {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardOutIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __out,
+ _Comp&& __comp) const noexcept = delete;
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_MERGE_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/stable_sort_family.h b/libcxx/include/__pstl/defaults/stable_sort_family.h
new file mode 100644
index 00000000000000..4f84a78b6435c1
--- /dev/null
+++ b/libcxx/include/__pstl/defaults/stable_sort_family.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_STABLE_SORT_FAMILY_H
+#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_STABLE_SORT_FAMILY_H
+
+#include <__config>
+#include <__pstl/backend_fwd.h>
+#include <__utility/empty.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// This header defines the default implementation for the stable_sort family of algorithms:
+// - sort
+template <class _Backend, class _RawExecutionPolicy>
+struct __stable_sort {
+ template <class _Policy, class _RandomAccessIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp)
+ const noexcept = delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __sort {
+ template <class _Policy, class _RandomAccessIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
+ _Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) const noexcept {
+ using _StableSort = __pstl::__stable_sort<_Backend, _RawExecutionPolicy>;
+ return _StableSort()(__policy, std::move(__first), std::move(__last), std::forward<_Comp>(__comp));
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_STABLE_SORT_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/transform_family.h b/libcxx/include/__pstl/defaults/transform_family.h
new file mode 100644
index 00000000000000..24d73fc2904f59
--- /dev/null
+++ b/libcxx/include/__pstl/defaults/transform_family.h
@@ -0,0 +1,176 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_FAMILY_H
+#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_FAMILY_H
+
+#include <__algorithm/copy_n.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__pstl/backend_fwd.h>
+#include <__utility/empty.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// This header defines the default implementation for the transform family of algorithms:
+// - replace_copy_if
+// - replace_copy
+// - move
+// - copy
+// - copy_n
+// - rotate_copy
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _UnaryOperation&& __op) const noexcept = delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform_binary {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _BinaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardOutIterator __out,
+ _BinaryOperation&& __op) const noexcept = delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace_copy_if {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Pred, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _Pred&& __pred,
+ _Tp const& __new_value) const noexcept {
+ using _Transform = __pstl::__transform<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ auto __res = _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), [&](_Ref __element) {
+ return __pred(__element) ? __new_value : __element;
+ });
+ if (__res == nullopt)
+ return nullopt;
+ return __empty{};
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __replace_copy {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _Tp const& __old_value,
+ _Tp const& __new_value) const noexcept {
+ using _ReplaceCopyIf = __pstl::__replace_copy_if<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ReplaceCopyIf()(
+ __policy,
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ [&](_Ref __element) { return __element == __old_value; },
+ __new_value);
+ }
+};
+
+// TODO: Use the std::copy/move shenanigans to forward to std::memmove
+// Investigate whether we want to still forward to std::transform(policy)
+// in that case for the execution::par part, or whether we actually want
+// to run everything serially in that case.
+template <class _Backend, class _RawExecutionPolicy>
+struct __move {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) const noexcept {
+ using _Transform = __pstl::__transform<_Backend, _RawExecutionPolicy>;
+ return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), [&](auto&& __element) {
+ return std::move(__element);
+ });
+ }
+};
+
+// TODO: Use the std::copy/move shenanigans to forward to std::memmove
+template <class _Backend, class _RawExecutionPolicy>
+struct __copy {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) const noexcept {
+ using _Transform = __pstl::__transform<_Backend, _RawExecutionPolicy>;
+ return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), __identity());
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __copy_n {
+ template <class _Policy, class _ForwardIterator, class _Size, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out) const noexcept {
+ if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ using _Copy = __pstl::__copy<_Backend, _RawExecutionPolicy>;
+ _ForwardIterator __last = __first + __n;
+ return _Copy()(__policy, std::move(__first), std::move(__last), std::move(__out));
+ } else {
+ // Otherwise, use the serial algorithm to avoid doing two passes over the input
+ return std::copy_n(std::move(__first), __n, std::move(__out));
+ }
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __rotate_copy {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __middle,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out) const noexcept {
+ using _Copy = __pstl::__copy<_Backend, _RawExecutionPolicy>;
+ auto __result_mid = _Copy()(__policy, __middle, std::move(__last), std::move(__out));
+ if (__result_mid == nullopt)
+ return nullopt;
+ return _Copy()(__policy, std::move(__first), std::move(__middle), *std::move(__result_mid));
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/transform_reduce_family.h b/libcxx/include/__pstl/defaults/transform_reduce_family.h
new file mode 100644
index 00000000000000..c3fc32c618f796
--- /dev/null
+++ b/libcxx/include/__pstl/defaults/transform_reduce_family.h
@@ -0,0 +1,175 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_REDUCE_FAMILY_H
+#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_REDUCE_FAMILY_H
+
+#include <__algorithm/equal.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__pstl/backend_fwd.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// This header defines the default implementation for the transform_reduce family of algorithms:
+// - count_if
+// - count
+// - equal(3 legs)
+// - equal
+// - reduce
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform_reduce {
+ template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_Tp>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _Tp const& __init,
+ _BinaryOperation&& __reduce,
+ _UnaryOperation&& __transform) const noexcept = delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __transform_reduce_binary {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation1,
+ class _BinaryOperation2>
+ _LIBCPP_HIDE_FROM_ABI optional<_Tp> operator()(
+ _Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _Tp const& __init,
+ _BinaryOperation1&& __reduce,
+ _BinaryOperation2&& __transform) const noexcept = delete;
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __count_if {
+ template <class _Policy, class _ForwardIterator, class _Predicate>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred) const noexcept {
+ using _TransformReduce = __pstl::__transform_reduce<_Backend, _RawExecutionPolicy>;
+ using _DiffT = __iter_diff_t<_ForwardIterator>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _TransformReduce()(
+ __policy, std::move(__first), std::move(__last), _DiffT{}, std::plus{}, [&](_Ref __element) -> _DiffT {
+ return __pred(__element) ? _DiffT(1) : _DiffT(0);
+ });
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __count {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
+ using _CountIf = __pstl::__count_if<_Backend, _RawExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _CountIf()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) -> bool {
+ return __element == __value;
+ });
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __equal_3leg {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _Predicate&& __pred) const noexcept {
+ using _TransformReduce = __pstl::__transform_reduce_binary<_Backend, _RawExecutionPolicy>;
+ return _TransformReduce()(
+ __policy,
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ true,
+ std::logical_and{},
+ std::forward<_Predicate>(__pred));
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __equal {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _Predicate&& __pred) const noexcept {
+ if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category<_ForwardIterator2>::value) {
+ if (__last1 - __first1 != __last2 - __first2)
+ return false;
+ // Fall back to the 3 legged algorithm
+ using _Equal3Leg = __pstl::__equal_3leg<_Backend, _RawExecutionPolicy>;
+ return _Equal3Leg()(
+ __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::forward<_Predicate>(__pred));
+ } else {
+ // If we don't have random access, fall back to the serial algorithm cause we can't do much
+ return std::equal(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::forward<_Predicate>(__pred));
+ }
+ }
+};
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __reduce {
+ template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_Tp>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation&& __op)
+ const noexcept {
+ using _TransformReduce = __pstl::__transform_reduce<_Backend, _RawExecutionPolicy>;
+ return _TransformReduce()(
+ __policy,
+ std::move(__first),
+ std::move(__last),
+ std::move(__init),
+ std::forward<_BinaryOperation>(__op),
+ __identity{});
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_REDUCE_FAMILY_H
diff --git a/libcxx/include/__pstl/run_backend.h b/libcxx/include/__pstl/run_backend.h
new file mode 100644
index 00000000000000..f5c5fca842886b
--- /dev/null
+++ b/libcxx/include/__pstl/run_backend.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_RUN_BACKEND_H
+#define _LIBCPP___PSTL_RUN_BACKEND_H
+
+#include <__config>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <new> // __throw_bad_alloc
+#include <optional>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _BackendFunction, class... _Args>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE auto __run_backend_impl(_Args&&... __args) noexcept {
+ return _BackendFunction{}(std::forward<_Args>(__args)...);
+}
+
+// This function is used to call a backend PSTL algorithm from a frontend algorithm.
+//
+// All PSTL backend algorithms return an optional denoting whether there was an
+// "infrastructure"-level failure (aka failure to allocate). This function takes
+// care of unwrapping that and throwing `bad_alloc()` in case there was a problem
+// in the underlying implementation.
+//
+// We must also be careful not to call any user code that could throw an exception
+// (such as moving or copying iterators) in here since that should terminate the
+// program, which is why we delegate to a noexcept helper below.
+template <class _BackendFunction, class... _Args>
+_LIBCPP_HIDE_FROM_ABI auto __run_backend(_Args&&... __args) {
+ auto __result = __pstl::__run_backend_impl<_BackendFunction>(std::forward<_Args>(__args)...);
+ if (__result == nullopt)
+ std::__throw_bad_alloc();
+ else
+ return std::move(*__result);
+}
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_RUN_BACKEND_H
diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 607f63e6d82206..486bdcb59656a8 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -73,27 +73,12 @@
{ include: [ "<__algorithm/pop_heap.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/prev_permutation.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_any_all_none_of.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backend.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backend.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/any_of.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/backend.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/fill.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/find_if.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/for_each.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/libdispatch.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/merge.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/serial.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/stable_sort.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/thread.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/transform.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_backends/cpu_backends/transform_reduce.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_copy.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_count.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_equal.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_fill.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_find.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_for_each.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_frontend_dispatch.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_generate.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_is_partitioned.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pstl_merge.h>", "private", "<algorithm>", "public" ] },
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index ed45a1b1833893..4222a69986460b 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -752,10 +752,6 @@ module std_private_algorithm_pstl_for_each [system
header "__algorithm/pstl_for_each.h"
export *
}
-module std_private_algorithm_pstl_frontend_dispatch [system] {
- header "__algorithm/pstl_frontend_dispatch.h"
- export std_private_utility_forward
-}
module std_private_algorithm_pstl_generate [system] { header "__algorithm/pstl_generate.h" }
module std_private_algorithm_pstl_is_partitioned [system] { header "__algorithm/pstl_is_partitioned.h" }
module std_private_algorithm_pstl_merge [system] { header "__algorithm/pstl_merge.h" }
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 16ccb80ba3326d..bae8cb690a43eb 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -326,7 +326,7 @@ set(LIBCXX_EXPERIMENTAL_SOURCES
experimental/keep.cpp
)
-if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "libdispatch")
+if (LIBCXX_PSTL_BACKEND STREQUAL "libdispatch")
list(APPEND LIBCXX_EXPERIMENTAL_SOURCES
pstl/libdispatch.cpp
)
diff --git a/libcxx/src/pstl/libdispatch.cpp b/libcxx/src/pstl/libdispatch.cpp
index 71d07fa88634a1..49a602772a96ac 100644
--- a/libcxx/src/pstl/libdispatch.cpp
+++ b/libcxx/src/pstl/libdispatch.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include <__algorithm/min.h>
-#include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
#include <__config>
+#include <__pstl/backends/libdispatch.h>
#include <dispatch/dispatch.h>
_LIBCPP_BEGIN_NAMESPACE_STD
>From a324ff9c984cc5f915356f76e64b2bb539d8ada9 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 12 Apr 2024 16:54:41 -0400
Subject: [PATCH 5/8] Allow chaining backends
---
libcxx/include/CMakeLists.txt | 30 +-
libcxx/include/__algorithm/pstl.h | 627 ++++++++++++++++++
.../__algorithm/pstl_any_all_none_of.h | 78 ---
libcxx/include/__algorithm/pstl_copy.h | 70 --
libcxx/include/__algorithm/pstl_count.h | 65 --
libcxx/include/__algorithm/pstl_equal.h | 117 ----
libcxx/include/__algorithm/pstl_fill.h | 66 --
libcxx/include/__algorithm/pstl_find.h | 75 ---
libcxx/include/__algorithm/pstl_for_each.h | 66 --
libcxx/include/__algorithm/pstl_generate.h | 66 --
.../include/__algorithm/pstl_is_partitioned.h | 52 --
libcxx/include/__algorithm/pstl_merge.h | 97 ---
libcxx/include/__algorithm/pstl_move.h | 54 --
libcxx/include/__algorithm/pstl_replace.h | 127 ----
libcxx/include/__algorithm/pstl_rotate_copy.h | 61 --
libcxx/include/__algorithm/pstl_sort.h | 63 --
libcxx/include/__algorithm/pstl_stable_sort.h | 63 --
libcxx/include/__algorithm/pstl_transform.h | 91 ---
.../{pstl_transform_reduce.h => pstl.h} | 63 +-
libcxx/include/__numeric/pstl_reduce.h | 87 ---
libcxx/include/__pstl/backend_fwd.h | 72 +-
libcxx/include/__pstl/backends/default.h | 505 ++++++++++++++
libcxx/include/__pstl/backends/libdispatch.h | 3 -
libcxx/include/__pstl/backends/serial.h | 13 +-
libcxx/include/__pstl/backends/std_thread.h | 9 +-
libcxx/include/__pstl/configuration.h | 23 +-
libcxx/include/__pstl/configuration_fwd.h | 41 ++
libcxx/include/__pstl/defaults.h | 20 -
.../include/__pstl/defaults/find_if_family.h | 134 ----
.../include/__pstl/defaults/for_each_family.h | 153 -----
libcxx/include/__pstl/defaults/merge_family.h | 50 --
.../__pstl/defaults/stable_sort_family.h | 58 --
.../__pstl/defaults/transform_family.h | 176 -----
.../__pstl/defaults/transform_reduce_family.h | 175 -----
libcxx/include/__pstl/dispatch.h | 51 ++
libcxx/include/algorithm | 17 +-
libcxx/include/libcxx.imp | 20 +-
libcxx/include/numeric | 3 +-
38 files changed, 1342 insertions(+), 2199 deletions(-)
create mode 100644 libcxx/include/__algorithm/pstl.h
delete mode 100644 libcxx/include/__algorithm/pstl_any_all_none_of.h
delete mode 100644 libcxx/include/__algorithm/pstl_copy.h
delete mode 100644 libcxx/include/__algorithm/pstl_count.h
delete mode 100644 libcxx/include/__algorithm/pstl_equal.h
delete mode 100644 libcxx/include/__algorithm/pstl_fill.h
delete mode 100644 libcxx/include/__algorithm/pstl_find.h
delete mode 100644 libcxx/include/__algorithm/pstl_for_each.h
delete mode 100644 libcxx/include/__algorithm/pstl_generate.h
delete mode 100644 libcxx/include/__algorithm/pstl_is_partitioned.h
delete mode 100644 libcxx/include/__algorithm/pstl_merge.h
delete mode 100644 libcxx/include/__algorithm/pstl_move.h
delete mode 100644 libcxx/include/__algorithm/pstl_replace.h
delete mode 100644 libcxx/include/__algorithm/pstl_rotate_copy.h
delete mode 100644 libcxx/include/__algorithm/pstl_sort.h
delete mode 100644 libcxx/include/__algorithm/pstl_stable_sort.h
delete mode 100644 libcxx/include/__algorithm/pstl_transform.h
rename libcxx/include/__numeric/{pstl_transform_reduce.h => pstl.h} (58%)
delete mode 100644 libcxx/include/__numeric/pstl_reduce.h
create mode 100644 libcxx/include/__pstl/backends/default.h
create mode 100644 libcxx/include/__pstl/configuration_fwd.h
delete mode 100644 libcxx/include/__pstl/defaults.h
delete mode 100644 libcxx/include/__pstl/defaults/find_if_family.h
delete mode 100644 libcxx/include/__pstl/defaults/for_each_family.h
delete mode 100644 libcxx/include/__pstl/defaults/merge_family.h
delete mode 100644 libcxx/include/__pstl/defaults/stable_sort_family.h
delete mode 100644 libcxx/include/__pstl/defaults/transform_family.h
delete mode 100644 libcxx/include/__pstl/defaults/transform_reduce_family.h
create mode 100644 libcxx/include/__pstl/dispatch.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 4208b07e6b33bb..b801ae8eaa0077 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -72,22 +72,7 @@ set(files
__algorithm/partition_point.h
__algorithm/pop_heap.h
__algorithm/prev_permutation.h
- __algorithm/pstl_any_all_none_of.h
- __algorithm/pstl_copy.h
- __algorithm/pstl_count.h
- __algorithm/pstl_equal.h
- __algorithm/pstl_fill.h
- __algorithm/pstl_find.h
- __algorithm/pstl_for_each.h
- __algorithm/pstl_generate.h
- __algorithm/pstl_is_partitioned.h
- __algorithm/pstl_merge.h
- __algorithm/pstl_move.h
- __algorithm/pstl_replace.h
- __algorithm/pstl_rotate_copy.h
- __algorithm/pstl_sort.h
- __algorithm/pstl_stable_sort.h
- __algorithm/pstl_transform.h
+ __algorithm/pstl.h
__algorithm/push_heap.h
__algorithm/ranges_adjacent_find.h
__algorithm/ranges_all_of.h
@@ -569,18 +554,19 @@ set(files
__numeric/iota.h
__numeric/midpoint.h
__numeric/partial_sum.h
- __numeric/pstl_reduce.h
- __numeric/pstl_transform_reduce.h
+ __numeric/pstl.h
__numeric/reduce.h
__numeric/saturation_arithmetic.h
__numeric/transform_exclusive_scan.h
__numeric/transform_inclusive_scan.h
__numeric/transform_reduce.h
__pstl/backend_fwd.h
+ __pstl/backends/default.h
__pstl/backends/libdispatch.h
__pstl/backends/serial.h
__pstl/backends/std_thread.h
__pstl/configuration.h
+ __pstl/configuration_fwd.h
__pstl/cpu_algos/any_of.h
__pstl/cpu_algos/cpu_traits.h
__pstl/cpu_algos/fill.h
@@ -590,13 +576,7 @@ set(files
__pstl/cpu_algos/stable_sort.h
__pstl/cpu_algos/transform_reduce.h
__pstl/cpu_algos/transform.h
- __pstl/defaults.h
- __pstl/defaults/find_if_family.h
- __pstl/defaults/for_each_family.h
- __pstl/defaults/merge_family.h
- __pstl/defaults/stable_sort_family.h
- __pstl/defaults/transform_family.h
- __pstl/defaults/transform_reduce_family.h
+ __pstl/dispatch.h
__pstl/run_backend.h
__random/bernoulli_distribution.h
__random/binomial_distribution.h
diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
new file mode 100644
index 00000000000000..c678b12258f105
--- /dev/null
+++ b/libcxx/include/__algorithm/pstl.h
@@ -0,0 +1,627 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_PSTL_H
+#define _LIBCPP___ALGORITHM_PSTL_H
+
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/configuration.h>
+#include <__pstl/dispatch.h>
+#include <__pstl/run_backend.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__any_of, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Pred,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__all_of, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Pred,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__none_of, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__dispatch<__pstl::__copy, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__out));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _Size,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__dispatch<__pstl::__copy_n, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__out));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
+count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__count_if, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+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 __iter_diff_t<_ForwardIterator>
+count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__count, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Pred,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI bool
+equal(_ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _Pred __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ using _Implementation = __pstl::__dispatch<__pstl::__equal_3leg, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI bool
+equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), equal_to{});
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Pred,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI bool
+equal(_ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _Pred __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ using _Implementation = __pstl::__dispatch<__pstl::__equal, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI bool
+equal(_ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ return std::equal(
+ __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), equal_to{});
+}
+
+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
+fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__fill, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_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
+fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__fill_n, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), __value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__find_if, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(__policy, std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator
+find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__find_if_not, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+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 _ForwardIterator
+find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__find, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Function,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__for_each, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__func));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Size,
+ class _Function,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__for_each_n, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__size), std::move(__func));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Generator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__generate, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__gen));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Size,
+ class _Generator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__generate_n, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__gen));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Predicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
+is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__is_partitioned, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _Comp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+merge(_ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __out,
+ _Comp __comp) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1));
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2));
+ using _Implementation = __pstl::__dispatch<__pstl::__merge, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__out),
+ std::move(__comp));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+merge(_ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1));
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2));
+ return std::merge(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__out),
+ less{});
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
+move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(std::move(*__first)));
+ using _Implementation = __pstl::__dispatch<__pstl::__move, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__out));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Pred,
+ class _Tp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+replace_if(_ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _Pred __pred,
+ const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__replace_if, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred), __new_value);
+}
+
+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
+replace(_ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ const _Tp& __old_value,
+ const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__replace, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __old_value, __new_value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _Pred,
+ class _Tp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _Pred __pred,
+ const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__dispatch<__pstl::__replace_copy_if, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ std::move(__pred),
+ __new_value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _Tp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void replace_copy(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ const _Tp& __old_value,
+ const _Tp& __new_value) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__dispatch<__pstl::__replace_copy, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ __old_value,
+ __new_value);
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __middle,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
+ using _Implementation = __pstl::__dispatch<__pstl::__rotate_copy, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__middle),
+ std::move(__last),
+ std::move(__out));
+}
+
+template <class _ExecutionPolicy,
+ class _RandomAccessIterator,
+ class _Comp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__sort, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
+}
+
+template <class _ExecutionPolicy,
+ class _RandomAccessIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
+}
+
+template <class _ExecutionPolicy,
+ class _RandomAccessIterator,
+ class _Comp,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__stable_sort, __pstl::__current_configuration, _RawPolicy>;
+ __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
+}
+
+template <class _ExecutionPolicy,
+ class _RandomAccessIterator,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI void
+stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
+ std::stable_sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _ForwardOutIterator,
+ class _UnaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _UnaryOperation __op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
+ using _Implementation = __pstl::__dispatch<__pstl::__transform, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ std::move(__op));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _ForwardOutIterator,
+ class _BinaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardOutIterator __out,
+ _BinaryOperation __op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+ _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
+ using _Implementation = __pstl::__dispatch<__pstl::__transform_binary, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__out),
+ std::move(__op));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_PSTL_H
diff --git a/libcxx/include/__algorithm/pstl_any_all_none_of.h b/libcxx/include/__algorithm/pstl_any_all_none_of.h
deleted file mode 100644
index ecc05c74db8c04..00000000000000
--- a/libcxx/include/__algorithm/pstl_any_all_none_of.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
-#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
-any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__any_of<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
-all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__all_of<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
-none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__none_of<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
diff --git a/libcxx/include/__algorithm/pstl_copy.h b/libcxx/include/__algorithm/pstl_copy.h
deleted file mode 100644
index de9cab902654c8..00000000000000
--- a/libcxx/include/__algorithm/pstl_copy.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H
-#define _LIBCPP___ALGORITHM_PSTL_COPY_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
- using _Implementation = __pstl::__copy<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__out));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _Size,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
- using _Implementation = __pstl::__copy_n<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__out));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_COPY_H
diff --git a/libcxx/include/__algorithm/pstl_count.h b/libcxx/include/__algorithm/pstl_count.h
deleted file mode 100644
index b5f018adbd57fc..00000000000000
--- a/libcxx/include/__algorithm/pstl_count.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_COUNT_H
-#define _LIBCPP___ALGORITHM_PSTL_COUNT_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
-count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__count_if<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
-}
-
-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 __iter_diff_t<_ForwardIterator>
-count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__count<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_COUNT_H
diff --git a/libcxx/include/__algorithm/pstl_equal.h b/libcxx/include/__algorithm/pstl_equal.h
deleted file mode 100644
index 88e3db0ac3960f..00000000000000
--- a/libcxx/include/__algorithm/pstl_equal.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_EQUAL_H
-#define _LIBCPP___ALGORITHM_PSTL_EQUAL_H
-
-#include <__config>
-#include <__functional/operations.h>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI bool
-equal(_ExecutionPolicy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _Pred __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- using _Implementation = __pstl::__equal_3leg<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__pred));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI bool
-equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- return std::equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), equal_to{});
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _Pred,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI bool
-equal(_ExecutionPolicy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _Pred __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- using _Implementation = __pstl::__equal<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- std::move(__pred));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI bool
-equal(_ExecutionPolicy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- return std::equal(
- __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), equal_to{});
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_EQUAL_H
diff --git a/libcxx/include/__algorithm/pstl_fill.h b/libcxx/include/__algorithm/pstl_fill.h
deleted file mode 100644
index eb4a6e7fe4696f..00000000000000
--- a/libcxx/include/__algorithm/pstl_fill.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H
-#define _LIBCPP___ALGORITHM_PSTL_FILL_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-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
-fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__fill<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_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
-fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__fill_n<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), __value);
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_FILL_H
diff --git a/libcxx/include/__algorithm/pstl_find.h b/libcxx/include/__algorithm/pstl_find.h
deleted file mode 100644
index f72d3244995480..00000000000000
--- a/libcxx/include/__algorithm/pstl_find.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H
-#define _LIBCPP___ALGORITHM_PSTL_FIND_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardIterator
-find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__find_if<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(__policy, std::move(__first), std::move(__last), std::move(__pred));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardIterator
-find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__find_if_not<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
-}
-
-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 _ForwardIterator
-find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__find<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_FIND_H
diff --git a/libcxx/include/__algorithm/pstl_for_each.h b/libcxx/include/__algorithm/pstl_for_each.h
deleted file mode 100644
index 29d856c4a5e6a9..00000000000000
--- a/libcxx/include/__algorithm/pstl_for_each.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
-#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Function,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__for_each<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__func));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Size,
- class _Function,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__for_each_n<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__size), std::move(__func));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
diff --git a/libcxx/include/__algorithm/pstl_generate.h b/libcxx/include/__algorithm/pstl_generate.h
deleted file mode 100644
index fbf1fc0bf22889..00000000000000
--- a/libcxx/include/__algorithm/pstl_generate.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_GENERATE_H
-#define _LIBCPP___ALGORITHM_PSTL_GENERATE_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Generator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__generate<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__gen));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Size,
- class _Generator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__generate_n<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__gen));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_GENERATE_H
diff --git a/libcxx/include/__algorithm/pstl_is_partitioned.h b/libcxx/include/__algorithm/pstl_is_partitioned.h
deleted file mode 100644
index 6360245c50e65d..00000000000000
--- a/libcxx/include/__algorithm/pstl_is_partitioned.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
-#define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Predicate,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
-is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__is_partitioned<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
diff --git a/libcxx/include/__algorithm/pstl_merge.h b/libcxx/include/__algorithm/pstl_merge.h
deleted file mode 100644
index 68747449f74bc0..00000000000000
--- a/libcxx/include/__algorithm/pstl_merge.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H
-#define _LIBCPP___ALGORITHM_PSTL_MERGE_H
-
-#include <__config>
-#include <__functional/operations.h>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _Comp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-merge(_ExecutionPolicy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __out,
- _Comp __comp) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1));
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2));
- using _Implementation = __pstl::__merge<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- std::move(__out),
- std::move(__comp));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-merge(_ExecutionPolicy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __out) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1));
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2));
- return std::merge(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- std::move(__out),
- less{});
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H
diff --git a/libcxx/include/__algorithm/pstl_move.h b/libcxx/include/__algorithm/pstl_move.h
deleted file mode 100644
index 998da5e15c100f..00000000000000
--- a/libcxx/include/__algorithm/pstl_move.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_MOVE_H
-#define _LIBCPP___ALGORITHM_PSTL_MOVE_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
-move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(std::move(*__first)));
- using _Implementation = __pstl::__move<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__out));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_MOVE_H
diff --git a/libcxx/include/__algorithm/pstl_replace.h b/libcxx/include/__algorithm/pstl_replace.h
deleted file mode 100644
index 7204301f3e5965..00000000000000
--- a/libcxx/include/__algorithm/pstl_replace.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H
-#define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Pred,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-replace_if(_ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _Pred __pred,
- const _Tp& __new_value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__replace_if<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred), __new_value);
-}
-
-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
-replace(_ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- const _Tp& __old_value,
- const _Tp& __new_value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__replace<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __old_value, __new_value);
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _Pred,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
- _ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __out,
- _Pred __pred,
- const _Tp& __new_value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
- using _Implementation = __pstl::__replace_copy_if<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first),
- std::move(__last),
- std::move(__out),
- std::move(__pred),
- __new_value);
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _Tp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void replace_copy(
- _ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __out,
- const _Tp& __old_value,
- const _Tp& __new_value) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
- using _Implementation = __pstl::__replace_copy<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first),
- std::move(__last),
- std::move(__out),
- __old_value,
- __new_value);
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H
diff --git a/libcxx/include/__algorithm/pstl_rotate_copy.h b/libcxx/include/__algorithm/pstl_rotate_copy.h
deleted file mode 100644
index 660684163667a3..00000000000000
--- a/libcxx/include/__algorithm/pstl_rotate_copy.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
-#define _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy(
- _ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __middle,
- _ForwardIterator __last,
- _ForwardOutIterator __out) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first));
- using _Implementation = __pstl::__rotate_copy<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first),
- std::move(__middle),
- std::move(__last),
- std::move(__out));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
diff --git a/libcxx/include/__algorithm/pstl_sort.h b/libcxx/include/__algorithm/pstl_sort.h
deleted file mode 100644
index 446daa1ae930e5..00000000000000
--- a/libcxx/include/__algorithm/pstl_sort.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_SORT_H
-#define _LIBCPP___ALGORITHM_PSTL_SORT_H
-
-#include <__config>
-#include <__functional/operations.h>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _RandomAccessIterator,
- class _Comp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
- using _Implementation = __pstl::__sort<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
-}
-
-template <class _ExecutionPolicy,
- class _RandomAccessIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
- std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_SORT_H
diff --git a/libcxx/include/__algorithm/pstl_stable_sort.h b/libcxx/include/__algorithm/pstl_stable_sort.h
deleted file mode 100644
index b761a80d106884..00000000000000
--- a/libcxx/include/__algorithm/pstl_stable_sort.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
-#define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
-
-#include <__config>
-#include <__functional/operations.h>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _RandomAccessIterator,
- class _Comp,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
- using _Implementation = __pstl::__stable_sort<__pstl::__configured_backend, _RawPolicy>;
- __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
-}
-
-template <class _ExecutionPolicy,
- class _RandomAccessIterator,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void
-stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
- _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator);
- std::stable_sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
diff --git a/libcxx/include/__algorithm/pstl_transform.h b/libcxx/include/__algorithm/pstl_transform.h
deleted file mode 100644
index ab4e0b1f9f29fb..00000000000000
--- a/libcxx/include/__algorithm/pstl_transform.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
-#define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
-
-#include <__config>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _ForwardOutIterator,
- class _UnaryOperation,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
- _ExecutionPolicy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __out,
- _UnaryOperation __op) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
- using _Implementation = __pstl::__transform<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first),
- std::move(__last),
- std::move(__out),
- std::move(__op));
-}
-
-template <class _ExecutionPolicy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _BinaryOperation,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
- _ExecutionPolicy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardOutIterator __out,
- _BinaryOperation __op) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
- _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
- using _Implementation = __pstl::__transform_binary<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__out),
- std::move(__op));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
diff --git a/libcxx/include/__numeric/pstl_transform_reduce.h b/libcxx/include/__numeric/pstl.h
similarity index 58%
rename from libcxx/include/__numeric/pstl_transform_reduce.h
rename to libcxx/include/__numeric/pstl.h
index 4c4044791fda0d..56bdb020073d55 100644
--- a/libcxx/include/__numeric/pstl_transform_reduce.h
+++ b/libcxx/include/__numeric/pstl.h
@@ -6,13 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
-#define _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
+#ifndef _LIBCPP___NUMERIC_PSTL_H
+#define _LIBCPP___NUMERIC_PSTL_H
#include <__config>
#include <__functional/operations.h>
#include <__iterator/cpp17_iterator_concepts.h>
+#include <__pstl/backend_fwd.h>
#include <__pstl/configuration.h>
+#include <__pstl/dispatch.h>
#include <__pstl/run_backend.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
@@ -31,6 +33,53 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _ExecutionPolicy,
+ class _ForwardIterator,
+ class _Tp,
+ class _BinaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _Tp reduce(
+ _ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__init),
+ std::move(__op));
+}
+
+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 _Tp
+reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__init), plus{});
+}
+
+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 __iter_value_type<_ForwardIterator>
+reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+ using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__run_backend<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ __iter_value_type<_ForwardIterator>(),
+ plus{});
+}
+
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
@@ -49,7 +98,8 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_BinaryOperation2 __transform) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- using _Implementation = __pstl::__transform_reduce_binary<__pstl::__configured_backend, _RawPolicy>;
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__transform_reduce_binary, __pstl::__current_configuration, _RawPolicy>;
return __pstl::__run_backend<_Implementation>(
std::forward<_ExecutionPolicy>(__policy),
std::move(__first1),
@@ -76,7 +126,8 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_Tp __init) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
- using _Implementation = __pstl::__transform_reduce_binary<__pstl::__configured_backend, _RawPolicy>;
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__transform_reduce_binary, __pstl::__current_configuration, _RawPolicy>;
return __pstl::__run_backend<_Implementation>(
std::forward<_ExecutionPolicy>(__policy),
std::move(__first1),
@@ -102,7 +153,7 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
_BinaryOperation __reduce,
_UnaryOperation __transform) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__transform_reduce<__pstl::__configured_backend, _RawPolicy>;
+ using _Implementation = __pstl::__dispatch<__pstl::__transform_reduce, __pstl::__current_configuration, _RawPolicy>;
return __pstl::__run_backend<_Implementation>(
std::forward<_ExecutionPolicy>(__policy),
std::move(__first),
@@ -118,4 +169,4 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H
+#endif // _LIBCPP___NUMERIC_PSTL_H
diff --git a/libcxx/include/__numeric/pstl_reduce.h b/libcxx/include/__numeric/pstl_reduce.h
deleted file mode 100644
index fd5f82690cf5f0..00000000000000
--- a/libcxx/include/__numeric/pstl_reduce.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___NUMERIC_PSTL_REDUCE_H
-#define _LIBCPP___NUMERIC_PSTL_REDUCE_H
-
-#include <__config>
-#include <__functional/operations.h>
-#include <__iterator/cpp17_iterator_concepts.h>
-#include <__pstl/configuration.h>
-#include <__pstl/run_backend.h>
-#include <__type_traits/enable_if.h>
-#include <__type_traits/is_execution_policy.h>
-#include <__type_traits/remove_cvref.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _ExecutionPolicy,
- class _ForwardIterator,
- class _Tp,
- class _BinaryOperation,
- class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
- enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Tp reduce(
- _ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __op) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__reduce<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first),
- std::move(__last),
- std::move(__init),
- std::move(__op));
-}
-
-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 _Tp
-reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__reduce<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__init), plus{});
-}
-
-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 __iter_value_type<_ForwardIterator>
-reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
- _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
- using _Implementation = __pstl::__reduce<__pstl::__configured_backend, _RawPolicy>;
- return __pstl::__run_backend<_Implementation>(
- std::forward<_ExecutionPolicy>(__policy),
- std::move(__first),
- std::move(__last),
- __iter_value_type<_ForwardIterator>(),
- plus{});
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___NUMERIC_PSTL_REDUCE_H
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index 8c2545ed49b478..8e236129c5dcb1 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -14,109 +14,103 @@
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __pstl {
-// find_if family
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __find_if;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __find;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __find_if_not;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __any_of;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __all_of;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __none_of;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __is_partitioned;
-// for_each family
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __for_each;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __for_each_n;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __fill;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __fill_n;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __replace;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __replace_if;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __generate;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __generate_n;
-// merge family
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __merge;
-// stable_sort family
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __stable_sort;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __sort;
-// transform family
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __transform;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __transform_binary;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __replace_copy_if;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __replace_copy;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __move;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __copy;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __copy_n;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __rotate_copy;
-// transform_reduce family
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __transform_reduce;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __transform_reduce_binary;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __count_if;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __count;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __equal_3leg;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __equal;
-template <class _Backend, class _RawExecutionPolicy>
+template <class _Backend, class _ExecutionPolicy>
struct __reduce;
} // namespace __pstl
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
new file mode 100644
index 00000000000000..9075afe5106876
--- /dev/null
+++ b/libcxx/include/__pstl/backends/default.h
@@ -0,0 +1,505 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_BACKENDS_DEFAULT_H
+#define _LIBCPP___PSTL_BACKENDS_DEFAULT_H
+
+#include <__algorithm/copy_n.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/fill_n.h>
+#include <__algorithm/for_each_n.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/not_fn.h>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/configuration_fwd.h>
+#include <__pstl/dispatch.h>
+#include <__utility/empty.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+//
+// This file provides an incomplete PSTL backend that implements all of the PSTL algorithms
+// based on a smaller set of basis operations.
+//
+// It is intended as a building block for other PSTL backends that implement some operations more
+// efficiently but may not want to define the full set of PSTL algorithms.
+//
+// This backend implements all the PSTL algorithms based on the following basis operations:
+//
+// find_if family
+// --------------
+// - find
+// - find_if_not
+// - any_of
+// - all_of
+// - none_of
+// - is_partitioned
+//
+// for_each family
+// ---------------
+// - for_each_n
+// - fill
+// - fill_n
+// - replace
+// - replace_if
+// - generate
+// - generate_n
+//
+// merge family
+// ------------
+// No other algorithms based on merge
+//
+// stable_sort family
+// ------------------
+// - sort
+//
+// transform_reduce and transform_reduce_binary family
+// ---------------------------------------------------
+// - count_if
+// - count
+// - equal(3 legs)
+// - equal
+// - reduce
+//
+// transform and transform_binary family
+// -------------------------------------
+// - replace_copy_if
+// - replace_copy
+// - move
+// - copy
+// - copy_n
+// - rotate_copy
+//
+
+//////////////////////////////////////////////////////////////
+// find_if family
+//////////////////////////////////////////////////////////////
+template <class _ExecutionPolicy>
+struct __find<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
+ using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
+ return _FindIf()(
+ __policy, std::move(__first), std::move(__last), [&](__iter_reference<_ForwardIterator> __element) {
+ return __element == __value;
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __find_if_not<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
+ return _FindIf()(__policy, __first, __last, std::not_fn(__pred));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __any_of<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
+ auto __res = _FindIf()(__policy, __first, __last, __pred);
+ if (!__res)
+ return nullopt;
+ return *__res != __last;
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __all_of<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _AnyOf = __dispatch<__any_of, __current_configuration, _ExecutionPolicy>;
+ auto __res = _AnyOf()(__policy, __first, __last, [&](__iter_reference<_ForwardIterator> __value) {
+ return !__pred(__value);
+ });
+ if (!__res)
+ return nullopt;
+ return !*__res;
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __none_of<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _AnyOf = __dispatch<__any_of, __current_configuration, _ExecutionPolicy>;
+ auto __res = _AnyOf()(__policy, __first, __last, __pred);
+ if (!__res)
+ return nullopt;
+ return !*__res;
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __is_partitioned<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
+ using _FindIfNot = __dispatch<__find_if_not, __current_configuration, _ExecutionPolicy>;
+ auto __maybe_first = _FindIfNot()(__policy, std::move(__first), std::move(__last), __pred);
+ if (__maybe_first == nullopt)
+ return nullopt;
+
+ __first = *__maybe_first;
+ if (__first == __last)
+ return true;
+ ++__first;
+ using _NoneOf = __dispatch<__none_of, __current_configuration, _ExecutionPolicy>;
+ return _NoneOf()(__policy, std::move(__first), std::move(__last), __pred);
+ }
+};
+
+//////////////////////////////////////////////////////////////
+// for_each family
+//////////////////////////////////////////////////////////////
+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>
+ 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));
+ } 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{};
+ }
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __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, _Tp const& __value) const noexcept {
+ using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __value; });
+ }
+};
+
+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>
+ 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);
+ } 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{}};
+ }
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __replace<__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, _Tp const& __old, _Tp const& __new)
+ const noexcept {
+ using _ReplaceIf = __dispatch<__replace_if, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ReplaceIf()(
+ __policy, std::move(__first), std::move(__last), [&](_Ref __element) { return __element == __old; }, __new);
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __replace_if<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Pred, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred, _Tp const& __new_value)
+ const noexcept {
+ using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) {
+ if (__pred(__element))
+ __element = __new_value;
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __generate<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Generator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator&& __gen) const noexcept {
+ using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __gen(); });
+ }
+};
+
+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>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Generator&& __gen) const noexcept {
+ using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) { __element = __gen(); });
+ }
+};
+
+//////////////////////////////////////////////////////////////
+// stable_sort family
+//////////////////////////////////////////////////////////////
+template <class _ExecutionPolicy>
+struct __sort<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _RandomAccessIterator, class _Comp>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
+ _Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) const noexcept {
+ using _StableSort = __dispatch<__stable_sort, __current_configuration, _ExecutionPolicy>;
+ return _StableSort()(__policy, std::move(__first), std::move(__last), std::forward<_Comp>(__comp));
+ }
+};
+
+//////////////////////////////////////////////////////////////
+// transform_reduce family
+//////////////////////////////////////////////////////////////
+template <class _ExecutionPolicy>
+struct __count_if<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Predicate>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred) const noexcept {
+ using _TransformReduce = __dispatch<__transform_reduce, __current_configuration, _ExecutionPolicy>;
+ using _DiffT = __iter_diff_t<_ForwardIterator>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _TransformReduce()(
+ __policy, std::move(__first), std::move(__last), _DiffT{}, std::plus{}, [&](_Ref __element) -> _DiffT {
+ return __pred(__element) ? _DiffT(1) : _DiffT(0);
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __count<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
+ using _CountIf = __dispatch<__count_if, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _CountIf()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) -> bool {
+ return __element == __value;
+ });
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __equal_3leg<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _Predicate&& __pred) const noexcept {
+ using _TransformReduce = __dispatch<__transform_reduce_binary, __current_configuration, _ExecutionPolicy>;
+ return _TransformReduce()(
+ __policy,
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ true,
+ std::logical_and{},
+ std::forward<_Predicate>(__pred));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __equal<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _Predicate&& __pred) const noexcept {
+ if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value &&
+ __has_random_access_iterator_category<_ForwardIterator2>::value) {
+ if (__last1 - __first1 != __last2 - __first2)
+ return false;
+ // Fall back to the 3 legged algorithm
+ using _Equal3Leg = __dispatch<__equal_3leg, __current_configuration, _ExecutionPolicy>;
+ return _Equal3Leg()(
+ __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::forward<_Predicate>(__pred));
+ } else {
+ // If we don't have random access, fall back to the serial algorithm cause we can't do much
+ return std::equal(
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::forward<_Predicate>(__pred));
+ }
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __reduce<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_Tp>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation&& __op)
+ const noexcept {
+ using _TransformReduce = __dispatch<__transform_reduce, __current_configuration, _ExecutionPolicy>;
+ return _TransformReduce()(
+ __policy,
+ std::move(__first),
+ std::move(__last),
+ std::move(__init),
+ std::forward<_BinaryOperation>(__op),
+ __identity{});
+ }
+};
+
+//////////////////////////////////////////////////////////////
+// transform family
+//////////////////////////////////////////////////////////////
+template <class _ExecutionPolicy>
+struct __replace_copy_if<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Pred, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _Pred&& __pred,
+ _Tp const& __new_value) const noexcept {
+ using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ auto __res = _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), [&](_Ref __element) {
+ return __pred(__element) ? __new_value : __element;
+ });
+ if (__res == nullopt)
+ return nullopt;
+ return __empty{};
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __replace_copy<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out,
+ _Tp const& __old_value,
+ _Tp const& __new_value) const noexcept {
+ using _ReplaceCopyIf = __dispatch<__replace_copy_if, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iter_reference<_ForwardIterator>;
+ return _ReplaceCopyIf()(
+ __policy,
+ std::move(__first),
+ std::move(__last),
+ std::move(__out),
+ [&](_Ref __element) { return __element == __old_value; },
+ __new_value);
+ }
+};
+
+// TODO: Use the std::copy/move shenanigans to forward to std::memmove
+// Investigate whether we want to still forward to std::transform(policy)
+// in that case for the execution::par part, or whether we actually want
+// to run everything serially in that case.
+template <class _ExecutionPolicy>
+struct __move<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) const noexcept {
+ using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
+ return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), [&](auto&& __element) {
+ return std::move(__element);
+ });
+ }
+};
+
+// TODO: Use the std::copy/move shenanigans to forward to std::memmove
+template <class _ExecutionPolicy>
+struct __copy<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
+ _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) const noexcept {
+ using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
+ return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), __identity());
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __copy_n<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _Size, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out) const noexcept {
+ if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ using _Copy = __dispatch<__copy, __current_configuration, _ExecutionPolicy>;
+ _ForwardIterator __last = __first + __n;
+ return _Copy()(__policy, std::move(__first), std::move(__last), std::move(__out));
+ } else {
+ // Otherwise, use the serial algorithm to avoid doing two passes over the input
+ return std::copy_n(std::move(__first), __n, std::move(__out));
+ }
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __rotate_copy<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+ operator()(_Policy&& __policy,
+ _ForwardIterator __first,
+ _ForwardIterator __middle,
+ _ForwardIterator __last,
+ _ForwardOutIterator __out) const noexcept {
+ using _Copy = __dispatch<__copy, __current_configuration, _ExecutionPolicy>;
+ auto __result_mid = _Copy()(__policy, __middle, std::move(__last), std::move(__out));
+ if (__result_mid == nullopt)
+ return nullopt;
+ return _Copy()(__policy, std::move(__first), std::move(__middle), *std::move(__result_mid));
+ }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___PSTL_BACKENDS_DEFAULT_H
diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index e723e39c802c23..2e2d55e3f962af 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -33,7 +33,6 @@
#include <__pstl/cpu_algos/stable_sort.h>
#include <__pstl/cpu_algos/transform.h>
#include <__pstl/cpu_algos/transform_reduce.h>
-#include <__pstl/defaults.h>
#include <__utility/empty.h>
#include <__utility/exception_guard.h>
#include <__utility/move.h>
@@ -45,8 +44,6 @@
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __pstl {
-struct __libdispatch_backend_tag {};
-
// ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do
// we.
// TODO: Do we want to add [[_Clang::__callback__(__func, __context, __)]]?
diff --git a/libcxx/include/__pstl/backends/serial.h b/libcxx/include/__pstl/backends/serial.h
index 2d67bc381783b5..eea4a7c8e02a64 100644
--- a/libcxx/include/__pstl/backends/serial.h
+++ b/libcxx/include/__pstl/backends/serial.h
@@ -17,7 +17,6 @@
#include <__config>
#include <__numeric/transform_reduce.h>
#include <__pstl/backend_fwd.h>
-#include <__pstl/defaults.h>
#include <__utility/empty.h>
#include <__utility/forward.h>
#include <__utility/move.h>
@@ -25,9 +24,17 @@
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __pstl {
-struct __serial_backend_tag {};
+//
+// This partial PSTL backend runs everything serially.
+//
+// TODO: Right now, the serial backend must be used with another backend
+// like the "default backend" because it doesn't implement all the
+// necessary PSTL operations. It would be better to dispatch all
+// algorithms to their serial counterpart directly, since this can
+// often be more efficient than the "default backend"'s implementation
+// if we end up running serially anyways.
+//
-// Mandatory implementations of the computational basis
template <class _ExecutionPolicy>
struct __find_if<__serial_backend_tag, _ExecutionPolicy> {
template <class _Policy, class _ForwardIterator, class _Pred>
diff --git a/libcxx/include/__pstl/backends/std_thread.h b/libcxx/include/__pstl/backends/std_thread.h
index 0795f0555277e5..1a273e0826f6c4 100644
--- a/libcxx/include/__pstl/backends/std_thread.h
+++ b/libcxx/include/__pstl/backends/std_thread.h
@@ -20,15 +20,16 @@
#include <__pstl/cpu_algos/stable_sort.h>
#include <__pstl/cpu_algos/transform.h>
#include <__pstl/cpu_algos/transform_reduce.h>
-#include <__pstl/defaults.h>
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __pstl {
-// This backend implementation is for testing purposes only and not meant for production use. This will be replaced
+//
+// This partial backend implementation is for testing purposes only and not meant for production use. This will be replaced
// by a proper implementation once the PSTL implementation is somewhat stable.
-
-struct __std_thread_backend_tag {};
+//
+// This is intended to be used on top of the "default backend".
+//
template <>
struct __cpu_traits<__std_thread_backend_tag> {
diff --git a/libcxx/include/__pstl/configuration.h b/libcxx/include/__pstl/configuration.h
index 89a45d6a111cd5..9884212f6765bc 100644
--- a/libcxx/include/__pstl/configuration.h
+++ b/libcxx/include/__pstl/configuration.h
@@ -10,32 +10,17 @@
#define _LIBCPP___PSTL_CONFIGURATION_H
#include <__config>
+#include <__pstl/configuration_fwd.h>
#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
+# include <__pstl/backends/default.h>
# include <__pstl/backends/serial.h>
#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
+# include <__pstl/backends/default.h>
# include <__pstl/backends/std_thread.h>
#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+# include <__pstl/backends/default.h>
# include <__pstl/backends/libdispatch.h>
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
-using __configured_backend = __serial_backend_tag;
-#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
-using __configured_backend = __std_thread_backend_tag;
-#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
-using __configured_backend = __libdispatch_backend_tag;
-#else
-
-// ...New vendors can add parallel backends here...
-
-# error "Invalid choice of a PSTL parallel backend"
-#endif
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
#endif // _LIBCPP___PSTL_CONFIGURATION_H
diff --git a/libcxx/include/__pstl/configuration_fwd.h b/libcxx/include/__pstl/configuration_fwd.h
new file mode 100644
index 00000000000000..2e56e3258c6a27
--- /dev/null
+++ b/libcxx/include/__pstl/configuration_fwd.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CONFIGURATION_FWD_H
+#define _LIBCPP___PSTL_CONFIGURATION_FWD_H
+
+#include <__config>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class... _Backends>
+struct __backend_configuration;
+
+struct __default_backend_tag;
+struct __libdispatch_backend_tag;
+struct __serial_backend_tag;
+struct __std_thread_backend_tag;
+
+#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
+using __current_configuration = __backend_configuration<__serial_backend_tag, __default_backend_tag>;
+#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
+using __current_configuration = __backend_configuration<__std_thread_backend_tag, __default_backend_tag>;
+#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+using __current_configuration = __backend_configuration<__libdispatch_backend_tag, __default_backend_tag>;
+#else
+
+// ...New vendors can add parallel backends here...
+
+# error "Invalid PSTL backend configuration"
+#endif
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_CONFIGURATION_FWD_H
diff --git a/libcxx/include/__pstl/defaults.h b/libcxx/include/__pstl/defaults.h
deleted file mode 100644
index 27b2c7b5e88e08..00000000000000
--- a/libcxx/include/__pstl/defaults.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___PSTL_DEFAULTS_H
-#define _LIBCPP___PSTL_DEFAULTS_H
-
-#include <__config>
-#include <__pstl/defaults/find_if_family.h>
-#include <__pstl/defaults/for_each_family.h>
-#include <__pstl/defaults/merge_family.h>
-#include <__pstl/defaults/stable_sort_family.h>
-#include <__pstl/defaults/transform_family.h>
-#include <__pstl/defaults/transform_reduce_family.h>
-
-#endif // _LIBCPP___PSTL_DEFAULTS_H
diff --git a/libcxx/include/__pstl/defaults/find_if_family.h b/libcxx/include/__pstl/defaults/find_if_family.h
deleted file mode 100644
index 4f7b2df8beac51..00000000000000
--- a/libcxx/include/__pstl/defaults/find_if_family.h
+++ /dev/null
@@ -1,134 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FIND_IF_FAMILY_H
-#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FIND_IF_FAMILY_H
-
-#include <__config>
-#include <__functional/not_fn.h>
-#include <__pstl/backend_fwd.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-// This header defines the default implementation for the find_if family of algorithms:
-// - find
-// - find_if_not
-// - any_of
-// - all_of
-// - none_of
-// - is_partitioned
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __find_if {
- template <class _Policy, class _ForwardIterator, class _Pred>
- _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator> operator()(
- _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept = delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __find {
- template <class _Policy, class _ForwardIterator, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
- using _FindIf = __pstl::__find_if<_Backend, _RawExecutionPolicy>;
- return _FindIf()(
- __policy, std::move(__first), std::move(__last), [&](__iter_reference<_ForwardIterator> __element) {
- return __element == __value;
- });
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __find_if_not {
- template <class _Policy, class _ForwardIterator, class _Pred>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
- using _FindIf = __pstl::__find_if<_Backend, _RawExecutionPolicy>;
- return _FindIf()(__policy, __first, __last, std::not_fn(__pred));
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __any_of {
- template <class _Policy, class _ForwardIterator, class _Pred>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
- using _FindIf = __pstl::__find_if<_Backend, _RawExecutionPolicy>;
- auto __res = _FindIf()(__policy, __first, __last, __pred);
- if (!__res)
- return nullopt;
- return *__res != __last;
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __all_of {
- template <class _Policy, class _ForwardIterator, class _Pred>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
- using _AnyOf = __pstl::__any_of<_Backend, _RawExecutionPolicy>;
- auto __res = _AnyOf()(__policy, __first, __last, [&](__iter_reference<_ForwardIterator> __value) {
- return !__pred(__value);
- });
- if (!__res)
- return nullopt;
- return !*__res;
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __none_of {
- template <class _Policy, class _ForwardIterator, class _Pred>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
- using _AnyOf = __pstl::__any_of<_Backend, _RawExecutionPolicy>;
- auto __res = _AnyOf()(__policy, __first, __last, __pred);
- if (!__res)
- return nullopt;
- return !*__res;
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __is_partitioned {
- template <class _Policy, class _ForwardIterator, class _Pred>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
- using _FindIfNot = __pstl::__find_if_not<_Backend, _RawExecutionPolicy>;
- auto __maybe_first = _FindIfNot()(__policy, std::move(__first), std::move(__last), __pred);
- if (__maybe_first == nullopt)
- return nullopt;
-
- __first = *__maybe_first;
- if (__first == __last)
- return true;
- ++__first;
- using _NoneOf = __pstl::__none_of<_Backend, _RawExecutionPolicy>;
- return _NoneOf()(__policy, std::move(__first), std::move(__last), __pred);
- }
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FIND_IF_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/for_each_family.h b/libcxx/include/__pstl/defaults/for_each_family.h
deleted file mode 100644
index 227709e8458a1a..00000000000000
--- a/libcxx/include/__pstl/defaults/for_each_family.h
+++ /dev/null
@@ -1,153 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FOR_EACH_FAMILY_H
-#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FOR_EACH_FAMILY_H
-
-#include <__algorithm/fill_n.h>
-#include <__algorithm/for_each_n.h>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__iterator/iterator_traits.h>
-#include <__pstl/backend_fwd.h>
-#include <__utility/empty.h>
-#include <__utility/move.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-// This header defines the default implementation for the for_each family of algorithms:
-// - for_each_n
-// - fill
-// - fill_n
-// - replace
-// - replace_if
-// - generate
-// - generate_n
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __for_each {
- template <class _Policy, class _ForwardIterator, class _Function>
- _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function&& __func) const noexcept =
- delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __for_each_n {
- template <class _Policy, class _ForwardIterator, class _Size, class _Function>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) const noexcept {
- if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
- _ForwardIterator __last = __first + __size;
- return _ForEach()(__policy, std::move(__first), std::move(__last), std::move(__func));
- } 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{};
- }
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __fill {
- template <class _Policy, class _ForwardIterator, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
- using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __value; });
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __fill_n {
- template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- 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 = __pstl::__fill<_Backend, _RawExecutionPolicy>;
- _ForwardIterator __last = __first + __n;
- return _Fill()(__policy, std::move(__first), std::move(__last), __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{}};
- }
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __replace {
- template <class _Policy, class _ForwardIterator, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __old, _Tp const& __new)
- const noexcept {
- using _ReplaceIf = __pstl::__replace_if<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _ReplaceIf()(
- __policy, std::move(__first), std::move(__last), [&](_Ref __element) { return __element == __old; }, __new);
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __replace_if {
- template <class _Policy, class _ForwardIterator, class _Pred, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
- _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred, _Tp const& __new_value)
- const noexcept {
- using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) {
- if (__pred(__element))
- __element = __new_value;
- });
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __generate {
- template <class _Policy, class _ForwardIterator, class _Generator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator&& __gen) const noexcept {
- using _ForEach = __pstl::__for_each<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __gen(); });
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __generate_n {
- template <class _Policy, class _ForwardIterator, class _Size, class _Generator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Generator&& __gen) const noexcept {
- using _ForEachN = __pstl::__for_each_n<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) { __element = __gen(); });
- }
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_FOR_EACH_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/merge_family.h b/libcxx/include/__pstl/defaults/merge_family.h
deleted file mode 100644
index 67e937d45bcc0f..00000000000000
--- a/libcxx/include/__pstl/defaults/merge_family.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_MERGE_FAMILY_H
-#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_MERGE_FAMILY_H
-
-#include <__config>
-#include <__pstl/backend_fwd.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-// This header defines the default implementation for the merge family of algorithms.
-// For now, there are no other algorithms in that family.
-template <class _Backend, class _RawExecutionPolicy>
-struct __merge {
- template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardOutIterator, class _Comp>
- _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
- _Policy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _ForwardOutIterator __out,
- _Comp&& __comp) const noexcept = delete;
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_MERGE_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/stable_sort_family.h b/libcxx/include/__pstl/defaults/stable_sort_family.h
deleted file mode 100644
index 4f84a78b6435c1..00000000000000
--- a/libcxx/include/__pstl/defaults/stable_sort_family.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_STABLE_SORT_FAMILY_H
-#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_STABLE_SORT_FAMILY_H
-
-#include <__config>
-#include <__pstl/backend_fwd.h>
-#include <__utility/empty.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-// This header defines the default implementation for the stable_sort family of algorithms:
-// - sort
-template <class _Backend, class _RawExecutionPolicy>
-struct __stable_sort {
- template <class _Policy, class _RandomAccessIterator, class _Comp>
- _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp)
- const noexcept = delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __sort {
- template <class _Policy, class _RandomAccessIterator, class _Comp>
- _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
- _Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) const noexcept {
- using _StableSort = __pstl::__stable_sort<_Backend, _RawExecutionPolicy>;
- return _StableSort()(__policy, std::move(__first), std::move(__last), std::forward<_Comp>(__comp));
- }
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_STABLE_SORT_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/transform_family.h b/libcxx/include/__pstl/defaults/transform_family.h
deleted file mode 100644
index 24d73fc2904f59..00000000000000
--- a/libcxx/include/__pstl/defaults/transform_family.h
+++ /dev/null
@@ -1,176 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_FAMILY_H
-#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_FAMILY_H
-
-#include <__algorithm/copy_n.h>
-#include <__config>
-#include <__functional/identity.h>
-#include <__pstl/backend_fwd.h>
-#include <__utility/empty.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-// This header defines the default implementation for the transform family of algorithms:
-// - replace_copy_if
-// - replace_copy
-// - move
-// - copy
-// - copy_n
-// - rotate_copy
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __transform {
- template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
- _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
- operator()(_Policy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __out,
- _UnaryOperation&& __op) const noexcept = delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __transform_binary {
- template <class _Policy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _ForwardOutIterator,
- class _BinaryOperation>
- _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
- operator()(_Policy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardOutIterator __out,
- _BinaryOperation&& __op) const noexcept = delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __replace_copy_if {
- template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Pred, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __out,
- _Pred&& __pred,
- _Tp const& __new_value) const noexcept {
- using _Transform = __pstl::__transform<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- auto __res = _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), [&](_Ref __element) {
- return __pred(__element) ? __new_value : __element;
- });
- if (__res == nullopt)
- return nullopt;
- return __empty{};
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __replace_copy {
- template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
- operator()(_Policy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _ForwardOutIterator __out,
- _Tp const& __old_value,
- _Tp const& __new_value) const noexcept {
- using _ReplaceCopyIf = __pstl::__replace_copy_if<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _ReplaceCopyIf()(
- __policy,
- std::move(__first),
- std::move(__last),
- std::move(__out),
- [&](_Ref __element) { return __element == __old_value; },
- __new_value);
- }
-};
-
-// TODO: Use the std::copy/move shenanigans to forward to std::memmove
-// Investigate whether we want to still forward to std::transform(policy)
-// in that case for the execution::par part, or whether we actually want
-// to run everything serially in that case.
-template <class _Backend, class _RawExecutionPolicy>
-struct __move {
- template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
- _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) const noexcept {
- using _Transform = __pstl::__transform<_Backend, _RawExecutionPolicy>;
- return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), [&](auto&& __element) {
- return std::move(__element);
- });
- }
-};
-
-// TODO: Use the std::copy/move shenanigans to forward to std::memmove
-template <class _Backend, class _RawExecutionPolicy>
-struct __copy {
- template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> operator()(
- _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out) const noexcept {
- using _Transform = __pstl::__transform<_Backend, _RawExecutionPolicy>;
- return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out), __identity());
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __copy_n {
- template <class _Policy, class _ForwardIterator, class _Size, class _ForwardOutIterator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
- operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out) const noexcept {
- if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
- using _Copy = __pstl::__copy<_Backend, _RawExecutionPolicy>;
- _ForwardIterator __last = __first + __n;
- return _Copy()(__policy, std::move(__first), std::move(__last), std::move(__out));
- } else {
- // Otherwise, use the serial algorithm to avoid doing two passes over the input
- return std::copy_n(std::move(__first), __n, std::move(__out));
- }
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __rotate_copy {
- template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
- operator()(_Policy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __middle,
- _ForwardIterator __last,
- _ForwardOutIterator __out) const noexcept {
- using _Copy = __pstl::__copy<_Backend, _RawExecutionPolicy>;
- auto __result_mid = _Copy()(__policy, __middle, std::move(__last), std::move(__out));
- if (__result_mid == nullopt)
- return nullopt;
- return _Copy()(__policy, std::move(__first), std::move(__middle), *std::move(__result_mid));
- }
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_FAMILY_H
diff --git a/libcxx/include/__pstl/defaults/transform_reduce_family.h b/libcxx/include/__pstl/defaults/transform_reduce_family.h
deleted file mode 100644
index c3fc32c618f796..00000000000000
--- a/libcxx/include/__pstl/defaults/transform_reduce_family.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_REDUCE_FAMILY_H
-#define _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_REDUCE_FAMILY_H
-
-#include <__algorithm/equal.h>
-#include <__config>
-#include <__functional/identity.h>
-#include <__functional/operations.h>
-#include <__iterator/concepts.h>
-#include <__iterator/iterator_traits.h>
-#include <__pstl/backend_fwd.h>
-#include <__utility/forward.h>
-#include <__utility/move.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace __pstl {
-
-// This header defines the default implementation for the transform_reduce family of algorithms:
-// - count_if
-// - count
-// - equal(3 legs)
-// - equal
-// - reduce
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __transform_reduce {
- template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
- _LIBCPP_HIDE_FROM_ABI optional<_Tp>
- operator()(_Policy&& __policy,
- _ForwardIterator __first,
- _ForwardIterator __last,
- _Tp const& __init,
- _BinaryOperation&& __reduce,
- _UnaryOperation&& __transform) const noexcept = delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __transform_reduce_binary {
- template <class _Policy,
- class _ForwardIterator1,
- class _ForwardIterator2,
- class _Tp,
- class _BinaryOperation1,
- class _BinaryOperation2>
- _LIBCPP_HIDE_FROM_ABI optional<_Tp> operator()(
- _Policy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _Tp const& __init,
- _BinaryOperation1&& __reduce,
- _BinaryOperation2&& __transform) const noexcept = delete;
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __count_if {
- template <class _Policy, class _ForwardIterator, class _Predicate>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> operator()(
- _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred) const noexcept {
- using _TransformReduce = __pstl::__transform_reduce<_Backend, _RawExecutionPolicy>;
- using _DiffT = __iter_diff_t<_ForwardIterator>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _TransformReduce()(
- __policy, std::move(__first), std::move(__last), _DiffT{}, std::plus{}, [&](_Ref __element) -> _DiffT {
- return __pred(__element) ? _DiffT(1) : _DiffT(0);
- });
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __count {
- template <class _Policy, class _ForwardIterator, class _Tp>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
- using _CountIf = __pstl::__count_if<_Backend, _RawExecutionPolicy>;
- using _Ref = __iter_reference<_ForwardIterator>;
- return _CountIf()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) -> bool {
- return __element == __value;
- });
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __equal_3leg {
- template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
- operator()(_Policy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _Predicate&& __pred) const noexcept {
- using _TransformReduce = __pstl::__transform_reduce_binary<_Backend, _RawExecutionPolicy>;
- return _TransformReduce()(
- __policy,
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- true,
- std::logical_and{},
- std::forward<_Predicate>(__pred));
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __equal {
- template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
- operator()(_Policy&& __policy,
- _ForwardIterator1 __first1,
- _ForwardIterator1 __last1,
- _ForwardIterator2 __first2,
- _ForwardIterator2 __last2,
- _Predicate&& __pred) const noexcept {
- if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value &&
- __has_random_access_iterator_category<_ForwardIterator2>::value) {
- if (__last1 - __first1 != __last2 - __first2)
- return false;
- // Fall back to the 3 legged algorithm
- using _Equal3Leg = __pstl::__equal_3leg<_Backend, _RawExecutionPolicy>;
- return _Equal3Leg()(
- __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::forward<_Predicate>(__pred));
- } else {
- // If we don't have random access, fall back to the serial algorithm cause we can't do much
- return std::equal(
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- std::forward<_Predicate>(__pred));
- }
- }
-};
-
-template <class _Backend, class _RawExecutionPolicy>
-struct __reduce {
- template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation>
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_Tp>
- operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation&& __op)
- const noexcept {
- using _TransformReduce = __pstl::__transform_reduce<_Backend, _RawExecutionPolicy>;
- return _TransformReduce()(
- __policy,
- std::move(__first),
- std::move(__last),
- std::move(__init),
- std::forward<_BinaryOperation>(__op),
- __identity{});
- }
-};
-
-} // namespace __pstl
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___ALGORITHM_PSTL_DEFAULTS_TRANSFORM_REDUCE_FAMILY_H
diff --git a/libcxx/include/__pstl/dispatch.h b/libcxx/include/__pstl/dispatch.h
new file mode 100644
index 00000000000000..bda3db48397470
--- /dev/null
+++ b/libcxx/include/__pstl/dispatch.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_DISPATCH_H
+#define _LIBCPP___PSTL_DISPATCH_H
+
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
+#include <__type_traits/type_identity.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <template <class, class> class _Algorithm, class _Backend, class _ExecutionPolicy, class = void>
+struct __is_implemented : false_type {};
+
+template <template <class, class> class _Algorithm, class _Backend, class _ExecutionPolicy>
+struct __is_implemented<_Algorithm,
+ _Backend,
+ _ExecutionPolicy,
+ __enable_if_t<sizeof(_Algorithm<_Backend, _ExecutionPolicy>)>> : true_type {};
+
+template <template <class, class> class _Algorithm, class _BackendConfiguration, class _ExecutionPolicy>
+struct __find_first_implemented;
+
+template <template <class, class> class _Algorithm, class _ExecutionPolicy>
+struct __find_first_implemented<_Algorithm, __backend_configuration<>, _ExecutionPolicy> {
+ static_assert(sizeof(_ExecutionPolicy) == 0,
+ "Could not find a PSTL backend for the given algorithm and execution policy");
+};
+
+template <template <class, class> class _Algorithm, class _B1, class... _Bn, class _ExecutionPolicy>
+struct __find_first_implemented<_Algorithm, __backend_configuration<_B1, _Bn...>, _ExecutionPolicy>
+ : _If<__is_implemented<_Algorithm, _B1, _ExecutionPolicy>::value,
+ __type_identity<_Algorithm<_B1, _ExecutionPolicy>>,
+ __find_first_implemented<_Algorithm, __backend_configuration<_Bn...>, _ExecutionPolicy> > {};
+
+template <template <class, class> class _Algorithm, class _BackendConfiguration, class _ExecutionPolicy>
+using __dispatch = typename __find_first_implemented<_Algorithm, _BackendConfiguration, _ExecutionPolicy>::type;
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_DISPATCH_H
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 0f62de7fa83f98..9925b0dcff2d8a 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -1864,22 +1864,7 @@ template <class BidirectionalIterator, class Compare>
#include <__algorithm/partition_point.h>
#include <__algorithm/pop_heap.h>
#include <__algorithm/prev_permutation.h>
-#include <__algorithm/pstl_any_all_none_of.h>
-#include <__algorithm/pstl_copy.h>
-#include <__algorithm/pstl_count.h>
-#include <__algorithm/pstl_equal.h>
-#include <__algorithm/pstl_fill.h>
-#include <__algorithm/pstl_find.h>
-#include <__algorithm/pstl_for_each.h>
-#include <__algorithm/pstl_generate.h>
-#include <__algorithm/pstl_is_partitioned.h>
-#include <__algorithm/pstl_merge.h>
-#include <__algorithm/pstl_move.h>
-#include <__algorithm/pstl_replace.h>
-#include <__algorithm/pstl_rotate_copy.h>
-#include <__algorithm/pstl_sort.h>
-#include <__algorithm/pstl_stable_sort.h>
-#include <__algorithm/pstl_transform.h>
+#include <__algorithm/pstl.h>
#include <__algorithm/push_heap.h>
#include <__algorithm/ranges_adjacent_find.h>
#include <__algorithm/ranges_all_of.h>
diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 486bdcb59656a8..b7f19795b23301 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -72,22 +72,7 @@
{ include: [ "<__algorithm/partition_point.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/pop_heap.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/prev_permutation.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_any_all_none_of.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_copy.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_count.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_equal.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_fill.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_find.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_for_each.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_generate.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_is_partitioned.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_merge.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_move.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_replace.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_rotate_copy.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_sort.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_stable_sort.h>", "private", "<algorithm>", "public" ] },
- { include: [ "<__algorithm/pstl_transform.h>", "private", "<algorithm>", "public" ] },
+ { include: [ "<__algorithm/pstl.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/push_heap.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/ranges_adjacent_find.h>", "private", "<algorithm>", "public" ] },
{ include: [ "<__algorithm/ranges_all_of.h>", "private", "<algorithm>", "public" ] },
@@ -560,8 +545,7 @@
{ include: [ "<__numeric/iota.h>", "private", "<numeric>", "public" ] },
{ include: [ "<__numeric/midpoint.h>", "private", "<numeric>", "public" ] },
{ include: [ "<__numeric/partial_sum.h>", "private", "<numeric>", "public" ] },
- { include: [ "<__numeric/pstl_reduce.h>", "private", "<numeric>", "public" ] },
- { include: [ "<__numeric/pstl_transform_reduce.h>", "private", "<numeric>", "public" ] },
+ { include: [ "<__numeric/pstl.h>", "private", "<numeric>", "public" ] },
{ include: [ "<__numeric/reduce.h>", "private", "<numeric>", "public" ] },
{ include: [ "<__numeric/saturation_arithmetic.h>", "private", "<numeric>", "public" ] },
{ include: [ "<__numeric/transform_exclusive_scan.h>", "private", "<numeric>", "public" ] },
diff --git a/libcxx/include/numeric b/libcxx/include/numeric
index 8b429fa2f7e7d5..9ef1539d123cd7 100644
--- a/libcxx/include/numeric
+++ b/libcxx/include/numeric
@@ -168,8 +168,7 @@ constexpr T saturate_cast(U x) noexcept; // freestanding, Sin
#include <__numeric/iota.h>
#include <__numeric/midpoint.h>
#include <__numeric/partial_sum.h>
-#include <__numeric/pstl_reduce.h>
-#include <__numeric/pstl_transform_reduce.h>
+#include <__numeric/pstl.h>
#include <__numeric/reduce.h>
#include <__numeric/saturation_arithmetic.h>
#include <__numeric/transform_exclusive_scan.h>
>From 882d5b29f31133ea0b44bd9715dfbdf5f2e8e8cb Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 12 Apr 2024 17:10:48 -0400
Subject: [PATCH 6/8] Fix test that is already fixed upstream
---
.../algorithms/pstl.libdispatch.chunk_partitions.pass.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/test/libcxx/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp b/libcxx/test/libcxx/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp
index 554924a0179d56..8c7016a80b811a 100644
--- a/libcxx/test/libcxx/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp
@@ -18,21 +18,21 @@
int main(int, char**) {
{
- auto chunks = std::__par_backend::__libdispatch::__partition_chunks(0);
+ auto chunks = std::__pstl::__libdispatch::__partition_chunks(0);
assert(chunks.__chunk_count_ == 1);
assert(chunks.__first_chunk_size_ == 0);
assert(chunks.__chunk_size_ == 0);
}
{
- auto chunks = std::__par_backend::__libdispatch::__partition_chunks(1);
+ auto chunks = std::__pstl::__libdispatch::__partition_chunks(1);
assert(chunks.__chunk_count_ == 1);
assert(chunks.__first_chunk_size_ == 1);
assert(chunks.__chunk_size_ == 1);
}
for (std::ptrdiff_t i = 2; i != 2ll << 20; ++i) {
- auto chunks = std::__par_backend::__libdispatch::__partition_chunks(i);
+ auto chunks = std::__pstl::__libdispatch::__partition_chunks(i);
assert(chunks.__chunk_count_ >= 1);
assert(chunks.__chunk_count_ <= i);
assert((chunks.__chunk_count_ - 1) * chunks.__chunk_size_ + chunks.__first_chunk_size_ == i);
>From ab4edd47f9b4c6ed8ff80df90bbfb1a7052b87d2 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 12 Apr 2024 17:18:21 -0400
Subject: [PATCH 7/8] Improve diagnostics
---
libcxx/include/__pstl/dispatch.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__pstl/dispatch.h b/libcxx/include/__pstl/dispatch.h
index bda3db48397470..939fad62dd9ebc 100644
--- a/libcxx/include/__pstl/dispatch.h
+++ b/libcxx/include/__pstl/dispatch.h
@@ -27,12 +27,17 @@ struct __is_implemented<_Algorithm,
_ExecutionPolicy,
__enable_if_t<sizeof(_Algorithm<_Backend, _ExecutionPolicy>)>> : true_type {};
+// Helpful to provide better error messages. This will show the algorithm and the execution policy
+// in the compiler diagnostic.
+template <template <class, class> class _Algorithm, class _ExecutionPolicy>
+constexpr bool __cant_find_backend_for = false;
+
template <template <class, class> class _Algorithm, class _BackendConfiguration, class _ExecutionPolicy>
struct __find_first_implemented;
template <template <class, class> class _Algorithm, class _ExecutionPolicy>
struct __find_first_implemented<_Algorithm, __backend_configuration<>, _ExecutionPolicy> {
- static_assert(sizeof(_ExecutionPolicy) == 0,
+ static_assert(__cant_find_backend_for<_Algorithm, _ExecutionPolicy>,
"Could not find a PSTL backend for the given algorithm and execution policy");
};
>From e6cef34aa10c6326dfa2ab52de0e4c1b4c6ba470 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 12 Apr 2024 17:29:01 -0400
Subject: [PATCH 8/8] Format
---
libcxx/include/__pstl/backends/std_thread.h | 4 ++--
libcxx/test/support/test_iterators.h | 4 +---
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/libcxx/include/__pstl/backends/std_thread.h b/libcxx/include/__pstl/backends/std_thread.h
index 1a273e0826f6c4..b342161379fcd6 100644
--- a/libcxx/include/__pstl/backends/std_thread.h
+++ b/libcxx/include/__pstl/backends/std_thread.h
@@ -25,8 +25,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace __pstl {
//
-// This partial backend implementation is for testing purposes only and not meant for production use. This will be replaced
-// by a proper implementation once the PSTL implementation is somewhat stable.
+// This partial backend implementation is for testing purposes only and not meant for production use. This will be
+// replaced by a proper implementation once the PSTL implementation is somewhat stable.
//
// This is intended to be used on top of the "default backend".
//
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index e2a3c2cdae41ec..aa819ecd4733bd 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -1508,9 +1508,7 @@ class iterator_wrapper {
return iter;
}
- friend Derived operator+(difference_type i, Derived iter) {
- return iter + i;
- }
+ friend Derived operator+(difference_type i, Derived iter) { return iter + i; }
friend bool operator==(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ == rhs.iter_; }
friend bool operator!=(const iterator_wrapper& lhs, const iterator_wrapper& rhs) { return lhs.iter_ != rhs.iter_; }
More information about the libcxx-commits
mailing list