xref: /aosp_15_r20/external/libcxx/include/experimental/functional (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
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