[libcxx-commits] [libcxx] [libc++][c++17] P0452: Implementing PSTL overloads for `std::transform_{ex, in}clusive_scan` (PR #195548)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun May 3 13:25:21 PDT 2026
https://github.com/PaulXiCao created https://github.com/llvm/llvm-project/pull/195548
Closes 99948.
>From 8301a5ae47251c0c760aa9dc39b114f23cc5532b Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 12:44:33 +0200
Subject: [PATCH 1/9] mark paper status as complete
---
libcxx/docs/Status/Cxx17Papers.csv | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv
index ba2ceeedc2ce8..c3e6c4d16c6b4 100644
--- a/libcxx/docs/Status/Cxx17Papers.csv
+++ b/libcxx/docs/Status/Cxx17Papers.csv
@@ -95,7 +95,7 @@
"`P0317R1 <https://wg21.link/P0317R1>`__","Directory Entry Caching for Filesystem","2017-02 (Kona)","|Complete|","7","`#103684 <https://github.com/llvm/llvm-project/issues/103684>`__",""
"`P0430R2 <https://wg21.link/P0430R2>`__","File system library on non-POSIX-like operating systems","2017-02 (Kona)","|Complete|","7","`#103685 <https://github.com/llvm/llvm-project/issues/103685>`__",""
"`P0433R2 <https://wg21.link/P0433R2>`__","Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library","2017-02 (Kona)","|Complete|","14","`#103686 <https://github.com/llvm/llvm-project/issues/103686>`__",""
-"`P0452R1 <https://wg21.link/P0452R1>`__","Unifying <numeric> Parallel Algorithms","2017-02 (Kona)","|Partial|","","`#99948 <https://github.com/llvm/llvm-project/issues/99948>`__","The changes to ``std::transform_inclusive_scan`` and ``std::transform_exclusive_scan`` have not yet been implemented."
+"`P0452R1 <https://wg21.link/P0452R1>`__","Unifying <numeric> Parallel Algorithms","2017-02 (Kona)","|Complete|","","`#99948 <https://github.com/llvm/llvm-project/issues/99948>`__",""
"`P0467R2 <https://wg21.link/P0467R2>`__","Iterator Concerns for Parallel Algorithms","2017-02 (Kona)","|Partial|","","`#99949 <https://github.com/llvm/llvm-project/issues/99949>`__",""
"`P0492R2 <https://wg21.link/P0492R2>`__","Proposed Resolution of C++17 National Body Comments for Filesystems","2017-02 (Kona)","|Complete|","7","`#103687 <https://github.com/llvm/llvm-project/issues/103687>`__",""
"`P0518R1 <https://wg21.link/P0518R1>`__","Allowing copies as arguments to function objects given to parallel algorithms in response to CH11","2017-02 (Kona)","|Nothing To Do|","","`#103689 <https://github.com/llvm/llvm-project/issues/103689>`__",""
>From 60d06f0b569478b21882830fcd886bffdc5d3cfe Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 12:44:47 +0200
Subject: [PATCH 2/9] backend_fwd: __transform_exclusive_scan
---
libcxx/include/__pstl/backend_fwd.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index a52e6db954d0c..3cad5b8c461f0 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -303,6 +303,17 @@ struct __is_sorted;
// optional<bool>
// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Comp&& __comp) const noexcept;
+template <class _Backend, class _ExecutionPolicy>
+struct __transform_exclusive_scan;
+// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2,
+// class _Tp, class _BinaryOperation, class _UnaryOperation>
+// optional<_ForwardIterator2>
+// operator()(_Policy&&,
+// _ForwardIterator1 __first, _ForwardIterator1 __last,
+// _ForwardIterator2 __result,
+// _Tp __init,
+// _BinaryOperation __binary_op,
+// _UnaryOperation __unary_op) const noexcept;
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
>From 74bfc8ad3df48b1b158aa55e4a8bf3553cb66e5f Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 19:05:10 +0200
Subject: [PATCH 3/9] backend_fwd: __transform_inclusive_scan
---
libcxx/include/__pstl/backend_fwd.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index 3cad5b8c461f0..bf0e3cd47488f 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -314,6 +314,27 @@ struct __transform_exclusive_scan;
// _Tp __init,
// _BinaryOperation __binary_op,
// _UnaryOperation __unary_op) const noexcept;
+
+template <class _Backend, class _ExecutionPolicy>
+struct __transform_inclusive_scan;
+// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2,
+// class _BinaryOperation, class _UnaryOperation>
+// optional<_ForwardIterator2>
+// operator()(_Policy&&,
+// _ForwardIterator1 __first, _ForwardIterator1 __last,
+// _ForwardIterator2 __result,
+// _BinaryOperation __binary_op,
+// _UnaryOperation __unary_op) const noexcept;
+//
+// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2,
+// class _BinaryOperation, class _UnaryOperation, class _Tp>
+// optional<_ForwardIterator2>
+// operator()(_Policy&&,
+// _ForwardIterator1 __first, _ForwardIterator1 __last,
+// _ForwardIterator2 __result,
+// _BinaryOperation __binary_op,
+// _UnaryOperation __unary_op,
+// _Tp __init) const noexcept;
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
>From 6077b955a9d72c7da60438adafa5a6a6cd6b850b Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 19:17:45 +0200
Subject: [PATCH 4/9] transform_exclusive_scan for __serial_backend_tag
---
libcxx/include/__pstl/backends/serial.h | 27 +++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/libcxx/include/__pstl/backends/serial.h b/libcxx/include/__pstl/backends/serial.h
index f4142016ccc79..a96b79eded118 100644
--- a/libcxx/include/__pstl/backends/serial.h
+++ b/libcxx/include/__pstl/backends/serial.h
@@ -16,6 +16,7 @@
#include <__algorithm/stable_sort.h>
#include <__algorithm/transform.h>
#include <__config>
+#include <__numeric/transform_exclusive_scan.h>
#include <__numeric/transform_reduce.h>
#include <__pstl/backend_fwd.h>
#include <__utility/empty.h>
@@ -175,6 +176,32 @@ struct __transform_reduce_binary<__serial_backend_tag, _ExecutionPolicy> {
}
};
+template <class _ExecutionPolicy>
+struct __transform_exclusive_scan<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation,
+ class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2> operator()(
+ _Policy&&,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _Tp __init,
+ _BinaryOperation&& __binary_op,
+ _UnaryOperation&& __unary_op) const noexcept {
+ return std::transform_exclusive_scan(
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::move(__init),
+ std::forward<_BinaryOperation>(__binary_op),
+ std::forward<_UnaryOperation>(__unary_op));
+ }
+};
+
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
>From f869e770057cda22d20014a175210a2cb47b4649 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 21:31:32 +0200
Subject: [PATCH 5/9] transform_inclusive_scan for __serial_backend_tag
---
libcxx/include/__pstl/backends/serial.h | 46 +++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/libcxx/include/__pstl/backends/serial.h b/libcxx/include/__pstl/backends/serial.h
index a96b79eded118..5bae6397bcc53 100644
--- a/libcxx/include/__pstl/backends/serial.h
+++ b/libcxx/include/__pstl/backends/serial.h
@@ -17,6 +17,7 @@
#include <__algorithm/transform.h>
#include <__config>
#include <__numeric/transform_exclusive_scan.h>
+#include <__numeric/transform_inclusive_scan.h>
#include <__numeric/transform_reduce.h>
#include <__pstl/backend_fwd.h>
#include <__utility/empty.h>
@@ -202,6 +203,51 @@ struct __transform_exclusive_scan<__serial_backend_tag, _ExecutionPolicy> {
}
};
+template <class _ExecutionPolicy>
+struct __transform_inclusive_scan<__serial_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryOperation,
+ class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2>
+ operator()(_Policy&&,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _BinaryOperation&& __binary_op,
+ _UnaryOperation&& __unary_op) const noexcept {
+ return std::transform_inclusive_scan(
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::forward<_BinaryOperation>(__binary_op),
+ std::forward<_UnaryOperation>(__unary_op));
+ }
+
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryOperation,
+ class _UnaryOperation,
+ class _Tp>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2> operator()(
+ _Policy&&,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _BinaryOperation&& __binary_op,
+ _UnaryOperation&& __unary_op,
+ _Tp __init) const noexcept {
+ return std::transform_inclusive_scan(
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::forward<_BinaryOperation>(__binary_op),
+ std::forward<_UnaryOperation>(__unary_op),
+ std::move(__init));
+ }
+};
} // namespace __pstl
_LIBCPP_END_NAMESPACE_STD
>From 5dd255fe68ac956e2735e94cc67c265f8c822c4b Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 21:42:37 +0200
Subject: [PATCH 6/9] transform_*_scan for default_backend
---
libcxx/include/__pstl/backends/default.h | 77 ++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index be90715af13b5..9762124f3d9ce 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -21,6 +21,8 @@
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
+#include <__numeric/transform_exclusive_scan.h>
+#include <__numeric/transform_inclusive_scan.h>
#include <__pstl/backend_fwd.h>
#include <__pstl/dispatch.h>
#include <__utility/empty.h>
@@ -420,6 +422,81 @@ struct __is_sorted<__default_backend_tag, _ExecutionPolicy> {
}
};
+//////////////////////////////////////////////////////////////
+// transform_*clusive_scan family
+//////////////////////////////////////////////////////////////
+template <class _ExecutionPolicy>
+struct __transform_exclusive_scan<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation,
+ class _UnaryOperation>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2> operator()(
+ _Policy&&,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _Tp __init,
+ _BinaryOperation&& __binary_op,
+ _UnaryOperation&& __unary_op) const noexcept {
+ return std::transform_exclusive_scan(
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::move(__init),
+ std::forward<_BinaryOperation>(__binary_op),
+ std::forward<_UnaryOperation>(__unary_op));
+ }
+};
+
+template <class _ExecutionPolicy>
+struct __transform_inclusive_scan<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryOperation,
+ class _UnaryOperation>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2>
+ operator()(_Policy&&,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _BinaryOperation&& __binary_op,
+ _UnaryOperation&& __unary_op) const noexcept {
+ return std::transform_inclusive_scan(
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::forward<_BinaryOperation>(__binary_op),
+ std::forward<_UnaryOperation>(__unary_op));
+ }
+
+ template <class _Policy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryOperation,
+ class _UnaryOperation,
+ class _Tp>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator2> operator()(
+ _Policy&&,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _BinaryOperation&& __binary_op,
+ _UnaryOperation&& __unary_op,
+ _Tp __init) const noexcept {
+ return std::transform_inclusive_scan(
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::forward<_BinaryOperation>(__binary_op),
+ std::forward<_UnaryOperation>(__unary_op),
+ std::move(__init));
+ }
+};
+
//////////////////////////////////////////////////////////////
// transform family
//////////////////////////////////////////////////////////////
>From ba42c590fcdf6d8072217f7d4fc4a138f0e81c88 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 21:56:43 +0200
Subject: [PATCH 7/9] pstl: transform_exclusive_scan
---
libcxx/include/__numeric/pstl.h | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/libcxx/include/__numeric/pstl.h b/libcxx/include/__numeric/pstl.h
index fe7b2cc7a82cc..442b32e8ab12a 100644
--- a/libcxx/include/__numeric/pstl.h
+++ b/libcxx/include/__numeric/pstl.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___NUMERIC_PSTL_H
#define _LIBCPP___NUMERIC_PSTL_H
+#include "__pstl/backend_fwd.h"
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -165,6 +166,36 @@ _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce(
std::move(__transform));
}
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation,
+ class _UnaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator2 transform_exclusive_scan(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _Tp __init,
+ _BinaryOperation __binary_op,
+ _UnaryOperation __unary_op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_exclusive_scan requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_exclusive_scan requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__transform_exclusive_scan, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::move(__init),
+ std::move(__binary_op),
+ std::move(__unary_op));
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
>From 966477d08be10e8c7886db1ef2f5cb2e67b64aea Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 21:59:45 +0200
Subject: [PATCH 8/9] pstl: transform_inclusive_scan
---
libcxx/include/__numeric/pstl.h | 57 +++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/libcxx/include/__numeric/pstl.h b/libcxx/include/__numeric/pstl.h
index 442b32e8ab12a..41ba3c85c2366 100644
--- a/libcxx/include/__numeric/pstl.h
+++ b/libcxx/include/__numeric/pstl.h
@@ -196,6 +196,63 @@ _LIBCPP_HIDE_FROM_ABI _ForwardIterator2 transform_exclusive_scan(
std::move(__unary_op));
}
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryOperation,
+ class _UnaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator2 transform_inclusive_scan(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _BinaryOperation __binary_op,
+ _UnaryOperation __unary_op) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_inclusive_scan requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_inclusive_scan requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__transform_inclusive_scan, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::move(__binary_op),
+ std::move(__unary_op));
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _Tp,
+ class _BinaryOperation,
+ class _UnaryOperation,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _ForwardIterator2 transform_inclusive_scan(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first,
+ _ForwardIterator1 __last,
+ _ForwardIterator2 __result,
+ _BinaryOperation __binary_op,
+ _UnaryOperation __unary_op,
+ _Tp __init) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_inclusive_scan requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_inclusive_scan requires ForwardIterators");
+ using _Implementation =
+ __pstl::__dispatch<__pstl::__transform_inclusive_scan, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first),
+ std::move(__last),
+ std::move(__result),
+ std::move(__binary_op),
+ std::move(__unary_op),
+ std::move(__init));
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
>From db659b7bd9c74b172ec29b7425336485b65420f3 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 22:21:30 +0200
Subject: [PATCH 9/9] tests
---
.../pstl.transform_exclusive_scan.pass.cpp | 73 +++++++++++
.../pstl.transform_inclusive_scan.pass.cpp | 118 ++++++++++++++++++
2 files changed, 191 insertions(+)
create mode 100644 libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/pstl.transform_exclusive_scan.pass.cpp
create mode 100644 libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/pstl.transform_inclusive_scan.pass.cpp
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/pstl.transform_exclusive_scan.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/pstl.transform_exclusive_scan.pass.cpp
new file mode 100644
index 0000000000000..506c83ea6ccbd
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/pstl.transform_exclusive_scan.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// <numeric>
+
+// template<class ExecutionPolicy,
+// class ForwardIterator1, class ForwardIterator2, class T,
+// class BinaryOperation, class UnaryOperation>
+// ForwardIterator2
+// transform_exclusive_scan(ExecutionPolicy&& exec,
+// ForwardIterator1 first, ForwardIterator1 last,
+// ForwardIterator2 result,
+// T init,
+// BinaryOperation binary_op,
+// UnaryOperation unary_op);
+
+#include <cassert>
+#include <numeric>
+#include <string>
+#include <vector>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "type_algorithms.h"
+
+template <class Iter>
+struct Test {
+ template <class Policy>
+ void operator()(Policy&& policy) {
+ for (int size : {0, 1, 2, 100, 350}) {
+ std::vector<int> a(size);
+ for (int i = 0; i != size; ++i)
+ a[i] = i;
+
+ std::vector<int> expected(size);
+ std::transform_exclusive_scan(
+ a.begin(), a.end(), expected.begin(), 0, std::plus{}, [](int x) { return x + 1; });
+
+ std::vector<int> result(size);
+ auto ret = std::transform_exclusive_scan(
+ policy,
+ Iter(std::data(a)),
+ Iter(std::data(a) + std::size(a)),
+ std::data(result),
+ 0,
+ [check = std::string("Banane")](int i, int j) {
+ assert(check == "Banane");
+ return i + j;
+ },
+ [check = std::string("Banane")](int i) {
+ assert(check == "Banane");
+ return i + 1;
+ });
+ static_assert(std::is_same_v<decltype(ret), int*>);
+ assert(ret == std::data(result) + size);
+ assert(result == expected);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
+ return 0;
+}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/pstl.transform_inclusive_scan.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/pstl.transform_inclusive_scan.pass.cpp
new file mode 100644
index 0000000000000..54c800a29f243
--- /dev/null
+++ b/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/pstl.transform_inclusive_scan.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// <numeric>
+
+// template<class ExecutionPolicy,
+// class ForwardIterator1, class ForwardIterator2,
+// class BinaryOperation, class UnaryOperation>
+// ForwardIterator2
+// transform_inclusive_scan(ExecutionPolicy&& exec,
+// ForwardIterator1 first, ForwardIterator1 last,
+// ForwardIterator2 result,
+// BinaryOperation binary_op,
+// UnaryOperation unary_op);
+//
+// template<class ExecutionPolicy,
+// class ForwardIterator1, class ForwardIterator2,
+// class BinaryOperation, class UnaryOperation, class T>
+// ForwardIterator2
+// transform_inclusive_scan(ExecutionPolicy&& exec,
+// ForwardIterator1 first, ForwardIterator1 last,
+// ForwardIterator2 result,
+// BinaryOperation binary_op,
+// UnaryOperation unary_op,
+// T init);
+
+#include <cassert>
+#include <numeric>
+#include <string>
+#include <vector>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "type_algorithms.h"
+
+template <class Iter>
+struct TestNoInit {
+ template <class Policy>
+ void operator()(Policy&& policy) {
+ for (int size : {0, 1, 2, 100, 350}) {
+ std::vector<int> a(size);
+ for (int i = 0; i != size; ++i)
+ a[i] = i + 1;
+
+ std::vector<int> expected(size);
+ std::transform_inclusive_scan(
+ a.begin(), a.end(), expected.begin(), std::plus{}, [](int x) { return x + 1; });
+
+ std::vector<int> result(size);
+ auto ret = std::transform_inclusive_scan(
+ policy,
+ Iter(std::data(a)),
+ Iter(std::data(a) + std::size(a)),
+ std::data(result),
+ [check = std::string("Banane")](int i, int j) {
+ assert(check == "Banane");
+ return i + j;
+ },
+ [check = std::string("Banane")](int i) {
+ assert(check == "Banane");
+ return i + 1;
+ });
+ static_assert(std::is_same_v<decltype(ret), int*>);
+ assert(ret == std::data(result) + size);
+ assert(result == expected);
+ }
+ }
+};
+
+template <class Iter>
+struct TestWithInit {
+ template <class Policy>
+ void operator()(Policy&& policy) {
+ for (int size : {0, 1, 2, 100, 350}) {
+ std::vector<int> a(size);
+ for (int i = 0; i != size; ++i)
+ a[i] = i;
+
+ std::vector<int> expected(size);
+ std::transform_inclusive_scan(
+ a.begin(), a.end(), expected.begin(), std::plus{}, [](int x) { return x + 1; }, 100);
+
+ std::vector<int> result(size);
+ auto ret = std::transform_inclusive_scan(
+ policy,
+ Iter(std::data(a)),
+ Iter(std::data(a) + std::size(a)),
+ std::data(result),
+ [check = std::string("Banane")](int i, int j) {
+ assert(check == "Banane");
+ return i + j;
+ },
+ [check = std::string("Banane")](int i) {
+ assert(check == "Banane");
+ return i + 1;
+ },
+ 100);
+ static_assert(std::is_same_v<decltype(ret), int*>);
+ assert(ret == std::data(result) + size);
+ assert(result == expected);
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestNoInit>{});
+ types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<TestWithInit>{});
+ return 0;
+}
More information about the libcxx-commits
mailing list