functional 14 KB

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