[libcxx-commits] [libcxx] [WIP] Specialize std::search for char (PR #130476)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Mar 11 17:58:25 PDT 2025
https://github.com/hiraditya updated https://github.com/llvm/llvm-project/pull/130476
>From 19f796df9d6f7ad7164e535970599daf66cf2f70 Mon Sep 17 00:00:00 2001
From: AdityaK <hiraditya at msn.com>
Date: Tue, 11 Mar 2025 17:48:21 -0700
Subject: [PATCH] [WIP] Specialize std::search for char
Bug: #130432
---
libcxx/include/__algorithm/search.h | 35 ++++++++++++++++++-
.../alg.search/search.pass.cpp | 11 ++++++
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index 161fd39d861a6..82ba3cedc3049 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -17,9 +17,11 @@
#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_callable.h>
+#include <__type_traits/is_same.h>
#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -159,6 +161,29 @@ _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 _ForwardIterator1, class _ForwardIterator2, class _CharT, class _Traits>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 search_str(
+ _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
+ auto __size2 = __last2 - __first2;
+ if (__size2 == 0)
+ return __first1;
+
+ auto __size1 = __last1 - __first1;
+ if (__size1 < __size2) {
+ return __last1;
+ }
+ using value_type = remove_const_t<typename iterator_traits<_ForwardIterator1>::value_type>;
+
+ const value_type* __r = std::__search_substring<_CharT, _Traits>(__first1, __last1, __first2, __last2);
+ if (__r == __first1)
+ return __first1;
+
+ if (__r == __last1)
+ return __last1;
+
+ return __r;
+}
+
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
search(_ForwardIterator1 __first1,
@@ -175,7 +200,15 @@ search(_ForwardIterator1 __first1,
template <class _ForwardIterator1, class _ForwardIterator2>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
- return std::search(__first1, __last1, __first2, __last2, __equal_to());
+ using value_type = __remove_const_t<typename iterator_traits<_ForwardIterator1>::value_type>;
+ if constexpr (is_same<value_type, char>::value || is_same<value_type, wchar_t>::value ||
+ is_same<value_type, char8_t>::value || is_same<value_type, char16_t>::value ||
+ is_same<value_type, char32_t>::value) {
+ using _CharT = value_type;
+ using _Traits = char_traits<_CharT>;
+ return std::search_str<_ForwardIterator1, _ForwardIterator2, _CharT, _Traits>(__first1, __last1, __first2, __last2);
+ } else
+ return std::search(__first1, __last1, __first2, __last2, __equal_to());
}
#if _LIBCPP_STD_VER >= 17
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 3bf2fd9d6bb04..9677dd0be2d70 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
@@ -104,6 +104,17 @@ void 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);
+}
+
int main(int, char**) {
test<forward_iterator<const int*>, forward_iterator<const int*> >();
test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
More information about the libcxx-commits
mailing list