| 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 |