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