1 1.1 joerg // -*- C++ -*- 2 1.1 joerg //===-------------------------- functional --------------------------------===// 3 1.1 joerg // 4 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 6 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 1.1 joerg // 8 1.1 joerg //===----------------------------------------------------------------------===// 9 1.1 joerg 10 1.1 joerg #ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL 11 1.1 joerg #define _LIBCPP_EXPERIMENTAL_FUNCTIONAL 12 1.1 joerg 13 1.1 joerg /* 14 1.1 joerg experimental/functional synopsis 15 1.1 joerg 16 1.1 joerg #include <algorithm> 17 1.1 joerg 18 1.1 joerg namespace std { 19 1.1 joerg namespace experimental { 20 1.1 joerg inline namespace fundamentals_v1 { 21 1.1 joerg 22 1.1 joerg // See C++14 20.9.9, Function object binders 23 1.1 joerg template <class T> constexpr bool is_bind_expression_v 24 1.1 joerg = is_bind_expression<T>::value; 25 1.1 joerg template <class T> constexpr int is_placeholder_v 26 1.1 joerg = is_placeholder<T>::value; 27 1.1 joerg 28 1.1 joerg // 4.2, Class template function 29 1.1 joerg template<class> class function; // undefined 30 1.1 joerg template<class R, class... ArgTypes> class function<R(ArgTypes...)>; 31 1.1 joerg 32 1.1 joerg template<class R, class... ArgTypes> 33 1.1 joerg void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&); 34 1.1 joerg 35 1.1 joerg template<class R, class... ArgTypes> 36 1.1 joerg bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; 37 1.1 joerg template<class R, class... ArgTypes> 38 1.1 joerg bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept; 39 1.1 joerg template<class R, class... ArgTypes> 40 1.1 joerg bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept; 41 1.1 joerg template<class R, class... ArgTypes> 42 1.1 joerg bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept; 43 1.1 joerg 44 1.1 joerg // 4.3, Searchers 45 1.1 joerg template<class ForwardIterator, class BinaryPredicate = equal_to<>> 46 1.1 joerg class default_searcher; 47 1.1 joerg 48 1.1 joerg template<class RandomAccessIterator, 49 1.1 joerg class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 50 1.1 joerg class BinaryPredicate = equal_to<>> 51 1.1 joerg class boyer_moore_searcher; 52 1.1 joerg 53 1.1 joerg template<class RandomAccessIterator, 54 1.1 joerg class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 55 1.1 joerg class BinaryPredicate = equal_to<>> 56 1.1 joerg class boyer_moore_horspool_searcher; 57 1.1 joerg 58 1.1 joerg template<class ForwardIterator, class BinaryPredicate = equal_to<>> 59 1.1 joerg default_searcher<ForwardIterator, BinaryPredicate> 60 1.1 joerg make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, 61 1.1 joerg BinaryPredicate pred = BinaryPredicate()); 62 1.1 joerg 63 1.1 joerg template<class RandomAccessIterator, 64 1.1 joerg class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 65 1.1 joerg class BinaryPredicate = equal_to<>> 66 1.1 joerg boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate> 67 1.1 joerg make_boyer_moore_searcher( 68 1.1 joerg RandomAccessIterator pat_first, RandomAccessIterator pat_last, 69 1.1 joerg Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); 70 1.1 joerg 71 1.1 joerg template<class RandomAccessIterator, 72 1.1 joerg class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 73 1.1 joerg class BinaryPredicate = equal_to<>> 74 1.1 joerg boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate> 75 1.1 joerg make_boyer_moore_horspool_searcher( 76 1.1 joerg RandomAccessIterator pat_first, RandomAccessIterator pat_last, 77 1.1 joerg Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); 78 1.1 joerg 79 1.1 joerg } // namespace fundamentals_v1 80 1.1 joerg } // namespace experimental 81 1.1 joerg 82 1.1 joerg template<class R, class... ArgTypes, class Alloc> 83 1.1 joerg struct uses_allocator<experimental::function<R(ArgTypes...)>, Alloc>; 84 1.1 joerg 85 1.1 joerg } // namespace std 86 1.1 joerg 87 1.1 joerg */ 88 1.1 joerg 89 1.1 joerg #include <experimental/__config> 90 1.1 joerg #include <functional> 91 1.1 joerg #include <algorithm> 92 1.1 joerg #include <type_traits> 93 1.1 joerg #include <vector> 94 1.1 joerg #include <array> 95 1.1 joerg #include <unordered_map> 96 1.1 joerg 97 1.1 joerg #include <__debug> 98 1.1 joerg 99 1.1 joerg #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 100 1.1 joerg #pragma GCC system_header 101 1.1 joerg #endif 102 1.1 joerg 103 1.1 joerg _LIBCPP_PUSH_MACROS 104 1.1 joerg #include <__undef_macros> 105 1.1 joerg 106 1.1 joerg 107 1.1 joerg _LIBCPP_BEGIN_NAMESPACE_LFTS 108 1.1 joerg 109 1.1 joerg #if _LIBCPP_STD_VER > 11 110 1.1 joerg // default searcher 111 1.1 joerg template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> 112 1.1 joerg class _LIBCPP_TEMPLATE_VIS default_searcher { 113 1.1 joerg public: 114 1.1 joerg _LIBCPP_INLINE_VISIBILITY 115 1.1 joerg default_searcher(_ForwardIterator __f, _ForwardIterator __l, 116 1.1 joerg _BinaryPredicate __p = _BinaryPredicate()) 117 1.1 joerg : __first_(__f), __last_(__l), __pred_(__p) {} 118 1.1 joerg 119 1.1 joerg template <typename _ForwardIterator2> 120 1.1 joerg _LIBCPP_INLINE_VISIBILITY 121 1.1 joerg pair<_ForwardIterator2, _ForwardIterator2> 122 1.1 joerg operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const 123 1.1 joerg { 124 1.1 joerg return _VSTD::__search(__f, __l, __first_, __last_, __pred_, 125 1.1 joerg typename iterator_traits<_ForwardIterator>::iterator_category(), 126 1.1 joerg typename iterator_traits<_ForwardIterator2>::iterator_category()); 127 1.1 joerg } 128 1.1 joerg 129 1.1 joerg private: 130 1.1 joerg _ForwardIterator __first_; 131 1.1 joerg _ForwardIterator __last_; 132 1.1 joerg _BinaryPredicate __pred_; 133 1.1 joerg }; 134 1.1 joerg 135 1.1 joerg template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> 136 1.1 joerg _LIBCPP_INLINE_VISIBILITY 137 1.1 joerg default_searcher<_ForwardIterator, _BinaryPredicate> 138 1.1 joerg make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ()) 139 1.1 joerg { 140 1.1 joerg return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p); 141 1.1 joerg } 142 1.1 joerg 143 1.1 joerg template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable; 144 1.1 joerg 145 1.1 joerg // General case for BM data searching; use a map 146 1.1 joerg template<class _Key, typename _Value, class _Hash, class _BinaryPredicate> 147 1.1 joerg class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { 148 1.1 joerg public: // TODO private: 149 1.1 joerg typedef _Value value_type; 150 1.1 joerg typedef _Key key_type; 151 1.1 joerg 152 1.1 joerg const _Value __default_value_; 153 1.1 joerg std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table; 154 1.1 joerg 155 1.1 joerg public: 156 1.1 joerg _LIBCPP_INLINE_VISIBILITY 157 1.1 joerg _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred) 158 1.1 joerg : __default_value_(__default), __table(__sz, __hf, __pred) {} 159 1.1 joerg 160 1.1 joerg _LIBCPP_INLINE_VISIBILITY 161 1.1 joerg void insert(const key_type &__key, value_type __val) 162 1.1 joerg { 163 1.1 joerg __table [__key] = __val; // Would skip_.insert (val) be better here? 164 1.1 joerg } 165 1.1 joerg 166 1.1 joerg _LIBCPP_INLINE_VISIBILITY 167 1.1 joerg value_type operator [](const key_type & __key) const 168 1.1 joerg { 169 1.1 joerg auto __it = __table.find (__key); 170 1.1 joerg return __it == __table.end() ? __default_value_ : __it->second; 171 1.1 joerg } 172 1.1 joerg }; 173 1.1 joerg 174 1.1 joerg 175 1.1 joerg // Special case small numeric values; use an array 176 1.1 joerg template<class _Key, typename _Value, class _Hash, class _BinaryPredicate> 177 1.1 joerg class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { 178 1.1 joerg private: 179 1.1 joerg typedef _Value value_type; 180 1.1 joerg typedef _Key key_type; 181 1.1 joerg 182 1.1 joerg typedef typename make_unsigned<key_type>::type unsigned_key_type; 183 1.1 joerg typedef std::array<value_type, numeric_limits<unsigned_key_type>::max()> skip_map; 184 1.1 joerg skip_map __table; 185 1.1 joerg 186 1.1 joerg public: 187 1.1 joerg _LIBCPP_INLINE_VISIBILITY 188 1.1 joerg _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/) 189 1.1 joerg { 190 1.1 joerg std::fill_n(__table.begin(), __table.size(), __default); 191 1.1 joerg } 192 1.1 joerg 193 1.1 joerg _LIBCPP_INLINE_VISIBILITY 194 1.1 joerg void insert(key_type __key, value_type __val) 195 1.1 joerg { 196 1.1 joerg __table[static_cast<unsigned_key_type>(__key)] = __val; 197 1.1 joerg } 198 1.1 joerg 199 1.1 joerg _LIBCPP_INLINE_VISIBILITY 200 1.1 joerg value_type operator [](key_type __key) const 201 1.1 joerg { 202 1.1 joerg return __table[static_cast<unsigned_key_type>(__key)]; 203 1.1 joerg } 204 1.1 joerg }; 205 1.1 joerg 206 1.1 joerg 207 1.1 joerg template <class _RandomAccessIterator1, 208 1.1 joerg class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, 209 1.1 joerg class _BinaryPredicate = equal_to<>> 210 1.1 joerg class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { 211 1.1 joerg private: 212 1.1 joerg typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; 213 1.1 joerg typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; 214 1.1 joerg typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate, 215 1.1 joerg is_integral<value_type>::value && // what about enums? 216 1.1 joerg sizeof(value_type) == 1 && 217 1.1 joerg is_same<_Hash, hash<value_type>>::value && 218 1.1 joerg is_same<_BinaryPredicate, equal_to<>>::value 219 1.1 joerg > skip_table_type; 220 1.1 joerg 221 1.1 joerg public: 222 1.1 joerg boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 223 1.1 joerg _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) 224 1.1 joerg : __first_(__f), __last_(__l), __pred_(__pred), 225 1.1 joerg __pattern_length_(_VSTD::distance(__first_, __last_)), 226 1.1 joerg __skip_{make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)}, 227 1.1 joerg __suffix_{make_shared<vector<difference_type>>(__pattern_length_ + 1)} 228 1.1 joerg { 229 1.1 joerg // build the skip table 230 1.1 joerg for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) 231 1.1 joerg __skip_->insert(*__f, __i); 232 1.1 joerg 233 1.1 joerg this->__build_suffix_table ( __first_, __last_, __pred_ ); 234 1.1 joerg } 235 1.1 joerg 236 1.1 joerg template <typename _RandomAccessIterator2> 237 1.1 joerg pair<_RandomAccessIterator2, _RandomAccessIterator2> 238 1.1 joerg operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const 239 1.1 joerg { 240 1.1 joerg static_assert ( std::is_same< 241 1.1 joerg typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type, 242 1.1 joerg typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type 243 1.1 joerg >::value, 244 1.1 joerg "Corpus and Pattern iterators must point to the same type" ); 245 1.1 joerg 246 1.1 joerg if (__f == __l ) return make_pair(__l, __l); // empty corpus 247 1.1 joerg if (__first_ == __last_) return make_pair(__f, __f); // empty pattern 248 1.1 joerg 249 1.1 joerg // If the pattern is larger than the corpus, we can't find it! 250 1.1 joerg if ( __pattern_length_ > _VSTD::distance(__f, __l)) 251 1.1 joerg return make_pair(__l, __l); 252 1.1 joerg 253 1.1 joerg // Do the search 254 1.1 joerg return this->__search(__f, __l); 255 1.1 joerg } 256 1.1 joerg 257 1.1 joerg public: // TODO private: 258 1.1 joerg _RandomAccessIterator1 __first_; 259 1.1 joerg _RandomAccessIterator1 __last_; 260 1.1 joerg _BinaryPredicate __pred_; 261 1.1 joerg difference_type __pattern_length_; 262 1.1 joerg shared_ptr<skip_table_type> __skip_; 263 1.1 joerg shared_ptr<vector<difference_type>> __suffix_; 264 1.1 joerg 265 1.1 joerg template <typename _RandomAccessIterator2> 266 1.1 joerg pair<_RandomAccessIterator2, _RandomAccessIterator2> 267 1.1 joerg __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const 268 1.1 joerg { 269 1.1 joerg _RandomAccessIterator2 __cur = __f; 270 1.1 joerg const _RandomAccessIterator2 __last = __l - __pattern_length_; 271 1.1 joerg const skip_table_type & __skip = *__skip_.get(); 272 1.1 joerg const vector<difference_type> & __suffix = *__suffix_.get(); 273 1.1 joerg 274 1.1 joerg while (__cur <= __last) 275 1.1 joerg { 276 1.1 joerg 277 1.1 joerg // Do we match right where we are? 278 1.1 joerg difference_type __j = __pattern_length_; 279 1.1 joerg while (__pred_(__first_ [__j-1], __cur [__j-1])) { 280 1.1 joerg __j--; 281 1.1 joerg // We matched - we're done! 282 1.1 joerg if ( __j == 0 ) 283 1.1 joerg return make_pair(__cur, __cur + __pattern_length_); 284 1.1 joerg } 285 1.1 joerg 286 1.1 joerg // Since we didn't match, figure out how far to skip forward 287 1.1 joerg difference_type __k = __skip[__cur [ __j - 1 ]]; 288 1.1 joerg difference_type __m = __j - __k - 1; 289 1.1 joerg if (__k < __j && __m > __suffix[ __j ]) 290 1.1 joerg __cur += __m; 291 1.1 joerg else 292 1.1 joerg __cur += __suffix[ __j ]; 293 1.1 joerg } 294 1.1 joerg 295 1.1 joerg return make_pair(__l, __l); // We didn't find anything 296 1.1 joerg } 297 1.1 joerg 298 1.1 joerg 299 1.1 joerg template<typename _Iterator, typename _Container> 300 1.1 joerg void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix ) 301 1.1 joerg { 302 1.1 joerg const size_t __count = _VSTD::distance(__f, __l); 303 1.1 joerg 304 1.1 joerg __prefix[0] = 0; 305 1.1 joerg size_t __k = 0; 306 1.1 joerg for ( size_t __i = 1; __i < __count; ++__i ) 307 1.1 joerg { 308 1.1 joerg while ( __k > 0 && !__pred ( __f[__k], __f[__i] )) 309 1.1 joerg __k = __prefix [ __k - 1 ]; 310 1.1 joerg 311 1.1 joerg if ( __pred ( __f[__k], __f[__i] )) 312 1.1 joerg __k++; 313 1.1 joerg __prefix [ __i ] = __k; 314 1.1 joerg } 315 1.1 joerg } 316 1.1 joerg 317 1.1 joerg void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 318 1.1 joerg _BinaryPredicate __pred) 319 1.1 joerg { 320 1.1 joerg const size_t __count = _VSTD::distance(__f, __l); 321 1.1 joerg vector<difference_type> & __suffix = *__suffix_.get(); 322 1.1 joerg if (__count > 0) 323 1.1 joerg { 324 1.1 joerg vector<value_type> __scratch(__count); 325 1.1 joerg 326 1.1 joerg __compute_bm_prefix(__f, __l, __pred, __scratch); 327 1.1 joerg for ( size_t __i = 0; __i <= __count; __i++ ) 328 1.1 joerg __suffix[__i] = __count - __scratch[__count-1]; 329 1.1 joerg 330 1.1 joerg typedef reverse_iterator<_RandomAccessIterator1> _RevIter; 331 1.1 joerg __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch); 332 1.1 joerg 333 1.1 joerg for ( size_t __i = 0; __i < __count; __i++ ) 334 1.1 joerg { 335 1.1 joerg const size_t __j = __count - __scratch[__i]; 336 1.1 joerg const difference_type __k = __i - __scratch[__i] + 1; 337 1.1 joerg 338 1.1 joerg if (__suffix[__j] > __k) 339 1.1 joerg __suffix[__j] = __k; 340 1.1 joerg } 341 1.1 joerg } 342 1.1 joerg } 343 1.1 joerg 344 1.1 joerg }; 345 1.1 joerg 346 1.1 joerg template<class _RandomAccessIterator, 347 1.1 joerg class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, 348 1.1 joerg class _BinaryPredicate = equal_to<>> 349 1.1 joerg _LIBCPP_INLINE_VISIBILITY 350 1.1 joerg boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> 351 1.1 joerg make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, 352 1.1 joerg _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) 353 1.1 joerg { 354 1.1 joerg return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); 355 1.1 joerg } 356 1.1 joerg 357 1.1 joerg // boyer-moore-horspool 358 1.1 joerg template <class _RandomAccessIterator1, 359 1.1 joerg class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, 360 1.1 joerg class _BinaryPredicate = equal_to<>> 361 1.1 joerg class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { 362 1.1 joerg private: 363 1.1 joerg typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; 364 1.1 joerg typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; 365 1.1 joerg typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate, 366 1.1 joerg is_integral<value_type>::value && // what about enums? 367 1.1 joerg sizeof(value_type) == 1 && 368 1.1 joerg is_same<_Hash, hash<value_type>>::value && 369 1.1 joerg is_same<_BinaryPredicate, equal_to<>>::value 370 1.1 joerg > skip_table_type; 371 1.1 joerg 372 1.1 joerg public: 373 1.1 joerg boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 374 1.1 joerg _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) 375 1.1 joerg : __first_(__f), __last_(__l), __pred_(__pred), 376 1.1 joerg __pattern_length_(_VSTD::distance(__first_, __last_)), 377 1.1 joerg __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)} 378 1.1 joerg { 379 1.1 joerg // build the skip table 380 1.1 joerg if ( __f != __l ) 381 1.1 joerg { 382 1.1 joerg __l = __l - 1; 383 1.1 joerg for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) 384 1.1 joerg __skip_->insert(*__f, __pattern_length_ - 1 - __i); 385 1.1 joerg } 386 1.1 joerg } 387 1.1 joerg 388 1.1 joerg template <typename _RandomAccessIterator2> 389 1.1 joerg pair<_RandomAccessIterator2, _RandomAccessIterator2> 390 1.1 joerg operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const 391 1.1 joerg { 392 1.1 joerg static_assert ( std::is_same< 393 1.1 joerg typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type, 394 1.1 joerg typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type 395 1.1 joerg >::value, 396 1.1 joerg "Corpus and Pattern iterators must point to the same type" ); 397 1.1 joerg 398 1.1 joerg if (__f == __l ) return make_pair(__l, __l); // empty corpus 399 1.1 joerg if (__first_ == __last_) return make_pair(__f, __f); // empty pattern 400 1.1 joerg 401 1.1 joerg // If the pattern is larger than the corpus, we can't find it! 402 1.1 joerg if ( __pattern_length_ > _VSTD::distance(__f, __l)) 403 1.1 joerg return make_pair(__l, __l); 404 1.1 joerg 405 1.1 joerg // Do the search 406 1.1 joerg return this->__search(__f, __l); 407 1.1 joerg } 408 1.1 joerg 409 1.1 joerg private: 410 1.1 joerg _RandomAccessIterator1 __first_; 411 1.1 joerg _RandomAccessIterator1 __last_; 412 1.1 joerg _BinaryPredicate __pred_; 413 1.1 joerg difference_type __pattern_length_; 414 1.1 joerg shared_ptr<skip_table_type> __skip_; 415 1.1 joerg 416 1.1 joerg template <typename _RandomAccessIterator2> 417 1.1 joerg pair<_RandomAccessIterator2, _RandomAccessIterator2> 418 1.1 joerg __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { 419 1.1 joerg _RandomAccessIterator2 __cur = __f; 420 1.1 joerg const _RandomAccessIterator2 __last = __l - __pattern_length_; 421 1.1 joerg const skip_table_type & __skip = *__skip_.get(); 422 1.1 joerg 423 1.1 joerg while (__cur <= __last) 424 1.1 joerg { 425 1.1 joerg // Do we match right where we are? 426 1.1 joerg difference_type __j = __pattern_length_; 427 1.1 joerg while (__pred_(__first_[__j-1], __cur[__j-1])) 428 1.1 joerg { 429 1.1 joerg __j--; 430 1.1 joerg // We matched - we're done! 431 1.1 joerg if ( __j == 0 ) 432 1.1 joerg return make_pair(__cur, __cur + __pattern_length_); 433 1.1 joerg } 434 1.1 joerg __cur += __skip[__cur[__pattern_length_-1]]; 435 1.1 joerg } 436 1.1 joerg 437 1.1 joerg return make_pair(__l, __l); 438 1.1 joerg } 439 1.1 joerg }; 440 1.1 joerg 441 1.1 joerg template<class _RandomAccessIterator, 442 1.1 joerg class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, 443 1.1 joerg class _BinaryPredicate = equal_to<>> 444 1.1 joerg _LIBCPP_INLINE_VISIBILITY 445 1.1 joerg boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> 446 1.1 joerg make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, 447 1.1 joerg _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) 448 1.1 joerg { 449 1.1 joerg return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); 450 1.1 joerg } 451 1.1 joerg 452 1.1 joerg #endif // _LIBCPP_STD_VER > 11 453 1.1 joerg 454 1.1 joerg _LIBCPP_END_NAMESPACE_LFTS 455 1.1 joerg 456 1.1 joerg _LIBCPP_POP_MACROS 457 1.1 joerg 458 1.1 joerg #endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */ 459