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