[libcxx-commits] [libcxx] [WIP] Specialize std::search for char (PR #130476)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Mar 9 00:51:48 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: AdityaK (hiraditya)

<details>
<summary>Changes</summary>

Bug: #<!-- -->130432

---
Full diff: https://github.com/llvm/llvm-project/pull/130476.diff


2 Files Affected:

- (modified) libcxx/include/__algorithm/search.h (+30) 
- (modified) libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search.pass.cpp (+12) 


``````````diff
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index 161fd39d861a6..f9c2f151e4f36 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -17,8 +17,10 @@
 #include <__iterator/advance.h>
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
+#include <__string/char_traits.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/invoke.h>
+#include <__type_traits/is_same.h>
 #include <__type_traits/is_callable.h>
 #include <__utility/pair.h>
 
@@ -159,6 +161,34 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __searc
   return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
 }
 
+template <class _Iter1,
+          class _Sent1,
+          class _Iter2,
+          class _Sent2,
+          __enable_if_t<__has_random_access_iterator_category<_Iter1>::value &&
+                            __has_random_access_iterator_category<_Iter2>::value &&
+                            is_same<typename iterator_traits<_Iter1>::value_type, char>::value &&
+                            is_same<typename iterator_traits<_Iter2>::value_type, typename iterator_traits<_Iter2>::value_type>::value,
+                        int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> search(
+    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2) {
+  auto __size2 = __last2 - __first2;
+  if (__size2 == 0)
+    return std::make_pair(__first1, __first1);
+
+  auto __size1 = __last1 - __first1;
+  if (__size1 < __size2) {
+    return std::make_pair(__last1, __last1);
+  }
+  using value_type = typename iterator_traits<_Iter1>::value_type;
+
+  const value_type* __r = std::__search_substring(__first1, __last1, __first2, __last2);
+  if (__r == __size1)
+    return std::make_pair(__first1, __first1);
+
+  return std::make_pair(__first1 + __r, __first1 + __r + __size2);
+}
+
 template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
 search(_ForwardIterator1 __first1,
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search.pass.cpp
index b4b841f273c46..8320f3d13ed30 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search.pass.cpp
@@ -116,6 +116,17 @@ adl_test()
     assert(std::search(Iter(ua), Iter(ua), Iter(ua), Iter(ua)) == Iter(ua));
 }
 
+void test_str() {
+    const char* s = "abcde";
+    const char* f = "abc";
+    const char* l = "cde";
+    assert(std::search(s, s+5, f, f+3) == s);
+    assert(std::search(s, s+5, l, l+3) == s+2);
+    assert(std::search(s, s+5, s, s+1) == s);
+    assert(std::search(s, s+5, s, s+5) == s);
+    assert(std::search(s, s+5, s+5, s+5) == s+5);
+}
+
 int main(int, char**)
 {
     test<forward_iterator<const int*>, forward_iterator<const int*> >();
@@ -130,6 +141,7 @@ int main(int, char**)
 
     adl_test<forward_iterator<User::S*> >();
     adl_test<random_access_iterator<User::S*> >();
+    test_str();
 
 #if TEST_STD_VER > 14
 {

``````````

</details>


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


More information about the libcxx-commits mailing list