[libcxx-commits] [libcxx] [libc++][pstl] Default implementation of parallel std::find_first_of (PR #206328)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 1 10:06:11 PDT 2026


================
@@ -181,6 +183,25 @@ 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, class _Predicate>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator1>
+  operator()(_Policy&& __policy,
+             _ForwardIterator1 __first1,
+             _ForwardIterator1 __last1,
+             _ForwardIterator2 __first2,
+             _ForwardIterator2 __last2,
+             _Predicate&& __pred) const noexcept {
+    using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
+    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); });
+    });
----------------
ldionne wrote:

I think I just clarified what I was trying to say yesterday when I opened #206784 . What would be nice is for this code:

```c++
return _FindIf()(__policy, std::move(__first1), std::move(__last1), [&](_Ref1 __element) {
  return std::any_of(__first2, __last2, [&](_Ref2 __value) { return __pred(__element, __value); });
});
```

to basically desugar to

```c++
return _FindIf()(__policy, std::move(__first1), std::move(__last1), [&](_Ref1 __element) {
  return std::find(__first2, __last2, __element);
});
```

when the predicate is `equal_to`. Then we'd allow for vectorization. I see two ways of achieving this:

1. Here, branch off on `desugars_to<__equal_tag` and call `std::find` directly, or
2. Write this as `std::any_of(__first2, __last2, __partial(__equal_to{}, __element))`. Since `any_of` uses `find_if` under the hood, if `find_if` gets `__partial(OP, ...)` where `OP` desugars to `equal_to`, we can actually call `std::find` under the hood.

(2) is more complicated but more general. (1) is more pragmatic and directly applicable in this patch.

Thoughts? CC @philnik777 

https://github.com/llvm/llvm-project/pull/206328


More information about the libcxx-commits mailing list