[libcxx-commits] [libcxx] [libc++] Refactor __search_forward_impl to use __mismatch (PR #192785)
Shonie Caplan via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 18 03:49:28 PDT 2026
https://github.com/shoniecaplan created https://github.com/llvm/llvm-project/pull/192785
- For: #129326
Replace hand-written inner match loop in `__search_forward_impl` with a call to `std::__mismatch`.
Existing benchmark results are equivalent to the original implementation.
---
Also fixes a few grammatical errors in the function's comments.
Regarding the original issue's mention of `std::find` replacing the first while loop: I don't see a way for this to be done with `std::find` as the `_Iter1` and `_Sent1` types may not match. I was not able to get that working.
>From a9fb73de379bf7f8728047949e2b40fe00332021 Mon Sep 17 00:00:00 2001
From: Shonie Caplan <shonie4caplan at gmail.com>
Date: Sat, 18 Apr 2026 19:45:19 +0900
Subject: [PATCH] [libc++] Refactor __search_forward_impl to use __mismatch
- For: #129326
Replace hand-written inner match loop in __search_forward_impl with a call to std::__mismatch.
Existing benchmark results are equivalent to the original implementation.
---
libcxx/include/__algorithm/search.h | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index 161fd39d861a6..33b7a6218f930 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -12,6 +12,7 @@
#include <__algorithm/comp.h>
#include <__algorithm/iterator_operations.h>
+#include <__algorithm/mismatch.h>
#include <__config>
#include <__functional/identity.h>
#include <__iterator/advance.h>
@@ -38,10 +39,12 @@ template <class _AlgPolicy,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_forward_impl(
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+
if (__first2 == __last2)
return std::make_pair(__first1, __first1); // Everything matches an empty sequence
+
while (true) {
- // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
+ // Find first element in sequence 1 that matches *__first2
while (true) {
if (__first1 == __last1) { // return __last1 if no element matches *__first2
_IterOps<_AlgPolicy>::__advance_to(__first1, __last1);
@@ -51,21 +54,19 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __searc
break;
++__first1;
}
- // *__first1 matches *__first2, now match elements after here
+
+ // *__first1 matches *__first2, now match the elements after here
_Iter1 __m1 = __first1;
_Iter2 __m2 = __first2;
- while (true) {
- if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
- return std::make_pair(__first1, ++__m1);
- if (++__m1 == __last1) { // Otherwise if source exhaused, pattern not found
- return std::make_pair(__m1, __m1);
- }
+ std::pair<_Iter1, _Iter2> __pair = std::__mismatch(++__m1, __last1, ++__m2, __last2, __pred, __proj1, __proj2);
+ if (__pair.second == __last2) { // Reach end of __m2, so this is the answer
+ return std::make_pair(__first1, __pair.first);
- // if there is a mismatch, restart with a new __first1
- if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
- ++__first1;
- break;
- } // else there is a match, check next elements
+ } else if (__pair.first == __last1) { // Otherwise if source exhausted, pattern not found
+ return std::make_pair(__pair.first, __pair.first);
+
+ } else { // if there is a mismatch, restart with a new __first1
+ ++__first1;
}
}
}
More information about the libcxx-commits
mailing list