|
17 | 17 | #include <__iterator/advance.h> |
18 | 18 | #include <__iterator/concepts.h> |
19 | 19 | #include <__iterator/iterator_traits.h> |
| 20 | +#include <__string/char_traits.h> |
| 21 | +#include <__type_traits/desugars_to.h> |
20 | 22 | #include <__type_traits/enable_if.h> |
21 | 23 | #include <__type_traits/invoke.h> |
22 | 24 | #include <__type_traits/is_callable.h> |
| 25 | +#include <__type_traits/is_same.h> |
23 | 26 | #include <__utility/pair.h> |
24 | 27 |
|
25 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
@@ -159,6 +162,49 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __searc |
159 | 162 | return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); |
160 | 163 | } |
161 | 164 |
|
| 165 | +template < |
| 166 | + class _Iter1, |
| 167 | + class _Sent1, |
| 168 | + class _Iter2, |
| 169 | + class _Sent2, |
| 170 | + class _Pred, |
| 171 | + class _Proj1, |
| 172 | + class _Proj2, |
| 173 | + __enable_if_t<__desugars_to_v<__equal_tag, _Pred, typename iterator_traits<_Iter1>::value_type, typename iterator_traits<_Iter1>::value_type> && |
| 174 | + __is_identity<_Proj1>::value && __is_identity<_Proj2>::value && |
| 175 | + __has_random_access_iterator_category<_Iter1>::value && |
| 176 | + __has_random_access_iterator_category<_Iter2>::value && |
| 177 | + (is_same_v<typename iterator_traits<_Iter1>::value_type, char> || |
| 178 | + is_same_v<typename iterator_traits<_Iter1>::value_type, wchar_t> || |
| 179 | + is_same_v<typename iterator_traits<_Iter1>::value_type, char8_t> || |
| 180 | + is_same_v<typename iterator_traits<_Iter1>::value_type, char16_t> || |
| 181 | + is_same_v<typename iterator_traits<_Iter1>::value_type, char32_t>), |
| 182 | + int> = 0> |
| 183 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl( |
| 184 | + _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { |
| 185 | + using value_type = __remove_const_t<typename iterator_traits<_Iter1>::value_type>; |
| 186 | + using _CharT = value_type; |
| 187 | + using _Traits = char_traits<_CharT>; |
| 188 | + |
| 189 | + auto __size2 = __last2 - __first2; |
| 190 | + if (__size2 == 0) |
| 191 | + return {__first1, __first1}; |
| 192 | + |
| 193 | + auto __size1 = __last1 - __first1; |
| 194 | + if (__size1 < __size2) { |
| 195 | + return {__last1, __last1}; |
| 196 | + } |
| 197 | + |
| 198 | + const value_type* __r = std::__search_substring<_CharT, _Traits>(__first1, __last1, __first2, __last2); |
| 199 | + if (__r == __first1) |
| 200 | + return {__first1, __first1}; |
| 201 | + |
| 202 | + if (__r == __last1) |
| 203 | + return {__last1, __last1}; |
| 204 | + |
| 205 | + return {__r, __r + __size1}; |
| 206 | +} |
| 207 | + |
162 | 208 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> |
163 | 209 | [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 |
164 | 210 | search(_ForwardIterator1 __first1, |
|
0 commit comments