[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
Tue May 5 14:04:39 PDT 2026


https://github.com/PaulXiCao updated https://github.com/llvm/llvm-project/pull/195548

>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 01/23] 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 02/23] 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 03/23] 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 04/23] 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 05/23] 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 06/23] 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 07/23] 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 08/23] 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 09/23] 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;
+}

>From 177f4cae3a22124503a5e5ba7e72d63aa7397ae6 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Sun, 3 May 2026 22:30:57 +0200
Subject: [PATCH 10/23] format tests

---
 .../pstl.transform_exclusive_scan.pass.cpp                     | 3 +--
 .../pstl.transform_inclusive_scan.pass.cpp                     | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

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
index 506c83ea6ccbd..d796bb5e75425 100644
--- 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
@@ -42,8 +42,7 @@ struct Test {
         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::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(
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
index 54c800a29f243..0951790a56ba2 100644
--- 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
@@ -52,8 +52,7 @@ struct TestNoInit {
         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::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(

>From 0837bb2f6c26e4c503da270b8d6c10c73e590ffa Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Mon, 4 May 2026 21:25:58 +0200
Subject: [PATCH 11/23] cpu traits: comments about transform_scans

---
 libcxx/include/__pstl/cpu_algos/cpu_traits.h | 27 ++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/libcxx/include/__pstl/cpu_algos/cpu_traits.h b/libcxx/include/__pstl/cpu_algos/cpu_traits.h
index ec1622419d049..93baf43928c9c 100644
--- a/libcxx/include/__pstl/cpu_algos/cpu_traits.h
+++ b/libcxx/include/__pstl/cpu_algos/cpu_traits.h
@@ -66,6 +66,33 @@ namespace __pstl {
 //      Size of SIMD lanes.
 //      TODO: Merge this with __native_vector_size from __algorithm/simd_utils.h
 //
+// Optional extended operations
+// ============================
+// Backends may specialize these to provide a parallel implementation.
+// If not specialized, the dispatch chain falls through to the next backend (typically default.h serial).
+//
+//  template <class _RandomAccessIterator1, class _RandomAccessIterator2,
+//            class _Tp, class _BinaryOperation, class _UnaryOperation>
+//  optional<_RandomAccessIterator2>
+//  __transform_exclusive_scan(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
+//                             _RandomAccessIterator2 __result, _Tp __init,
+//                             _BinaryOperation __binary_op, _UnaryOperation __unary_op);
+//
+//  // without init (_Tp{} used as identity for chunk-0 offset)
+//  template <class _RandomAccessIterator1, class _RandomAccessIterator2,
+//            class _BinaryOperation, class _UnaryOperation>
+//  optional<_RandomAccessIterator2>
+//  __transform_inclusive_scan(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
+//                             _RandomAccessIterator2 __result,
+//                             _BinaryOperation __binary_op, _UnaryOperation __unary_op);
+//
+//  // with init
+//  template <class _RandomAccessIterator1, class _RandomAccessIterator2,
+//            class _BinaryOperation, class _UnaryOperation, class _Tp>
+//  optional<_RandomAccessIterator2>
+//  __transform_inclusive_scan(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
+//                             _RandomAccessIterator2 __result,
+//                             _BinaryOperation __binary_op, _UnaryOperation __unary_op, _Tp __init);
 //
 // Exception handling
 // ==================

>From 4664633a6fbad34ae77c32c96dfa237c0ac2a6da Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Mon, 4 May 2026 22:08:37 +0200
Subject: [PATCH 12/23] cpu_algos: dispatch for transform_exclusive_scan

---
 libcxx/include/CMakeLists.txt                 |  1 +
 .../include/__pstl/cpu_algos/transform_scan.h | 79 +++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 libcxx/include/__pstl/cpu_algos/transform_scan.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 497aadfd799bf..7dcf26ad24c84 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -675,6 +675,7 @@ set(files
   __pstl/cpu_algos/stable_sort.h
   __pstl/cpu_algos/transform.h
   __pstl/cpu_algos/transform_reduce.h
+  __pstl/cpu_algos/transform_scan.h
   __pstl/dispatch.h
   __pstl/handle_exception.h
   __random/bernoulli_distribution.h
diff --git a/libcxx/include/__pstl/cpu_algos/transform_scan.h b/libcxx/include/__pstl/cpu_algos/transform_scan.h
new file mode 100644
index 0000000000000..ea89ccad8aca0
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/transform_scan.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_TRANSFORM_SCAN_H
+#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_SCAN_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__numeric/transform_exclusive_scan.h>
+#include <__pstl/backend_fwd.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>
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_transform_exclusive_scan {
+  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 {
+    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_exclusive_scan(
+          std::move(__first),
+          std::move(__last),
+          std::move(__result),
+          std::move(__init),
+          std::move(__binary_op),
+          std::move(__unary_op));
+    } else {
+      return std::transform_exclusive_scan(
+          std::move(__first),
+          std::move(__last),
+          std::move(__result),
+          std::move(__init),
+          std::move(__binary_op),
+          std::move(__unary_op));
+    }
+  }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_SCAN_H

>From 65b4840d7925eebc050ca58d8409cdefbda8ad8f Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Mon, 4 May 2026 22:12:34 +0200
Subject: [PATCH 13/23] cpu_algos: dispatch for transform_inclusive_scans

---
 .../include/__pstl/cpu_algos/transform_scan.h | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/libcxx/include/__pstl/cpu_algos/transform_scan.h b/libcxx/include/__pstl/cpu_algos/transform_scan.h
index ea89ccad8aca0..9f6a5597179b8 100644
--- a/libcxx/include/__pstl/cpu_algos/transform_scan.h
+++ b/libcxx/include/__pstl/cpu_algos/transform_scan.h
@@ -13,6 +13,7 @@
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__numeric/transform_exclusive_scan.h>
+#include <__numeric/transform_inclusive_scan.h>
 #include <__pstl/backend_fwd.h>
 #include <__pstl/cpu_algos/cpu_traits.h>
 #include <__type_traits/is_execution_policy.h>
@@ -69,6 +70,67 @@ struct __cpu_parallel_transform_exclusive_scan {
   }
 };
 
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_transform_inclusive_scan {
+  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 {
+    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_inclusive_scan(
+          std::move(__first), std::move(__last), std::move(__result), std::move(__binary_op), std::move(__unary_op));
+    } else {
+      return std::transform_inclusive_scan(
+          std::move(__first), std::move(__last), std::move(__result), std::move(__binary_op), std::move(__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 {
+    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_inclusive_scan(
+          std::move(__first),
+          std::move(__last),
+          std::move(__result),
+          std::move(__binary_op),
+          std::move(__unary_op),
+          std::move(__init));
+    } else {
+      return std::transform_inclusive_scan(
+          std::move(__first),
+          std::move(__last),
+          std::move(__result),
+          std::move(__binary_op),
+          std::move(__unary_op),
+          std::move(__init));
+    }
+  }
+};
+
 } // namespace __pstl
 _LIBCPP_END_NAMESPACE_STD
 

>From 4ea6e12093998890cdf6df87379519fdee945b4a Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Mon, 4 May 2026 23:19:00 +0200
Subject: [PATCH 14/23] libdispatch: __transform_exclusive_scan

---
 libcxx/include/__pstl/backends/libdispatch.h | 77 ++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index 88d4231d29a0a..ea90f2f311698 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -255,6 +255,83 @@ struct __cpu_traits<__libdispatch_backend_tag> {
         __combiner);
   }
 
+  template < class _RandomAccessIterator1,
+             class _RandomAccessIterator2,
+             class _Tp,
+             class _BinaryOperation,
+             class _UnaryOperation>
+  _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_exclusive_scan(
+      _RandomAccessIterator1 __first,
+      _RandomAccessIterator1 __last,
+      _RandomAccessIterator2 __result,
+      _Tp __init,
+      _BinaryOperation __binary_op,
+      _UnaryOperation __unary_op) noexcept {
+    auto __n = __last - __first;
+    if (__n == 0)
+      return __result;
+
+    auto __partitions  = __libdispatch::__partition_chunks(__n);
+    auto __chunk_count = __partitions.__chunk_count_;
+
+    auto __destroy = [__chunk_count](_Tp* __ptr) {
+      std::destroy_n(__ptr, __chunk_count);
+      std::allocator<_Tp>().deallocate(__ptr, __chunk_count);
+    };
+    unique_ptr<_Tp[], decltype(__destroy)> __chunk_totals(
+        [&]() -> _Tp* {
+#  if _LIBCPP_HAS_EXCEPTIONS
+          try {
+#  endif
+            return std::allocator<_Tp>().allocate(__chunk_count);
+#  if _LIBCPP_HAS_EXCEPTIONS
+          } catch (const std::bad_alloc&) {
+            return nullptr;
+          }
+#  endif
+        }(),
+        std::move(__destroy));
+    if (!__chunk_totals)
+      return nullopt;
+
+    // Phase 1: parallel chunk totals
+    __libdispatch::__dispatch_apply(__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_);
+      std::__construct_at(
+          __chunk_totals.get() + __chunk,
+          std::transform_reduce(
+              __first + __index, __first + __index + __this_chunk_size, _Tp{}, __binary_op, __unary_op));
+    });
+
+    // Phase 2: serial exclusive prefix of totals to per-chunk offsets (in-place)
+    std::exclusive_scan(
+        __chunk_totals.get(),
+        __chunk_totals.get() + __chunk_count,
+        __chunk_totals.get(),
+        std::move(__init),
+        __binary_op);
+
+    // Phase 3: parallel per-chunk serial scan
+    __libdispatch::__dispatch_apply(__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_);
+      std::transform_exclusive_scan(
+          __first + __index,
+          __first + __index + __this_chunk_size,
+          __result + __index,
+          std::move(__chunk_totals.get()[__chunk]),
+          __binary_op,
+          __unary_op);
+    });
+
+    return __result + __n;
+  }
+
   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) {

>From a0be67f38624a5d068425908181d5ecd2153740e Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Mon, 4 May 2026 23:21:04 +0200
Subject: [PATCH 15/23] test: add missing includes

---
 .../pstl.transform_exclusive_scan.pass.cpp                       | 1 +
 .../pstl.transform_inclusive_scan.pass.cpp                       | 1 +
 2 files changed, 2 insertions(+)

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
index d796bb5e75425..9efae4cd907ed 100644
--- 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
@@ -24,6 +24,7 @@
 //                            UnaryOperation unary_op);
 
 #include <cassert>
+#include <functional>
 #include <numeric>
 #include <string>
 #include <vector>
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
index 0951790a56ba2..1130f07d3da16 100644
--- 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
@@ -34,6 +34,7 @@
 //                            T init);
 
 #include <cassert>
+#include <functional>
 #include <numeric>
 #include <string>
 #include <vector>

>From fbb6ab849c9d3fd850a5252dc46e4a32d86ca7ad Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 20:57:59 +0200
Subject: [PATCH 16/23] libdispatch: add missing includes

---
 libcxx/include/__pstl/backends/libdispatch.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index ea90f2f311698..58516013d1be3 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -25,7 +25,9 @@
 #include <__memory/destroy.h>
 #include <__memory/unique_ptr.h>
 #include <__new/exceptions.h>
+#include <__numeric/exclusive_scan.h>
 #include <__numeric/reduce.h>
+#include <__numeric/transform_exclusive_scan.h>
 #include <__pstl/backend_fwd.h>
 #include <__pstl/cpu_algos/any_of.h>
 #include <__pstl/cpu_algos/cpu_traits.h>

>From 3f852fe2c4c0f2dea04adc1e13deb536a1d21490 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 21:23:31 +0200
Subject: [PATCH 17/23] libdispatch: __transform_inclusive_scan w/ init

---
 libcxx/include/__pstl/backends/libdispatch.h | 78 ++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index 58516013d1be3..4ecd84daa73a8 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -28,6 +28,7 @@
 #include <__numeric/exclusive_scan.h>
 #include <__numeric/reduce.h>
 #include <__numeric/transform_exclusive_scan.h>
+#include <__numeric/transform_inclusive_scan.h>
 #include <__pstl/backend_fwd.h>
 #include <__pstl/cpu_algos/any_of.h>
 #include <__pstl/cpu_algos/cpu_traits.h>
@@ -334,6 +335,83 @@ struct __cpu_traits<__libdispatch_backend_tag> {
     return __result + __n;
   }
 
+  template < class _RandomAccessIterator1,
+             class _RandomAccessIterator2,
+             class _BinaryOperation,
+             class _UnaryOperation,
+             class _Tp>
+  _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_inclusive_scan(
+      _RandomAccessIterator1 __first,
+      _RandomAccessIterator1 __last,
+      _RandomAccessIterator2 __result,
+      _BinaryOperation __binary_op,
+      _UnaryOperation __unary_op,
+      _Tp __init) noexcept {
+    auto __n = __last - __first;
+    if (__n == 0)
+      return __result;
+
+    auto __partitions  = __libdispatch::__partition_chunks(__n);
+    auto __chunk_count = __partitions.__chunk_count_;
+
+    auto __destroy = [__chunk_count](_Tp* __ptr) {
+      std::destroy_n(__ptr, __chunk_count);
+      std::allocator<_Tp>().deallocate(__ptr, __chunk_count);
+    };
+    unique_ptr<_Tp[], decltype(__destroy)> __chunk_totals(
+        [&]() -> _Tp* {
+#  if _LIBCPP_HAS_EXCEPTIONS
+          try {
+#  endif
+            return std::allocator<_Tp>().allocate(__chunk_count);
+#  if _LIBCPP_HAS_EXCEPTIONS
+          } catch (const std::bad_alloc&) {
+            return nullptr;
+          }
+#  endif
+        }(),
+        std::move(__destroy));
+    if (!__chunk_totals)
+      return nullopt;
+
+    // Phase 1: parallel chunk totals
+    __libdispatch::__dispatch_apply(__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_);
+      std::__construct_at(
+          __chunk_totals.get() + __chunk,
+          std::transform_reduce(
+              __first + __index, __first + __index + __this_chunk_size, _Tp{}, __binary_op, __unary_op));
+    });
+
+    // Phase 2: serial exclusive prefix of totals to per-chunk offsets (in-place)
+    std::exclusive_scan(
+        __chunk_totals.get(),
+        __chunk_totals.get() + __chunk_count,
+        __chunk_totals.get(),
+        std::move(__init),
+        __binary_op);
+
+    // Phase 3: parallel per-chunk serial scan
+    __libdispatch::__dispatch_apply(__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_);
+      std::transform_inclusive_scan(
+          __first + __index,
+          __first + __index + __this_chunk_size,
+          __result + __index,
+          __binary_op,
+          __unary_op,
+          std::move(__chunk_totals.get()[__chunk]));
+    });
+
+    return __result + __n;
+  }
+
   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) {

>From ba63fcc06a32df2a2fd918940cd18bfed89e91a6 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 21:36:37 +0200
Subject: [PATCH 18/23] libdispatch: __transform_inclusive_scan w/o init

---
 libcxx/include/__pstl/backends/libdispatch.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index 4ecd84daa73a8..c6118e9d4bf47 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -39,6 +39,7 @@
 #include <__pstl/cpu_algos/stable_sort.h>
 #include <__pstl/cpu_algos/transform.h>
 #include <__pstl/cpu_algos/transform_reduce.h>
+#include <__type_traits/invoke.h>
 #include <__utility/empty.h>
 #include <__utility/exception_guard.h>
 #include <__utility/move.h>
@@ -335,6 +336,23 @@ struct __cpu_traits<__libdispatch_backend_tag> {
     return __result + __n;
   }
 
+  template < class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryOperation, class _UnaryOperation>
+  _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_inclusive_scan(
+      _RandomAccessIterator1 __first,
+      _RandomAccessIterator1 __last,
+      _RandomAccessIterator2 __result,
+      _BinaryOperation __binary_op,
+      _UnaryOperation __unary_op) noexcept {
+    using _Tp = invoke_result_t<_UnaryOperation, iter_reference_t<_RandomAccessIterator1>>;
+    return __transform_inclusive_scan(
+        std::move(__first),
+        std::move(__last),
+        std::move(__result),
+        std::move(__binary_op),
+        std::move(__unary_op),
+        _Tp{});
+  }
+
   template < class _RandomAccessIterator1,
              class _RandomAccessIterator2,
              class _BinaryOperation,

>From 042f435bf68a5f7e0160ee8644b69d42224ddfb2 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 22:22:59 +0200
Subject: [PATCH 19/23] libdispatch: DRY. unify impls

---
 libcxx/include/__pstl/backends/libdispatch.h | 132 +++++++++----------
 1 file changed, 62 insertions(+), 70 deletions(-)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index c6118e9d4bf47..e5a0a9c151c65 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -259,18 +259,21 @@ struct __cpu_traits<__libdispatch_backend_tag> {
         __combiner);
   }
 
