Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.     class _Not_fn
  380.     {
  381.       _Fn _M_fn;
  382.  
  383.     public:
  384.       template<typename _Fn2>
  385.         explicit
  386.         _Not_fn(_Fn2&& __fn) : _M_fn(std::forward<_Fn2>(__fn)) { }
  387.  
  388.       _Not_fn(const _Not_fn& __fn) = default;
  389.       _Not_fn(_Not_fn&& __fn) = default;
  390.       _Not_fn& operator=(const _Not_fn& __fn) = default;
  391.       _Not_fn& operator=(_Not_fn&& __fn) = default;
  392.       ~_Not_fn() = default;
  393.  
  394.       template<typename... _Args>
  395.         auto
  396.         operator()(_Args&&... __args)
  397.         noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
  398.         -> decltype(!_M_fn(std::forward<_Args>(__args)...))
  399.         { return !_M_fn(std::forward<_Args>(__args)...); }
  400.  
  401.       template<typename... _Args>
  402.         auto
  403.         operator()(_Args&&... __args) const
  404.         noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
  405.         -> decltype(!_M_fn(std::forward<_Args>(__args)...))
  406.         { return !_M_fn(std::forward<_Args>(__args)...); }
  407.  
  408.       template<typename... _Args>
  409.         auto
  410.         operator()(_Args&&... __args) volatile
  411.         noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
  412.         -> decltype(!_M_fn(std::forward<_Args>(__args)...))
  413.         { return !_M_fn(std::forward<_Args>(__args)...); }
  414.  
  415.       template<typename... _Args>
  416.         auto
  417.         operator()(_Args&&... __args) const volatile
  418.         noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
  419.         -> decltype(!_M_fn(std::forward<_Args>(__args)...))
  420.         { return !_M_fn(std::forward<_Args>(__args)...); }
  421.     };
  422.  
  423.   /// [func.not_fn] Function template not_fn
  424.   template<typename _Fn>
  425.     inline auto
  426.     not_fn(_Fn&& __fn)
  427.     noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
  428.     {
  429.       using __maybe_type = _Maybe_wrap_member_pointer<std::decay_t<_Fn>>;
  430.       return _Not_fn<typename __maybe_type::type>{std::forward<_Fn>(__fn)};
  431.     }
  432.  
  433. _GLIBCXX_END_NAMESPACE_VERSION
  434. } // namespace fundamentals_v2
  435. } // namespace experimental
  436. } // namespace std
  437.  
  438. #endif // C++14
  439.  
  440. #endif // _GLIBCXX_EXPERIMENTAL_FUNCTIONAL
  441.