xref: /openbsd-src/gnu/llvm/libcxx/include/experimental/functional (revision 76d0caaeb19ae0808d90af1d0b3b7b50b3e5383f)
146035553Spatrick// -*- C++ -*-
246035553Spatrick//===-------------------------- functional --------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL
1146035553Spatrick#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick   experimental/functional synopsis
1546035553Spatrick
1646035553Spatrick#include <algorithm>
1746035553Spatrick
1846035553Spatricknamespace std {
1946035553Spatricknamespace experimental {
2046035553Spatrickinline namespace fundamentals_v1 {
2146035553Spatrick
2246035553Spatrick    // See C++14 20.9.9, Function object binders
2346035553Spatrick    template <class T> constexpr bool is_bind_expression_v
2446035553Spatrick      = is_bind_expression<T>::value;
2546035553Spatrick    template <class T> constexpr int is_placeholder_v
2646035553Spatrick      = is_placeholder<T>::value;
2746035553Spatrick
2846035553Spatrick    // 4.2, Class template function
2946035553Spatrick    template<class> class function; // undefined
3046035553Spatrick    template<class R, class... ArgTypes> class function<R(ArgTypes...)>;
3146035553Spatrick
3246035553Spatrick    template<class R, class... ArgTypes>
3346035553Spatrick    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
3446035553Spatrick
3546035553Spatrick    template<class R, class... ArgTypes>
3646035553Spatrick    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
3746035553Spatrick    template<class R, class... ArgTypes>
3846035553Spatrick    bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
3946035553Spatrick    template<class R, class... ArgTypes>
4046035553Spatrick    bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
4146035553Spatrick    template<class R, class... ArgTypes>
4246035553Spatrick    bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
4346035553Spatrick
4446035553Spatrick    // 4.3, Searchers
4546035553Spatrick    template<class ForwardIterator, class BinaryPredicate = equal_to<>>
4646035553Spatrick      class default_searcher;
4746035553Spatrick
4846035553Spatrick    template<class RandomAccessIterator,
4946035553Spatrick             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
5046035553Spatrick             class BinaryPredicate = equal_to<>>
5146035553Spatrick      class boyer_moore_searcher;
5246035553Spatrick
5346035553Spatrick    template<class RandomAccessIterator,
5446035553Spatrick             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
5546035553Spatrick             class BinaryPredicate = equal_to<>>
5646035553Spatrick      class boyer_moore_horspool_searcher;
5746035553Spatrick
5846035553Spatrick    template<class ForwardIterator, class BinaryPredicate = equal_to<>>
5946035553Spatrick    default_searcher<ForwardIterator, BinaryPredicate>
6046035553Spatrick    make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
6146035553Spatrick                          BinaryPredicate pred = BinaryPredicate());
6246035553Spatrick
6346035553Spatrick    template<class RandomAccessIterator,
6446035553Spatrick             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
6546035553Spatrick             class BinaryPredicate = equal_to<>>
6646035553Spatrick    boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
6746035553Spatrick    make_boyer_moore_searcher(
6846035553Spatrick        RandomAccessIterator pat_first, RandomAccessIterator pat_last,
6946035553Spatrick        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
7046035553Spatrick
7146035553Spatrick    template<class RandomAccessIterator,
7246035553Spatrick             class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
7346035553Spatrick             class BinaryPredicate = equal_to<>>
7446035553Spatrick    boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
7546035553Spatrick    make_boyer_moore_horspool_searcher(
7646035553Spatrick        RandomAccessIterator pat_first, RandomAccessIterator pat_last,
7746035553Spatrick        Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
7846035553Spatrick
7946035553Spatrick  } // namespace fundamentals_v1
8046035553Spatrick  } // namespace experimental
8146035553Spatrick
8246035553Spatrick  template<class R, class... ArgTypes, class Alloc>
8346035553Spatrick  struct uses_allocator<experimental::function<R(ArgTypes...)>, Alloc>;
8446035553Spatrick
8546035553Spatrick} // namespace std
8646035553Spatrick
8746035553Spatrick*/
8846035553Spatrick
89*76d0caaeSpatrick#include <__memory/uses_allocator.h>
9046035553Spatrick#include <experimental/__config>
9146035553Spatrick#include <functional>
9246035553Spatrick#include <algorithm>
9346035553Spatrick#include <type_traits>
9446035553Spatrick#include <vector>
9546035553Spatrick#include <array>
9646035553Spatrick#include <unordered_map>
9746035553Spatrick
9846035553Spatrick#include <__debug>
9946035553Spatrick
10046035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
10146035553Spatrick#pragma GCC system_header
10246035553Spatrick#endif
10346035553Spatrick
10446035553Spatrick_LIBCPP_PUSH_MACROS
10546035553Spatrick#include <__undef_macros>
10646035553Spatrick
10746035553Spatrick
10846035553Spatrick_LIBCPP_BEGIN_NAMESPACE_LFTS
10946035553Spatrick
11046035553Spatrick#if _LIBCPP_STD_VER > 11
11146035553Spatrick// default searcher
11246035553Spatricktemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
113*76d0caaeSpatrickclass _LIBCPP_TEMPLATE_VIS default_searcher {
11446035553Spatrickpublic:
11546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
11646035553Spatrick    default_searcher(_ForwardIterator __f, _ForwardIterator __l,
11746035553Spatrick                       _BinaryPredicate __p = _BinaryPredicate())
11846035553Spatrick        : __first_(__f), __last_(__l), __pred_(__p) {}
11946035553Spatrick
12046035553Spatrick    template <typename _ForwardIterator2>
12146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
12246035553Spatrick    pair<_ForwardIterator2, _ForwardIterator2>
12346035553Spatrick    operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const
12446035553Spatrick    {
12546035553Spatrick        return _VSTD::__search(__f, __l, __first_, __last_, __pred_,
126*76d0caaeSpatrick            typename iterator_traits<_ForwardIterator>::iterator_category(),
127*76d0caaeSpatrick            typename iterator_traits<_ForwardIterator2>::iterator_category());
12846035553Spatrick    }
12946035553Spatrick
13046035553Spatrickprivate:
13146035553Spatrick    _ForwardIterator __first_;
13246035553Spatrick    _ForwardIterator __last_;
13346035553Spatrick    _BinaryPredicate __pred_;
13446035553Spatrick    };
13546035553Spatrick
13646035553Spatricktemplate<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
13746035553Spatrick_LIBCPP_INLINE_VISIBILITY
13846035553Spatrickdefault_searcher<_ForwardIterator, _BinaryPredicate>
13946035553Spatrickmake_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
14046035553Spatrick{
14146035553Spatrick    return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);
14246035553Spatrick}
14346035553Spatrick
14446035553Spatricktemplate<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable;
14546035553Spatrick
14646035553Spatrick//  General case for BM data searching; use a map
14746035553Spatricktemplate<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
14846035553Spatrickclass _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> {
14946035553Spatrickpublic: // TODO private:
15046035553Spatrick    typedef _Value value_type;
15146035553Spatrick    typedef _Key   key_type;
15246035553Spatrick
15346035553Spatrick    const _Value __default_value_;
15446035553Spatrick    std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table;
15546035553Spatrick
15646035553Spatrickpublic:
15746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
158*76d0caaeSpatrick    _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred)
15946035553Spatrick        : __default_value_(__default), __table(__sz, __hf, __pred) {}
16046035553Spatrick
16146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
16246035553Spatrick    void insert(const key_type &__key, value_type __val)
16346035553Spatrick    {
16446035553Spatrick        __table [__key] = __val;    // Would skip_.insert (val) be better here?
16546035553Spatrick    }
16646035553Spatrick
16746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
16846035553Spatrick    value_type operator [](const key_type & __key) const
16946035553Spatrick    {
17046035553Spatrick        auto __it = __table.find (__key);
17146035553Spatrick        return __it == __table.end() ? __default_value_ : __it->second;
17246035553Spatrick    }
17346035553Spatrick};
17446035553Spatrick
17546035553Spatrick
17646035553Spatrick//  Special case small numeric values; use an array
17746035553Spatricktemplate<class _Key, typename _Value, class _Hash, class _BinaryPredicate>
17846035553Spatrickclass _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> {
17946035553Spatrickprivate:
18046035553Spatrick    typedef _Value value_type;
18146035553Spatrick    typedef _Key   key_type;
18246035553Spatrick
183*76d0caaeSpatrick    typedef typename make_unsigned<key_type>::type unsigned_key_type;
184*76d0caaeSpatrick    typedef std::array<value_type, numeric_limits<unsigned_key_type>::max()> skip_map;
18546035553Spatrick    skip_map __table;
18646035553Spatrick
18746035553Spatrickpublic:
18846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
189*76d0caaeSpatrick    _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/)
19046035553Spatrick    {
19146035553Spatrick        std::fill_n(__table.begin(), __table.size(), __default);
19246035553Spatrick    }
19346035553Spatrick
19446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
19546035553Spatrick    void insert(key_type __key, value_type __val)
19646035553Spatrick    {
19746035553Spatrick        __table[static_cast<unsigned_key_type>(__key)] = __val;
19846035553Spatrick    }
19946035553Spatrick
20046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
20146035553Spatrick    value_type operator [](key_type __key) const
20246035553Spatrick    {
20346035553Spatrick        return __table[static_cast<unsigned_key_type>(__key)];
20446035553Spatrick    }
20546035553Spatrick};
20646035553Spatrick
20746035553Spatrick
20846035553Spatricktemplate <class _RandomAccessIterator1,
20946035553Spatrick          class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
21046035553Spatrick          class _BinaryPredicate = equal_to<>>
211*76d0caaeSpatrickclass _LIBCPP_TEMPLATE_VIS boyer_moore_searcher {
21246035553Spatrickprivate:
21346035553Spatrick    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
21446035553Spatrick    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type      value_type;
21546035553Spatrick    typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
216*76d0caaeSpatrick                    is_integral<value_type>::value && // what about enums?
21746035553Spatrick                    sizeof(value_type) == 1 &&
21846035553Spatrick                    is_same<_Hash, hash<value_type>>::value &&
21946035553Spatrick                    is_same<_BinaryPredicate, equal_to<>>::value
22046035553Spatrick            > skip_table_type;
22146035553Spatrick
22246035553Spatrickpublic:
22346035553Spatrick    boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
22446035553Spatrick                _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
22546035553Spatrick            : __first_(__f), __last_(__l), __pred_(__pred),
22646035553Spatrick              __pattern_length_(_VSTD::distance(__first_, __last_)),
22746035553Spatrick              __skip_{make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)},
22846035553Spatrick              __suffix_{make_shared<vector<difference_type>>(__pattern_length_ + 1)}
22946035553Spatrick        {
23046035553Spatrick    //  build the skip table
23146035553Spatrick        for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
23246035553Spatrick            __skip_->insert(*__f, __i);
23346035553Spatrick
23446035553Spatrick        this->__build_suffix_table ( __first_, __last_, __pred_ );
23546035553Spatrick        }
23646035553Spatrick
23746035553Spatrick    template <typename _RandomAccessIterator2>
23846035553Spatrick    pair<_RandomAccessIterator2, _RandomAccessIterator2>
23946035553Spatrick    operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
24046035553Spatrick    {
24146035553Spatrick        static_assert ( std::is_same<
24246035553Spatrick                typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
24346035553Spatrick                typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
24446035553Spatrick                    >::value,
24546035553Spatrick                "Corpus and Pattern iterators must point to the same type" );
24646035553Spatrick
24746035553Spatrick        if (__f      == __l )    return make_pair(__l, __l); // empty corpus
24846035553Spatrick        if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
24946035553Spatrick
25046035553Spatrick    //  If the pattern is larger than the corpus, we can't find it!
25146035553Spatrick        if ( __pattern_length_ > _VSTD::distance(__f, __l))
25246035553Spatrick            return make_pair(__l, __l);
25346035553Spatrick
25446035553Spatrick    //  Do the search
25546035553Spatrick        return this->__search(__f, __l);
25646035553Spatrick    }
25746035553Spatrick
25846035553Spatrickpublic: // TODO private:
25946035553Spatrick    _RandomAccessIterator1               __first_;
26046035553Spatrick    _RandomAccessIterator1               __last_;
26146035553Spatrick    _BinaryPredicate                     __pred_;
26246035553Spatrick    difference_type                      __pattern_length_;
26346035553Spatrick    shared_ptr<skip_table_type>          __skip_;
26446035553Spatrick    shared_ptr<vector<difference_type>>  __suffix_;
26546035553Spatrick
26646035553Spatrick    template <typename _RandomAccessIterator2>
26746035553Spatrick    pair<_RandomAccessIterator2, _RandomAccessIterator2>
26846035553Spatrick    __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
26946035553Spatrick    {
27046035553Spatrick        _RandomAccessIterator2 __cur = __f;
27146035553Spatrick        const _RandomAccessIterator2 __last = __l - __pattern_length_;
27246035553Spatrick        const skip_table_type &         __skip   = *__skip_.get();
27346035553Spatrick        const vector<difference_type> & __suffix = *__suffix_.get();
27446035553Spatrick
27546035553Spatrick        while (__cur <= __last)
27646035553Spatrick        {
27746035553Spatrick
27846035553Spatrick        //  Do we match right where we are?
27946035553Spatrick            difference_type __j = __pattern_length_;
28046035553Spatrick            while (__pred_(__first_ [__j-1], __cur [__j-1])) {
28146035553Spatrick                __j--;
28246035553Spatrick            //  We matched - we're done!
28346035553Spatrick                if ( __j == 0 )
28446035553Spatrick                    return make_pair(__cur, __cur + __pattern_length_);
28546035553Spatrick                }
28646035553Spatrick
28746035553Spatrick        //  Since we didn't match, figure out how far to skip forward
28846035553Spatrick            difference_type __k = __skip[__cur [ __j - 1 ]];
28946035553Spatrick            difference_type __m = __j - __k - 1;
29046035553Spatrick            if (__k < __j && __m > __suffix[ __j ])
29146035553Spatrick                __cur += __m;
29246035553Spatrick            else
29346035553Spatrick                __cur += __suffix[ __j ];
29446035553Spatrick        }
29546035553Spatrick
29646035553Spatrick        return make_pair(__l, __l);     // We didn't find anything
29746035553Spatrick    }
29846035553Spatrick
29946035553Spatrick
30046035553Spatrick    template<typename _Iterator, typename _Container>
30146035553Spatrick    void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix )
30246035553Spatrick    {
303*76d0caaeSpatrick        const size_t __count = _VSTD::distance(__f, __l);
30446035553Spatrick
30546035553Spatrick        __prefix[0] = 0;
306*76d0caaeSpatrick        size_t __k = 0;
307*76d0caaeSpatrick        for ( size_t __i = 1; __i < __count; ++__i )
30846035553Spatrick        {
30946035553Spatrick            while ( __k > 0 && !__pred ( __f[__k], __f[__i] ))
31046035553Spatrick                __k = __prefix [ __k - 1 ];
31146035553Spatrick
31246035553Spatrick            if ( __pred ( __f[__k], __f[__i] ))
31346035553Spatrick                __k++;
31446035553Spatrick            __prefix [ __i ] = __k;
31546035553Spatrick        }
31646035553Spatrick    }
31746035553Spatrick
31846035553Spatrick    void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
31946035553Spatrick                                                    _BinaryPredicate __pred)
32046035553Spatrick    {
321*76d0caaeSpatrick        const size_t __count = _VSTD::distance(__f, __l);
32246035553Spatrick        vector<difference_type> & __suffix = *__suffix_.get();
32346035553Spatrick        if (__count > 0)
32446035553Spatrick        {
325*76d0caaeSpatrick            vector<value_type> __scratch(__count);
32646035553Spatrick
32746035553Spatrick            __compute_bm_prefix(__f, __l, __pred, __scratch);
328*76d0caaeSpatrick            for ( size_t __i = 0; __i <= __count; __i++ )
32946035553Spatrick                __suffix[__i] = __count - __scratch[__count-1];
33046035553Spatrick
331*76d0caaeSpatrick            typedef reverse_iterator<_RandomAccessIterator1> _RevIter;
33246035553Spatrick            __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch);
33346035553Spatrick
334*76d0caaeSpatrick            for ( size_t __i = 0; __i < __count; __i++ )
33546035553Spatrick            {
336*76d0caaeSpatrick                const size_t     __j = __count - __scratch[__i];
33746035553Spatrick                const difference_type __k = __i     - __scratch[__i] + 1;
33846035553Spatrick
33946035553Spatrick                if (__suffix[__j] > __k)
34046035553Spatrick                    __suffix[__j] = __k;
34146035553Spatrick            }
34246035553Spatrick        }
34346035553Spatrick    }
34446035553Spatrick
34546035553Spatrick};
34646035553Spatrick
34746035553Spatricktemplate<class _RandomAccessIterator,
34846035553Spatrick         class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
34946035553Spatrick         class _BinaryPredicate = equal_to<>>
35046035553Spatrick_LIBCPP_INLINE_VISIBILITY
35146035553Spatrickboyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
35246035553Spatrickmake_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
35346035553Spatrick                    _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
35446035553Spatrick{
35546035553Spatrick    return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
35646035553Spatrick}
35746035553Spatrick
35846035553Spatrick// boyer-moore-horspool
35946035553Spatricktemplate <class _RandomAccessIterator1,
36046035553Spatrick          class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>,
36146035553Spatrick          class _BinaryPredicate = equal_to<>>
362*76d0caaeSpatrickclass _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher {
36346035553Spatrickprivate:
36446035553Spatrick    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type;
36546035553Spatrick    typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type      value_type;
36646035553Spatrick    typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate,
367*76d0caaeSpatrick                    is_integral<value_type>::value && // what about enums?
36846035553Spatrick                    sizeof(value_type) == 1 &&
36946035553Spatrick                    is_same<_Hash, hash<value_type>>::value &&
37046035553Spatrick                    is_same<_BinaryPredicate, equal_to<>>::value
37146035553Spatrick            > skip_table_type;
37246035553Spatrick
37346035553Spatrickpublic:
37446035553Spatrick    boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l,
37546035553Spatrick                _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate())
37646035553Spatrick            : __first_(__f), __last_(__l), __pred_(__pred),
37746035553Spatrick              __pattern_length_(_VSTD::distance(__first_, __last_)),
37846035553Spatrick              __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)}
37946035553Spatrick        {
38046035553Spatrick    //  build the skip table
38146035553Spatrick            if ( __f != __l )
38246035553Spatrick            {
38346035553Spatrick                __l = __l - 1;
38446035553Spatrick                for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i )
38546035553Spatrick                    __skip_->insert(*__f, __pattern_length_ - 1 - __i);
38646035553Spatrick            }
38746035553Spatrick        }
38846035553Spatrick
38946035553Spatrick    template <typename _RandomAccessIterator2>
39046035553Spatrick    pair<_RandomAccessIterator2, _RandomAccessIterator2>
39146035553Spatrick    operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const
39246035553Spatrick    {
39346035553Spatrick        static_assert ( std::is_same<
39446035553Spatrick                typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type>::type,
39546035553Spatrick                typename std::__uncvref<typename std::iterator_traits<_RandomAccessIterator2>::value_type>::type
39646035553Spatrick                    >::value,
39746035553Spatrick                "Corpus and Pattern iterators must point to the same type" );
39846035553Spatrick
39946035553Spatrick        if (__f      == __l )    return make_pair(__l, __l); // empty corpus
40046035553Spatrick        if (__first_ == __last_) return make_pair(__f, __f); // empty pattern
40146035553Spatrick
40246035553Spatrick    //  If the pattern is larger than the corpus, we can't find it!
40346035553Spatrick        if ( __pattern_length_ > _VSTD::distance(__f, __l))
40446035553Spatrick            return make_pair(__l, __l);
40546035553Spatrick
40646035553Spatrick    //  Do the search
40746035553Spatrick        return this->__search(__f, __l);
40846035553Spatrick    }
40946035553Spatrick
41046035553Spatrickprivate:
41146035553Spatrick    _RandomAccessIterator1      __first_;
41246035553Spatrick    _RandomAccessIterator1      __last_;
41346035553Spatrick    _BinaryPredicate            __pred_;
41446035553Spatrick    difference_type             __pattern_length_;
41546035553Spatrick    shared_ptr<skip_table_type> __skip_;
41646035553Spatrick
41746035553Spatrick    template <typename _RandomAccessIterator2>
41846035553Spatrick    pair<_RandomAccessIterator2, _RandomAccessIterator2>
41946035553Spatrick    __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const {
42046035553Spatrick        _RandomAccessIterator2 __cur = __f;
42146035553Spatrick        const _RandomAccessIterator2 __last = __l - __pattern_length_;
42246035553Spatrick        const skip_table_type & __skip = *__skip_.get();
42346035553Spatrick
42446035553Spatrick        while (__cur <= __last)
42546035553Spatrick        {
42646035553Spatrick        //  Do we match right where we are?
42746035553Spatrick            difference_type __j = __pattern_length_;
42846035553Spatrick            while (__pred_(__first_[__j-1], __cur[__j-1]))
42946035553Spatrick            {
43046035553Spatrick                __j--;
43146035553Spatrick            //  We matched - we're done!
43246035553Spatrick                if ( __j == 0 )
43346035553Spatrick                    return make_pair(__cur, __cur + __pattern_length_);
43446035553Spatrick            }
43546035553Spatrick            __cur += __skip[__cur[__pattern_length_-1]];
43646035553Spatrick        }
43746035553Spatrick
43846035553Spatrick        return make_pair(__l, __l);
43946035553Spatrick    }
44046035553Spatrick};
44146035553Spatrick
44246035553Spatricktemplate<class _RandomAccessIterator,
44346035553Spatrick         class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>,
44446035553Spatrick         class _BinaryPredicate = equal_to<>>
44546035553Spatrick_LIBCPP_INLINE_VISIBILITY
44646035553Spatrickboyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>
44746035553Spatrickmake_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l,
44846035553Spatrick                    _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ())
44946035553Spatrick{
45046035553Spatrick    return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p);
45146035553Spatrick}
45246035553Spatrick
45346035553Spatrick#endif // _LIBCPP_STD_VER > 11
45446035553Spatrick
45546035553Spatrick_LIBCPP_END_NAMESPACE_LFTS
45646035553Spatrick
45746035553Spatrick_LIBCPP_POP_MACROS
45846035553Spatrick
45946035553Spatrick#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */
460