xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/std/functional (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj// <functional> -*- C++ -*-
238fd1498Szrj
338fd1498Szrj// Copyright (C) 2001-2018 Free Software Foundation, Inc.
438fd1498Szrj//
538fd1498Szrj// This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj// software; you can redistribute it and/or modify it under the
738fd1498Szrj// terms of the GNU General Public License as published by the
838fd1498Szrj// Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj// any later version.
1038fd1498Szrj
1138fd1498Szrj// This library is distributed in the hope that it will be useful,
1238fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj// GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj// permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj// 3.1, as published by the Free Software Foundation.
1938fd1498Szrj
2038fd1498Szrj// You should have received a copy of the GNU General Public License and
2138fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj// <http://www.gnu.org/licenses/>.
2438fd1498Szrj
2538fd1498Szrj/*
2638fd1498Szrj * Copyright (c) 1997
2738fd1498Szrj * Silicon Graphics Computer Systems, Inc.
2838fd1498Szrj *
2938fd1498Szrj * Permission to use, copy, modify, distribute and sell this software
3038fd1498Szrj * and its documentation for any purpose is hereby granted without fee,
3138fd1498Szrj * provided that the above copyright notice appear in all copies and
3238fd1498Szrj * that both that copyright notice and this permission notice appear
3338fd1498Szrj * in supporting documentation.  Silicon Graphics makes no
3438fd1498Szrj * representations about the suitability of this software for any
3538fd1498Szrj * purpose.  It is provided "as is" without express or implied warranty.
3638fd1498Szrj *
3738fd1498Szrj */
3838fd1498Szrj
3938fd1498Szrj/** @file include/functional
4038fd1498Szrj *  This is a Standard C++ Library header.
4138fd1498Szrj */
4238fd1498Szrj
4338fd1498Szrj#ifndef _GLIBCXX_FUNCTIONAL
4438fd1498Szrj#define _GLIBCXX_FUNCTIONAL 1
4538fd1498Szrj
4638fd1498Szrj#pragma GCC system_header
4738fd1498Szrj
4838fd1498Szrj#include <bits/c++config.h>
4938fd1498Szrj#include <bits/stl_function.h>
5038fd1498Szrj
5138fd1498Szrj#if __cplusplus >= 201103L
5238fd1498Szrj
5338fd1498Szrj#include <new>
5438fd1498Szrj#include <tuple>
5538fd1498Szrj#include <type_traits>
5638fd1498Szrj#include <bits/functional_hash.h>
5738fd1498Szrj#include <bits/invoke.h>
5838fd1498Szrj#include <bits/refwrap.h>	// std::reference_wrapper and _Mem_fn_traits
5938fd1498Szrj#include <bits/std_function.h>	// std::function
6038fd1498Szrj#if __cplusplus > 201402L
6138fd1498Szrj# include <unordered_map>
6238fd1498Szrj# include <vector>
6338fd1498Szrj# include <array>
6438fd1498Szrj# include <utility>
6538fd1498Szrj# include <bits/stl_algo.h>
6638fd1498Szrj#endif
6738fd1498Szrj
6838fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default)
6938fd1498Szrj{
7038fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION
7138fd1498Szrj
7238fd1498Szrj#if __cplusplus > 201402L
7338fd1498Szrj# define __cpp_lib_invoke 201411
7438fd1498Szrj
7538fd1498Szrj  /// Invoke a callable object.
7638fd1498Szrj  template<typename _Callable, typename... _Args>
7738fd1498Szrj    inline invoke_result_t<_Callable, _Args...>
7838fd1498Szrj    invoke(_Callable&& __fn, _Args&&... __args)
7938fd1498Szrj    noexcept(is_nothrow_invocable_v<_Callable, _Args...>)
8038fd1498Szrj    {
8138fd1498Szrj      return std::__invoke(std::forward<_Callable>(__fn),
8238fd1498Szrj			   std::forward<_Args>(__args)...);
8338fd1498Szrj    }
8438fd1498Szrj#endif
8538fd1498Szrj
8638fd1498Szrj  template<typename _MemFunPtr,
8738fd1498Szrj	   bool __is_mem_fn = is_member_function_pointer<_MemFunPtr>::value>
8838fd1498Szrj    class _Mem_fn_base
8938fd1498Szrj    : public _Mem_fn_traits<_MemFunPtr>::__maybe_type
9038fd1498Szrj    {
9138fd1498Szrj      using _Traits = _Mem_fn_traits<_MemFunPtr>;
9238fd1498Szrj
9338fd1498Szrj      using _Arity = typename _Traits::__arity;
9438fd1498Szrj      using _Varargs = typename _Traits::__vararg;
9538fd1498Szrj
9638fd1498Szrj      template<typename _Func, typename... _BoundArgs>
9738fd1498Szrj	friend struct _Bind_check_arity;
9838fd1498Szrj
9938fd1498Szrj      _MemFunPtr _M_pmf;
10038fd1498Szrj
10138fd1498Szrj    public:
10238fd1498Szrj
10338fd1498Szrj      using result_type = typename _Traits::__result_type;
10438fd1498Szrj
10538fd1498Szrj      explicit constexpr
10638fd1498Szrj      _Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { }
10738fd1498Szrj
10838fd1498Szrj      template<typename... _Args>
10938fd1498Szrj	auto
11038fd1498Szrj	operator()(_Args&&... __args) const
11138fd1498Szrj	noexcept(noexcept(
11238fd1498Szrj	      std::__invoke(_M_pmf, std::forward<_Args>(__args)...)))
11338fd1498Szrj	-> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
11438fd1498Szrj	{ return std::__invoke(_M_pmf, std::forward<_Args>(__args)...); }
11538fd1498Szrj    };
11638fd1498Szrj
11738fd1498Szrj  // Partial specialization for member object pointers.
11838fd1498Szrj  template<typename _MemObjPtr>
11938fd1498Szrj    class _Mem_fn_base<_MemObjPtr, false>
12038fd1498Szrj    {
12138fd1498Szrj      using _Arity = integral_constant<size_t, 0>;
12238fd1498Szrj      using _Varargs = false_type;
12338fd1498Szrj
12438fd1498Szrj      template<typename _Func, typename... _BoundArgs>
12538fd1498Szrj	friend struct _Bind_check_arity;
12638fd1498Szrj
12738fd1498Szrj      _MemObjPtr _M_pm;
12838fd1498Szrj
12938fd1498Szrj    public:
13038fd1498Szrj      explicit constexpr
13138fd1498Szrj      _Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { }
13238fd1498Szrj
13338fd1498Szrj      template<typename _Tp>
13438fd1498Szrj	auto
13538fd1498Szrj	operator()(_Tp&& __obj) const
13638fd1498Szrj	noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj))))
13738fd1498Szrj	-> decltype(std::__invoke(_M_pm, std::forward<_Tp>(__obj)))
13838fd1498Szrj	{ return std::__invoke(_M_pm, std::forward<_Tp>(__obj)); }
13938fd1498Szrj    };
14038fd1498Szrj
14138fd1498Szrj  template<typename _MemberPointer>
14238fd1498Szrj    struct _Mem_fn; // undefined
14338fd1498Szrj
14438fd1498Szrj  template<typename _Res, typename _Class>
14538fd1498Szrj    struct _Mem_fn<_Res _Class::*>
14638fd1498Szrj    : _Mem_fn_base<_Res _Class::*>
14738fd1498Szrj    {
14838fd1498Szrj      using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base;
14938fd1498Szrj    };
15038fd1498Szrj
15138fd1498Szrj  // _GLIBCXX_RESOLVE_LIB_DEFECTS
15238fd1498Szrj  // 2048.  Unnecessary mem_fn overloads
15338fd1498Szrj  /**
15438fd1498Szrj   *  @brief Returns a function object that forwards to the member
15538fd1498Szrj   *  pointer @a pm.
15638fd1498Szrj   *  @ingroup functors
15738fd1498Szrj   */
15838fd1498Szrj  template<typename _Tp, typename _Class>
15938fd1498Szrj    inline _Mem_fn<_Tp _Class::*>
16038fd1498Szrj    mem_fn(_Tp _Class::* __pm) noexcept
16138fd1498Szrj    {
16238fd1498Szrj      return _Mem_fn<_Tp _Class::*>(__pm);
16338fd1498Szrj    }
16438fd1498Szrj
16538fd1498Szrj  /**
16638fd1498Szrj   *  @brief Determines if the given type _Tp is a function object that
16738fd1498Szrj   *  should be treated as a subexpression when evaluating calls to
16838fd1498Szrj   *  function objects returned by bind().
16938fd1498Szrj   *
17038fd1498Szrj   *  C++11 [func.bind.isbind].
17138fd1498Szrj   *  @ingroup binders
17238fd1498Szrj   */
17338fd1498Szrj  template<typename _Tp>
17438fd1498Szrj    struct is_bind_expression
17538fd1498Szrj    : public false_type { };
17638fd1498Szrj
17738fd1498Szrj  /**
17838fd1498Szrj   *  @brief Determines if the given type _Tp is a placeholder in a
17938fd1498Szrj   *  bind() expression and, if so, which placeholder it is.
18038fd1498Szrj   *
18138fd1498Szrj   *  C++11 [func.bind.isplace].
18238fd1498Szrj   *  @ingroup binders
18338fd1498Szrj   */
18438fd1498Szrj  template<typename _Tp>
18538fd1498Szrj    struct is_placeholder
18638fd1498Szrj    : public integral_constant<int, 0>
18738fd1498Szrj    { };
18838fd1498Szrj
18938fd1498Szrj#if __cplusplus > 201402L
19038fd1498Szrj  template <typename _Tp> inline constexpr bool is_bind_expression_v
19138fd1498Szrj    = is_bind_expression<_Tp>::value;
19238fd1498Szrj  template <typename _Tp> inline constexpr int is_placeholder_v
19338fd1498Szrj    = is_placeholder<_Tp>::value;
19438fd1498Szrj#endif // C++17
19538fd1498Szrj
19638fd1498Szrj  /** @brief The type of placeholder objects defined by libstdc++.
19738fd1498Szrj   *  @ingroup binders
19838fd1498Szrj   */
19938fd1498Szrj  template<int _Num> struct _Placeholder { };
20038fd1498Szrj
20138fd1498Szrj  /** @namespace std::placeholders
20238fd1498Szrj   *  @brief ISO C++11 entities sub-namespace for functional.
20338fd1498Szrj   *  @ingroup binders
20438fd1498Szrj   */
20538fd1498Szrj  namespace placeholders
20638fd1498Szrj  {
20738fd1498Szrj  /* Define a large number of placeholders. There is no way to
20838fd1498Szrj   * simplify this with variadic templates, because we're introducing
20938fd1498Szrj   * unique names for each.
21038fd1498Szrj   */
21138fd1498Szrj    extern const _Placeholder<1> _1;
21238fd1498Szrj    extern const _Placeholder<2> _2;
21338fd1498Szrj    extern const _Placeholder<3> _3;
21438fd1498Szrj    extern const _Placeholder<4> _4;
21538fd1498Szrj    extern const _Placeholder<5> _5;
21638fd1498Szrj    extern const _Placeholder<6> _6;
21738fd1498Szrj    extern const _Placeholder<7> _7;
21838fd1498Szrj    extern const _Placeholder<8> _8;
21938fd1498Szrj    extern const _Placeholder<9> _9;
22038fd1498Szrj    extern const _Placeholder<10> _10;
22138fd1498Szrj    extern const _Placeholder<11> _11;
22238fd1498Szrj    extern const _Placeholder<12> _12;
22338fd1498Szrj    extern const _Placeholder<13> _13;
22438fd1498Szrj    extern const _Placeholder<14> _14;
22538fd1498Szrj    extern const _Placeholder<15> _15;
22638fd1498Szrj    extern const _Placeholder<16> _16;
22738fd1498Szrj    extern const _Placeholder<17> _17;
22838fd1498Szrj    extern const _Placeholder<18> _18;
22938fd1498Szrj    extern const _Placeholder<19> _19;
23038fd1498Szrj    extern const _Placeholder<20> _20;
23138fd1498Szrj    extern const _Placeholder<21> _21;
23238fd1498Szrj    extern const _Placeholder<22> _22;
23338fd1498Szrj    extern const _Placeholder<23> _23;
23438fd1498Szrj    extern const _Placeholder<24> _24;
23538fd1498Szrj    extern const _Placeholder<25> _25;
23638fd1498Szrj    extern const _Placeholder<26> _26;
23738fd1498Szrj    extern const _Placeholder<27> _27;
23838fd1498Szrj    extern const _Placeholder<28> _28;
23938fd1498Szrj    extern const _Placeholder<29> _29;
24038fd1498Szrj  }
24138fd1498Szrj
24238fd1498Szrj  /**
24338fd1498Szrj   *  Partial specialization of is_placeholder that provides the placeholder
24438fd1498Szrj   *  number for the placeholder objects defined by libstdc++.
24538fd1498Szrj   *  @ingroup binders
24638fd1498Szrj   */
24738fd1498Szrj  template<int _Num>
24838fd1498Szrj    struct is_placeholder<_Placeholder<_Num> >
24938fd1498Szrj    : public integral_constant<int, _Num>
25038fd1498Szrj    { };
25138fd1498Szrj
25238fd1498Szrj  template<int _Num>
25338fd1498Szrj    struct is_placeholder<const _Placeholder<_Num> >
25438fd1498Szrj    : public integral_constant<int, _Num>
25538fd1498Szrj    { };
25638fd1498Szrj
25738fd1498Szrj
25838fd1498Szrj  // Like tuple_element_t but SFINAE-friendly.
25938fd1498Szrj  template<std::size_t __i, typename _Tuple>
26038fd1498Szrj    using _Safe_tuple_element_t
26138fd1498Szrj      = typename enable_if<(__i < tuple_size<_Tuple>::value),
26238fd1498Szrj			   tuple_element<__i, _Tuple>>::type::type;
26338fd1498Szrj
26438fd1498Szrj  /**
26538fd1498Szrj   *  Maps an argument to bind() into an actual argument to the bound
26638fd1498Szrj   *  function object [func.bind.bind]/10. Only the first parameter should
26738fd1498Szrj   *  be specified: the rest are used to determine among the various
26838fd1498Szrj   *  implementations. Note that, although this class is a function
26938fd1498Szrj   *  object, it isn't entirely normal because it takes only two
27038fd1498Szrj   *  parameters regardless of the number of parameters passed to the
27138fd1498Szrj   *  bind expression. The first parameter is the bound argument and
27238fd1498Szrj   *  the second parameter is a tuple containing references to the
27338fd1498Szrj   *  rest of the arguments.
27438fd1498Szrj   */
27538fd1498Szrj  template<typename _Arg,
27638fd1498Szrj	   bool _IsBindExp = is_bind_expression<_Arg>::value,
27738fd1498Szrj	   bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)>
27838fd1498Szrj    class _Mu;
27938fd1498Szrj
28038fd1498Szrj  /**
28138fd1498Szrj   *  If the argument is reference_wrapper<_Tp>, returns the
28238fd1498Szrj   *  underlying reference.
28338fd1498Szrj   *  C++11 [func.bind.bind] p10 bullet 1.
28438fd1498Szrj   */
28538fd1498Szrj  template<typename _Tp>
28638fd1498Szrj    class _Mu<reference_wrapper<_Tp>, false, false>
28738fd1498Szrj    {
28838fd1498Szrj    public:
28938fd1498Szrj      /* Note: This won't actually work for const volatile
29038fd1498Szrj       * reference_wrappers, because reference_wrapper::get() is const
29138fd1498Szrj       * but not volatile-qualified. This might be a defect in the TR.
29238fd1498Szrj       */
29338fd1498Szrj      template<typename _CVRef, typename _Tuple>
29438fd1498Szrj	_Tp&
29538fd1498Szrj	operator()(_CVRef& __arg, _Tuple&) const volatile
29638fd1498Szrj	{ return __arg.get(); }
29738fd1498Szrj    };
29838fd1498Szrj
29938fd1498Szrj  /**
30038fd1498Szrj   *  If the argument is a bind expression, we invoke the underlying
30138fd1498Szrj   *  function object with the same cv-qualifiers as we are given and
30238fd1498Szrj   *  pass along all of our arguments (unwrapped).
30338fd1498Szrj   *  C++11 [func.bind.bind] p10 bullet 2.
30438fd1498Szrj   */
30538fd1498Szrj  template<typename _Arg>
30638fd1498Szrj    class _Mu<_Arg, true, false>
30738fd1498Szrj    {
30838fd1498Szrj    public:
30938fd1498Szrj      template<typename _CVArg, typename... _Args>
31038fd1498Szrj	auto
31138fd1498Szrj	operator()(_CVArg& __arg,
31238fd1498Szrj		   tuple<_Args...>& __tuple) const volatile
31338fd1498Szrj	-> decltype(__arg(declval<_Args>()...))
31438fd1498Szrj	{
31538fd1498Szrj	  // Construct an index tuple and forward to __call
31638fd1498Szrj	  typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
31738fd1498Szrj	    _Indexes;
31838fd1498Szrj	  return this->__call(__arg, __tuple, _Indexes());
31938fd1498Szrj	}
32038fd1498Szrj
32138fd1498Szrj    private:
32238fd1498Szrj      // Invokes the underlying function object __arg by unpacking all
32338fd1498Szrj      // of the arguments in the tuple.
32438fd1498Szrj      template<typename _CVArg, typename... _Args, std::size_t... _Indexes>
32538fd1498Szrj	auto
32638fd1498Szrj	__call(_CVArg& __arg, tuple<_Args...>& __tuple,
32738fd1498Szrj	       const _Index_tuple<_Indexes...>&) const volatile
32838fd1498Szrj	-> decltype(__arg(declval<_Args>()...))
32938fd1498Szrj	{
33038fd1498Szrj	  return __arg(std::get<_Indexes>(std::move(__tuple))...);
33138fd1498Szrj	}
33238fd1498Szrj    };
33338fd1498Szrj
33438fd1498Szrj  /**
33538fd1498Szrj   *  If the argument is a placeholder for the Nth argument, returns
33638fd1498Szrj   *  a reference to the Nth argument to the bind function object.
33738fd1498Szrj   *  C++11 [func.bind.bind] p10 bullet 3.
33838fd1498Szrj   */
33938fd1498Szrj  template<typename _Arg>
34038fd1498Szrj    class _Mu<_Arg, false, true>
34138fd1498Szrj    {
34238fd1498Szrj    public:
34338fd1498Szrj      template<typename _Tuple>
34438fd1498Szrj	_Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&&
34538fd1498Szrj	operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
34638fd1498Szrj	{
34738fd1498Szrj	  return
34838fd1498Szrj	    ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple));
34938fd1498Szrj	}
35038fd1498Szrj    };
35138fd1498Szrj
35238fd1498Szrj  /**
35338fd1498Szrj   *  If the argument is just a value, returns a reference to that
35438fd1498Szrj   *  value. The cv-qualifiers on the reference are determined by the caller.
35538fd1498Szrj   *  C++11 [func.bind.bind] p10 bullet 4.
35638fd1498Szrj   */
35738fd1498Szrj  template<typename _Arg>
35838fd1498Szrj    class _Mu<_Arg, false, false>
35938fd1498Szrj    {
36038fd1498Szrj    public:
36138fd1498Szrj      template<typename _CVArg, typename _Tuple>
36238fd1498Szrj	_CVArg&&
36338fd1498Szrj	operator()(_CVArg&& __arg, _Tuple&) const volatile
36438fd1498Szrj	{ return std::forward<_CVArg>(__arg); }
36538fd1498Szrj    };
36638fd1498Szrj
36738fd1498Szrj  // std::get<I> for volatile-qualified tuples
36838fd1498Szrj  template<std::size_t _Ind, typename... _Tp>
36938fd1498Szrj    inline auto
37038fd1498Szrj    __volget(volatile tuple<_Tp...>& __tuple)
37138fd1498Szrj    -> __tuple_element_t<_Ind, tuple<_Tp...>> volatile&
37238fd1498Szrj    { return std::get<_Ind>(const_cast<tuple<_Tp...>&>(__tuple)); }
37338fd1498Szrj
37438fd1498Szrj  // std::get<I> for const-volatile-qualified tuples
37538fd1498Szrj  template<std::size_t _Ind, typename... _Tp>
37638fd1498Szrj    inline auto
37738fd1498Szrj    __volget(const volatile tuple<_Tp...>& __tuple)
37838fd1498Szrj    -> __tuple_element_t<_Ind, tuple<_Tp...>> const volatile&
37938fd1498Szrj    { return std::get<_Ind>(const_cast<const tuple<_Tp...>&>(__tuple)); }
38038fd1498Szrj
38138fd1498Szrj  /// Type of the function object returned from bind().
38238fd1498Szrj  template<typename _Signature>
38338fd1498Szrj    struct _Bind;
38438fd1498Szrj
38538fd1498Szrj   template<typename _Functor, typename... _Bound_args>
38638fd1498Szrj    class _Bind<_Functor(_Bound_args...)>
38738fd1498Szrj    : public _Weak_result_type<_Functor>
38838fd1498Szrj    {
38938fd1498Szrj      typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
39038fd1498Szrj	_Bound_indexes;
39138fd1498Szrj
39238fd1498Szrj      _Functor _M_f;
39338fd1498Szrj      tuple<_Bound_args...> _M_bound_args;
39438fd1498Szrj
39538fd1498Szrj      // Call unqualified
39638fd1498Szrj      template<typename _Result, typename... _Args, std::size_t... _Indexes>
39738fd1498Szrj	_Result
39838fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
39938fd1498Szrj	{
40038fd1498Szrj	  return std::__invoke(_M_f,
40138fd1498Szrj	      _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)...
40238fd1498Szrj	      );
40338fd1498Szrj	}
40438fd1498Szrj
40538fd1498Szrj      // Call as const
40638fd1498Szrj      template<typename _Result, typename... _Args, std::size_t... _Indexes>
40738fd1498Szrj	_Result
40838fd1498Szrj	__call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
40938fd1498Szrj	{
41038fd1498Szrj	  return std::__invoke(_M_f,
41138fd1498Szrj	      _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)...
41238fd1498Szrj	      );
41338fd1498Szrj	}
41438fd1498Szrj
41538fd1498Szrj      // Call as volatile
41638fd1498Szrj      template<typename _Result, typename... _Args, std::size_t... _Indexes>
41738fd1498Szrj	_Result
41838fd1498Szrj	__call_v(tuple<_Args...>&& __args,
41938fd1498Szrj		 _Index_tuple<_Indexes...>) volatile
42038fd1498Szrj	{
42138fd1498Szrj	  return std::__invoke(_M_f,
42238fd1498Szrj	      _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)...
42338fd1498Szrj	      );
42438fd1498Szrj	}
42538fd1498Szrj
42638fd1498Szrj      // Call as const volatile
42738fd1498Szrj      template<typename _Result, typename... _Args, std::size_t... _Indexes>
42838fd1498Szrj	_Result
42938fd1498Szrj	__call_c_v(tuple<_Args...>&& __args,
43038fd1498Szrj		   _Index_tuple<_Indexes...>) const volatile
43138fd1498Szrj	{
43238fd1498Szrj	  return std::__invoke(_M_f,
43338fd1498Szrj	      _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)...
43438fd1498Szrj	      );
43538fd1498Szrj	}
43638fd1498Szrj
43738fd1498Szrj      template<typename _BoundArg, typename _CallArgs>
43838fd1498Szrj	using _Mu_type = decltype(
43938fd1498Szrj	    _Mu<typename remove_cv<_BoundArg>::type>()(
44038fd1498Szrj	      std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) );
44138fd1498Szrj
44238fd1498Szrj      template<typename _Fn, typename _CallArgs, typename... _BArgs>
44338fd1498Szrj	using _Res_type_impl
44438fd1498Szrj	  = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>&&...) >::type;
44538fd1498Szrj
44638fd1498Szrj      template<typename _CallArgs>
44738fd1498Szrj	using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>;
44838fd1498Szrj
44938fd1498Szrj      template<typename _CallArgs>
45038fd1498Szrj	using __dependent = typename
45138fd1498Szrj	  enable_if<bool(tuple_size<_CallArgs>::value+1), _Functor>::type;
45238fd1498Szrj
45338fd1498Szrj      template<typename _CallArgs, template<class> class __cv_quals>
45438fd1498Szrj	using _Res_type_cv = _Res_type_impl<
45538fd1498Szrj	  typename __cv_quals<__dependent<_CallArgs>>::type,
45638fd1498Szrj	  _CallArgs,
45738fd1498Szrj	  typename __cv_quals<_Bound_args>::type...>;
45838fd1498Szrj
45938fd1498Szrj     public:
46038fd1498Szrj      template<typename... _Args>
46138fd1498Szrj	explicit _Bind(const _Functor& __f, _Args&&... __args)
46238fd1498Szrj	: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
46338fd1498Szrj	{ }
46438fd1498Szrj
46538fd1498Szrj      template<typename... _Args>
46638fd1498Szrj	explicit _Bind(_Functor&& __f, _Args&&... __args)
46738fd1498Szrj	: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
46838fd1498Szrj	{ }
46938fd1498Szrj
47038fd1498Szrj      _Bind(const _Bind&) = default;
47138fd1498Szrj
47238fd1498Szrj      _Bind(_Bind&& __b)
47338fd1498Szrj      : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args))
47438fd1498Szrj      { }
47538fd1498Szrj
47638fd1498Szrj      // Call unqualified
47738fd1498Szrj      template<typename... _Args,
47838fd1498Szrj	       typename _Result = _Res_type<tuple<_Args...>>>
47938fd1498Szrj	_Result
48038fd1498Szrj	operator()(_Args&&... __args)
48138fd1498Szrj	{
48238fd1498Szrj	  return this->__call<_Result>(
48338fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
48438fd1498Szrj	      _Bound_indexes());
48538fd1498Szrj	}
48638fd1498Szrj
48738fd1498Szrj      // Call as const
48838fd1498Szrj      template<typename... _Args,
48938fd1498Szrj	       typename _Result = _Res_type_cv<tuple<_Args...>, add_const>>
49038fd1498Szrj	_Result
49138fd1498Szrj	operator()(_Args&&... __args) const
49238fd1498Szrj	{
49338fd1498Szrj	  return this->__call_c<_Result>(
49438fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
49538fd1498Szrj	      _Bound_indexes());
49638fd1498Szrj	}
49738fd1498Szrj
49838fd1498Szrj#if __cplusplus > 201402L
49938fd1498Szrj# define _GLIBCXX_DEPR_BIND \
50038fd1498Szrj      [[deprecated("std::bind does not support volatile in C++17")]]
50138fd1498Szrj#else
50238fd1498Szrj# define _GLIBCXX_DEPR_BIND
50338fd1498Szrj#endif
50438fd1498Szrj      // Call as volatile
50538fd1498Szrj      template<typename... _Args,
50638fd1498Szrj	       typename _Result = _Res_type_cv<tuple<_Args...>, add_volatile>>
50738fd1498Szrj	_GLIBCXX_DEPR_BIND
50838fd1498Szrj	_Result
50938fd1498Szrj	operator()(_Args&&... __args) volatile
51038fd1498Szrj	{
51138fd1498Szrj	  return this->__call_v<_Result>(
51238fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
51338fd1498Szrj	      _Bound_indexes());
51438fd1498Szrj	}
51538fd1498Szrj
51638fd1498Szrj      // Call as const volatile
51738fd1498Szrj      template<typename... _Args,
51838fd1498Szrj	       typename _Result = _Res_type_cv<tuple<_Args...>, add_cv>>
51938fd1498Szrj	_GLIBCXX_DEPR_BIND
52038fd1498Szrj	_Result
52138fd1498Szrj	operator()(_Args&&... __args) const volatile
52238fd1498Szrj	{
52338fd1498Szrj	  return this->__call_c_v<_Result>(
52438fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
52538fd1498Szrj	      _Bound_indexes());
52638fd1498Szrj	}
52738fd1498Szrj    };
52838fd1498Szrj
52938fd1498Szrj  /// Type of the function object returned from bind<R>().
53038fd1498Szrj  template<typename _Result, typename _Signature>
53138fd1498Szrj    struct _Bind_result;
53238fd1498Szrj
53338fd1498Szrj  template<typename _Result, typename _Functor, typename... _Bound_args>
53438fd1498Szrj    class _Bind_result<_Result, _Functor(_Bound_args...)>
53538fd1498Szrj    {
53638fd1498Szrj      typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
53738fd1498Szrj	_Bound_indexes;
53838fd1498Szrj
53938fd1498Szrj      _Functor _M_f;
54038fd1498Szrj      tuple<_Bound_args...> _M_bound_args;
54138fd1498Szrj
54238fd1498Szrj      // sfinae types
54338fd1498Szrj      template<typename _Res>
54438fd1498Szrj	using __enable_if_void
54538fd1498Szrj	  = typename enable_if<is_void<_Res>{}>::type;
54638fd1498Szrj
54738fd1498Szrj      template<typename _Res>
54838fd1498Szrj	using __disable_if_void
54938fd1498Szrj	  = typename enable_if<!is_void<_Res>{}, _Result>::type;
55038fd1498Szrj
55138fd1498Szrj      // Call unqualified
55238fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
55338fd1498Szrj	__disable_if_void<_Res>
55438fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
55538fd1498Szrj	{
55638fd1498Szrj	  return std::__invoke(_M_f, _Mu<_Bound_args>()
55738fd1498Szrj		      (std::get<_Indexes>(_M_bound_args), __args)...);
55838fd1498Szrj	}
55938fd1498Szrj
56038fd1498Szrj      // Call unqualified, return void
56138fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
56238fd1498Szrj	__enable_if_void<_Res>
56338fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
56438fd1498Szrj	{
56538fd1498Szrj	  std::__invoke(_M_f, _Mu<_Bound_args>()
56638fd1498Szrj	       (std::get<_Indexes>(_M_bound_args), __args)...);
56738fd1498Szrj	}
56838fd1498Szrj
56938fd1498Szrj      // Call as const
57038fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
57138fd1498Szrj	__disable_if_void<_Res>
57238fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
57338fd1498Szrj	{
57438fd1498Szrj	  return std::__invoke(_M_f, _Mu<_Bound_args>()
57538fd1498Szrj		      (std::get<_Indexes>(_M_bound_args), __args)...);
57638fd1498Szrj	}
57738fd1498Szrj
57838fd1498Szrj      // Call as const, return void
57938fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
58038fd1498Szrj	__enable_if_void<_Res>
58138fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
58238fd1498Szrj	{
58338fd1498Szrj	  std::__invoke(_M_f, _Mu<_Bound_args>()
58438fd1498Szrj	       (std::get<_Indexes>(_M_bound_args),  __args)...);
58538fd1498Szrj	}
58638fd1498Szrj
58738fd1498Szrj      // Call as volatile
58838fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
58938fd1498Szrj	__disable_if_void<_Res>
59038fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile
59138fd1498Szrj	{
59238fd1498Szrj	  return std::__invoke(_M_f, _Mu<_Bound_args>()
59338fd1498Szrj		      (__volget<_Indexes>(_M_bound_args), __args)...);
59438fd1498Szrj	}
59538fd1498Szrj
59638fd1498Szrj      // Call as volatile, return void
59738fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
59838fd1498Szrj	__enable_if_void<_Res>
59938fd1498Szrj	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile
60038fd1498Szrj	{
60138fd1498Szrj	  std::__invoke(_M_f, _Mu<_Bound_args>()
60238fd1498Szrj	       (__volget<_Indexes>(_M_bound_args), __args)...);
60338fd1498Szrj	}
60438fd1498Szrj
60538fd1498Szrj      // Call as const volatile
60638fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
60738fd1498Szrj	__disable_if_void<_Res>
60838fd1498Szrj	__call(tuple<_Args...>&& __args,
60938fd1498Szrj	       _Index_tuple<_Indexes...>) const volatile
61038fd1498Szrj	{
61138fd1498Szrj	  return std::__invoke(_M_f, _Mu<_Bound_args>()
61238fd1498Szrj		      (__volget<_Indexes>(_M_bound_args), __args)...);
61338fd1498Szrj	}
61438fd1498Szrj
61538fd1498Szrj      // Call as const volatile, return void
61638fd1498Szrj      template<typename _Res, typename... _Args, std::size_t... _Indexes>
61738fd1498Szrj	__enable_if_void<_Res>
61838fd1498Szrj	__call(tuple<_Args...>&& __args,
61938fd1498Szrj	       _Index_tuple<_Indexes...>) const volatile
62038fd1498Szrj	{
62138fd1498Szrj	  std::__invoke(_M_f, _Mu<_Bound_args>()
62238fd1498Szrj	       (__volget<_Indexes>(_M_bound_args), __args)...);
62338fd1498Szrj	}
62438fd1498Szrj
62538fd1498Szrj    public:
62638fd1498Szrj      typedef _Result result_type;
62738fd1498Szrj
62838fd1498Szrj      template<typename... _Args>
62938fd1498Szrj	explicit _Bind_result(const _Functor& __f, _Args&&... __args)
63038fd1498Szrj	: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
63138fd1498Szrj	{ }
63238fd1498Szrj
63338fd1498Szrj      template<typename... _Args>
63438fd1498Szrj	explicit _Bind_result(_Functor&& __f, _Args&&... __args)
63538fd1498Szrj	: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
63638fd1498Szrj	{ }
63738fd1498Szrj
63838fd1498Szrj      _Bind_result(const _Bind_result&) = default;
63938fd1498Szrj
64038fd1498Szrj      _Bind_result(_Bind_result&& __b)
64138fd1498Szrj      : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args))
64238fd1498Szrj      { }
64338fd1498Szrj
64438fd1498Szrj      // Call unqualified
64538fd1498Szrj      template<typename... _Args>
64638fd1498Szrj	result_type
64738fd1498Szrj	operator()(_Args&&... __args)
64838fd1498Szrj	{
64938fd1498Szrj	  return this->__call<_Result>(
65038fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
65138fd1498Szrj	      _Bound_indexes());
65238fd1498Szrj	}
65338fd1498Szrj
65438fd1498Szrj      // Call as const
65538fd1498Szrj      template<typename... _Args>
65638fd1498Szrj	result_type
65738fd1498Szrj	operator()(_Args&&... __args) const
65838fd1498Szrj	{
65938fd1498Szrj	  return this->__call<_Result>(
66038fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
66138fd1498Szrj	      _Bound_indexes());
66238fd1498Szrj	}
66338fd1498Szrj
66438fd1498Szrj      // Call as volatile
66538fd1498Szrj      template<typename... _Args>
66638fd1498Szrj	_GLIBCXX_DEPR_BIND
66738fd1498Szrj	result_type
66838fd1498Szrj	operator()(_Args&&... __args) volatile
66938fd1498Szrj	{
67038fd1498Szrj	  return this->__call<_Result>(
67138fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
67238fd1498Szrj	      _Bound_indexes());
67338fd1498Szrj	}
67438fd1498Szrj
67538fd1498Szrj      // Call as const volatile
67638fd1498Szrj      template<typename... _Args>
67738fd1498Szrj	_GLIBCXX_DEPR_BIND
67838fd1498Szrj	result_type
67938fd1498Szrj	operator()(_Args&&... __args) const volatile
68038fd1498Szrj	{
68138fd1498Szrj	  return this->__call<_Result>(
68238fd1498Szrj	      std::forward_as_tuple(std::forward<_Args>(__args)...),
68338fd1498Szrj	      _Bound_indexes());
68438fd1498Szrj	}
68538fd1498Szrj    };
68638fd1498Szrj#undef _GLIBCXX_DEPR_BIND
68738fd1498Szrj
68838fd1498Szrj  /**
68938fd1498Szrj   *  @brief Class template _Bind is always a bind expression.
69038fd1498Szrj   *  @ingroup binders
69138fd1498Szrj   */
69238fd1498Szrj  template<typename _Signature>
69338fd1498Szrj    struct is_bind_expression<_Bind<_Signature> >
69438fd1498Szrj    : public true_type { };
69538fd1498Szrj
69638fd1498Szrj  /**
69738fd1498Szrj   *  @brief Class template _Bind is always a bind expression.
69838fd1498Szrj   *  @ingroup binders
69938fd1498Szrj   */
70038fd1498Szrj  template<typename _Signature>
70138fd1498Szrj    struct is_bind_expression<const _Bind<_Signature> >
70238fd1498Szrj    : public true_type { };
70338fd1498Szrj
70438fd1498Szrj  /**
70538fd1498Szrj   *  @brief Class template _Bind is always a bind expression.
70638fd1498Szrj   *  @ingroup binders
70738fd1498Szrj   */
70838fd1498Szrj  template<typename _Signature>
70938fd1498Szrj    struct is_bind_expression<volatile _Bind<_Signature> >
71038fd1498Szrj    : public true_type { };
71138fd1498Szrj
71238fd1498Szrj  /**
71338fd1498Szrj   *  @brief Class template _Bind is always a bind expression.
71438fd1498Szrj   *  @ingroup binders
71538fd1498Szrj   */
71638fd1498Szrj  template<typename _Signature>
71738fd1498Szrj    struct is_bind_expression<const volatile _Bind<_Signature>>
71838fd1498Szrj    : public true_type { };
71938fd1498Szrj
72038fd1498Szrj  /**
72138fd1498Szrj   *  @brief Class template _Bind_result is always a bind expression.
72238fd1498Szrj   *  @ingroup binders
72338fd1498Szrj   */
72438fd1498Szrj  template<typename _Result, typename _Signature>
72538fd1498Szrj    struct is_bind_expression<_Bind_result<_Result, _Signature>>
72638fd1498Szrj    : public true_type { };
72738fd1498Szrj
72838fd1498Szrj  /**
72938fd1498Szrj   *  @brief Class template _Bind_result is always a bind expression.
73038fd1498Szrj   *  @ingroup binders
73138fd1498Szrj   */
73238fd1498Szrj  template<typename _Result, typename _Signature>
73338fd1498Szrj    struct is_bind_expression<const _Bind_result<_Result, _Signature>>
73438fd1498Szrj    : public true_type { };
73538fd1498Szrj
73638fd1498Szrj  /**
73738fd1498Szrj   *  @brief Class template _Bind_result is always a bind expression.
73838fd1498Szrj   *  @ingroup binders
73938fd1498Szrj   */
74038fd1498Szrj  template<typename _Result, typename _Signature>
74138fd1498Szrj    struct is_bind_expression<volatile _Bind_result<_Result, _Signature>>
74238fd1498Szrj    : public true_type { };
74338fd1498Szrj
74438fd1498Szrj  /**
74538fd1498Szrj   *  @brief Class template _Bind_result is always a bind expression.
74638fd1498Szrj   *  @ingroup binders
74738fd1498Szrj   */
74838fd1498Szrj  template<typename _Result, typename _Signature>
74938fd1498Szrj    struct is_bind_expression<const volatile _Bind_result<_Result, _Signature>>
75038fd1498Szrj    : public true_type { };
75138fd1498Szrj
75238fd1498Szrj  template<typename _Func, typename... _BoundArgs>
75338fd1498Szrj    struct _Bind_check_arity { };
75438fd1498Szrj
75538fd1498Szrj  template<typename _Ret, typename... _Args, typename... _BoundArgs>
75638fd1498Szrj    struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...>
75738fd1498Szrj    {
75838fd1498Szrj      static_assert(sizeof...(_BoundArgs) == sizeof...(_Args),
75938fd1498Szrj                   "Wrong number of arguments for function");
76038fd1498Szrj    };
76138fd1498Szrj
76238fd1498Szrj  template<typename _Ret, typename... _Args, typename... _BoundArgs>
76338fd1498Szrj    struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...>
76438fd1498Szrj    {
76538fd1498Szrj      static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args),
76638fd1498Szrj                   "Wrong number of arguments for function");
76738fd1498Szrj    };
76838fd1498Szrj
76938fd1498Szrj  template<typename _Tp, typename _Class, typename... _BoundArgs>
77038fd1498Szrj    struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...>
77138fd1498Szrj    {
77238fd1498Szrj      using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity;
77338fd1498Szrj      using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs;
77438fd1498Szrj      static_assert(_Varargs::value
77538fd1498Szrj		    ? sizeof...(_BoundArgs) >= _Arity::value + 1
77638fd1498Szrj		    : sizeof...(_BoundArgs) == _Arity::value + 1,
77738fd1498Szrj		    "Wrong number of arguments for pointer-to-member");
77838fd1498Szrj    };
77938fd1498Szrj
78038fd1498Szrj  // Trait type used to remove std::bind() from overload set via SFINAE
78138fd1498Szrj  // when first argument has integer type, so that std::bind() will
78238fd1498Szrj  // not be a better match than ::bind() from the BSD Sockets API.
78338fd1498Szrj  template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type>
78438fd1498Szrj    using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>;
78538fd1498Szrj
78638fd1498Szrj  template<bool _SocketLike, typename _Func, typename... _BoundArgs>
78738fd1498Szrj    struct _Bind_helper
78838fd1498Szrj    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
78938fd1498Szrj    {
79038fd1498Szrj      typedef typename decay<_Func>::type __func_type;
79138fd1498Szrj      typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type;
79238fd1498Szrj    };
79338fd1498Szrj
79438fd1498Szrj  // Partial specialization for is_socketlike == true, does not define
79538fd1498Szrj  // nested type so std::bind() will not participate in overload resolution
79638fd1498Szrj  // when the first argument might be a socket file descriptor.
79738fd1498Szrj  template<typename _Func, typename... _BoundArgs>
79838fd1498Szrj    struct _Bind_helper<true, _Func, _BoundArgs...>
79938fd1498Szrj    { };
80038fd1498Szrj
80138fd1498Szrj  /**
80238fd1498Szrj   *  @brief Function template for std::bind.
80338fd1498Szrj   *  @ingroup binders
80438fd1498Szrj   */
80538fd1498Szrj  template<typename _Func, typename... _BoundArgs>
80638fd1498Szrj    inline typename
80738fd1498Szrj    _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
80838fd1498Szrj    bind(_Func&& __f, _BoundArgs&&... __args)
80938fd1498Szrj    {
81038fd1498Szrj      typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
81138fd1498Szrj      return typename __helper_type::type(std::forward<_Func>(__f),
81238fd1498Szrj					  std::forward<_BoundArgs>(__args)...);
81338fd1498Szrj    }
81438fd1498Szrj
81538fd1498Szrj  template<typename _Result, typename _Func, typename... _BoundArgs>
81638fd1498Szrj    struct _Bindres_helper
81738fd1498Szrj    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
81838fd1498Szrj    {
81938fd1498Szrj      typedef typename decay<_Func>::type __functor_type;
82038fd1498Szrj      typedef _Bind_result<_Result,
82138fd1498Szrj			   __functor_type(typename decay<_BoundArgs>::type...)>
82238fd1498Szrj	type;
82338fd1498Szrj    };
82438fd1498Szrj
82538fd1498Szrj  /**
82638fd1498Szrj   *  @brief Function template for std::bind<R>.
82738fd1498Szrj   *  @ingroup binders
82838fd1498Szrj   */
82938fd1498Szrj  template<typename _Result, typename _Func, typename... _BoundArgs>
83038fd1498Szrj    inline
83138fd1498Szrj    typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type
83238fd1498Szrj    bind(_Func&& __f, _BoundArgs&&... __args)
83338fd1498Szrj    {
83438fd1498Szrj      typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type;
83538fd1498Szrj      return typename __helper_type::type(std::forward<_Func>(__f),
83638fd1498Szrj					  std::forward<_BoundArgs>(__args)...);
83738fd1498Szrj    }
83838fd1498Szrj
83938fd1498Szrj#if __cplusplus >= 201402L
84038fd1498Szrj  /// Generalized negator.
84138fd1498Szrj  template<typename _Fn>
84238fd1498Szrj    class _Not_fn
84338fd1498Szrj    {
84438fd1498Szrj      template<typename _Fn2, typename... _Args>
84538fd1498Szrj	using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type;
84638fd1498Szrj
84738fd1498Szrj      template<typename _Tp>
84838fd1498Szrj	static decltype(!std::declval<_Tp>())
84938fd1498Szrj	_S_not() noexcept(noexcept(!std::declval<_Tp>()));
85038fd1498Szrj
85138fd1498Szrj    public:
85238fd1498Szrj      template<typename _Fn2>
85338fd1498Szrj	_Not_fn(_Fn2&& __fn, int)
85438fd1498Szrj	: _M_fn(std::forward<_Fn2>(__fn)) { }
85538fd1498Szrj
85638fd1498Szrj      _Not_fn(const _Not_fn& __fn) = default;
85738fd1498Szrj      _Not_fn(_Not_fn&& __fn) = default;
85838fd1498Szrj      ~_Not_fn() = default;
85938fd1498Szrj
86038fd1498Szrj      // Macro to define operator() with given cv-qualifiers ref-qualifiers,
86138fd1498Szrj      // forwarding _M_fn and the function arguments with the same qualifiers,
86238fd1498Szrj      // and deducing the return type and exception-specification.
86338fd1498Szrj#define _GLIBCXX_NOT_FN_CALL_OP( _QUALS )				\
86438fd1498Szrj      template<typename... _Args>					\
86538fd1498Szrj	decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())		\
86638fd1498Szrj	operator()(_Args&&... __args) _QUALS				\
867*58e805e6Szrj	noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value	\
868*58e805e6Szrj	    && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()))	\
86938fd1498Szrj	{								\
87038fd1498Szrj	  return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn),	\
87138fd1498Szrj				std::forward<_Args>(__args)...);	\
87238fd1498Szrj	}
87338fd1498Szrj      _GLIBCXX_NOT_FN_CALL_OP( & )
87438fd1498Szrj      _GLIBCXX_NOT_FN_CALL_OP( const & )
87538fd1498Szrj      _GLIBCXX_NOT_FN_CALL_OP( && )
87638fd1498Szrj      _GLIBCXX_NOT_FN_CALL_OP( const && )
87738fd1498Szrj#undef _GLIBCXX_NOT_FN_CALL
87838fd1498Szrj
87938fd1498Szrj    private:
88038fd1498Szrj      _Fn _M_fn;
88138fd1498Szrj    };
88238fd1498Szrj
88338fd1498Szrj  template<typename _Tp, typename _Pred>
88438fd1498Szrj    struct __is_byte_like : false_type { };
88538fd1498Szrj
88638fd1498Szrj  template<typename _Tp>
88738fd1498Szrj    struct __is_byte_like<_Tp, equal_to<_Tp>>
88838fd1498Szrj    : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { };
88938fd1498Szrj
89038fd1498Szrj  template<typename _Tp>
89138fd1498Szrj    struct __is_byte_like<_Tp, equal_to<void>>
89238fd1498Szrj    : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { };
89338fd1498Szrj
89438fd1498Szrj#if __cplusplus >= 201703L
89538fd1498Szrj  // Declare std::byte (full definition is in <cstddef>).
89638fd1498Szrj  enum class byte : unsigned char;
89738fd1498Szrj
89838fd1498Szrj  template<>
89938fd1498Szrj    struct __is_byte_like<byte, equal_to<byte>>
90038fd1498Szrj    : true_type { };
90138fd1498Szrj
90238fd1498Szrj  template<>
90338fd1498Szrj    struct __is_byte_like<byte, equal_to<void>>
90438fd1498Szrj    : true_type { };
90538fd1498Szrj
90638fd1498Szrj#define __cpp_lib_not_fn 201603
90738fd1498Szrj  /// [func.not_fn] Function template not_fn
90838fd1498Szrj  template<typename _Fn>
90938fd1498Szrj    inline auto
91038fd1498Szrj    not_fn(_Fn&& __fn)
91138fd1498Szrj    noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
91238fd1498Szrj    {
91338fd1498Szrj      return _Not_fn<std::decay_t<_Fn>>{std::forward<_Fn>(__fn), 0};
91438fd1498Szrj    }
91538fd1498Szrj
91638fd1498Szrj  // Searchers
91738fd1498Szrj#define __cpp_lib_boyer_moore_searcher 201603
91838fd1498Szrj
91938fd1498Szrj  template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>>
92038fd1498Szrj    class default_searcher
92138fd1498Szrj    {
92238fd1498Szrj    public:
92338fd1498Szrj      default_searcher(_ForwardIterator1 __pat_first,
92438fd1498Szrj		       _ForwardIterator1 __pat_last,
92538fd1498Szrj		       _BinaryPredicate __pred = _BinaryPredicate())
92638fd1498Szrj      : _M_m(__pat_first, __pat_last, std::move(__pred))
92738fd1498Szrj      { }
92838fd1498Szrj
92938fd1498Szrj      template<typename _ForwardIterator2>
93038fd1498Szrj        pair<_ForwardIterator2, _ForwardIterator2>
93138fd1498Szrj	operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const
93238fd1498Szrj	{
93338fd1498Szrj	  _ForwardIterator2 __first_ret =
93438fd1498Szrj	    std::search(__first, __last, std::get<0>(_M_m), std::get<1>(_M_m),
93538fd1498Szrj			std::get<2>(_M_m));
93638fd1498Szrj	  auto __ret = std::make_pair(__first_ret, __first_ret);
93738fd1498Szrj	  if (__ret.first != __last)
93838fd1498Szrj	    std::advance(__ret.second, std::distance(std::get<0>(_M_m),
93938fd1498Szrj						     std::get<1>(_M_m)));
94038fd1498Szrj	  return __ret;
94138fd1498Szrj	}
94238fd1498Szrj
94338fd1498Szrj    private:
94438fd1498Szrj      tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m;
94538fd1498Szrj    };
94638fd1498Szrj
94738fd1498Szrj  template<typename _Key, typename _Tp, typename _Hash, typename _Pred>
94838fd1498Szrj    struct __boyer_moore_map_base
94938fd1498Szrj    {
95038fd1498Szrj      template<typename _RAIter>
95138fd1498Szrj	__boyer_moore_map_base(_RAIter __pat, size_t __patlen,
95238fd1498Szrj			       _Hash&& __hf, _Pred&& __pred)
95338fd1498Szrj	: _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) }
95438fd1498Szrj	{
95538fd1498Szrj	  if (__patlen > 0)
95638fd1498Szrj	    for (__diff_type __i = 0; __i < __patlen - 1; ++__i)
95738fd1498Szrj	      _M_bad_char[__pat[__i]] = __patlen - 1 - __i;
95838fd1498Szrj	}
95938fd1498Szrj
96038fd1498Szrj      using __diff_type = _Tp;
96138fd1498Szrj
96238fd1498Szrj      __diff_type
96338fd1498Szrj      _M_lookup(_Key __key, __diff_type __not_found) const
96438fd1498Szrj      {
96538fd1498Szrj	auto __iter = _M_bad_char.find(__key);
96638fd1498Szrj	if (__iter == _M_bad_char.end())
96738fd1498Szrj	  return __not_found;
96838fd1498Szrj	return __iter->second;
96938fd1498Szrj      }
97038fd1498Szrj
97138fd1498Szrj      _Pred
97238fd1498Szrj      _M_pred() const { return _M_bad_char.key_eq(); }
97338fd1498Szrj
97438fd1498Szrj      _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char;
97538fd1498Szrj    };
97638fd1498Szrj
97738fd1498Szrj  template<typename _Tp, size_t _Len, typename _Pred>
97838fd1498Szrj    struct __boyer_moore_array_base
97938fd1498Szrj    {
98038fd1498Szrj      template<typename _RAIter, typename _Unused>
98138fd1498Szrj	__boyer_moore_array_base(_RAIter __pat, size_t __patlen,
98238fd1498Szrj				 _Unused&&, _Pred&& __pred)
98338fd1498Szrj	: _M_bad_char{ _GLIBCXX_STD_C::array<_Tp, _Len>{}, std::move(__pred) }
98438fd1498Szrj	{
98538fd1498Szrj	  std::get<0>(_M_bad_char).fill(__patlen);
98638fd1498Szrj	  if (__patlen > 0)
98738fd1498Szrj	    for (__diff_type __i = 0; __i < __patlen - 1; ++__i)
98838fd1498Szrj	      {
98938fd1498Szrj		auto __ch = __pat[__i];
99038fd1498Szrj		using _UCh = make_unsigned_t<decltype(__ch)>;
99138fd1498Szrj		auto __uch = static_cast<_UCh>(__ch);
99238fd1498Szrj		std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i;
99338fd1498Szrj	      }
99438fd1498Szrj	}
99538fd1498Szrj
99638fd1498Szrj      using __diff_type = _Tp;
99738fd1498Szrj
99838fd1498Szrj      template<typename _Key>
99938fd1498Szrj	__diff_type
100038fd1498Szrj	_M_lookup(_Key __key, __diff_type __not_found) const
100138fd1498Szrj	{
100238fd1498Szrj	  auto __ukey = static_cast<make_unsigned_t<_Key>>(__key);
100338fd1498Szrj	  if (__ukey >= _Len)
100438fd1498Szrj	    return __not_found;
100538fd1498Szrj	  return std::get<0>(_M_bad_char)[__ukey];
100638fd1498Szrj	}
100738fd1498Szrj
100838fd1498Szrj      const _Pred&
100938fd1498Szrj      _M_pred() const { return std::get<1>(_M_bad_char); }
101038fd1498Szrj
101138fd1498Szrj      tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char;
101238fd1498Szrj    };
101338fd1498Szrj
101438fd1498Szrj  // Use __boyer_moore_array_base when pattern consists of narrow characters
101538fd1498Szrj  // (or std::byte) and uses std::equal_to as the predicate.
101638fd1498Szrj  template<typename _RAIter, typename _Hash, typename _Pred,
101738fd1498Szrj           typename _Val = typename iterator_traits<_RAIter>::value_type,
101838fd1498Szrj	   typename _Diff = typename iterator_traits<_RAIter>::difference_type>
101938fd1498Szrj    using __boyer_moore_base_t
102038fd1498Szrj      = conditional_t<__is_byte_like<_Val, _Pred>::value,
102138fd1498Szrj		      __boyer_moore_array_base<_Diff, 256, _Pred>,
102238fd1498Szrj		      __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>;
102338fd1498Szrj
102438fd1498Szrj  template<typename _RAIter, typename _Hash
102538fd1498Szrj	     = hash<typename iterator_traits<_RAIter>::value_type>,
102638fd1498Szrj	   typename _BinaryPredicate = equal_to<>>
102738fd1498Szrj    class boyer_moore_searcher
102838fd1498Szrj    : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>
102938fd1498Szrj    {
103038fd1498Szrj      using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>;
103138fd1498Szrj      using typename _Base::__diff_type;
103238fd1498Szrj
103338fd1498Szrj    public:
103438fd1498Szrj      boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last,
103538fd1498Szrj			   _Hash __hf = _Hash(),
103638fd1498Szrj			   _BinaryPredicate __pred = _BinaryPredicate());
103738fd1498Szrj
103838fd1498Szrj      template<typename _RandomAccessIterator2>
103938fd1498Szrj        pair<_RandomAccessIterator2, _RandomAccessIterator2>
104038fd1498Szrj	operator()(_RandomAccessIterator2 __first,
104138fd1498Szrj		   _RandomAccessIterator2 __last) const;
104238fd1498Szrj
104338fd1498Szrj    private:
104438fd1498Szrj      bool
104538fd1498Szrj      _M_is_prefix(_RAIter __word, __diff_type __len,
104638fd1498Szrj		   __diff_type __pos)
104738fd1498Szrj      {
104838fd1498Szrj	const auto& __pred = this->_M_pred();
104938fd1498Szrj	__diff_type __suffixlen = __len - __pos;
105038fd1498Szrj	for (__diff_type __i = 0; __i < __suffixlen; ++__i)
105138fd1498Szrj	  if (!__pred(__word[__i], __word[__pos + __i]))
105238fd1498Szrj	    return false;
105338fd1498Szrj	return true;
105438fd1498Szrj      }
105538fd1498Szrj
105638fd1498Szrj      __diff_type
105738fd1498Szrj      _M_suffix_length(_RAIter __word, __diff_type __len,
105838fd1498Szrj		       __diff_type __pos)
105938fd1498Szrj      {
106038fd1498Szrj	const auto& __pred = this->_M_pred();
106138fd1498Szrj	__diff_type __i = 0;
106238fd1498Szrj	while (__pred(__word[__pos - __i], __word[__len - 1 - __i])
106338fd1498Szrj	       && __i < __pos)
106438fd1498Szrj	  {
106538fd1498Szrj	    ++__i;
106638fd1498Szrj	  }
106738fd1498Szrj	return __i;
106838fd1498Szrj      }
106938fd1498Szrj
107038fd1498Szrj      template<typename _Tp>
107138fd1498Szrj	__diff_type
107238fd1498Szrj	_M_bad_char_shift(_Tp __c) const
107338fd1498Szrj	{ return this->_M_lookup(__c, _M_pat_end - _M_pat); }
107438fd1498Szrj
107538fd1498Szrj      _RAIter _M_pat;
107638fd1498Szrj      _RAIter _M_pat_end;
107738fd1498Szrj      _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix;
107838fd1498Szrj    };
107938fd1498Szrj
108038fd1498Szrj  template<typename _RAIter, typename _Hash
108138fd1498Szrj	     = hash<typename iterator_traits<_RAIter>::value_type>,
108238fd1498Szrj	   typename _BinaryPredicate = equal_to<>>
108338fd1498Szrj    class boyer_moore_horspool_searcher
108438fd1498Szrj    : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>
108538fd1498Szrj    {
108638fd1498Szrj      using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>;
108738fd1498Szrj      using typename _Base::__diff_type;
108838fd1498Szrj
108938fd1498Szrj    public:
109038fd1498Szrj      boyer_moore_horspool_searcher(_RAIter __pat,
109138fd1498Szrj				    _RAIter __pat_end,
109238fd1498Szrj				    _Hash __hf = _Hash(),
109338fd1498Szrj				    _BinaryPredicate __pred
109438fd1498Szrj				    = _BinaryPredicate())
109538fd1498Szrj      : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)),
109638fd1498Szrj	_M_pat(__pat), _M_pat_end(__pat_end)
109738fd1498Szrj      { }
109838fd1498Szrj
109938fd1498Szrj      template<typename _RandomAccessIterator2>
110038fd1498Szrj        pair<_RandomAccessIterator2, _RandomAccessIterator2>
110138fd1498Szrj	operator()(_RandomAccessIterator2 __first,
110238fd1498Szrj		   _RandomAccessIterator2 __last) const
110338fd1498Szrj	{
110438fd1498Szrj	  const auto& __pred = this->_M_pred();
110538fd1498Szrj	  auto __patlen = _M_pat_end - _M_pat;
110638fd1498Szrj	  if (__patlen == 0)
110738fd1498Szrj	    return std::make_pair(__first, __first);
110838fd1498Szrj	  auto __len = __last - __first;
110938fd1498Szrj	  while (__len >= __patlen)
111038fd1498Szrj	    {
111138fd1498Szrj	      for (auto __scan = __patlen - 1;
111238fd1498Szrj		   __pred(__first[__scan], _M_pat[__scan]); --__scan)
111338fd1498Szrj		if (__scan == 0)
111438fd1498Szrj		  return std::make_pair(__first, __first + __patlen);
111538fd1498Szrj	      auto __shift = _M_bad_char_shift(__first[__patlen - 1]);
111638fd1498Szrj	      __len -= __shift;
111738fd1498Szrj	      __first += __shift;
111838fd1498Szrj	    }
111938fd1498Szrj	  return std::make_pair(__last, __last);
112038fd1498Szrj	}
112138fd1498Szrj
112238fd1498Szrj    private:
112338fd1498Szrj      template<typename _Tp>
112438fd1498Szrj	__diff_type
112538fd1498Szrj	_M_bad_char_shift(_Tp __c) const
112638fd1498Szrj	{ return this->_M_lookup(__c, _M_pat_end - _M_pat); }
112738fd1498Szrj
112838fd1498Szrj      _RAIter _M_pat;
112938fd1498Szrj      _RAIter _M_pat_end;
113038fd1498Szrj    };
113138fd1498Szrj
113238fd1498Szrj  template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
113338fd1498Szrj    boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
113438fd1498Szrj    boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end,
113538fd1498Szrj			 _Hash __hf, _BinaryPredicate __pred)
113638fd1498Szrj    : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)),
113738fd1498Szrj      _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat)
113838fd1498Szrj    {
113938fd1498Szrj      auto __patlen = __pat_end - __pat;
114038fd1498Szrj      if (__patlen == 0)
114138fd1498Szrj	return;
114238fd1498Szrj      __diff_type __last_prefix = __patlen - 1;
114338fd1498Szrj      for (__diff_type __p = __patlen - 1; __p >= 0; --__p)
114438fd1498Szrj	{
114538fd1498Szrj	  if (_M_is_prefix(__pat, __patlen, __p + 1))
114638fd1498Szrj	    __last_prefix = __p + 1;
114738fd1498Szrj	  _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p);
114838fd1498Szrj	}
114938fd1498Szrj      for (__diff_type __p = 0; __p < __patlen - 1; ++__p)
115038fd1498Szrj	{
115138fd1498Szrj	  auto __slen = _M_suffix_length(__pat, __patlen, __p);
115238fd1498Szrj	  auto __pos = __patlen - 1 - __slen;
115338fd1498Szrj	  if (!__pred(__pat[__p - __slen], __pat[__pos]))
115438fd1498Szrj	    _M_good_suffix[__pos] = __patlen - 1 - __p + __slen;
115538fd1498Szrj	}
115638fd1498Szrj    }
115738fd1498Szrj
115838fd1498Szrj  template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
115938fd1498Szrj  template<typename _RandomAccessIterator2>
116038fd1498Szrj    pair<_RandomAccessIterator2, _RandomAccessIterator2>
116138fd1498Szrj    boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
116238fd1498Szrj    operator()(_RandomAccessIterator2 __first,
116338fd1498Szrj	       _RandomAccessIterator2 __last) const
116438fd1498Szrj    {
116538fd1498Szrj      auto __patlen = _M_pat_end - _M_pat;
116638fd1498Szrj      if (__patlen == 0)
116738fd1498Szrj	return std::make_pair(__first, __first);
116838fd1498Szrj      const auto& __pred = this->_M_pred();
116938fd1498Szrj      __diff_type __i = __patlen - 1;
117038fd1498Szrj      auto __stringlen = __last - __first;
117138fd1498Szrj      while (__i < __stringlen)
117238fd1498Szrj	{
117338fd1498Szrj	  __diff_type __j = __patlen - 1;
117438fd1498Szrj	  while (__j >= 0 && __pred(__first[__i], _M_pat[__j]))
117538fd1498Szrj	    {
117638fd1498Szrj	      --__i;
117738fd1498Szrj	      --__j;
117838fd1498Szrj	    }
117938fd1498Szrj	  if (__j < 0)
118038fd1498Szrj	    {
118138fd1498Szrj	      const auto __match = __first + __i + 1;
118238fd1498Szrj	      return std::make_pair(__match, __match + __patlen);
118338fd1498Szrj	    }
118438fd1498Szrj	  __i += std::max(_M_bad_char_shift(__first[__i]),
118538fd1498Szrj			  _M_good_suffix[__j]);
118638fd1498Szrj	}
118738fd1498Szrj      return std::make_pair(__last, __last);
118838fd1498Szrj    }
118938fd1498Szrj
119038fd1498Szrj#endif // C++17
119138fd1498Szrj#endif // C++14
119238fd1498Szrj
119338fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION
119438fd1498Szrj} // namespace std
119538fd1498Szrj
119638fd1498Szrj#endif // C++11
119738fd1498Szrj
119838fd1498Szrj#endif // _GLIBCXX_FUNCTIONAL
1199