1// <experimental/functional> -*- C++ -*-
2
3// Copyright (C) 2014-2016 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 */
28
29#ifndef _GLIBCXX_EXPERIMENTAL_FUNCTIONAL
30#define _GLIBCXX_EXPERIMENTAL_FUNCTIONAL 1
31
32#pragma GCC system_header
33
34#if __cplusplus <= 201103L
35# include <bits/c++14_warning.h>
36#else
37
38#include <functional>
39#include <tuple>
40#include <iterator>
41#include <unordered_map>
42#include <vector>
43#include <array>
44#include <bits/stl_algo.h>
45#ifdef _GLIBCXX_PARALLEL
46# include <parallel/algorithm> // For std::__parallel::search
47#endif
48#include <experimental/bits/lfts_config.h>
49
50namespace std _GLIBCXX_VISIBILITY(default)
51{
52namespace experimental
53{
54inline namespace fundamentals_v1
55{
56_GLIBCXX_BEGIN_NAMESPACE_VERSION
57
58  // See C++14 §20.9.9, Function object binders
59
60  /// Variable template for std::is_bind_expression
61  template<typename _Tp>
62    constexpr bool is_bind_expression_v = std::is_bind_expression<_Tp>::value;
63
64  /// Variable template for std::is_placeholder
65  template<typename _Tp>
66    constexpr int is_placeholder_v = std::is_placeholder<_Tp>::value;
67
68#define __cpp_lib_experimental_boyer_moore_searching 201411
69
70  // Searchers
71
72  template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>>
73    class default_searcher
74    {
75    public:
76      default_searcher(_ForwardIterator1 __pat_first,
77		       _ForwardIterator1 __pat_last,
78		       _BinaryPredicate __pred = _BinaryPredicate())
79      : _M_m(__pat_first, __pat_last, std::move(__pred))
80      { }
81
82      template<typename _ForwardIterator2>
83	_ForwardIterator2
84	operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const
85	{
86	  return std::search(__first, __last,
87			     std::get<0>(_M_m), std::get<1>(_M_m),
88			     std::get<2>(_M_m));
89	}
90
91    private:
92      std::tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m;
93    };
94
95  template<typename _Key, typename _Tp, typename _Hash, typename _Pred>
96    struct __boyer_moore_map_base
97    {
98      template<typename _RAIter>
99	__boyer_moore_map_base(_RAIter __pat, size_t __patlen,
100			       _Hash&& __hf, _Pred&& __pred)
101	: _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) }
102	{
103	  if (__patlen > 0)
104	    for (__diff_type __i = 0; __i < __patlen - 1; ++__i)
105	      _M_bad_char[__pat[__i]] = __patlen - 1 - __i;
106	}
107
108      using __diff_type = _Tp;
109
110      __diff_type
111      _M_lookup(_Key __key, __diff_type __not_found) const
112      {
113	auto __iter = _M_bad_char.find(__key);
114	if (__iter == _M_bad_char.end())
115	  return __not_found;
116	return __iter->second;
117      }
118
119      _Pred
120      _M_pred() const { return _M_bad_char.key_eq(); }
121
122      _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char;
123    };
124
125  template<typename _Tp, size_t _Len, typename _Pred>
126    struct __boyer_moore_array_base
127    {
128      template<typename _RAIter, typename _Unused>
129	__boyer_moore_array_base(_RAIter __pat, size_t __patlen,
130				 _Unused&&, _Pred&& __pred)
131	: _M_bad_char{ _GLIBCXX_STD_C::array<_Tp, _Len>{}, std::move(__pred) }
132	{
133	  std::get<0>(_M_bad_char).fill(__patlen);
134	  if (__patlen > 0)
135	    for (__diff_type __i = 0; __i < __patlen - 1; ++__i)
136	      {
137		auto __ch = __pat[__i];
138		using _UCh = std::make_unsigned_t<decltype(__ch)>;
139		auto __uch = static_cast<_UCh>(__ch);
140		std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i;
141	      }
142	}
143
144      using __diff_type = _Tp;
145
146      template<typename _Key>
147	__diff_type
148	_M_lookup(_Key __key, __diff_type __not_found) const
149	{
150	  auto __ukey = static_cast<std::make_unsigned_t<_Key>>(__key);
151	  if (__ukey >= _Len)
152	    return __not_found;
153	  return std::get<0>(_M_bad_char)[__ukey];
154	}
155
156      const _Pred&
157      _M_pred() const { return std::get<1>(_M_bad_char); }
158
159      std::tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char;
160    };
161
162  template<typename _Pred>
163    struct __is_std_equal_to : std::false_type { };
164
165  template<>
166    struct __is_std_equal_to<std::equal_to<void>> : std::true_type { };
167
168  // Use __boyer_moore_array_base when pattern consists of narrow characters
169  // and uses std::equal_to as the predicate.
170  template<typename _RAIter, typename _Hash, typename _Pred,
171           typename _Val = typename iterator_traits<_RAIter>::value_type,
172	   typename _Diff = typename iterator_traits<_RAIter>::difference_type>
173    using __boyer_moore_base_t
174      = std::conditional_t<sizeof(_Val) == 1 && is_integral<_Val>::value
175			   && __is_std_equal_to<_Pred>::value,
176			   __boyer_moore_array_base<_Diff, 256, _Pred>,
177			   __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>;
178
179  template<typename _RAIter, typename _Hash
180	     = std::hash<typename std::iterator_traits<_RAIter>::value_type>,
181	   typename _BinaryPredicate = std::equal_to<>>
182    class boyer_moore_searcher
183    : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>
184    {
185      using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>;
186      using typename _Base::__diff_type;
187
188    public:
189      boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last,
190			   _Hash __hf = _Hash(),
191			   _BinaryPredicate __pred = _BinaryPredicate());
192
193      template<typename _RandomAccessIterator2>
194	_RandomAccessIterator2
195	operator()(_RandomAccessIterator2 __first,
196		   _RandomAccessIterator2 __last) const;
197
198    private:
199      bool
200      _M_is_prefix(_RAIter __word, __diff_type __len,
201		   __diff_type __pos)
202      {
203	const auto& __pred = this->_M_pred();
204	__diff_type __suffixlen = __len - __pos;
205	for (__diff_type __i = 0; __i < __suffixlen; ++__i)
206	  if (!__pred(__word[__i], __word[__pos + __i]))
207	    return false;
208	return true;
209      }
210
211      __diff_type
212      _M_suffix_length(_RAIter __word, __diff_type __len,
213		       __diff_type __pos)
214      {
215	const auto& __pred = this->_M_pred();
216	__diff_type __i = 0;
217	while (__pred(__word[__pos - __i], __word[__len - 1 - __i])
218	       && __i < __pos)
219	  {
220	    ++__i;
221	  }
222	return __i;
223      }
224
225      template<typename _Tp>
226	__diff_type
227	_M_bad_char_shift(_Tp __c) const
228	{ return this->_M_lookup(__c, _M_pat_end - _M_pat); }
229
230      _RAIter _M_pat;
231      _RAIter _M_pat_end;
232      _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix;
233    };
234
235  template<typename _RAIter, typename _Hash
236	     = std::hash<typename std::iterator_traits<_RAIter>::value_type>,
237	   typename _BinaryPredicate = std::equal_to<>>
238    class boyer_moore_horspool_searcher
239    : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>
240    {
241      using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>;
242      using typename _Base::__diff_type;
243
244    public:
245      boyer_moore_horspool_searcher(_RAIter __pat,
246				    _RAIter __pat_end,
247				    _Hash __hf = _Hash(),
248				    _BinaryPredicate __pred
249				    = _BinaryPredicate())
250      : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)),
251	_M_pat(__pat), _M_pat_end(__pat_end)
252      { }
253
254      template<typename _RandomAccessIterator2>
255	_RandomAccessIterator2
256	operator()(_RandomAccessIterator2 __first,
257		   _RandomAccessIterator2 __last) const
258	{
259	  const auto& __pred = this->_M_pred();
260	  auto __patlen = _M_pat_end - _M_pat;
261	  if (__patlen == 0)
262	    return __first;
263	  auto __len = __last - __first;
264	  while (__len >= __patlen)
265	    {
266	      for (auto __scan = __patlen - 1;
267		   __pred(__first[__scan], _M_pat[__scan]); --__scan)
268		if (__scan == 0)
269		  return __first;
270	      auto __shift = _M_bad_char_shift(__first[__patlen - 1]);
271	      __len -= __shift;
272	      __first += __shift;
273	    }
274	  return __last;
275	}
276
277    private:
278      template<typename _Tp>
279	__diff_type
280	_M_bad_char_shift(_Tp __c) const
281	{ return this->_M_lookup(__c, _M_pat_end - _M_pat); }
282
283      _RAIter _M_pat;
284      _RAIter _M_pat_end;
285    };
286
287  /// Generator function for default_searcher
288  template<typename _ForwardIterator,
289	   typename _BinaryPredicate = std::equal_to<>>
290    inline default_searcher<_ForwardIterator, _BinaryPredicate>
291    make_default_searcher(_ForwardIterator __pat_first,
292			  _ForwardIterator __pat_last,
293			  _BinaryPredicate __pred = _BinaryPredicate())
294    { return { __pat_first, __pat_last, __pred }; }
295
296  /// Generator function for boyer_moore_searcher
297  template<typename _RAIter, typename _Hash
298	     = std::hash<typename std::iterator_traits<_RAIter>::value_type>,
299	   typename _BinaryPredicate = equal_to<>>
300    inline boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>
301    make_boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last,
302			      _Hash __hf = _Hash(),
303			      _BinaryPredicate __pred = _BinaryPredicate())
304    { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; }
305
306  /// Generator function for boyer_moore_horspool_searcher
307  template<typename _RAIter, typename _Hash
308	     = std::hash<typename std::iterator_traits<_RAIter>::value_type>,
309	   typename _BinaryPredicate = equal_to<>>
310    inline boyer_moore_horspool_searcher<_RAIter, _Hash, _BinaryPredicate>
311    make_boyer_moore_horspool_searcher(_RAIter __pat_first, _RAIter __pat_last,
312				       _Hash __hf = _Hash(),
313				       _BinaryPredicate __pred
314				       = _BinaryPredicate())
315    { return { __pat_first, __pat_last, std::move(__hf), std::move(__pred) }; }
316
317  template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
318    boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
319    boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end,
320			 _Hash __hf, _BinaryPredicate __pred)
321    : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)),
322      _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat)
323    {
324      auto __patlen = __pat_end - __pat;
325      if (__patlen == 0)
326	return;
327      __diff_type __last_prefix = __patlen - 1;
328      for (__diff_type __p = __patlen - 1; __p >= 0; --__p)
329	{
330	  if (_M_is_prefix(__pat, __patlen, __p + 1))
331	    __last_prefix = __p + 1;
332	  _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p);
333	}
334      for (__diff_type __p = 0; __p < __patlen - 1; ++__p)
335	{
336	  auto __slen = _M_suffix_length(__pat, __patlen, __p);
337	  auto __pos = __patlen - 1 - __slen;
338	  if (!__pred(__pat[__p - __slen], __pat[__pos]))
339	    _M_good_suffix[__pos] = __patlen - 1 - __p + __slen;
340	}
341    }
342
343  template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
344  template<typename _RandomAccessIterator2>
345    _RandomAccessIterator2
346    boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
347    operator()(_RandomAccessIterator2 __first,
348	       _RandomAccessIterator2 __last) const
349    {
350      auto __patlen = _M_pat_end - _M_pat;
351      if (__patlen == 0)
352	return __first;
353      const auto& __pred = this->_M_pred();
354      __diff_type __i = __patlen - 1;
355      auto __stringlen = __last - __first;
356      while (__i < __stringlen)
357	{
358	  __diff_type __j = __patlen - 1;
359	  while (__j >= 0 && __pred(__first[__i], _M_pat[__j]))
360	    {
361	      --__i;
362	      --__j;
363	    }
364	  if (__j < 0)
365	    return __first + __i + 1;
366	  __i += std::max(_M_bad_char_shift(__first[__i]),
367			  _M_good_suffix[__j]);
368	}
369      return __last;
370    }
371
372_GLIBCXX_END_NAMESPACE_VERSION
373} // namespace fundamentals_v1
374
375inline namespace fundamentals_v2
376{
377_GLIBCXX_BEGIN_NAMESPACE_VERSION
378
379#define __cpp_lib_experimental_not_fn 201406
380
381  /// Generalized negator.
382  template<typename _Fn>
383    class _Not_fn
384    {
385      _Fn _M_fn;
386
387    public:
388      template<typename _Fn2>
389	explicit
390	_Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { }
391
392      _Not_fn(const _Not_fn& __fn) = default;
393      _Not_fn(_Not_fn&& __fn) = default;
394      _Not_fn& operator=(const _Not_fn& __fn) = default;
395      _Not_fn& operator=(_Not_fn&& __fn) = default;
396      ~_Not_fn() = default;
397
398      template<typename... _Args>
399	auto
400	operator()(_Args&&... __args)
401	noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
402	-> decltype(!_M_fn(std::forward<_Args>(__args)...))
403	{ return !_M_fn(std::forward<_Args>(__args)...); }
404
405      template<typename... _Args>
406	auto
407	operator()(_Args&&... __args) const
408	noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
409	-> decltype(!_M_fn(std::forward<_Args>(__args)...))
410	{ return !_M_fn(std::forward<_Args>(__args)...); }
411
412      template<typename... _Args>
413	auto
414	operator()(_Args&&... __args) volatile
415	noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
416	-> decltype(!_M_fn(std::forward<_Args>(__args)...))
417	{ return !_M_fn(std::forward<_Args>(__args)...); }
418
419      template<typename... _Args>
420	auto
421	operator()(_Args&&... __args) const volatile
422	noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
423	-> decltype(!_M_fn(std::forward<_Args>(__args)...))
424	{ return !_M_fn(std::forward<_Args>(__args)...); }
425    };
426
427  /// [func.not_fn] Function template not_fn
428  template<typename _Fn>
429    inline auto
430    not_fn(_Fn&& __fn)
431    noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
432    {
433      using __maybe_type = _Maybe_wrap_member_pointer<std::decay_t<_Fn>>;
434      return _Not_fn<typename __maybe_type::type>{std::forward<_Fn>(__fn), 0};
435    }
436
437_GLIBCXX_END_NAMESPACE_VERSION
438} // namespace fundamentals_v2
439} // namespace experimental
440} // namespace std
441
442#endif // C++14
443
444#endif // _GLIBCXX_EXPERIMENTAL_FUNCTIONAL
445