146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL 1146035553Spatrick#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL 1246035553Spatrick 1346035553Spatrick/* 1446035553Spatrick experimental/functional synopsis 1546035553Spatrick 1646035553Spatrick#include <algorithm> 1746035553Spatrick 1846035553Spatricknamespace std { 1946035553Spatricknamespace experimental { 2046035553Spatrickinline namespace fundamentals_v1 { 2146035553Spatrick // 4.3, Searchers 2246035553Spatrick template<class ForwardIterator, class BinaryPredicate = equal_to<>> 2346035553Spatrick class default_searcher; 2446035553Spatrick 2546035553Spatrick template<class RandomAccessIterator, 2646035553Spatrick class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 2746035553Spatrick class BinaryPredicate = equal_to<>> 2846035553Spatrick class boyer_moore_searcher; 2946035553Spatrick 3046035553Spatrick template<class RandomAccessIterator, 3146035553Spatrick class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 3246035553Spatrick class BinaryPredicate = equal_to<>> 3346035553Spatrick class boyer_moore_horspool_searcher; 3446035553Spatrick 3546035553Spatrick template<class ForwardIterator, class BinaryPredicate = equal_to<>> 3646035553Spatrick default_searcher<ForwardIterator, BinaryPredicate> 3746035553Spatrick make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, 3846035553Spatrick BinaryPredicate pred = BinaryPredicate()); 3946035553Spatrick 4046035553Spatrick template<class RandomAccessIterator, 4146035553Spatrick class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 4246035553Spatrick class BinaryPredicate = equal_to<>> 4346035553Spatrick boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate> 4446035553Spatrick make_boyer_moore_searcher( 4546035553Spatrick RandomAccessIterator pat_first, RandomAccessIterator pat_last, 4646035553Spatrick Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); 4746035553Spatrick 4846035553Spatrick template<class RandomAccessIterator, 4946035553Spatrick class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, 5046035553Spatrick class BinaryPredicate = equal_to<>> 5146035553Spatrick boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate> 5246035553Spatrick make_boyer_moore_horspool_searcher( 5346035553Spatrick RandomAccessIterator pat_first, RandomAccessIterator pat_last, 5446035553Spatrick Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); 5546035553Spatrick 5646035553Spatrick } // namespace fundamentals_v1 5746035553Spatrick } // namespace experimental 5846035553Spatrick 5946035553Spatrick} // namespace std 6046035553Spatrick 6146035553Spatrick*/ 6246035553Spatrick 63*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 64*4bdff4beSrobert#include <__debug> 65*4bdff4beSrobert#include <__functional/identity.h> 6676d0caaeSpatrick#include <__memory/uses_allocator.h> 67*4bdff4beSrobert#include <array> 6846035553Spatrick#include <experimental/__config> 6946035553Spatrick#include <functional> 7046035553Spatrick#include <type_traits> 7146035553Spatrick#include <unordered_map> 72*4bdff4beSrobert#include <vector> 7346035553Spatrick 7446035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 7546035553Spatrick# pragma GCC system_header 7646035553Spatrick#endif 7746035553Spatrick 7846035553Spatrick_LIBCPP_PUSH_MACROS 7946035553Spatrick#include <__undef_macros> 8046035553Spatrick 8146035553Spatrick_LIBCPP_BEGIN_NAMESPACE_LFTS 8246035553Spatrick 83*4bdff4beSrobert#ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS 84*4bdff4beSrobert# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER 85*4bdff4beSrobert# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER 86*4bdff4beSrobert# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER 87*4bdff4beSrobert#else 88*4bdff4beSrobert# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead") 89*4bdff4beSrobert# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_searcher will be removed in LLVM 17. Use std::boyer_moore_searcher instead") 90*4bdff4beSrobert# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_horspool_searcher will be removed in LLVM 17. Use std::boyer_moore_horspool_searcher instead") 91*4bdff4beSrobert#endif 92*4bdff4beSrobert 9346035553Spatrick#if _LIBCPP_STD_VER > 11 9446035553Spatrick// default searcher 9546035553Spatricktemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>> 96*4bdff4beSrobertclass _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher { 9746035553Spatrickpublic: 9846035553Spatrick _LIBCPP_INLINE_VISIBILITY 9946035553Spatrick default_searcher(_ForwardIterator __f, _ForwardIterator __l, 10046035553Spatrick _BinaryPredicate __p = _BinaryPredicate()) 10146035553Spatrick : __first_(__f), __last_(__l), __pred_(__p) {} 10246035553Spatrick 10346035553Spatrick template <typename _ForwardIterator2> 10446035553Spatrick _LIBCPP_INLINE_VISIBILITY 10546035553Spatrick pair<_ForwardIterator2, _ForwardIterator2> 10646035553Spatrick operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const 10746035553Spatrick { 108*4bdff4beSrobert auto __proj = __identity(); 109*4bdff4beSrobert return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); 11046035553Spatrick } 11146035553Spatrick 11246035553Spatrickprivate: 11346035553Spatrick _ForwardIterator __first_; 11446035553Spatrick _ForwardIterator __last_; 11546035553Spatrick _BinaryPredicate __pred_; 11646035553Spatrick }; 11746035553Spatrick 11846035553Spatricktemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>> 119*4bdff4beSrobert_LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY 12046035553Spatrickdefault_searcher<_ForwardIterator, _BinaryPredicate> 12146035553Spatrickmake_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ()) 12246035553Spatrick{ 12346035553Spatrick return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p); 12446035553Spatrick} 12546035553Spatrick 12646035553Spatricktemplate<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable; 12746035553Spatrick 12846035553Spatrick// General case for BM data searching; use a map 12946035553Spatricktemplate<class _Key, typename _Value, class _Hash, class _BinaryPredicate> 13046035553Spatrickclass _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { 13146035553Spatrick typedef _Value value_type; 13246035553Spatrick typedef _Key key_type; 13346035553Spatrick 13446035553Spatrick const _Value __default_value_; 135*4bdff4beSrobert std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_; 13646035553Spatrick 13746035553Spatrickpublic: 13846035553Spatrick _LIBCPP_INLINE_VISIBILITY 13976d0caaeSpatrick _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred) 140*4bdff4beSrobert : __default_value_(__default), __table_(__sz, __hf, __pred) {} 14146035553Spatrick 14246035553Spatrick _LIBCPP_INLINE_VISIBILITY 14346035553Spatrick void insert(const key_type &__key, value_type __val) 14446035553Spatrick { 145*4bdff4beSrobert __table_ [__key] = __val; // Would skip_.insert (val) be better here? 14646035553Spatrick } 14746035553Spatrick 14846035553Spatrick _LIBCPP_INLINE_VISIBILITY 14946035553Spatrick value_type operator [](const key_type & __key) const 15046035553Spatrick { 151*4bdff4beSrobert auto __it = __table_.find (__key); 152*4bdff4beSrobert return __it == __table_.end() ? __default_value_ : __it->second; 15346035553Spatrick } 15446035553Spatrick}; 15546035553Spatrick 15646035553Spatrick 15746035553Spatrick// Special case small numeric values; use an array 15846035553Spatricktemplate<class _Key, typename _Value, class _Hash, class _BinaryPredicate> 15946035553Spatrickclass _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { 16046035553Spatrickprivate: 16146035553Spatrick typedef _Value value_type; 16246035553Spatrick typedef _Key key_type; 16346035553Spatrick 164*4bdff4beSrobert typedef __make_unsigned_t<key_type> unsigned_key_type; 165*4bdff4beSrobert typedef std::array<value_type, 256> skip_map; 166*4bdff4beSrobert skip_map __table_; 16746035553Spatrick 16846035553Spatrickpublic: 16946035553Spatrick _LIBCPP_INLINE_VISIBILITY 17076d0caaeSpatrick _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/) 17146035553Spatrick { 172*4bdff4beSrobert std::fill_n(__table_.begin(), __table_.size(), __default); 17346035553Spatrick } 17446035553Spatrick 17546035553Spatrick _LIBCPP_INLINE_VISIBILITY 17646035553Spatrick void insert(key_type __key, value_type __val) 17746035553Spatrick { 178*4bdff4beSrobert __table_[static_cast<unsigned_key_type>(__key)] = __val; 17946035553Spatrick } 18046035553Spatrick 18146035553Spatrick _LIBCPP_INLINE_VISIBILITY 18246035553Spatrick value_type operator [](key_type __key) const 18346035553Spatrick { 184*4bdff4beSrobert return __table_[static_cast<unsigned_key_type>(__key)]; 18546035553Spatrick } 18646035553Spatrick}; 18746035553Spatrick 18846035553Spatrick 18946035553Spatricktemplate <class _RandomAccessIterator1, 19046035553Spatrick class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, 19146035553Spatrick class _BinaryPredicate = equal_to<>> 192*4bdff4beSrobertclass _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { 19346035553Spatrickprivate: 19446035553Spatrick typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; 19546035553Spatrick typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; 19646035553Spatrick typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate, 19776d0caaeSpatrick is_integral<value_type>::value && // what about enums? 19846035553Spatrick sizeof(value_type) == 1 && 19946035553Spatrick is_same<_Hash, hash<value_type>>::value && 20046035553Spatrick is_same<_BinaryPredicate, equal_to<>>::value 20146035553Spatrick > skip_table_type; 20246035553Spatrick 20346035553Spatrickpublic: 20446035553Spatrick boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 20546035553Spatrick _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) 20646035553Spatrick : __first_(__f), __last_(__l), __pred_(__pred), 20746035553Spatrick __pattern_length_(_VSTD::distance(__first_, __last_)), 208*4bdff4beSrobert __skip_{std::make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)}, 209*4bdff4beSrobert __suffix_{std::make_shared<vector<difference_type>>(__pattern_length_ + 1)} 21046035553Spatrick { 21146035553Spatrick // build the skip table 21246035553Spatrick for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) 21346035553Spatrick __skip_->insert(*__f, __i); 21446035553Spatrick 21546035553Spatrick this->__build_suffix_table ( __first_, __last_, __pred_ ); 21646035553Spatrick } 21746035553Spatrick 21846035553Spatrick template <typename _RandomAccessIterator2> 21946035553Spatrick pair<_RandomAccessIterator2, _RandomAccessIterator2> 22046035553Spatrick operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const 22146035553Spatrick { 222*4bdff4beSrobert static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type, 223*4bdff4beSrobert typename iterator_traits<_RandomAccessIterator2>::value_type>::value, 22446035553Spatrick "Corpus and Pattern iterators must point to the same type"); 22546035553Spatrick 226*4bdff4beSrobert if (__f == __l ) return std::make_pair(__l, __l); // empty corpus 227*4bdff4beSrobert if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern 22846035553Spatrick 22946035553Spatrick // If the pattern is larger than the corpus, we can't find it! 23046035553Spatrick if ( __pattern_length_ > _VSTD::distance(__f, __l)) 231*4bdff4beSrobert return std::make_pair(__l, __l); 23246035553Spatrick 23346035553Spatrick // Do the search 23446035553Spatrick return this->__search(__f, __l); 23546035553Spatrick } 23646035553Spatrick 237*4bdff4beSrobertprivate: 23846035553Spatrick _RandomAccessIterator1 __first_; 23946035553Spatrick _RandomAccessIterator1 __last_; 24046035553Spatrick _BinaryPredicate __pred_; 24146035553Spatrick difference_type __pattern_length_; 24246035553Spatrick shared_ptr<skip_table_type> __skip_; 24346035553Spatrick shared_ptr<vector<difference_type>> __suffix_; 24446035553Spatrick 24546035553Spatrick template <typename _RandomAccessIterator2> 24646035553Spatrick pair<_RandomAccessIterator2, _RandomAccessIterator2> 24746035553Spatrick __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const 24846035553Spatrick { 24946035553Spatrick _RandomAccessIterator2 __cur = __f; 25046035553Spatrick const _RandomAccessIterator2 __last = __l - __pattern_length_; 25146035553Spatrick const skip_table_type & __skip = *__skip_.get(); 25246035553Spatrick const vector<difference_type> & __suffix = *__suffix_.get(); 25346035553Spatrick 25446035553Spatrick while (__cur <= __last) 25546035553Spatrick { 25646035553Spatrick 25746035553Spatrick // Do we match right where we are? 25846035553Spatrick difference_type __j = __pattern_length_; 25946035553Spatrick while (__pred_(__first_ [__j-1], __cur [__j-1])) { 26046035553Spatrick __j--; 26146035553Spatrick // We matched - we're done! 26246035553Spatrick if ( __j == 0 ) 263*4bdff4beSrobert return std::make_pair(__cur, __cur + __pattern_length_); 26446035553Spatrick } 26546035553Spatrick 26646035553Spatrick // Since we didn't match, figure out how far to skip forward 26746035553Spatrick difference_type __k = __skip[__cur [ __j - 1 ]]; 26846035553Spatrick difference_type __m = __j - __k - 1; 26946035553Spatrick if (__k < __j && __m > __suffix[ __j ]) 27046035553Spatrick __cur += __m; 27146035553Spatrick else 27246035553Spatrick __cur += __suffix[ __j ]; 27346035553Spatrick } 27446035553Spatrick 275*4bdff4beSrobert return std::make_pair(__l, __l); // We didn't find anything 27646035553Spatrick } 27746035553Spatrick 27846035553Spatrick 27946035553Spatrick template<typename _Iterator, typename _Container> 28046035553Spatrick void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix ) 28146035553Spatrick { 28276d0caaeSpatrick const size_t __count = _VSTD::distance(__f, __l); 28346035553Spatrick 28446035553Spatrick __prefix[0] = 0; 28576d0caaeSpatrick size_t __k = 0; 28676d0caaeSpatrick for ( size_t __i = 1; __i < __count; ++__i ) 28746035553Spatrick { 28846035553Spatrick while ( __k > 0 && !__pred ( __f[__k], __f[__i] )) 28946035553Spatrick __k = __prefix [ __k - 1 ]; 29046035553Spatrick 29146035553Spatrick if ( __pred ( __f[__k], __f[__i] )) 29246035553Spatrick __k++; 29346035553Spatrick __prefix [ __i ] = __k; 29446035553Spatrick } 29546035553Spatrick } 29646035553Spatrick 29746035553Spatrick void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 29846035553Spatrick _BinaryPredicate __pred) 29946035553Spatrick { 30076d0caaeSpatrick const size_t __count = _VSTD::distance(__f, __l); 30146035553Spatrick vector<difference_type> & __suffix = *__suffix_.get(); 30246035553Spatrick if (__count > 0) 30346035553Spatrick { 304*4bdff4beSrobert vector<difference_type> __scratch(__count); 30546035553Spatrick 30646035553Spatrick __compute_bm_prefix(__f, __l, __pred, __scratch); 30776d0caaeSpatrick for ( size_t __i = 0; __i <= __count; __i++ ) 30846035553Spatrick __suffix[__i] = __count - __scratch[__count-1]; 30946035553Spatrick 31076d0caaeSpatrick typedef reverse_iterator<_RandomAccessIterator1> _RevIter; 31146035553Spatrick __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch); 31246035553Spatrick 31376d0caaeSpatrick for ( size_t __i = 0; __i < __count; __i++ ) 31446035553Spatrick { 31576d0caaeSpatrick const size_t __j = __count - __scratch[__i]; 31646035553Spatrick const difference_type __k = __i - __scratch[__i] + 1; 31746035553Spatrick 31846035553Spatrick if (__suffix[__j] > __k) 31946035553Spatrick __suffix[__j] = __k; 32046035553Spatrick } 32146035553Spatrick } 32246035553Spatrick } 32346035553Spatrick 32446035553Spatrick}; 32546035553Spatrick 32646035553Spatricktemplate<class _RandomAccessIterator, 32746035553Spatrick class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, 32846035553Spatrick class _BinaryPredicate = equal_to<>> 329*4bdff4beSrobert_LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY 33046035553Spatrickboyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> 33146035553Spatrickmake_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, 33246035553Spatrick _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) 33346035553Spatrick{ 33446035553Spatrick return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); 33546035553Spatrick} 33646035553Spatrick 33746035553Spatrick// boyer-moore-horspool 33846035553Spatricktemplate <class _RandomAccessIterator1, 33946035553Spatrick class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, 34046035553Spatrick class _BinaryPredicate = equal_to<>> 341*4bdff4beSrobertclass _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { 34246035553Spatrickprivate: 34346035553Spatrick typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; 34446035553Spatrick typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; 34546035553Spatrick typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate, 34676d0caaeSpatrick is_integral<value_type>::value && // what about enums? 34746035553Spatrick sizeof(value_type) == 1 && 34846035553Spatrick is_same<_Hash, hash<value_type>>::value && 34946035553Spatrick is_same<_BinaryPredicate, equal_to<>>::value 35046035553Spatrick > skip_table_type; 35146035553Spatrick 35246035553Spatrickpublic: 35346035553Spatrick boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, 35446035553Spatrick _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) 35546035553Spatrick : __first_(__f), __last_(__l), __pred_(__pred), 35646035553Spatrick __pattern_length_(_VSTD::distance(__first_, __last_)), 35746035553Spatrick __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)} 35846035553Spatrick { 35946035553Spatrick // build the skip table 36046035553Spatrick if ( __f != __l ) 36146035553Spatrick { 36246035553Spatrick __l = __l - 1; 36346035553Spatrick for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) 36446035553Spatrick __skip_->insert(*__f, __pattern_length_ - 1 - __i); 36546035553Spatrick } 36646035553Spatrick } 36746035553Spatrick 36846035553Spatrick template <typename _RandomAccessIterator2> 36946035553Spatrick pair<_RandomAccessIterator2, _RandomAccessIterator2> 37046035553Spatrick operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const 37146035553Spatrick { 372*4bdff4beSrobert static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type, 373*4bdff4beSrobert typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value, 37446035553Spatrick "Corpus and Pattern iterators must point to the same type"); 37546035553Spatrick 376*4bdff4beSrobert if (__f == __l ) return std::make_pair(__l, __l); // empty corpus 377*4bdff4beSrobert if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern 37846035553Spatrick 37946035553Spatrick // If the pattern is larger than the corpus, we can't find it! 38046035553Spatrick if ( __pattern_length_ > _VSTD::distance(__f, __l)) 381*4bdff4beSrobert return std::make_pair(__l, __l); 38246035553Spatrick 38346035553Spatrick // Do the search 38446035553Spatrick return this->__search(__f, __l); 38546035553Spatrick } 38646035553Spatrick 38746035553Spatrickprivate: 38846035553Spatrick _RandomAccessIterator1 __first_; 38946035553Spatrick _RandomAccessIterator1 __last_; 39046035553Spatrick _BinaryPredicate __pred_; 39146035553Spatrick difference_type __pattern_length_; 39246035553Spatrick shared_ptr<skip_table_type> __skip_; 39346035553Spatrick 39446035553Spatrick template <typename _RandomAccessIterator2> 39546035553Spatrick pair<_RandomAccessIterator2, _RandomAccessIterator2> 39646035553Spatrick __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { 39746035553Spatrick _RandomAccessIterator2 __cur = __f; 39846035553Spatrick const _RandomAccessIterator2 __last = __l - __pattern_length_; 39946035553Spatrick const skip_table_type & __skip = *__skip_.get(); 40046035553Spatrick 40146035553Spatrick while (__cur <= __last) 40246035553Spatrick { 40346035553Spatrick // Do we match right where we are? 40446035553Spatrick difference_type __j = __pattern_length_; 40546035553Spatrick while (__pred_(__first_[__j-1], __cur[__j-1])) 40646035553Spatrick { 40746035553Spatrick __j--; 40846035553Spatrick // We matched - we're done! 40946035553Spatrick if ( __j == 0 ) 410*4bdff4beSrobert return std::make_pair(__cur, __cur + __pattern_length_); 41146035553Spatrick } 41246035553Spatrick __cur += __skip[__cur[__pattern_length_-1]]; 41346035553Spatrick } 41446035553Spatrick 415*4bdff4beSrobert return std::make_pair(__l, __l); 41646035553Spatrick } 41746035553Spatrick}; 41846035553Spatrick 41946035553Spatricktemplate<class _RandomAccessIterator, 42046035553Spatrick class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, 42146035553Spatrick class _BinaryPredicate = equal_to<>> 422*4bdff4beSrobert_LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY 42346035553Spatrickboyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> 42446035553Spatrickmake_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, 42546035553Spatrick _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) 42646035553Spatrick{ 42746035553Spatrick return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); 42846035553Spatrick} 42946035553Spatrick 43046035553Spatrick#endif // _LIBCPP_STD_VER > 11 43146035553Spatrick 43246035553Spatrick_LIBCPP_END_NAMESPACE_LFTS 43346035553Spatrick 43446035553Spatrick_LIBCPP_POP_MACROS 43546035553Spatrick 43646035553Spatrick#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */ 437