+private:
   template < class _RandomAccessIterator1,
              class _RandomAccessIterator2,
              class _Tp,
              class _BinaryOperation,
-             class _UnaryOperation>
-  _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_exclusive_scan(
+             class _UnaryOperation,
+             class _Phase3Func>
+  _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_scan(
       _RandomAccessIterator1 __first,
       _RandomAccessIterator1 __last,
       _RandomAccessIterator2 __result,
       _Tp __init,
       _BinaryOperation __binary_op,
-      _UnaryOperation __unary_op) noexcept {
+      _UnaryOperation __unary_op,
+      _Phase3Func __phase3) noexcept {
     auto __n = __last - __first;
     if (__n == 0)
       return __result;
@@ -324,18 +327,50 @@ struct __cpu_traits<__libdispatch_backend_tag> {
       auto __index           = __chunk == 0 ? 0
                                             : (__chunk * __partitions.__chunk_size_) +
                                         (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
-      std::transform_exclusive_scan(
-          __first + __index,
-          __first + __index + __this_chunk_size,
-          __result + __index,
-          std::move(__chunk_totals.get()[__chunk]),
-          __binary_op,
-          __unary_op);
+      __phase3(__first + __index,
+               __first + __index + __this_chunk_size,
+               __result + __index,
+               std::move(__chunk_totals.get()[__chunk]));
     });
 
     return __result + __n;
   }
 
+public:
+  template < class _RandomAccessIterator1,
+             class _RandomAccessIterator2,
+             class _Tp,
+             class _BinaryOperation,
+             class _UnaryOperation>
+  _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_exclusive_scan(
+      _RandomAccessIterator1 __first,
+      _RandomAccessIterator1 __last,
+      _RandomAccessIterator2 __result,
+      _Tp __init,
+      _BinaryOperation __binary_op,
+      _UnaryOperation __unary_op) noexcept {
+    auto __phase3 = [&](_RandomAccessIterator1 __chunk_first,
+                        _RandomAccessIterator1 __chunk_last,
+                        _RandomAccessIterator2 __chunk_result,
+                        _Tp __chunk_offset) {
+      std::transform_exclusive_scan(
+          std::move(__chunk_first),
+          std::move(__chunk_last),
+          std::move(__chunk_result),
+          std::move(__chunk_offset),
+          __binary_op,
+          __unary_op);
+    };
+    return __transform_scan(
+        std::move(__first),
+        std::move(__last),
+        std::move(__result),
+        std::move(__init),
+        __binary_op,
+        __unary_op,
+        std::move(__phase3));
+  }
+
   template < class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryOperation, class _UnaryOperation>
   _LIBCPP_HIDE_FROM_ABI static optional<_RandomAccessIterator2> __transform_inclusive_scan(
       _RandomAccessIterator1 __first,
@@ -365,69 +400,26 @@ struct __cpu_traits<__libdispatch_backend_tag> {
       _BinaryOperation __binary_op,
       _UnaryOperation __unary_op,
       _Tp __init) noexcept {
-    auto __n = __last - __first;
-    if (__n == 0)
-      return __result;
-
-    auto __partitions  = __libdispatch::__partition_chunks(__n);
-    auto __chunk_count = __partitions.__chunk_count_;
-
-    auto __destroy = [__chunk_count](_Tp* __ptr) {
-      std::destroy_n(__ptr, __chunk_count);
-      std::allocator<_Tp>().deallocate(__ptr, __chunk_count);
-    };
-    unique_ptr<_Tp[], decltype(__destroy)> __chunk_totals(
-        [&]() -> _Tp* {
-#  if _LIBCPP_HAS_EXCEPTIONS
-          try {
-#  endif
-            return std::allocator<_Tp>().allocate(__chunk_count);
-#  if _LIBCPP_HAS_EXCEPTIONS
-          } catch (const std::bad_alloc&) {
-            return nullptr;
-          }
-#  endif
-        }(),
-        std::move(__destroy));
-    if (!__chunk_totals)
-      return nullopt;
-
-    // Phase 1: parallel chunk totals
-    __libdispatch::__dispatch_apply(__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_);
-      std::__construct_at(
-          __chunk_totals.get() + __chunk,
-          std::transform_reduce(
-              __first + __index, __first + __index + __this_chunk_size, _Tp{}, __binary_op, __unary_op));
-    });
-
-    // Phase 2: serial exclusive prefix of totals to per-chunk offsets (in-place)
-    std::exclusive_scan(
-        __chunk_totals.get(),
-        __chunk_totals.get() + __chunk_count,
-        __chunk_totals.get(),
-        std::move(__init),
-        __binary_op);
-
-    // Phase 3: parallel per-chunk serial scan
-    __libdispatch::__dispatch_apply(__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_);
+    auto __phase3 = [&](_RandomAccessIterator1 __chunk_first,
+                        _RandomAccessIterator1 __chunk_last,
+                        _RandomAccessIterator2 __chunk_result,
+                        _Tp __chunk_offset) {
       std::transform_inclusive_scan(
-          __first + __index,
-          __first + __index + __this_chunk_size,
-          __result + __index,
+          std::move(__chunk_first),
+          std::move(__chunk_last),
+          std::move(__chunk_result),
           __binary_op,
           __unary_op,
-          std::move(__chunk_totals.get()[__chunk]));
-    });
-
-    return __result + __n;
+          std::move(__chunk_offset));
+    };
+    return __transform_scan(
+        std::move(__first),
+        std::move(__last),
+        std::move(__result),
+        std::move(__init),
+        std::move(__binary_op),
+        std::move(__unary_op),
+        std::move(__phase3));
   }
 
   template <class _RandomAccessIterator, class _Comp, class _LeafSort>

