blob: 873973d8acb0953c5438c1958e7b6b55b12a41b1 [file] [log] [blame]
Marshall Clow205c3332015-07-20 16:39:281// -*- C++ -*-
Louis Dionneeb8650a2021-11-17 21:25:012//===----------------------------------------------------------------------===//
Marshall Clow205c3332015-07-20 16:39:283//
Chandler Carruth57b08b02019-01-19 10:56:404// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Marshall Clow205c3332015-07-20 16:39:287//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL
11#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL
12
13/*
14 experimental/functional synopsis
15
16#include <algorithm>
17
18namespace std {
19namespace experimental {
20inline namespace fundamentals_v1 {
Marshall Clow205c3332015-07-20 16:39:2821 // 4.3, Searchers
22 template<class ForwardIterator, class BinaryPredicate = equal_to<>>
23 class default_searcher;
24
25 template<class RandomAccessIterator,
26 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
27 class BinaryPredicate = equal_to<>>
28 class boyer_moore_searcher;
29
30 template<class RandomAccessIterator,
31 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
32 class BinaryPredicate = equal_to<>>
33 class boyer_moore_horspool_searcher;
34
35 template<class ForwardIterator, class BinaryPredicate = equal_to<>>
36 default_searcher<ForwardIterator, BinaryPredicate>
37 make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
38 BinaryPredicate pred = BinaryPredicate());
39
40 template<class RandomAccessIterator,
41 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
42 class BinaryPredicate = equal_to<>>
43 boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
44 make_boyer_moore_searcher(
45 RandomAccessIterator pat_first, RandomAccessIterator pat_last,
46 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
47
48 template<class RandomAccessIterator,
49 class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
50 class BinaryPredicate = equal_to<>>
51 boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
52 make_boyer_moore_horspool_searcher(
53 RandomAccessIterator pat_first, RandomAccessIterator pat_last,
54 Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
55
56 } // namespace fundamentals_v1
57 } // namespace experimental
58
Marshall Clow205c3332015-07-20 16:39:2859} // namespace std
60
61*/
62
Louis Dionne385cc252022-03-25 16:55:3663#include <__assert> // all public C++ headers provide the assertion handler
Arthur O'Dwyer4d81a462022-01-07 14:45:0564#include <__debug>
Nikolas Klauser101d1e92022-07-13 16:07:2665#include <__functional/identity.h>
Christopher Di Bella050b0642021-07-01 13:25:3566#include <__memory/uses_allocator.h>
Arthur O'Dwyer4d81a462022-01-07 14:45:0567#include <array>
Marshall Clow205c3332015-07-20 16:39:2868#include <experimental/__config>
69#include <functional>
Marshall Clowf44bd932015-09-08 17:59:0970#include <type_traits>
Marshall Clowf44bd932015-09-08 17:59:0971#include <unordered_map>
Arthur O'Dwyer4d81a462022-01-07 14:45:0572#include <vector>
Marshall Clow205c3332015-07-20 16:39:2873
74#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Arthur O'Dwyerfa6b9e42022-02-02 01:16:4075# pragma GCC system_header
Marshall Clow205c3332015-07-20 16:39:2876#endif
77
Eric Fiseliera016efb2017-05-31 22:07:4978_LIBCPP_PUSH_MACROS
79#include <__undef_macros>
80
Marshall Clow205c3332015-07-20 16:39:2881_LIBCPP_BEGIN_NAMESPACE_LFTS
82
Nikolas Klauser971e9c82022-06-17 14:02:5383#ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS
84# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER
85# define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER
86# define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER
87#else
Joe Loser6ebc2a12022-08-20 23:21:1388# define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead")
89# 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# 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")
Nikolas Klauser971e9c82022-06-17 14:02:5391#endif
92
Marshall Clowf44bd932015-09-08 17:59:0993#if _LIBCPP_STD_VER > 11
Marshall Clow205c3332015-07-20 16:39:2894// default searcher
95template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
Nikolas Klauser971e9c82022-06-17 14:02:5396class _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher {
Marshall Clow205c3332015-07-20 16:39:2897public:
Marshall Clowf44bd932015-09-08 17:59:0998 _LIBCPP_INLINE_VISIBILITY
Louis Dionne6b77ebd2019-10-23 17:40:1599 default_searcher(_ForwardIterator __f, _ForwardIterator __l,
Marshall Clow205c3332015-07-20 16:39:28100 _BinaryPredicate __p = _BinaryPredicate())
101 : __first_(__f), __last_(__l), __pred_(__p) {}
102
103 template <typename _ForwardIterator2>
Marshall Clowf44bd932015-09-08 17:59:09104 _LIBCPP_INLINE_VISIBILITY
Marshall Clow28cc4dd2016-03-08 15:12:52105 pair<_ForwardIterator2, _ForwardIterator2>
106 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
Marshall Clowf44bd932015-09-08 17:59:09107 {
Nikolas Klauser101d1e92022-07-13 16:07:26108 auto __proj = __identity();
109 return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj);
Marshall Clowf44bd932015-09-08 17:59:09110 }
Marshall Clow205c3332015-07-20 16:39:28111
112private:
113 _ForwardIterator __first_;
114 _ForwardIterator __last_;
115 _BinaryPredicate __pred_;
116 };
117
118template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
Nikolas Klauser971e9c82022-06-17 14:02:53119_LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY
Marshall Clow205c3332015-07-20 16:39:28120default_searcher<_ForwardIterator, _BinaryPredicate>
121make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
122{
123 return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);
124}
125
Marshall Clowf44bd932015-09-08 17:59:09126template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable;
127
128// General case for BM data searching; use a map
129template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
130class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
Marshall Clowf44bd932015-09-08 17:59:09131 typedef _Value value_type;
132 typedef _Key key_type;
133
134 const _Value __default_value_;
Nikolas Klauser84fc2c32022-09-02 14:19:07135 std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_;
Louis Dionne6b77ebd2019-10-23 17:40:15136
Marshall Clowf44bd932015-09-08 17:59:09137public:
138 _LIBCPP_INLINE_VISIBILITY
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00139 _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
Nikolas Klauser84fc2c32022-09-02 14:19:07140 : __default_value_(__default), __table_(__sz, __hf, __pred) {}
Louis Dionne6b77ebd2019-10-23 17:40:15141
Marshall Clowf44bd932015-09-08 17:59:09142 _LIBCPP_INLINE_VISIBILITY
143 void insert(const key_type &__key, value_type __val)
144 {
Nikolas Klauser84fc2c32022-09-02 14:19:07145 __table_ [__key] = __val; // Would skip_.insert (val) be better here?
Marshall Clowf44bd932015-09-08 17:59:09146 }
147
148 _LIBCPP_INLINE_VISIBILITY
149 value_type operator [](const key_type & __key) const
150 {
Nikolas Klauser84fc2c32022-09-02 14:19:07151 auto __it = __table_.find (__key);
152 return __it == __table_.end() ? __default_value_ : __it->second;
Marshall Clowf44bd932015-09-08 17:59:09153 }
154};
Louis Dionne6b77ebd2019-10-23 17:40:15155
Marshall Clowf44bd932015-09-08 17:59:09156
157// Special case small numeric values; use an array
158template<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
159class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
160private:
161 typedef _Value value_type;
162 typedef _Key key_type;
163
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00164 typedef typename make_unsigned<key_type>::type unsigned_key_type;
Nikolas Klauser971e9c82022-06-17 14:02:53165 typedef std::array<value_type, 256> skip_map;
Nikolas Klauser84fc2c32022-09-02 14:19:07166 skip_map __table_;
Marshall Clowf44bd932015-09-08 17:59:09167
168public:
169 _LIBCPP_INLINE_VISIBILITY
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00170 _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
Marshall Clowf44bd932015-09-08 17:59:09171 {
Nikolas Klauser84fc2c32022-09-02 14:19:07172 std::fill_n(__table_.begin(), __table_.size(), __default);
Marshall Clowf44bd932015-09-08 17:59:09173 }
Louis Dionne6b77ebd2019-10-23 17:40:15174
Marshall Clowf44bd932015-09-08 17:59:09175 _LIBCPP_INLINE_VISIBILITY
176 void insert(key_type __key, value_type __val)
177 {
Nikolas Klauser84fc2c32022-09-02 14:19:07178 __table_[static_cast<unsigned_key_type>(__key)] = __val;
Marshall Clowf44bd932015-09-08 17:59:09179 }
180
181 _LIBCPP_INLINE_VISIBILITY
182 value_type operator [](key_type __key) const
183 {
Nikolas Klauser84fc2c32022-09-02 14:19:07184 return __table_[static_cast<unsigned_key_type>(__key)];
Marshall Clowf44bd932015-09-08 17:59:09185 }
186};
187
188
Louis Dionne6b77ebd2019-10-23 17:40:15189template <class _RandomAccessIterator1,
190 class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
Marshall Clowf44bd932015-09-08 17:59:09191 class _BinaryPredicate = equal_to<>>
Nikolas Klauser971e9c82022-06-17 14:02:53192class _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
Marshall Clowf44bd932015-09-08 17:59:09193private:
194 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
195 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
196 typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
Arthur O'Dwyer6491d992021-05-10 17:13:04197 is_integral<value_type>::value && // what about enums?
Marshall Clowf44bd932015-09-08 17:59:09198 sizeof(value_type) == 1 &&
199 is_same<_Hash, hash<value_type>>::value &&
200 is_same<_BinaryPredicate, equal_to<>>::value
201 > skip_table_type;
Louis Dionne6b77ebd2019-10-23 17:40:15202
Marshall Clowf44bd932015-09-08 17:59:09203public:
Louis Dionne6b77ebd2019-10-23 17:40:15204 boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
Marshall Clowf44bd932015-09-08 17:59:09205 _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
206 : __first_(__f), __last_(__l), __pred_(__pred),
207 __pattern_length_(_VSTD::distance(__first_, __last_)),
208 __skip_{make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)},
209 __suffix_{make_shared<vector<difference_type>>(__pattern_length_ + 1)}
210 {
211 // build the skip table
212 for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
213 __skip_->insert(*__f, __i);
214
215 this->__build_suffix_table ( __first_, __last_, __pred_ );
216 }
Louis Dionne6b77ebd2019-10-23 17:40:15217
Marshall Clowf44bd932015-09-08 17:59:09218 template <typename _RandomAccessIterator2>
Marshall Clow28cc4dd2016-03-08 15:12:52219 pair<_RandomAccessIterator2, _RandomAccessIterator2>
Marshall Clowf44bd932015-09-08 17:59:09220 operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
221 {
Nikolas Klauserf7558062022-02-17 21:53:20222 static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type,
223 typename iterator_traits<_RandomAccessIterator2>::value_type>::value,
224 "Corpus and Pattern iterators must point to the same type");
Marshall Clowf44bd932015-09-08 17:59:09225
Marshall Clow28cc4dd2016-03-08 15:12:52226 if (__f == __l ) return make_pair(__l, __l); // empty corpus
227 if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
Marshall Clowf44bd932015-09-08 17:59:09228
229 // If the pattern is larger than the corpus, we can't find it!
Arthur O'Dwyer6491d992021-05-10 17:13:04230 if ( __pattern_length_ > _VSTD::distance(__f, __l))
Marshall Clow28cc4dd2016-03-08 15:12:52231 return make_pair(__l, __l);
Marshall Clowf44bd932015-09-08 17:59:09232
Louis Dionne6b77ebd2019-10-23 17:40:15233 // Do the search
Marshall Clowf44bd932015-09-08 17:59:09234 return this->__search(__f, __l);
235 }
Louis Dionne6b77ebd2019-10-23 17:40:15236
Joe Loser66dea852022-02-07 00:47:45237private:
Marshall Clowf44bd932015-09-08 17:59:09238 _RandomAccessIterator1 __first_;
239 _RandomAccessIterator1 __last_;
240 _BinaryPredicate __pred_;
241 difference_type __pattern_length_;
242 shared_ptr<skip_table_type> __skip_;
243 shared_ptr<vector<difference_type>> __suffix_;
244
245 template <typename _RandomAccessIterator2>
Marshall Clow28cc4dd2016-03-08 15:12:52246 pair<_RandomAccessIterator2, _RandomAccessIterator2>
247 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
Marshall Clowf44bd932015-09-08 17:59:09248 {
249 _RandomAccessIterator2 __cur = __f;
250 const _RandomAccessIterator2 __last = __l - __pattern_length_;
251 const skip_table_type & __skip = *__skip_.get();
252 const vector<difference_type> & __suffix = *__suffix_.get();
Louis Dionne6b77ebd2019-10-23 17:40:15253
Marshall Clowf44bd932015-09-08 17:59:09254 while (__cur <= __last)
255 {
256
257 // Do we match right where we are?
258 difference_type __j = __pattern_length_;
259 while (__pred_(__first_ [__j-1], __cur [__j-1])) {
260 __j--;
261 // We matched - we're done!
262 if ( __j == 0 )
Marshall Clow28cc4dd2016-03-08 15:12:52263 return make_pair(__cur, __cur + __pattern_length_);
Marshall Clowf44bd932015-09-08 17:59:09264 }
Louis Dionne6b77ebd2019-10-23 17:40:15265
Marshall Clowf44bd932015-09-08 17:59:09266 // Since we didn't match, figure out how far to skip forward
267 difference_type __k = __skip[__cur [ __j - 1 ]];
268 difference_type __m = __j - __k - 1;
269 if (__k < __j && __m > __suffix[ __j ])
270 __cur += __m;
271 else
272 __cur += __suffix[ __j ];
273 }
Louis Dionne6b77ebd2019-10-23 17:40:15274
Marshall Clow28cc4dd2016-03-08 15:12:52275 return make_pair(__l, __l); // We didn't find anything
Marshall Clowf44bd932015-09-08 17:59:09276 }
277
278
279 template<typename _Iterator, typename _Container>
280 void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix )
281 {
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00282 const size_t __count = _VSTD::distance(__f, __l);
Louis Dionne6b77ebd2019-10-23 17:40:15283
Marshall Clowf44bd932015-09-08 17:59:09284 __prefix[0] = 0;
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00285 size_t __k = 0;
286 for ( size_t __i = 1; __i < __count; ++__i )
Marshall Clowf44bd932015-09-08 17:59:09287 {
288 while ( __k > 0 && !__pred ( __f[__k], __f[__i] ))
289 __k = __prefix [ __k - 1 ];
Louis Dionne6b77ebd2019-10-23 17:40:15290
Marshall Clowf44bd932015-09-08 17:59:09291 if ( __pred ( __f[__k], __f[__i] ))
292 __k++;
293 __prefix [ __i ] = __k;
294 }
295 }
296
Louis Dionne6b77ebd2019-10-23 17:40:15297 void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
Marshall Clowf44bd932015-09-08 17:59:09298 _BinaryPredicate __pred)
299 {
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00300 const size_t __count = _VSTD::distance(__f, __l);
Marshall Clowf44bd932015-09-08 17:59:09301 vector<difference_type> & __suffix = *__suffix_.get();
302 if (__count > 0)
303 {
Nikolas Klauser971e9c82022-06-17 14:02:53304 vector<difference_type> __scratch(__count);
Louis Dionne6b77ebd2019-10-23 17:40:15305
Marshall Clowf44bd932015-09-08 17:59:09306 __compute_bm_prefix(__f, __l, __pred, __scratch);
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00307 for ( size_t __i = 0; __i <= __count; __i++ )
Marshall Clowf44bd932015-09-08 17:59:09308 __suffix[__i] = __count - __scratch[__count-1];
Louis Dionne6b77ebd2019-10-23 17:40:15309
Arthur O'Dwyer6491d992021-05-10 17:13:04310 typedef reverse_iterator<_RandomAccessIterator1> _RevIter;
Marshall Clowf44bd932015-09-08 17:59:09311 __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch);
Louis Dionne6b77ebd2019-10-23 17:40:15312
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00313 for ( size_t __i = 0; __i < __count; __i++ )
Marshall Clowf44bd932015-09-08 17:59:09314 {
Arthur O'Dwyer0b8da5f2021-05-10 17:07:00315 const size_t __j = __count - __scratch[__i];
Marshall Clowf44bd932015-09-08 17:59:09316 const difference_type __k = __i - __scratch[__i] + 1;
Louis Dionne6b77ebd2019-10-23 17:40:15317
Marshall Clowf44bd932015-09-08 17:59:09318 if (__suffix[__j] > __k)
319 __suffix[__j] = __k;
320 }
321 }
322 }
323
324};
325
Louis Dionne6b77ebd2019-10-23 17:40:15326template<class _RandomAccessIterator,
327 class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
Marshall Clowf44bd932015-09-08 17:59:09328 class _BinaryPredicate = equal_to<>>
Nikolas Klauser971e9c82022-06-17 14:02:53329_LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY
Marshall Clowf44bd932015-09-08 17:59:09330boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
Louis Dionne6b77ebd2019-10-23 17:40:15331make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
Marshall Clowf44bd932015-09-08 17:59:09332 _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
333{
334 return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
335}
336
337// boyer-moore-horspool
Louis Dionne6b77ebd2019-10-23 17:40:15338template <class _RandomAccessIterator1,
339 class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
Marshall Clowf44bd932015-09-08 17:59:09340 class _BinaryPredicate = equal_to<>>
Nikolas Klauser971e9c82022-06-17 14:02:53341class _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
Marshall Clowf44bd932015-09-08 17:59:09342private:
343 typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
344 typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type;
345 typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
Arthur O'Dwyer6491d992021-05-10 17:13:04346 is_integral<value_type>::value && // what about enums?
Marshall Clowf44bd932015-09-08 17:59:09347 sizeof(value_type) == 1 &&
348 is_same<_Hash, hash<value_type>>::value &&
349 is_same<_BinaryPredicate, equal_to<>>::value
350 > skip_table_type;
351
352public:
Louis Dionne6b77ebd2019-10-23 17:40:15353 boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
Marshall Clowf44bd932015-09-08 17:59:09354 _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
355 : __first_(__f), __last_(__l), __pred_(__pred),
356 __pattern_length_(_VSTD::distance(__first_, __last_)),
357 __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)}
358 {
359 // build the skip table
360 if ( __f != __l )
361 {
362 __l = __l - 1;
363 for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
364 __skip_->insert(*__f, __pattern_length_ - 1 - __i);
365 }
366 }
Louis Dionne6b77ebd2019-10-23 17:40:15367
Marshall Clow28cc4dd2016-03-08 15:12:52368 template <typename _RandomAccessIterator2>
369 pair<_RandomAccessIterator2, _RandomAccessIterator2>
Marshall Clowf44bd932015-09-08 17:59:09370 operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
371 {
Nikolas Klauserf7558062022-02-17 21:53:20372 static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type,
373 typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value,
374 "Corpus and Pattern iterators must point to the same type");
Marshall Clowf44bd932015-09-08 17:59:09375
Marshall Clow28cc4dd2016-03-08 15:12:52376 if (__f == __l ) return make_pair(__l, __l); // empty corpus
377 if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
Marshall Clowf44bd932015-09-08 17:59:09378
379 // If the pattern is larger than the corpus, we can't find it!
Arthur O'Dwyer6491d992021-05-10 17:13:04380 if ( __pattern_length_ > _VSTD::distance(__f, __l))
Marshall Clow28cc4dd2016-03-08 15:12:52381 return make_pair(__l, __l);
Marshall Clowf44bd932015-09-08 17:59:09382
Louis Dionne6b77ebd2019-10-23 17:40:15383 // Do the search
Marshall Clowf44bd932015-09-08 17:59:09384 return this->__search(__f, __l);
385 }
Louis Dionne6b77ebd2019-10-23 17:40:15386
Marshall Clowf44bd932015-09-08 17:59:09387private:
388 _RandomAccessIterator1 __first_;
389 _RandomAccessIterator1 __last_;
390 _BinaryPredicate __pred_;
391 difference_type __pattern_length_;
392 shared_ptr<skip_table_type> __skip_;
393
394 template <typename _RandomAccessIterator2>
Marshall Clow28cc4dd2016-03-08 15:12:52395 pair<_RandomAccessIterator2, _RandomAccessIterator2>
396 __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const {
Marshall Clowf44bd932015-09-08 17:59:09397 _RandomAccessIterator2 __cur = __f;
398 const _RandomAccessIterator2 __last = __l - __pattern_length_;
399 const skip_table_type & __skip = *__skip_.get();
400
401 while (__cur <= __last)
402 {
403 // Do we match right where we are?
404 difference_type __j = __pattern_length_;
405 while (__pred_(__first_[__j-1], __cur[__j-1]))
406 {
407 __j--;
408 // We matched - we're done!
409 if ( __j == 0 )
Marshall Clow28cc4dd2016-03-08 15:12:52410 return make_pair(__cur, __cur + __pattern_length_);
Marshall Clowf44bd932015-09-08 17:59:09411 }
412 __cur += __skip[__cur[__pattern_length_-1]];
413 }
Louis Dionne6b77ebd2019-10-23 17:40:15414
Marshall Clow28cc4dd2016-03-08 15:12:52415 return make_pair(__l, __l);
Marshall Clowf44bd932015-09-08 17:59:09416 }
417};
418
Louis Dionne6b77ebd2019-10-23 17:40:15419template<class _RandomAccessIterator,
420 class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
Marshall Clowf44bd932015-09-08 17:59:09421 class _BinaryPredicate = equal_to<>>
Nikolas Klauser971e9c82022-06-17 14:02:53422_LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY
Marshall Clowf44bd932015-09-08 17:59:09423boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
Louis Dionne6b77ebd2019-10-23 17:40:15424make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
Marshall Clowf44bd932015-09-08 17:59:09425 _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
426{
427 return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
428}
429
430#endif // _LIBCPP_STD_VER > 11
Marshall Clow205c3332015-07-20 16:39:28431
432_LIBCPP_END_NAMESPACE_LFTS
433
Eric Fiseliera016efb2017-05-31 22:07:49434_LIBCPP_POP_MACROS
435
Marshall Clow205c3332015-07-20 16:39:28436#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */