| 1 | 
 // <experimental/functional> -*- C++ -*- | 
 
 
 
 
 
 | 2 | 
  | 
 
 
 
 
 
 | 3 | 
 // Copyright (C) 2014-2021 Free Software Foundation, Inc. | 
 
 
 
 
 
 | 4 | 
 // | 
 
 
 
 
 
 | 5 | 
 // This file is part of the GNU ISO C++ Library.  This library is free | 
 
 
 
 
 
 | 6 | 
 // software; you can redistribute it and/or modify it under the | 
 
 
 
 
 
 | 7 | 
 // terms of the GNU General Public License as published by the | 
 
 
 
 
 
 | 8 | 
 // Free Software Foundation; either version 3, or (at your option) | 
 
 
 
 
 
 | 9 | 
 // any later version. | 
 
 
 
 
 
 | 10 | 
  | 
 
 
 
 
 
 | 11 | 
 // This library is distributed in the hope that it will be useful, | 
 
 
 
 
 
 | 12 | 
 // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 
 
 
 
 
 | 13 | 
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 
 
 
 
 
 | 14 | 
 // GNU General Public License for more details. | 
 
 
 
 
 
 | 15 | 
  | 
 
 
 
 
 
 | 16 | 
 // Under Section 7 of GPL version 3, you are granted additional | 
 
 
 
 
 
 | 17 | 
 // permissions described in the GCC Runtime Library Exception, version | 
 
 
 
 
 
 | 18 | 
 // 3.1, as published by the Free Software Foundation. | 
 
 
 
 
 
 | 19 | 
  | 
 
 
 
 
 
 | 20 | 
 // You should have received a copy of the GNU General Public License and | 
 
 
 
 
 
 | 21 | 
 // a copy of the GCC Runtime Library Exception along with this program; | 
 
 
 
 
 
 | 22 | 
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
 
 
 
 
 
 | 23 | 
 // <http://www.gnu.org/licenses/>. | 
 
 
 
 
 
 | 24 | 
  | 
 
 
 
 
 
 | 25 | 
 /** @file experimental/functional | 
 
 
 
 
 
 | 26 | 
  *  This is a TS C++ Library header. | 
 
 
 
 
 
 | 27 | 
  *  @ingroup libfund-ts | 
 
 
 
 
 
 | 28 | 
  */ | 
 
 
 
 
 
 | 29 | 
  | 
 
 
 
 
 
 | 30 | 
 #ifndef _GLIBCXX_EXPERIMENTAL_FUNCTIONAL | 
 
 
 
 
 
 | 31 | 
 #define _GLIBCXX_EXPERIMENTAL_FUNCTIONAL 1 | 
 
 
 
 
 
 | 32 | 
  | 
 
 
 
 
 
 | 33 | 
 #pragma GCC system_header | 
 
 
 
 
 
 | 34 | 
  | 
 
 
 
 
 
 | 35 | 
 #if __cplusplus >= 201402L | 
 
 
 
 
 
 | 36 | 
  | 
 
 
 
 
 
 | 37 | 
 #include <functional> | 
 
 
 
 
 
 | 38 | 
 #include <tuple> | 
 
 
 
 
 
 | 39 | 
 #include <iterator> | 
 
 
 
 
 
 | 40 | 
 #include <unordered_map> | 
 
 
 
 
 
 | 41 | 
 #include <vector> | 
 
 
 
 
 
 | 42 | 
 #include <array> | 
 
 
 
 
 
 | 43 | 
 #include <bits/stl_algo.h> | 
 
 
 
 
 
 | 44 | 
 #ifdef _GLIBCXX_PARALLEL | 
 
 
 
 
 
 | 45 | 
 # include <parallel/algorithm> // For std::__parallel::search | 
 
 
 
 
 
 | 46 | 
 #endif | 
 
 
 
 
 
 | 47 | 
 #include <experimental/bits/lfts_config.h> | 
 
 
 
 
 
 | 48 | 
  | 
 
 
 
 
 
 | 49 | 
 namespace std _GLIBCXX_VISIBILITY(default) | 
 
 
 
 
 
 | 50 | 
 { | 
 
 
 
 
 
 | 51 | 
 _GLIBCXX_BEGIN_NAMESPACE_VERSION | 
 
 
 
 
 
 | 52 | 
  | 
 
 
 
 
 
 | 53 | 
 namespace experimental | 
 
 
 
 
 
 | 54 | 
 { | 
 
 
 
 
 
 | 55 | 
 inline namespace fundamentals_v1 | 
 
 
 
 
 
 | 56 | 
 { | 
 
 
 
 
 
 | 57 | 
   // See C++14 20.9.9, Function object binders | 
 
 
 
 
 
 | 58 | 
  | 
 
 
 
 
 
 | 59 | 
   /// Variable template for std::is_bind_expression | 
 
 
 
 
 
 | 60 | 
   template<typename _Tp> | 
 
 
 
 
 
 | 61 | 
     constexpr bool is_bind_expression_v = std::is_bind_expression<_Tp>::value; | 
 
 
 
 
 
 | 62 | 
  | 
 
 
 
 
 
 | 63 | 
   /// Variable template for std::is_placeholder | 
 
 
 
 
 
 | 64 | 
   template<typename _Tp> | 
 
 
 
 
 
 | 65 | 
     constexpr int is_placeholder_v = std::is_placeholder<_Tp>::value; | 
 
 
 
 
 
 | 66 | 
  | 
 
 
 
 
 
 | 67 | 
 #define __cpp_lib_experimental_boyer_moore_searching 201411 | 
 
 
 
 
 
 | 68 | 
  | 
 
 
 
 
 
 | 69 | 
   // Searchers | 
 
 
 
 
 
 | 70 | 
  | 
 
 
 
 
 
 | 71 | 
   template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>> | 
 
 
 
 
 
 | 72 | 
     class default_searcher | 
 
 
 
 
 
 | 73 | 
     { | 
 
 
 
 
 
 | 74 | 
     public: | 
 
 
 
 
 
 | 75 | 
       default_searcher(_ForwardIterator1 __pat_first, | 
 
 
 
 
 
 | 76 | 
                        _ForwardIterator1 __pat_last, | 
 
 
 
 
 
 | 77 | 
                        _BinaryPredicate __pred = _BinaryPredicate()) | 
 
 
 
 
 
 | 78 | 
       : _M_m(__pat_first, __pat_last, std::move(__pred)) | 
 
 
 
 
 
 | 79 | 
       { } | 
 
 
 
 
 
 | 80 | 
  | 
 
 
 
 
 
 | 81 | 
       template<typename _ForwardIterator2> | 
 
 
 
 
 
 | 82 | 
         _ForwardIterator2 | 
 
 
 
 
 
 | 83 | 
         operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const | 
 
 
 
 
 
 | 84 | 
         { | 
 
 
 
 
 
 | 85 | 
           return std::search(__first, __last, | 
 
 
 
 
 
 | 86 | 
                              std::get<0>(_M_m), std::get<1>(_M_m), | 
 
 
 
 
 
 | 87 | 
                              std::get<2>(_M_m)); | 
 
 
 
 
 
 | 88 | 
         } | 
 
 
 
 
 
 | 89 | 
  | 
 
 
 
 
 
 | 90 | 
     private: | 
 
 
 
 
 
 | 91 | 
       std::tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; | 
 
 
 
 
 
 | 92 | 
     }; | 
 
 
 
 
 
 | 93 | 
  | 
 
 
 
 
 
 | 94 | 
   template<typename _Key, typename _Tp, typename _Hash, typename _Pred> | 
 
 
 
 
 
 | 95 | 
     struct __boyer_moore_map_base | 
 
 
 
 
 
 | 96 | 
     { | 
 
 
 
 
 
 | 97 | 
       template<typename _RAIter> | 
 
 
 
 
 
 | 98 | 
         __boyer_moore_map_base(_RAIter __pat, size_t __patlen, | 
 
 
 
 
 
 | 99 | 
                                _Hash&& __hf, _Pred&& __pred) | 
 
 
 
 
 
 | 100 | 
         : _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) } | 
 
 
 
 
 
 | 101 | 
         { | 
 
 
 
 
 
 | 102 | 
           if (__patlen > 0) | 
 
 
 
 
 
 | 103 | 
             for (__diff_type __i = 0; __i < __patlen - 1; ++__i) | 
 
 
 
 
 
 | 104 | 
               _M_bad_char[__pat[__i]] = __patlen - 1 - __i; | 
 
 
 
 
 
 | 105 | 
         } | 
 
 
 
 
 
 | 106 | 
  | 
 
 
 
 
 
 | 107 | 
       using __diff_type = _Tp; | 
 
 
 
 
 
 | 108 | 
  | 
 
 
 
 
 
 | 109 | 
       __diff_type | 
 
 
 
 
 
 | 110 | 
       _M_lookup(_Key __key, __diff_type __not_found) const | 
 
 
 
 
 
 | 111 | 
       { | 
 
 
 
 
 
 | 112 | 
         auto __iter = _M_bad_char.find(__key); | 
 
 
 
 
 
 | 113 | 
         if (__iter == _M_bad_char.end()) | 
 
 
 
 
 
 | 114 | 
           return __not_found; | 
 
 
 
 
 
 | 115 | 
         return __iter->second; | 
 
 
 
 
 
 | 116 | 
       } | 
 
 
 
 
 
 | 117 | 
  | 
 
 
 
 
 
 | 118 | 
       _Pred | 
 
 
 
 
 
 | 119 | 
       _M_pred() const { return _M_bad_char.key_eq(); } | 
 
 
 
 
 
 | 120 | 
  | 
 
 
 
 
 
 | 121 | 
       _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char; | 
 
 
 
 
 
 | 122 | 
     }; | 
 
 
 
 
 
 | 123 | 
  | 
 
 
 
 
 
 | 124 | 
   template<typename _Tp, size_t _Len, typename _Pred> | 
 
 
 
 
 
 | 125 | 
     struct __boyer_moore_array_base | 
 
 
 
 
 
 | 126 | 
     { | 
 
 
 
 
 
 | 127 | 
       template<typename _RAIter, typename _Unused> | 
 
 
 
 
 
 | 128 | 
         __boyer_moore_array_base(_RAIter __pat, size_t __patlen, | 
 
 
 
 
 
 | 129 | 
                                  _Unused&&, _Pred&& __pred) | 
 
 
 
 
 
 | 130 | 
         : _M_bad_char{ std::array<_Tp, _Len>{}, std::move(__pred) } | 
 
 
 
 
 
 | 131 | 
         { | 
 
 
 
 
 
 | 132 | 
           std::get<0>(_M_bad_char).fill(__patlen); | 
 
 
 
 
 
 | 133 | 
           if (__patlen > 0) | 
 
 
 
 
 
 | 134 | 
             for (__diff_type __i = 0; __i < __patlen - 1; ++__i) | 
 
 
 
 
 
 | 135 | 
               { | 
 
 
 
 
 
 | 136 | 
                 auto __ch = __pat[__i]; | 
 
 
 
 
 
 | 137 | 
                 using _UCh = std::make_unsigned_t<decltype(__ch)>; | 
 
 
 
 
 
 | 138 | 
                 auto __uch = static_cast<_UCh>(__ch); | 
 
 
 
 
 
 | 139 | 
                 std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i; | 
 
 
 
 
 
 | 140 | 
               } | 
 
 
 
 
 
 | 141 | 
         } | 
 
 
 
 
 
 | 142 | 
  | 
 
 
 
 
 
 | 143 | 
       using __diff_type = _Tp; | 
 
 
 
 
 
 | 144 | 
  | 
 
 
 
 
 
 | 145 | 
       template<typename _Key> | 
 
 
 
 
 
 | 146 | 
         __diff_type | 
 
 
 
 
 
 | 147 | 
         _M_lookup(_Key __key, __diff_type __not_found) const | 
 
 
 
 
 
 | 148 | 
         { | 
 
 
 
 
 
 | 149 | 
           auto __ukey = static_cast<std::make_unsigned_t<_Key>>(__key); | 
 
 
 
 
 
 | 150 | 
           if (__ukey >= _Len) | 
 
 
 
 
 
 | 151 | 
             return __not_found; | 
 
 
 
 
 
 | 152 | 
           return std::get<0>(_M_bad_char)[__ukey]; | 
 
 
 
 
 
 | 153 | 
         } | 
 
 
 
 
 
 | 154 | 
  | 
 
 
 
 
 
 | 155 | 
       const _Pred& | 
 
 
 
 
 
 | 156 | 
       _M_pred() const { return std::get<1>(_M_bad_char); } | 
 
 
 
 
 
 | 157 | 
  | 
 
 
 
 
 
 | 158 | 
       std::tuple<std::array<_Tp, _Len>, _Pred> _M_bad_char; | 
 
 
 
 
 
 | 159 | 
     }; | 
 
 
 
 
 
 | 160 | 
  | 
 
 
 
 
 
 | 161 | 
   // Use __boyer_moore_array_base when pattern consists of narrow characters | 
 
 
 
 
 
 | 162 | 
   // (or std::byte) and uses std::equal_to as the predicate. | 
 
 
 
 
 
 | 163 | 
   template<typename _RAIter, typename _Hash, typename _Pred, | 
 
 
 
 
 
 | 164 | 
            typename _Val = typename iterator_traits<_RAIter>::value_type, | 
 
 
 
 
 
 | 165 | 
            typename _Diff = typename iterator_traits<_RAIter>::difference_type> | 
 
 
 
 
 
 | 166 | 
     using __boyer_moore_base_t | 
 
 
 
 
 
 | 167 | 
       = std::conditional_t<std::__is_byte_like<_Val, _Pred>::value, | 
 
 
 
 
 
 | 168 | 
                            __boyer_moore_array_base<_Diff, 256, _Pred>, | 
 
 
 
 
 
 | 169 | 
                            __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>; | 
 
 
 
 
 
 | 170 | 
  | 
 
 
 
 
 
 | 171 | 
   template<typename _RAIter, typename _Hash | 
 
 
 
 
 
 | 172 | 
              = std::hash<typename std::iterator_traits<_RAIter>::value_type>, | 
 
 
 
 
 
 | 173 | 
            typename _BinaryPredicate = std::equal_to<>> | 
 
 
 
 
 
 | 174 | 
     class boyer_moore_searcher | 
 
 
 
 
 
 | 175 | 
     : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> | 
 
 
 
 
 
 | 176 | 
     { | 
 
 
 
 
 
 | 177 | 
       using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; | 
 
 
 
 
 
 | 178 | 
       using typename _Base::__diff_type; | 
 
 
 
 
 
 | 179 | 
  | 
 
 
 
 
 
 | 180 | 
     public: | 
 
 
 
 
 
 | 181 | 
       boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, | 
 
 
 
 
 
 | 182 | 
                            _Hash __hf = _Hash(), | 
 
 
 
 
 
 | 183 | 
                            _BinaryPredicate __pred = _BinaryPredicate()); | 
 
 
 
 
 
 | 184 | 
  | 
 
 
 
 
 
 | 185 | 
       template<typename _RandomAccessIterator2> | 
 
 
 
 
 
 | 186 | 
         _RandomAccessIterator2 | 
 
 
 
 
 
 | 187 | 
         operator()(_RandomAccessIterator2 __first, | 
 
 
 
 
 
 | 188 | 
                    _RandomAccessIterator2 __last) const; | 
 
 
 
 
 
 | 189 | 
  | 
 
 
 
 
 
 | 190 | 
     private: | 
 
 
 
 
 
 | 191 | 
       bool | 
 
 
 
 
 
 | 192 | 
       _M_is_prefix(_RAIter __word, __diff_type __len, | 
 
 
 
 
 
 | 193 | 
                    __diff_type __pos) | 
 
 
 
 
 
 | 194 | 
       { | 
 
 
 
 
 
 | 195 | 
         const auto& __pred = this->_M_pred(); | 
 
 
 
 
 
 | 196 | 
         __diff_type __suffixlen = __len - __pos; | 
 
 
 
 
 
 | 197 | 
         for (__diff_type __i = 0; __i < __suffixlen; ++__i) | 
 
 
 
 
 
 | 198 | 
           if (!__pred(__word[__i], __word[__pos + __i])) | 
 
 
 
 
 
 | 199 | 
             return false; | 
 
 
 
 
 
 | 200 | 
         return true; | 
 
 
 
 
 
 | 201 | 
       } | 
 
 
 
 
 
 | 202 | 
  | 
 
 
 
 
 
 | 203 | 
       __diff_type | 
 
 
 
 
 
 | 204 | 
       _M_suffix_length(_RAIter __word, __diff_type __len, | 
 
 
 
 
 
 | 205 | 
                        __diff_type __pos) | 
 
 
 
 
 
 | 206 | 
       { | 
 
 
 
 
 
 | 207 | 
         const auto& __pred = this->_M_pred(); | 
 
 
 
 
 
 | 208 | 
         __diff_type __i = 0; | 
 
 
 
 
 
 | 209 | 
         while (__pred(__word[__pos - __i], __word[__len - 1 - __i]) | 
 
 
 
 
 
 | 210 | 
                && __i < __pos) | 
 
 
 
 
 
 | 211 | 
           { | 
 
 
 
 
 
 | 212 | 
             ++__i; | 
 
 
 
 
 
 | 213 | 
           } | 
 
 
 
 
 
 | 214 | 
         return __i; | 
 
 
 
 
 
 | 215 | 
       } | 
 
 
 
 
 
 | 216 | 
  | 
 
 
 
 
 
 | 217 | 
       template<typename _Tp> | 
 
 
 
 
 
 | 218 | 
         __diff_type | 
 
 
 
 
 
 | 219 | 
         _M_bad_char_shift(_Tp __c) const | 
 
 
 
 
 
 | 220 | 
         { return this->_M_lookup(__c, _M_pat_end - _M_pat); } | 
 
 
 
 
 
 | 221 | 
  | 
 
 
 
 
 
 | 222 | 
       _RAIter _M_pat; | 
 
 
 
 
 
 | 223 | 
       _RAIter _M_pat_end; | 
 
 
 
 
 
 | 224 | 
       _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix; | 
 
 
 
 
 
 | 225 | 
     }; | 
 
 
 
 
 
 | 226 | 
  | 
 
 
 
 
 
 | 227 | 
   template<typename _RAIter, typename _Hash | 
 
 
 
 
 
 | 228 | 
              = std::hash<typename std::iterator_traits<_RAIter>::value_type>, | 
 
 
 
 
 
 | 229 | 
            typename _BinaryPredicate = std::equal_to<>> | 
 
 
 
 
 
 | 230 | 
     class boyer_moore_horspool_searcher | 
 
 
 
 
 
 | 231 | 
     : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> | 
 
 
 
 
 
 | 232 | 
     { | 
 
 
 
 
 
 | 233 | 
       using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; | 
 
 
 
 
 
 | 234 | 
       using typename _Base::__diff_type; | 
 
 
 
 
 
 | 235 | 
  | 
 
 
 
 
 
 | 236 | 
     public: | 
 
 
 
 
 
 | 237 | 
       boyer_moore_horspool_searcher(_RAIter __pat, | 
 
 
 
 
 
 | 238 | 
                                     _RAIter __pat_end, | 
 
 
 
 
 
 | 239 | 
                                     _Hash __hf = _Hash(), | 
 
 
 
 
 
 | 240 | 
                                     _BinaryPredicate __pred | 
 
 
 
 
 
 | 241 | 
                                     = _BinaryPredicate()) | 
 
 
 
 
 
 | 242 | 
       : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), | 
 
 
 
 
 
 | 243 | 
         _M_pat(__pat), _M_pat_end(__pat_end) | 
 
 
 
 
 
 | 244 | 
       { } | 
 
 
 
 
 
 | 245 | 
  | 
 
 
 
 
 
 | 246 | 
       template<typename _RandomAccessIterator2> | 
 
 
 
 
 
 | 247 | 
         _RandomAccessIterator2 | 
 
 
 
 
 
 | 248 | 
         operator()(_RandomAccessIterator2 __first, | 
 
 
 
 
 
 | 249 | 
                    _RandomAccessIterator2 __last) const | 
 
 
 
 
 
 | 250 | 
         { | 
 
 
 
 
 
 | 251 | 
           const auto& __pred = this->_M_pred(); | 
 
 
 
 
 
 | 252 | 
           auto __patlen = _M_pat_end - _M_pat; | 
 
 
 
 
 
 | 253 | 
           if (__patlen == 0) | 
 
 
 
 
 
 | 254 | 
             return __first; | 
 
 
 
 
 
 | 255 | 
           auto __len = __last - __first; | 
 
 
 
 
 
 | 256 | 
           while (__len >= __patlen) | 
 
 
 
 
 
 | 257 | 
             { | 
 
 
 
 
 
 | 258 | 
               for (auto __scan = __patlen - 1; | 
 
 
 
 
 
 | 259 | 
                    __pred(__first[__scan], _M_pat[__scan]); --__scan) | 
 
 
 
 
 
 | 260 | 
                 if (__scan == 0) | 
 
 
 
 
 
 | 261 | 
                   return __first; | 
 
 
 
 
 
 | 262 | 
               auto __shift = _M_bad_char_shift(__first[__patlen - 1]); | 
 
 
 
 
 
 | 263 | 
               __len -= __shift; | 
 
 
 
 
 
 | 264 | 
               __first += __shift; | 
 
 
 
 
 
 | 265 | 
             } | 
 
 
 
 
 
 | 266 | 
           return __last; | 
 
 
 
 
 
 | 267 | 
         } | 
 
 
 
 
 
 | 268 | 
  | 
 
 
 
 
 
 | 269 | 
     private: | 
 
 
 
 
 
 | 270 | 
       template<typename _Tp> | 
 
 
 
 
 
 | 271 | 
         __diff_type | 
 
 
 
 
 
 | 272 | 
         _M_bad_char_shift(_Tp __c) const | 
 
 
 
 
 
 | 273 | 
         { return this->_M_lookup(__c, _M_pat_end - _M_pat); } | 
 
 
 
 
 
 | 274 | 
  | 
 
 
 
 
 
 | 275 | 
       _RAIter _M_pat; | 
 
 
 
 
 
 | 276 | 
       _RAIter _M_pat_end; | 
 
 
 
 
 
 | 277 | 
     }; | 
 
 
 
 
 
 | 278 | 
  | 
 
 
 
 
 
 | 279 | 
   /// Generator function for default_searcher | 
 
 
 
 
 
 | 280 | 
   template<typename _ForwardIterator, | 
 
 
 
 
 
 | 281 | 
            typename _BinaryPredicate = std::equal_to<>> | 
 
 
 
 
 
 | 282 | 
     inline default_searcher<_ForwardIterator, _BinaryPredicate> | 
 
 
 
 
 
 | 283 | 
     make_default_searcher(_ForwardIterator __pat_first, | 
 
 
 
 
 
 | 284 | 
                           _ForwardIterator __pat_last, | 
 
 
 
 
 
 | 285 | 
                           _BinaryPredicate __pred = _BinaryPredicate()) | 
 
 
 
 
 
 | 286 | 
     { return { __pat_first, __pat_last, __pred }; } | 
 
 
 
 
 
 | 287 | 
  | 
 
 
 
 
 
 | 288 | 
   /// Generator function for boyer_moore_searcher | 
 
 
 
 
 
 | 289 | 
   template<typename _RAIter, typename _Hash | 
 
 
 
 
 
 | 290 | 
              = std::hash<typename std::iterator_traits<_RAIter>::value_type>, | 
 
 
 
 
 
 | 291 | 
            typename _BinaryPredicate = equal_to<>> | 
 
 
 
 
 
 | 292 | 
     inline boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate> | 
 
 
 
 
 
 | 293 | 
     make_boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, | 
 
 
 
 
 
 | 294 | 
                               _Hash __hf = _Hash(), | 
 
 
 
 
 
 | 295 | 
                               _BinaryPredicate __pred = _BinaryPredicate()) | 
 
 
 
 
 
 | 296 | 
     { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; } | 
 
 
 
 
 
 | 297 | 
  | 
 
 
 
 
 
 | 298 | 
   /// Generator function for boyer_moore_horspool_searcher | 
 
 
 
 
 
 | 299 | 
   template<typename _RAIter, typename _Hash | 
 
 
 
 
 
 | 300 | 
              = std::hash<typename std::iterator_traits<_RAIter>::value_type>, | 
 
 
 
 
 
 | 301 | 
            typename _BinaryPredicate = equal_to<>> | 
 
 
 
 
 
 | 302 | 
     inline boyer_moore_horspool_searcher<_RAIter, _Hash, _BinaryPredicate> | 
 
 
 
 
 
 | 303 | 
     make_boyer_moore_horspool_searcher(_RAIter __pat_first, _RAIter __pat_last, | 
 
 
 
 
 
 | 304 | 
                                        _Hash __hf = _Hash(), | 
 
 
 
 
 
 | 305 | 
                                        _BinaryPredicate __pred | 
 
 
 
 
 
 | 306 | 
                                        = _BinaryPredicate()) | 
 
 
 
 
 
 | 307 | 
     { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; } | 
 
 
 
 
 
 | 308 | 
  | 
 
 
 
 
 
 | 309 | 
   template<typename _RAIter, typename _Hash, typename _BinaryPredicate> | 
 
 
 
 
 
 | 310 | 
     boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: | 
 
 
 
 
 
 | 311 | 
     boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end, | 
 
 
 
 
 
 | 312 | 
                          _Hash __hf, _BinaryPredicate __pred) | 
 
 
 
 
 
 | 313 | 
     : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), | 
 
 
 
 
 
 | 314 | 
       _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat) | 
 
 
 
 
 
 | 315 | 
     { | 
 
 
 
 
 
 | 316 | 
       auto __patlen = __pat_end - __pat; | 
 
 
 
 
 
 | 317 | 
       if (__patlen == 0) | 
 
 
 
 
 
 | 318 | 
         return; | 
 
 
 
 
 
 | 319 | 
       __diff_type __last_prefix = __patlen - 1; | 
 
 
 
 
 
 | 320 | 
       for (__diff_type __p = __patlen - 1; __p >= 0; --__p) | 
 
 
 
 
 
 | 321 | 
         { | 
 
 
 
 
 
 | 322 | 
           if (_M_is_prefix(__pat, __patlen, __p + 1)) | 
 
 
 
 
 
 | 323 | 
             __last_prefix = __p + 1; | 
 
 
 
 
 
 | 324 | 
           _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p); | 
 
 
 
 
 
 | 325 | 
         } | 
 
 
 
 
 
 | 326 | 
       for (__diff_type __p = 0; __p < __patlen - 1; ++__p) | 
 
 
 
 
 
 | 327 | 
         { | 
 
 
 
 
 
 | 328 | 
           auto __slen = _M_suffix_length(__pat, __patlen, __p); | 
 
 
 
 
 
 | 329 | 
           auto __pos = __patlen - 1 - __slen; | 
 
 
 
 
 
 | 330 | 
           if (!__pred(__pat[__p - __slen], __pat[__pos])) | 
 
 
 
 
 
 | 331 | 
             _M_good_suffix[__pos] = __patlen - 1 - __p + __slen; | 
 
 
 
 
 
 | 332 | 
         } | 
 
 
 
 
 
 | 333 | 
     } | 
 
 
 
 
 
 | 334 | 
  | 
 
 
 
 
 
 | 335 | 
   template<typename _RAIter, typename _Hash, typename _BinaryPredicate> | 
 
 
 
 
 
 | 336 | 
   template<typename _RandomAccessIterator2> | 
 
 
 
 
 
 | 337 | 
     _RandomAccessIterator2 | 
 
 
 
 
 
 | 338 | 
     boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: | 
 
 
 
 
 
 | 339 | 
     operator()(_RandomAccessIterator2 __first, | 
 
 
 
 
 
 | 340 | 
                _RandomAccessIterator2 __last) const | 
 
 
 
 
 
 | 341 | 
     { | 
 
 
 
 
 
 | 342 | 
       auto __patlen = _M_pat_end - _M_pat; | 
 
 
 
 
 
 | 343 | 
       if (__patlen == 0) | 
 
 
 
 
 
 | 344 | 
         return __first; | 
 
 
 
 
 
 | 345 | 
       const auto& __pred = this->_M_pred(); | 
 
 
 
 
 
 | 346 | 
       __diff_type __i = __patlen - 1; | 
 
 
 
 
 
 | 347 | 
       auto __stringlen = __last - __first; | 
 
 
 
 
 
 | 348 | 
       while (__i < __stringlen) | 
 
 
 
 
 
 | 349 | 
         { | 
 
 
 
 
 
 | 350 | 
           __diff_type __j = __patlen - 1; | 
 
 
 
 
 
 | 351 | 
           while (__j >= 0 && __pred(__first[__i], _M_pat[__j])) | 
 
 
 
 
 
 | 352 | 
             { | 
 
 
 
 
 
 | 353 | 
               --__i; | 
 
 
 
 
 
 | 354 | 
               --__j; | 
 
 
 
 
 
 | 355 | 
             } | 
 
 
 
 
 
 | 356 | 
           if (__j < 0) | 
 
 
 
 
 
 | 357 | 
             return __first + __i + 1; | 
 
 
 
 
 
 | 358 | 
           __i += std::max(_M_bad_char_shift(__first[__i]), | 
 
 
 
 
 
 | 359 | 
                           _M_good_suffix[__j]); | 
 
 
 
 
 
 | 360 | 
         } | 
 
 
 
 
 
 | 361 | 
       return __last; | 
 
 
 
 
 
 | 362 | 
     } | 
 
 
 
 
 
 | 363 | 
 } // namespace fundamentals_v1 | 
 
 
 
 
 
 | 364 | 
  | 
 
 
 
 
 
 | 365 | 
 inline namespace fundamentals_v2 | 
 
 
 
 
 
 | 366 | 
 { | 
 
 
 
 
 
 | 367 | 
 #define __cpp_lib_experimental_not_fn 201406 | 
 
 
 
 
 
 | 368 | 
  | 
 
 
 
 
 
 | 369 | 
   /// [func.not_fn] Function template not_fn | 
 
 
 
 
 
 | 370 | 
   template<typename _Fn> | 
 
 
 
 
 
 | 371 | 
     inline auto | 
 
 
 
 
 
 | 372 | 
     not_fn(_Fn&& __fn) | 
 
 
 
 
 
 | 373 | 
     noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value) | 
 
 
 
 
 
 | 374 | 
     { | 
 
 
 
 
 
 | 375 | 
       return std::_Not_fn<std::decay_t<_Fn>>{std::forward<_Fn>(__fn), 0}; | 
 
 
 
 
 
 | 376 | 
     } | 
 
 
 
 
 
 | 377 | 
 } // namespace fundamentals_v2 | 
 
 
 
 
 
 | 378 | 
 } // namespace experimental | 
 
 
 
 
 
 | 379 | 
  | 
 
 
 
 
 
 | 380 | 
 _GLIBCXX_END_NAMESPACE_VERSION | 
 
 
 
 
 
 | 381 | 
 } // namespace std | 
 
 
 
 
 
 | 382 | 
  | 
 
 
 
 
 
 | 383 | 
 #endif // C++14 | 
 
 
 
 
 
 | 384 | 
  | 
 
 
 
 
 
 | 385 | 
 #endif // _GLIBCXX_EXPERIMENTAL_FUNCTIONAL |