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