libstdc++

functional

Go to the documentation of this file.
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