[libcxx-commits] [libcxx] [libc++][pstl] Default implementation of parallel std::find_first_of (PR #206328)
Michael G. Kazakov via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jun 28 05:31:07 PDT 2026
https://github.com/mikekazakov created https://github.com/llvm/llvm-project/pull/206328
This PR adds a default "one-liner" implementation of parallel `std::find_first_of` expressed as a call to `__find_if`.
The implementation uses a combination of `__find_of` and `std::any_of`:
```cpp
return FindIf()(policy, std::move(first1), std::move(last1), [&](Ref1 element) {
return std::any_of(first2, last2, [&](Ref2 value) { return pred(element, value); });
});
```
Included tests check that:
- Iterator-only version of the function is correct.
- Predicated version of the function is correct.
- The `nodiscard` policy is followed.
- The `noexcept` policy is followed.
- `static_assert` verifies an iterator category.
Part of #99938
>From 80420b031a2664ffaaac079b74864f6f035d0810 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Sun, 28 Jun 2026 11:21:56 +0100
Subject: [PATCH 1/4] Added implementation of find_first_of on top of __find_if
---
libcxx/include/__algorithm/pstl.h | 22 +++++
libcxx/include/__pstl/backend_fwd.h | 7 ++
libcxx/include/__pstl/backends/default.h | 19 ++++
.../pstl.find_first_of.pass.cpp | 87 +++++++++++++++++++
4 files changed, 135 insertions(+)
create mode 100644 libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp
diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index 10625ea3f8e3d..7d5b20ad96c1d 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -679,6 +679,28 @@ is_sorted(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterato
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
}
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator1 find_first_of(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "find_first_of requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "find_first_of requires ForwardIterators");
+ using _Implementation = __pstl::__dispatch<__pstl::__find_first_of, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2));
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index a52e6db954d0c..cf64e190ad4ed 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -109,6 +109,13 @@ struct __is_partitioned;
// optional<bool>
// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
+template <class _Backend, class _ExecutionPolicy>
+struct __find_first_of;
+// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2>
+// optional<_ForwardIterator1>
+// operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
+// _ForwardIterator2 __first2, _ForwardIterator2 __last2) const noexcept;
+
template <class _Backend, class _ExecutionPolicy>
struct __for_each;
// template <class _Policy, class _ForwardIterator, class _Function>
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index be90715af13b5..4fcd9b55e5066 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -12,6 +12,7 @@
#include <__algorithm/copy_n.h>
#include <__algorithm/equal.h>
#include <__algorithm/fill_n.h>
+#include <__algorithm/find.h>
#include <__algorithm/for_each_n.h>
#include <__algorithm/is_sorted.h>
#include <__config>
@@ -57,6 +58,7 @@ namespace __pstl {
// - all_of
// - none_of
// - is_partitioned
+// - find_first_of
//
// for_each family
// ---------------
@@ -181,6 +183,23 @@ struct __is_partitioned<__default_backend_tag, _ExecutionPolicy> {
}
};
+template <class _ExecutionPolicy>
+struct __find_first_of<__default_backend_tag, _ExecutionPolicy> {
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator1>
+ operator()(_Policy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2) const noexcept {
+ using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
+ using _Ref = __iterator_reference<_ForwardIterator1>;
+ return _FindIf()(__policy, std::move(__first1), std::move(__last1), [&](_Ref __element) {
+ return std::find(__first2, __last2, __element) != __last2;
+ });
+ }
+};
+
//////////////////////////////////////////////////////////////
// for_each family
//////////////////////////////////////////////////////////////
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp
new file mode 100644
index 0000000000000..c4093daa71ba7
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator1,
+// class ForwardIterator2>
+// ForwardIterator1 find_first_of(ExecutionPolicy&& exec,
+// ForwardIterator1 first1,
+// ForwardIterator1 last1,
+// ForwardIterator2 first2,
+// ForwardIterator2 last2);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <limits>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+
+template <class Iter>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ int a[] = {0};
+ unsigned sa = sizeof(a) / sizeof(a[0]);
+ assert(std::find_first_of(policy, Iter(a), Iter(a), Iter(a), Iter(a)) == Iter(a));
+ assert(std::find_first_of(policy, Iter(a), Iter(a + sa), Iter(a), Iter(a)) == Iter(a + sa));
+ }
+ {
+ int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ int ib[] = {1, 3, 5, 7};
+ unsigned sb = sizeof(ib) / sizeof(ib[0]);
+ assert(std::find_first_of(Iter(ia), Iter(ia + sa), Iter(ib), Iter(ib + sb)) == Iter(ia + 1));
+ int ic[] = {7};
+ assert(std::find_first_of(Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic + 1)) == Iter(ia + sa));
+ assert(std::find_first_of(Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic)) == Iter(ia + sa));
+ assert(std::find_first_of(Iter(ia), Iter(ia), Iter(ic), Iter(ic + 1)) == Iter(ia));
+ }
+ {
+ int a[8192];
+ unsigned sa = sizeof(a) / sizeof(a[0]);
+ std::iota(a, a + sa, 1);
+ a[1023] = -1;
+ a[2048] = -1;
+ a[3071] = -1;
+ int b[] = {-1, 999999};
+ unsigned sb = sizeof(b) / sizeof(b[0]);
+ assert(std::find_first_of(policy, Iter(a), Iter(a + sa), Iter(b), Iter(b + sb)) == Iter(a + 1023));
+ }
+ {
+ int a[1073];
+ unsigned sa = sizeof(a) / sizeof(a[0]);
+ std::iota(a, a + sa, 0);
+ int b[] = {1070, 1071, 1072, -1};
+ unsigned sb = sizeof(b) / sizeof(b[0]);
+ for (unsigned i = 0; i < sa; i = i <= 16 ? i + 1 : unsigned(3.1415 * i)) {
+ a[i] = -1;
+ assert(std::find_first_of(policy, Iter(a), Iter(a + sa), Iter(b), Iter(b + sb)) == Iter(a + i));
+ a[i] = i;
+ }
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::concatenate_t<types::forward_iterator_list<int*>,
+ types::bidirectional_iterator_list<int*>,
+ types::random_access_iterator_list<int*>>{},
+ TestIteratorWithPolicies<Test>{});
+
+ return 0;
+}
>From c4185be74a100792d2e08987b3991397446a39d1 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Sun, 28 Jun 2026 12:08:03 +0100
Subject: [PATCH 2/4] Added a predicate version of find_first_of
---
libcxx/include/__algorithm/pstl.h | 28 +++++-
libcxx/include/__pstl/backend_fwd.h | 4 +-
libcxx/include/__pstl/backends/default.h | 14 +--
.../pstl.find_first_of_pred.pass.cpp | 95 +++++++++++++++++++
4 files changed, 132 insertions(+), 9 deletions(-)
create mode 100644 libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of_pred.pass.cpp
diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index 7d5b20ad96c1d..84418222def52 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -698,7 +698,33 @@ template <class _ExecutionPolicy,
std::move(__first1),
std::move(__last1),
std::move(__first2),
- std::move(__last2));
+ std::move(__last2),
+ std::equal_to<>{});
+}
+
+template <class _ExecutionPolicy,
+ class _ForwardIterator1,
+ class _ForwardIterator2,
+ class _BinaryPredicate,
+ class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
+ enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ForwardIterator1 find_first_of(
+ _ExecutionPolicy&& __policy,
+ _ForwardIterator1 __first1,
+ _ForwardIterator1 __last1,
+ _ForwardIterator2 __first2,
+ _ForwardIterator2 __last2,
+ _BinaryPredicate __pred) {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "find_first_of requires ForwardIterators");
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "find_first_of requires ForwardIterators");
+ using _Implementation = __pstl::__dispatch<__pstl::__find_first_of, __pstl::__current_configuration, _RawPolicy>;
+ return __pstl::__handle_exception<_Implementation>(
+ std::forward<_ExecutionPolicy>(__policy),
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ std::move(__pred));
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index cf64e190ad4ed..1ea121367fbc7 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -111,10 +111,10 @@ struct __is_partitioned;
template <class _Backend, class _ExecutionPolicy>
struct __find_first_of;
-// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2>
+// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
// optional<_ForwardIterator1>
// operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
-// _ForwardIterator2 __first2, _ForwardIterator2 __last2) const noexcept;
+// _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred) const noexcept;
template <class _Backend, class _ExecutionPolicy>
struct __for_each;
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index 4fcd9b55e5066..6306b051f9dc4 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -9,10 +9,10 @@
#ifndef _LIBCPP___PSTL_BACKENDS_DEFAULT_H
#define _LIBCPP___PSTL_BACKENDS_DEFAULT_H
+#include <__algorithm/any_of.h>
#include <__algorithm/copy_n.h>
#include <__algorithm/equal.h>
#include <__algorithm/fill_n.h>
-#include <__algorithm/find.h>
#include <__algorithm/for_each_n.h>
#include <__algorithm/is_sorted.h>
#include <__config>
@@ -185,17 +185,19 @@ struct __is_partitioned<__default_backend_tag, _ExecutionPolicy> {
template <class _ExecutionPolicy>
struct __find_first_of<__default_backend_tag, _ExecutionPolicy> {
- template <class _Policy, class _ForwardIterator1, class _ForwardIterator2>
+ template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator1>
operator()(_Policy&& __policy,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
- _ForwardIterator2 __last2) const noexcept {
+ _ForwardIterator2 __last2,
+ _Predicate&& __pred) const noexcept {
using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
- using _Ref = __iterator_reference<_ForwardIterator1>;
- return _FindIf()(__policy, std::move(__first1), std::move(__last1), [&](_Ref __element) {
- return std::find(__first2, __last2, __element) != __last2;
+ using _Ref1 = __iterator_reference<_ForwardIterator1>;
+ using _Ref2 = __iterator_reference<_ForwardIterator2>;
+ return _FindIf()(__policy, std::move(__first1), std::move(__last1), [&](_Ref1 __element) {
+ return std::any_of(__first2, __last2, [&](_Ref2 __value) { return __pred(__element, __value); });
});
}
};
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of_pred.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of_pred.pass.cpp
new file mode 100644
index 0000000000000..00cb0f149a399
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of_pred.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template <class ExecutionPolicy,
+// class ForwardIterator1,
+// class ForwardIterator2,
+// class BinaryPredicate>
+// ForwardIterator1 find_first_of(ExecutionPolicy&& exec,
+// ForwardIterator1 first1,
+// ForwardIterator1 last1,
+// ForwardIterator2 first2,
+// ForwardIterator2 last2,
+// BinaryPredicate p);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <limits>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+
+struct Pred {
+ bool operator()(int l, int r) const {
+ return l + 1 == r; // ensures that the predicate is not equivalent to std::equal_to
+ }
+};
+
+template <class Iter>
+struct Test {
+ template <class ExecutionPolicy>
+ void operator()(ExecutionPolicy&& policy) {
+ {
+ int a[] = {0};
+ unsigned sa = sizeof(a) / sizeof(a[0]);
+ assert(std::find_first_of(policy, Iter(a), Iter(a), Iter(a), Iter(a), Pred{}) == Iter(a));
+ assert(std::find_first_of(policy, Iter(a), Iter(a + sa), Iter(a), Iter(a), Pred{}) == Iter(a + sa));
+ }
+ {
+ int ia[] = {0, 1, 2, 3, 0, 1, 2, 3};
+ unsigned sa = sizeof(ia) / sizeof(ia[0]);
+ int ib[] = {2, 4, 6, 8};
+ unsigned sb = sizeof(ib) / sizeof(ib[0]);
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia + sa), Iter(ib), Iter(ib + sb), Pred{}) == Iter(ia + 1));
+ int ic[] = {7};
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic + 1), Pred{}) == Iter(ia + sa));
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic), Pred{}) == Iter(ia + sa));
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia), Iter(ic), Iter(ic + 1), Pred{}) == Iter(ia));
+ }
+ {
+ int a[8192];
+ unsigned sa = sizeof(a) / sizeof(a[0]);
+ std::iota(a, a + sa, 1);
+ a[1023] = -2;
+ a[2048] = -2;
+ a[3071] = -2;
+ int b[] = {-1, 999999};
+ unsigned sb = sizeof(b) / sizeof(b[0]);
+ assert(std::find_first_of(policy, Iter(a), Iter(a + sa), Iter(b), Iter(b + sb), Pred{}) == Iter(a + 1023));
+ }
+ {
+ int a[1073];
+ unsigned sa = sizeof(a) / sizeof(a[0]);
+ std::iota(a, a + sa, 0);
+ int b[] = {1070, 1071, 1072, -1};
+ unsigned sb = sizeof(b) / sizeof(b[0]);
+ for (unsigned i = 0; i < sa; i = i <= 16 ? i + 1 : unsigned(3.1415 * i)) {
+ a[i] = -2;
+ assert(std::find_first_of(policy, Iter(a), Iter(a + sa), Iter(b), Iter(b + sb), Pred{}) == Iter(a + i));
+ a[i] = i;
+ }
+ }
+ }
+};
+
+int main(int, char**) {
+ types::for_each(types::concatenate_t<types::forward_iterator_list<int*>,
+ types::bidirectional_iterator_list<int*>,
+ types::random_access_iterator_list<int*>>{},
+ TestIteratorWithPolicies<Test>{});
+
+ return 0;
+}
>From 92e67cdebae5293ae478ecc9d385585e1f9b8d55 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Sun, 28 Jun 2026 12:30:10 +0100
Subject: [PATCH 3/4] Added verification for iterator types, nodiscard and
noexcept
---
.../pstl.iterator-requirements.verify.cpp | 7 +++++++
.../libcxx/algorithms/pstl.nodiscard.verify.cpp | 4 ++++
.../algorithms/pstl.exception_handling.pass.cpp | 15 +++++++++++++++
3 files changed, 26 insertions(+)
diff --git a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
index e5bd7e764c59b..1abaf5cc7b193 100644
--- a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
@@ -89,6 +89,13 @@ void f(non_forward_iterator non_fwd, non_output_iterator non_output, std::execut
(void)std::find_if_not(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: find_if_not}}
}
+ {
+ (void)std::find_first_of(
+ pol, non_fwd, non_fwd, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: find_first_of}}
+ (void)std::find_first_of(
+ pol, non_fwd, non_fwd, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: find_first_of}}
+ }
+
{
(void)std::for_each(pol, non_fwd, non_fwd, func); // expected-error@*:* {{static assertion failed: for_each}}
(void)std::for_each_n(pol, non_fwd, n, func); // expected-error@*:* {{static assertion failed: for_each_n}}
diff --git a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
index b6554cef6f32a..747d62bc66837 100644
--- a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
@@ -47,6 +47,10 @@ void test() {
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::find(std::execution::par, std::begin(a), std::end(a), 1);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_first_of(std::execution::par, std::begin(a), std::end(a), std::begin(b), std::end(b));
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_first_of(std::execution::par, std::begin(a), std::end(a), std::begin(b), std::end(b), pred2);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_partitioned(std::execution::par, std::begin(a), std::end(a), pred);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_sorted(std::execution::par, std::begin(a), std::end(a));
diff --git a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
index a3db159289393..9e6c8f5b8ce40 100644
--- a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
@@ -175,6 +175,21 @@ int main(int, char**) {
});
}
+ {
+ auto pred = maybe_throw(tokens[5], [](int x, int y) -> bool { return x == y; });
+
+ // find_first_of(first1, last1, first2, last2)
+ assert_non_throwing([=, &policy] {
+ (void)std::find_first_of(policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2));
+ });
+
+ // find_first_of(first1, last1, first2, last2, pred)
+ assert_non_throwing([=, &policy] {
+ (void)std::find_first_of(
+ policy, std::move(first1), std::move(last1), std::move(first2), std::move(last2), pred);
+ });
+ }
+
{
auto func = maybe_throw(tokens[5], [](int) {});
>From 65aa1ad5d9dd25a930e0cca5ba0c1d59fb3e8aa4 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Sun, 28 Jun 2026 13:09:11 +0100
Subject: [PATCH 4/4] Added a missing policy in the unit test
---
.../alg.find.first.of/pstl.find_first_of.pass.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp
index c4093daa71ba7..5768a8cf1f3c0 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/pstl.find_first_of.pass.cpp
@@ -45,11 +45,11 @@ struct Test {
unsigned sa = sizeof(ia) / sizeof(ia[0]);
int ib[] = {1, 3, 5, 7};
unsigned sb = sizeof(ib) / sizeof(ib[0]);
- assert(std::find_first_of(Iter(ia), Iter(ia + sa), Iter(ib), Iter(ib + sb)) == Iter(ia + 1));
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia + sa), Iter(ib), Iter(ib + sb)) == Iter(ia + 1));
int ic[] = {7};
- assert(std::find_first_of(Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic + 1)) == Iter(ia + sa));
- assert(std::find_first_of(Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic)) == Iter(ia + sa));
- assert(std::find_first_of(Iter(ia), Iter(ia), Iter(ic), Iter(ic + 1)) == Iter(ia));
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic + 1)) == Iter(ia + sa));
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia + sa), Iter(ic), Iter(ic)) == Iter(ia + sa));
+ assert(std::find_first_of(policy, Iter(ia), Iter(ia), Iter(ic), Iter(ic + 1)) == Iter(ia));
}
{
int a[8192];
More information about the libcxx-commits
mailing list