>From dd786e10fa234e69bc8c6a1540433257bba4d669 Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 22:26:00 +0200
Subject: [PATCH 20/23] libdispatch: add missing move

---
 libcxx/include/__pstl/backends/libdispatch.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index e5a0a9c151c65..6f45905f3cf2f 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -276,7 +276,7 @@ struct __cpu_traits<__libdispatch_backend_tag> {
       _Phase3Func __phase3) noexcept {
     auto __n = __last - __first;
     if (__n == 0)
-      return __result;
+      return std::move(__result);
 
     auto __partitions  = __libdispatch::__partition_chunks(__n);
     auto __chunk_count = __partitions.__chunk_count_;

>From ebab0b242572187b6ae5007fa5eae4d367fca84a Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 22:32:36 +0200
Subject: [PATCH 21/23] libdispatch: connect to cpu_algos/

---
 libcxx/include/__pstl/backends/libdispatch.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index 6f45905f3cf2f..ac96e46f3d19a 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -39,6 +39,7 @@
 #include <__pstl/cpu_algos/stable_sort.h>
 #include <__pstl/cpu_algos/transform.h>
 #include <__pstl/cpu_algos/transform_reduce.h>
+#include <__pstl/cpu_algos/transform_scan.h>
 #include <__type_traits/invoke.h>
 #include <__utility/empty.h>
 #include <__utility/exception_guard.h>
@@ -546,6 +547,14 @@ template <class _ExecutionPolicy>
 struct __transform_reduce<__libdispatch_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_transform_reduce<__libdispatch_backend_tag, _ExecutionPolicy> {};
 
+template <class _ExecutionPolicy>
+struct __transform_exclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy>
+    : __cpu_parallel_transform_exclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
+template <class _ExecutionPolicy>
+struct __transform_inclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy>
+    : __cpu_parallel_transform_inclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
 template <class _ExecutionPolicy>
 struct __transform_reduce_binary<__libdispatch_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_transform_reduce_binary<__libdispatch_backend_tag, _ExecutionPolicy> {};

>From 4f3c703e1d2c7d54a71e999c4ff68f381b8f86dc Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 22:39:49 +0200
Subject: [PATCH 22/23] tests: force multiple chunks independent of hardware

---
 libcxx/include/__pstl/backends/libdispatch.h              | 8 ++++----
 .../pstl.transform_exclusive_scan.pass.cpp                | 2 +-
 .../pstl.transform_inclusive_scan.pass.cpp                | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index ac96e46f3d19a..3e0c4bcfdc703 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -547,6 +547,10 @@ 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> {};
+
 template <class _ExecutionPolicy>
 struct __transform_exclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_transform_exclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy> {};
@@ -555,10 +559,6 @@ template <class _ExecutionPolicy>
 struct __transform_inclusive_scan<__libdispatch_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_transform_inclusive_scan<__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>
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
index 9efae4cd907ed..936fade43c57e 100644
--- 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
@@ -37,7 +37,7 @@ template <class Iter>
 struct Test {
   template <class Policy>
   void operator()(Policy&& policy) {
-    for (int size : {0, 1, 2, 100, 350}) {
+    for (int size : {0, 1, 2, 100, 350, 10000}) {
       std::vector<int> a(size);
       for (int i = 0; i != size; ++i)
         a[i] = i;
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
index 1130f07d3da16..fb476f582a833 100644
--- 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
@@ -47,7 +47,7 @@ template <class Iter>
 struct TestNoInit {
   template <class Policy>
   void operator()(Policy&& policy) {
-    for (int size : {0, 1, 2, 100, 350}) {
+    for (int size : {0, 1, 2, 100, 350, 10000}) {
       std::vector<int> a(size);
       for (int i = 0; i != size; ++i)
         a[i] = i + 1;

>From 41f6daaa40e257e8979f456fa7a5510bc694d6ab Mon Sep 17 00:00:00 2001
From: Paul <paulxicao7 at gmail.com>
Date: Tue, 5 May 2026 23:04:13 +0200
Subject: [PATCH 23/23] use clang-format v22.1

---
 libcxx/include/__pstl/backends/libdispatch.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index 3e0c4bcfdc703..79260ad3f86c7 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -241,7 +241,7 @@ struct __cpu_traits<__libdispatch_backend_tag> {
       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_);
+                                                  (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
       if (__this_chunk_size != 1) {
         std::__construct_at(
             __values.get() + __chunk,
@@ -307,7 +307,7 @@ struct __cpu_traits<__libdispatch_backend_tag> {
       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_);
+                                                  (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
       std::__construct_at(
           __chunk_totals.get() + __chunk,
           std::transform_reduce(
@@ -327,7 +327,7 @@ struct __cpu_traits<__libdispatch_backend_tag> {
       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_);
+                                                  (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
       __phase3(__first + __index,
                __first + __index + __this_chunk_size,
                __result + __index,



More information about the libcxx-commits mailing list