|
libstdc++
|
00001 // <experimental/functional> -*- C++ -*- 00002 00003 // Copyright (C) 2014-2015 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file experimental/functional 00026 * This is a TS C++ Library header. 00027 */ 00028 00029 #ifndef _GLIBCXX_EXPERIMENTAL_FUNCTIONAL 00030 #define _GLIBCXX_EXPERIMENTAL_FUNCTIONAL 1 00031 00032 #pragma GCC system_header 00033 00034 #if __cplusplus <= 201103L 00035 # include <bits/c++14_warning.h> 00036 #else 00037 00038 #include <functional> 00039 #include <tuple> 00040 #include <iterator> 00041 #include <unordered_map> 00042 #include <vector> 00043 #include <array> 00044 #include <bits/stl_algo.h> 00045 #include <experimental/lfts_config.h> 00046 00047 namespace std _GLIBCXX_VISIBILITY(default) 00048 { 00049 namespace experimental 00050 { 00051 inline namespace fundamentals_v1 00052 { 00053 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00054 00055 // See C++14 ยง20.9.9, Function object binders 00056 00057 /// Variable template for std::is_bind_expression 00058 template<typename _Tp> 00059 constexpr bool is_bind_expression_v = std::is_bind_expression<_Tp>::value; 00060 00061 /// Variable template for std::is_placeholder 00062 template<typename _Tp> 00063 constexpr int is_placeholder_v = std::is_placeholder<_Tp>::value; 00064 00065 #define __cpp_lib_experimental_boyer_moore_searching 201411 00066 00067 // Searchers 00068 00069 template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>> 00070 class default_searcher 00071 { 00072 public: 00073 default_searcher(_ForwardIterator1 __pat_first, 00074 _ForwardIterator1 __pat_last, 00075 _BinaryPredicate __pred = _BinaryPredicate()) 00076 : _M_m(__pat_first, __pat_last, std::move(__pred)) 00077 { } 00078 00079 template<typename _ForwardIterator2> 00080 _ForwardIterator2 00081 operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const 00082 { 00083 return std::search(__first, __last, 00084 std::get<0>(_M_m), std::get<1>(_M_m), 00085 std::get<2>(_M_m)); 00086 } 00087 00088 private: 00089 std::tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; 00090 }; 00091 00092 template<typename _Key, typename _Tp, typename _Hash, typename _Pred> 00093 struct __boyer_moore_map_base 00094 { 00095 template<typename _RAIter> 00096 __boyer_moore_map_base(_RAIter __pat, size_t __patlen, 00097 _Hash&& __hf, _Pred&& __pred) 00098 : _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) } 00099 { 00100 if (__patlen > 0) 00101 for (__diff_type __i = 0; __i < __patlen - 1; ++__i) 00102 _M_bad_char[__pat[__i]] = __patlen - 1 - __i; 00103 } 00104 00105 using __diff_type = _Tp; 00106 00107 __diff_type 00108 _M_lookup(_Key __key, __diff_type __not_found) const 00109 { 00110 auto __iter = _M_bad_char.find(__key); 00111 if (__iter == _M_bad_char.end()) 00112 return __not_found; 00113 return __iter->second; 00114 } 00115 00116 _Pred 00117 _M_pred() const { return _M_bad_char.key_eq(); } 00118 00119 _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char; 00120 }; 00121 00122 template<typename _Tp, size_t _Len, typename _Pred> 00123 struct __boyer_moore_array_base 00124 { 00125 template<typename _RAIter, typename _Unused> 00126 __boyer_moore_array_base(_RAIter __pat, size_t __patlen, 00127 _Unused&&, _Pred&& __pred) 00128 : _M_bad_char{ _GLIBCXX_STD_C::array<_Tp, _Len>{}, std::move(__pred) } 00129 { 00130 std::get<0>(_M_bad_char).fill(__patlen); 00131 if (__patlen > 0) 00132 for (__diff_type __i = 0; __i < __patlen - 1; ++__i) 00133 { 00134 auto __ch = __pat[__i]; 00135 using _UCh = std::make_unsigned_t<decltype(__ch)>; 00136 auto __uch = static_cast<_UCh>(__ch); 00137 std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i; 00138 } 00139 } 00140 00141 using __diff_type = _Tp; 00142 00143 template<typename _Key> 00144 __diff_type 00145 _M_lookup(_Key __key, __diff_type __not_found) const 00146 { 00147 auto __ukey = static_cast<std::make_unsigned_t<_Key>>(__key); 00148 if (__ukey >= _Len) 00149 return __not_found; 00150 return std::get<0>(_M_bad_char)[__ukey]; 00151 } 00152 00153 const _Pred& 00154 _M_pred() const { return std::get<1>(_M_bad_char); } 00155 00156 std::tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char; 00157 }; 00158 00159 template<typename _Pred> 00160 struct __is_std_equal_to : std::false_type { }; 00161 00162 template<> 00163 struct __is_std_equal_to<std::equal_to<void>> : std::true_type { }; 00164 00165 // Use __boyer_moore_array_base when pattern consists of narrow characters 00166 // and uses std::equal_to as the predicate. 00167 template<typename _RAIter, typename _Hash, typename _Pred, 00168 typename _Val = typename iterator_traits<_RAIter>::value_type, 00169 typename _Diff = typename iterator_traits<_RAIter>::difference_type> 00170 using __boyer_moore_base_t 00171 = std::conditional_t<sizeof(_Val) == 1 && is_integral<_Val>::value 00172 && __is_std_equal_to<_Pred>::value, 00173 __boyer_moore_array_base<_Diff, 256, _Pred>, 00174 __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>; 00175 00176 template<typename _RAIter, typename _Hash 00177 = std::hash<typename std::iterator_traits<_RAIter>::value_type>, 00178 typename _BinaryPredicate = std::equal_to<>> 00179 class boyer_moore_searcher 00180 : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> 00181 { 00182 using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; 00183 using typename _Base::__diff_type; 00184 00185 public: 00186 boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, 00187 _Hash __hf = _Hash(), 00188 _BinaryPredicate __pred = _BinaryPredicate()); 00189 00190 template<typename _RandomAccessIterator2> 00191 _RandomAccessIterator2 00192 operator()(_RandomAccessIterator2 __first, 00193 _RandomAccessIterator2 __last) const; 00194 00195 private: 00196 bool 00197 _M_is_prefix(_RAIter __word, __diff_type __len, 00198 __diff_type __pos) 00199 { 00200 const auto& __pred = this->_M_pred(); 00201 __diff_type __suffixlen = __len - __pos; 00202 for (__diff_type __i = 0; __i < __suffixlen; ++__i) 00203 if (!__pred(__word[__i], __word[__pos + __i])) 00204 return false; 00205 return true; 00206 } 00207 00208 __diff_type 00209 _M_suffix_length(_RAIter __word, __diff_type __len, 00210 __diff_type __pos) 00211 { 00212 const auto& __pred = this->_M_pred(); 00213 __diff_type __i = 0; 00214 while (__pred(__word[__pos - __i], __word[__len - 1 - __i]) 00215 && __i < __pos) 00216 { 00217 ++__i; 00218 } 00219 return __i; 00220 } 00221 00222 template<typename _Tp> 00223 __diff_type 00224 _M_bad_char_shift(_Tp __c) const 00225 { return this->_M_lookup(__c, _M_pat_end - _M_pat); } 00226 00227 _RAIter _M_pat; 00228 _RAIter _M_pat_end; 00229 _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix; 00230 }; 00231 00232 template<typename _RAIter, typename _Hash 00233 = std::hash<typename std::iterator_traits<_RAIter>::value_type>, 00234 typename _BinaryPredicate = std::equal_to<>> 00235 class boyer_moore_horspool_searcher 00236 : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> 00237 { 00238 using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; 00239 using typename _Base::__diff_type; 00240 00241 public: 00242 boyer_moore_horspool_searcher(_RAIter __pat, 00243 _RAIter __pat_end, 00244 _Hash __hf = _Hash(), 00245 _BinaryPredicate __pred 00246 = _BinaryPredicate()) 00247 : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), 00248 _M_pat(__pat), _M_pat_end(__pat_end) 00249 { } 00250 00251 template<typename _RandomAccessIterator2> 00252 _RandomAccessIterator2 00253 operator()(_RandomAccessIterator2 __first, 00254 _RandomAccessIterator2 __last) const 00255 { 00256 const auto& __pred = this->_M_pred(); 00257 auto __patlen = _M_pat_end - _M_pat; 00258 if (__patlen == 0) 00259 return __first; 00260 auto __len = __last - __first; 00261 while (__len >= __patlen) 00262 { 00263 for (auto __scan = __patlen - 1; 00264 __pred(__first[__scan], _M_pat[__scan]); --__scan) 00265 if (__scan == 0) 00266 return __first; 00267 auto __shift = _M_bad_char_shift(__first[__patlen - 1]); 00268 __len -= __shift; 00269 __first += __shift; 00270 } 00271 return __last; 00272 } 00273 00274 private: 00275 template<typename _Tp> 00276 __diff_type 00277 _M_bad_char_shift(_Tp __c) const 00278 { return this->_M_lookup(__c, _M_pat_end - _M_pat); } 00279 00280 _RAIter _M_pat; 00281 _RAIter _M_pat_end; 00282 }; 00283 00284 /// Generator function for default_searcher 00285 template<typename _ForwardIterator, 00286 typename _BinaryPredicate = std::equal_to<>> 00287 inline default_searcher<_ForwardIterator, _BinaryPredicate> 00288 make_default_searcher(_ForwardIterator __pat_first, 00289 _ForwardIterator __pat_last, 00290 _BinaryPredicate __pred = _BinaryPredicate()) 00291 { return { __pat_first, __pat_last, __pred }; } 00292 00293 /// Generator function for boyer_moore_searcher 00294 template<typename _RAIter, typename _Hash 00295 = std::hash<typename std::iterator_traits<_RAIter>::value_type>, 00296 typename _BinaryPredicate = equal_to<>> 00297 inline boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate> 00298 make_boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, 00299 _Hash __hf = _Hash(), 00300 _BinaryPredicate __pred = _BinaryPredicate()) 00301 { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; } 00302 00303 /// Generator function for boyer_moore_horspool_searcher 00304 template<typename _RAIter, typename _Hash 00305 = std::hash<typename std::iterator_traits<_RAIter>::value_type>, 00306 typename _BinaryPredicate = equal_to<>> 00307 inline boyer_moore_horspool_searcher<_RAIter, _Hash, _BinaryPredicate> 00308 make_boyer_moore_horspool_searcher(_RAIter __pat_first, _RAIter __pat_last, 00309 _Hash __hf = _Hash(), 00310 _BinaryPredicate __pred 00311 = _BinaryPredicate()) 00312 { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; } 00313 00314 template<typename _RAIter, typename _Hash, typename _BinaryPredicate> 00315 boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: 00316 boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end, 00317 _Hash __hf, _BinaryPredicate __pred) 00318 : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), 00319 _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat) 00320 { 00321 auto __patlen = __pat_end - __pat; 00322 if (__patlen == 0) 00323 return; 00324 __diff_type __last_prefix = __patlen - 1; 00325 for (__diff_type __p = __patlen - 1; __p >= 0; --__p) 00326 { 00327 if (_M_is_prefix(__pat, __patlen, __p + 1)) 00328 __last_prefix = __p + 1; 00329 _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p); 00330 } 00331 for (__diff_type __p = 0; __p < __patlen - 1; ++__p) 00332 { 00333 auto __slen = _M_suffix_length(__pat, __patlen, __p); 00334 auto __pos = __patlen - 1 - __slen; 00335 if (!__pred(__pat[__p - __slen], __pat[__pos])) 00336 _M_good_suffix[__pos] = __patlen - 1 - __p + __slen; 00337 } 00338 } 00339 00340 template<typename _RAIter, typename _Hash, typename _BinaryPredicate> 00341 template<typename _RandomAccessIterator2> 00342 _RandomAccessIterator2 00343 boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: 00344 operator()(_RandomAccessIterator2 __first, 00345 _RandomAccessIterator2 __last) const 00346 { 00347 auto __patlen = _M_pat_end - _M_pat; 00348 if (__patlen == 0) 00349 return __first; 00350 const auto& __pred = this->_M_pred(); 00351 __diff_type __i = __patlen - 1; 00352 auto __stringlen = __last - __first; 00353 while (__i < __stringlen) 00354 { 00355 __diff_type __j = __patlen - 1; 00356 while (__j >= 0 && __pred(__first[__i], _M_pat[__j])) 00357 { 00358 --__i; 00359 --__j; 00360 } 00361 if (__j < 0) 00362 return __first + __i + 1; 00363 __i += std::max(_M_bad_char_shift(__first[__i]), 00364 _M_good_suffix[__j]); 00365 } 00366 return __last; 00367 } 00368 00369 _GLIBCXX_END_NAMESPACE_VERSION 00370 } // namespace fundamentals_v1 00371 00372 inline namespace fundamentals_v2 00373 { 00374 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00375 00376 #define __cpp_lib_experimental_not_fn 201406 00377 00378 /// Generalized negator. 00379 template<typename _Fn> 00380 class _Not_fn 00381 { 00382 _Fn _M_fn; 00383 00384 public: 00385 template<typename _Fn2> 00386 explicit 00387 _Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { } 00388 00389 _Not_fn(const _Not_fn& __fn) = default; 00390 _Not_fn(_Not_fn&& __fn) = default; 00391 _Not_fn& operator=(const _Not_fn& __fn) = default; 00392 _Not_fn& operator=(_Not_fn&& __fn) = default; 00393 ~_Not_fn() = default; 00394 00395 template<typename... _Args> 00396 auto 00397 operator()(_Args&&... __args) 00398 noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...))) 00399 -> decltype(!_M_fn(std::forward<_Args>(__args)...)) 00400 { return !_M_fn(std::forward<_Args>(__args)...); } 00401 00402 template<typename... _Args> 00403 auto 00404 operator()(_Args&&... __args) const 00405 noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...))) 00406 -> decltype(!_M_fn(std::forward<_Args>(__args)...)) 00407 { return !_M_fn(std::forward<_Args>(__args)...); } 00408 00409 template<typename... _Args> 00410 auto 00411 operator()(_Args&&... __args) volatile 00412 noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...))) 00413 -> decltype(!_M_fn(std::forward<_Args>(__args)...)) 00414 { return !_M_fn(std::forward<_Args>(__args)...); } 00415 00416 template<typename... _Args> 00417 auto 00418 operator()(_Args&&... __args) const volatile 00419 noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...))) 00420 -> decltype(!_M_fn(std::forward<_Args>(__args)...)) 00421 { return !_M_fn(std::forward<_Args>(__args)...); } 00422 }; 00423 00424 /// [func.not_fn] Function template not_fn 00425 template<typename _Fn> 00426 inline auto 00427 not_fn(_Fn&& __fn) 00428 noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value) 00429 { 00430 using __maybe_type = _Maybe_wrap_member_pointer<std::decay_t<_Fn>>; 00431 return _Not_fn<typename __maybe_type::type>{std::forward<_Fn>(__fn), 0}; 00432 } 00433 00434 _GLIBCXX_END_NAMESPACE_VERSION 00435 } // namespace fundamentals_v2 00436 } // namespace experimental 00437 } // namespace std 00438 00439 #endif // C++14 00440 00441 #endif // _GLIBCXX_EXPERIMENTAL_FUNCTIONAL