// <functional> -*- C++ -*-

// Copyright (C) 2001-2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 * Copyright (c) 1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 */

/** @file include/functional
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_FUNCTIONAL
#define _GLIBCXX_FUNCTIONAL 1

#pragma GCC system_header

#include <bits/c++config.h>
#include <bits/stl_function.h> // std::equal_to, std::unary_function etc.

#if __cplusplus >= 201103L

#include <tuple>
#include <type_traits>
#include <bits/functional_hash.h>
#include <bits/invoke.h>
#include <bits/refwrap.h>	// std::reference_wrapper and _Mem_fn_traits
#if _GLIBCXX_HOSTED
# include <bits/std_function.h>	// std::function
#endif
#if __cplusplus >= 201703L
# if _GLIBCXX_HOSTED
#  include <unordered_map>
#  include <vector>
#  include <array>
# endif
# include <bits/stl_algo.h> // std::search
#endif
#if __cplusplus >= 202002L
# include <bits/ranges_cmp.h> // std::identity, ranges::equal_to etc.
# include <compare>
#endif
#if __cplusplus > 202002L && _GLIBCXX_HOSTED
# include <bits/move_only_function.h>
#endif

#endif // C++11

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /** @brief The type of placeholder objects defined by libstdc++.
   *  @ingroup binders
   *  @since C++11
   */
  template<int _Num> struct _Placeholder { };

#if __cplusplus >= 201103L

#if __cplusplus >= 201703L
# define __cpp_lib_invoke 201411L
# if __cplusplus > 201703L
#  define __cpp_lib_constexpr_functional 201907L
# endif

  /** Invoke a callable object.
   *
   * `std::invoke` takes a callable object as its first argument and calls it
   * with the remaining arguments. The callable object can be a pointer or
   * reference to a function, a lambda closure, a class with `operator()`,
   * or even a pointer-to-member.  For a pointer-to-member the first argument
   * must be a reference or pointer to the object that the pointer-to-member
   * will be applied to.
   *
   *  @since C++17
   */
  template<typename _Callable, typename... _Args>
    inline _GLIBCXX20_CONSTEXPR invoke_result_t<_Callable, _Args...>
    invoke(_Callable&& __fn, _Args&&... __args)
    noexcept(is_nothrow_invocable_v<_Callable, _Args...>)
    {
      return std::__invoke(std::forward<_Callable>(__fn),
			   std::forward<_Args>(__args)...);
    }

#if __cplusplus > 202002L
# define __cpp_lib_invoke_r 202106L

  /** Invoke a callable object and convert the result to `_Res`.
   *
   * `std::invoke_r<R>(f, args...)` is equivalent to `std::invoke(f, args...)`
   * with the result implicitly converted to `R`.
   *
   *  @since C++23
   */
  template<typename _Res, typename _Callable, typename... _Args>
    requires is_invocable_r_v<_Res, _Callable, _Args...>
    constexpr _Res
    invoke_r(_Callable&& __fn, _Args&&... __args)
    noexcept(is_nothrow_invocable_r_v<_Res, _Callable, _Args...>)
    {
      return std::__invoke_r<_Res>(std::forward<_Callable>(__fn),
				   std::forward<_Args>(__args)...);
    }
#endif // C++23
#endif // C++17

  /// @cond undocumented

  template<typename _MemFunPtr,
	   bool __is_mem_fn = is_member_function_pointer<_MemFunPtr>::value>
    class _Mem_fn_base
    : public _Mem_fn_traits<_MemFunPtr>::__maybe_type
    {
      using _Traits = _Mem_fn_traits<_MemFunPtr>;

      using _Arity = typename _Traits::__arity;
      using _Varargs = typename _Traits::__vararg;

      template<typename _Func, typename... _BoundArgs>
	friend struct _Bind_check_arity;

      _MemFunPtr _M_pmf;

    public:

      using result_type = typename _Traits::__result_type;

      explicit constexpr
      _Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { }

      template<typename... _Args>
	_GLIBCXX20_CONSTEXPR
	auto
	operator()(_Args&&... __args) const
	noexcept(noexcept(
	      std::__invoke(_M_pmf, std::forward<_Args>(__args)...)))
	-> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...))
	{ return std::__invoke(_M_pmf, std::forward<_Args>(__args)...); }
    };

  // Partial specialization for member object pointers.
  template<typename _MemObjPtr>
    class _Mem_fn_base<_MemObjPtr, false>
    {
      using _Arity = integral_constant<size_t, 0>;
      using _Varargs = false_type;

      template<typename _Func, typename... _BoundArgs>
	friend struct _Bind_check_arity;

      _MemObjPtr _M_pm;

    public:
      explicit constexpr
      _Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { }

      template<typename _Tp>
	_GLIBCXX20_CONSTEXPR
	auto
	operator()(_Tp&& __obj) const
	noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj))))
	-> decltype(std::__invoke(_M_pm, std::forward<_Tp>(__obj)))
	{ return std::__invoke(_M_pm, std::forward<_Tp>(__obj)); }
    };

  template<typename _MemberPointer>
    struct _Mem_fn; // undefined

  template<typename _Res, typename _Class>
    struct _Mem_fn<_Res _Class::*>
    : _Mem_fn_base<_Res _Class::*>
    {
      using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base;
    };
  /// @endcond

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 2048.  Unnecessary mem_fn overloads
  /**
   * @brief Returns a function object that forwards to the member pointer
   * pointer `pm`.
   *
   * This allows a pointer-to-member to be transformed into a function object
   * that can be called with an object expression as its first argument.
   *
   * For a pointer-to-data-member the result must be called with exactly one
   * argument, the object expression that would be used as the first operand
   * in a `obj.*memptr` or `objp->*memptr` expression.
   *
   * For a pointer-to-member-function the result must be called with an object
   * expression and any additional arguments to pass to the member function,
   * as in an expression like `(obj.*memfun)(args...)` or
   * `(objp->*memfun)(args...)`.
   *
   * The object expression can be a pointer, reference, `reference_wrapper`,
   * or smart pointer, and the call wrapper will dereference it as needed
   * to apply the pointer-to-member.
   *
   * @ingroup functors
   * @since C++11
   */
  template<typename _Tp, typename _Class>
    _GLIBCXX20_CONSTEXPR
    inline _Mem_fn<_Tp _Class::*>
    mem_fn(_Tp _Class::* __pm) noexcept
    {
      return _Mem_fn<_Tp _Class::*>(__pm);
    }

  /**
   * @brief Trait that identifies a bind expression.
   *
   * Determines if the given type `_Tp` is a function object that
   * should be treated as a subexpression when evaluating calls to
   * function objects returned by `std::bind`.
   *
   * C++11 [func.bind.isbind].
   * @ingroup binders
   * @since C++11
   */
  template<typename _Tp>
    struct is_bind_expression
    : public false_type { };

  /**
   *  @brief Determines if the given type _Tp is a placeholder in a
   *  bind() expression and, if so, which placeholder it is.
   *
   *  C++11 [func.bind.isplace].
   *  @ingroup binders
   *  @since C++11
   */
  template<typename _Tp>
    struct is_placeholder
    : public integral_constant<int, 0>
    { };

#if __cplusplus > 201402L
  template <typename _Tp> inline constexpr bool is_bind_expression_v
    = is_bind_expression<_Tp>::value;
  template <typename _Tp> inline constexpr int is_placeholder_v
    = is_placeholder<_Tp>::value;
#endif // C++17

  /** @namespace std::placeholders
   *  @brief ISO C++ 2011 namespace for std::bind placeholders.
   *  @ingroup binders
   *  @since C++11
   */
  namespace placeholders
  {
  /* Define a large number of placeholders. There is no way to
   * simplify this with variadic templates, because we're introducing
   * unique names for each.
   */
#if __cpp_inline_variables
#  define _GLIBCXX_PLACEHOLDER inline
#else
#  define _GLIBCXX_PLACEHOLDER extern
#endif

    _GLIBCXX_PLACEHOLDER const _Placeholder<1> _1;
    _GLIBCXX_PLACEHOLDER const _Placeholder<2> _2;
    _GLIBCXX_PLACEHOLDER const _Placeholder<3> _3;
    _GLIBCXX_PLACEHOLDER const _Placeholder<4> _4;
    _GLIBCXX_PLACEHOLDER const _Placeholder<5> _5;
    _GLIBCXX_PLACEHOLDER const _Placeholder<6> _6;
    _GLIBCXX_PLACEHOLDER const _Placeholder<7> _7;
    _GLIBCXX_PLACEHOLDER const _Placeholder<8> _8;
    _GLIBCXX_PLACEHOLDER const _Placeholder<9> _9;
    _GLIBCXX_PLACEHOLDER const _Placeholder<10> _10;
    _GLIBCXX_PLACEHOLDER const _Placeholder<11> _11;
    _GLIBCXX_PLACEHOLDER const _Placeholder<12> _12;
    _GLIBCXX_PLACEHOLDER const _Placeholder<13> _13;
    _GLIBCXX_PLACEHOLDER const _Placeholder<14> _14;
    _GLIBCXX_PLACEHOLDER const _Placeholder<15> _15;
    _GLIBCXX_PLACEHOLDER const _Placeholder<16> _16;
    _GLIBCXX_PLACEHOLDER const _Placeholder<17> _17;
    _GLIBCXX_PLACEHOLDER const _Placeholder<18> _18;
    _GLIBCXX_PLACEHOLDER const _Placeholder<19> _19;
    _GLIBCXX_PLACEHOLDER const _Placeholder<20> _20;
    _GLIBCXX_PLACEHOLDER const _Placeholder<21> _21;
    _GLIBCXX_PLACEHOLDER const _Placeholder<22> _22;
    _GLIBCXX_PLACEHOLDER const _Placeholder<23> _23;
    _GLIBCXX_PLACEHOLDER const _Placeholder<24> _24;
    _GLIBCXX_PLACEHOLDER const _Placeholder<25> _25;
    _GLIBCXX_PLACEHOLDER const _Placeholder<26> _26;
    _GLIBCXX_PLACEHOLDER const _Placeholder<27> _27;
    _GLIBCXX_PLACEHOLDER const _Placeholder<28> _28;
    _GLIBCXX_PLACEHOLDER const _Placeholder<29> _29;

#undef _GLIBCXX_PLACEHOLDER
  }

  /**
   *  Partial specialization of is_placeholder that provides the placeholder
   *  number for the placeholder objects defined by libstdc++.
   *  @ingroup binders
   *  @since C++11
   */
  template<int _Num>
    struct is_placeholder<_Placeholder<_Num> >
    : public integral_constant<int, _Num>
    { };

  template<int _Num>
    struct is_placeholder<const _Placeholder<_Num> >
    : public integral_constant<int, _Num>
    { };

  /// @cond undocumented

  // Like tuple_element_t but SFINAE-friendly.
  template<std::size_t __i, typename _Tuple>
    using _Safe_tuple_element_t
      = typename enable_if<(__i < tuple_size<_Tuple>::value),
			   tuple_element<__i, _Tuple>>::type::type;

  /**
   *  Maps an argument to bind() into an actual argument to the bound
   *  function object [func.bind.bind]/10. Only the first parameter should
   *  be specified: the rest are used to determine among the various
   *  implementations. Note that, although this class is a function
   *  object, it isn't entirely normal because it takes only two
   *  parameters regardless of the number of parameters passed to the
   *  bind expression. The first parameter is the bound argument and
   *  the second parameter is a tuple containing references to the
   *  rest of the arguments.
   */
  template<typename _Arg,
	   bool _IsBindExp = is_bind_expression<_Arg>::value,
	   bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)>
    class _Mu;

  /**
   *  If the argument is reference_wrapper<_Tp>, returns the
   *  underlying reference.
   *  C++11 [func.bind.bind] p10 bullet 1.
   */
  template<typename _Tp>
    class _Mu<reference_wrapper<_Tp>, false, false>
    {
    public:
      /* Note: This won't actually work for const volatile
       * reference_wrappers, because reference_wrapper::get() is const
       * but not volatile-qualified. This might be a defect in the TR.
       */
      template<typename _CVRef, typename _Tuple>
	_GLIBCXX20_CONSTEXPR
	_Tp&
	operator()(_CVRef& __arg, _Tuple&) const volatile
	{ return __arg.get(); }
    };

  /**
   *  If the argument is a bind expression, we invoke the underlying
   *  function object with the same cv-qualifiers as we are given and
   *  pass along all of our arguments (unwrapped).
   *  C++11 [func.bind.bind] p10 bullet 2.
   */
  template<typename _Arg>
    class _Mu<_Arg, true, false>
    {
    public:
      template<typename _CVArg, typename... _Args>
	_GLIBCXX20_CONSTEXPR
	auto
	operator()(_CVArg& __arg,
		   tuple<_Args...>& __tuple) const volatile
	-> decltype(__arg(declval<_Args>()...))
	{
	  // Construct an index tuple and forward to __call
	  typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
	    _Indexes;
	  return this->__call(__arg, __tuple, _Indexes());
	}

    private:
      // Invokes the underlying function object __arg by unpacking all
      // of the arguments in the tuple.
      template<typename _CVArg, typename... _Args, std::size_t... _Indexes>
	_GLIBCXX20_CONSTEXPR
	auto
	__call(_CVArg& __arg, tuple<_Args...>& __tuple,
	       const _Index_tuple<_Indexes...>&) const volatile
	-> decltype(__arg(declval<_Args>()...))
	{
	  return __arg(std::get<_Indexes>(std::move(__tuple))...);
	}
    };

  /**
   *  If the argument is a placeholder for the Nth argument, returns
   *  a reference to the Nth argument to the bind function object.
   *  C++11 [func.bind.bind] p10 bullet 3.
   */
  template<typename _Arg>
    class _Mu<_Arg, false, true>
    {
    public:
      template<typename _Tuple>
	_GLIBCXX20_CONSTEXPR
	_Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&&
	operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
	{
	  return
	    ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple));
	}
    };

  /**
   *  If the argument is just a value, returns a reference to that
   *  value. The cv-qualifiers on the reference are determined by the caller.
   *  C++11 [func.bind.bind] p10 bullet 4.
   */
  template<typename _Arg>
    class _Mu<_Arg, false, false>
    {
    public:
      template<typename _CVArg, typename _Tuple>
	_GLIBCXX20_CONSTEXPR
	_CVArg&&
	operator()(_CVArg&& __arg, _Tuple&) const volatile
	{ return std::forward<_CVArg>(__arg); }
    };

  // std::get<I> for volatile-qualified tuples
  template<std::size_t _Ind, typename... _Tp>
    inline auto
    __volget(volatile tuple<_Tp...>& __tuple)
    -> __tuple_element_t<_Ind, tuple<_Tp...>> volatile&
    { return std::get<_Ind>(const_cast<tuple<_Tp...>&>(__tuple)); }

  // std::get<I> for const-volatile-qualified tuples
  template<std::size_t _Ind, typename... _Tp>
    inline auto
    __volget(const volatile tuple<_Tp...>& __tuple)
    -> __tuple_element_t<_Ind, tuple<_Tp...>> const volatile&
    { return std::get<_Ind>(const_cast<const tuple<_Tp...>&>(__tuple)); }

  /// @endcond

#if __cplusplus == 201703L && _GLIBCXX_USE_DEPRECATED
# define _GLIBCXX_VOLATILE_BIND
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2487. bind() should be const-overloaded, not cv-overloaded
# define _GLIBCXX_DEPR_BIND \
      [[deprecated("std::bind does not support volatile in C++17")]]
#elif __cplusplus < 201703L
# define _GLIBCXX_VOLATILE_BIND
# define _GLIBCXX_DEPR_BIND
#endif

  /// Type of the function object returned from bind().
  template<typename _Signature>
    class _Bind;

   template<typename _Functor, typename... _Bound_args>
    class _Bind<_Functor(_Bound_args...)>
    : public _Weak_result_type<_Functor>
    {
      typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
	_Bound_indexes;

      _Functor _M_f;
      tuple<_Bound_args...> _M_bound_args;

      // Call unqualified
      template<typename _Result, typename... _Args, std::size_t... _Indexes>
	_GLIBCXX20_CONSTEXPR
	_Result
	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
	{
	  return std::__invoke(_M_f,
	      _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)...
	      );
	}

      // Call as const
      template<typename _Result, typename... _Args, std::size_t... _Indexes>
	_GLIBCXX20_CONSTEXPR
	_Result
	__call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
	{
	  return std::__invoke(_M_f,
	      _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)...
	      );
	}

#ifdef _GLIBCXX_VOLATILE_BIND
      // Call as volatile
      template<typename _Result, typename... _Args, std::size_t... _Indexes>
	_Result
	__call_v(tuple<_Args...>&& __args,
		 _Index_tuple<_Indexes...>) volatile
	{
	  return std::__invoke(_M_f,
	      _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)...
	      );
	}

      // Call as const volatile
      template<typename _Result, typename... _Args, std::size_t... _Indexes>
	_Result
	__call_c_v(tuple<_Args...>&& __args,
		   _Index_tuple<_Indexes...>) const volatile
	{
	  return std::__invoke(_M_f,
	      _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)...
	      );
	}
#endif // volatile

      template<typename _BoundArg, typename _CallArgs>
	using _Mu_type = decltype(
	    _Mu<typename remove_cv<_BoundArg>::type>()(
	      std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) );

      template<typename _Fn, typename _CallArgs, typename... _BArgs>
	using _Res_type_impl
	  = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>&&...) >::type;

      template<typename _CallArgs>
	using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>;

      template<typename _CallArgs>
	using __dependent = typename
	  enable_if<bool(tuple_size<_CallArgs>::value+1), _Functor>::type;

      template<typename _CallArgs, template<class> class __cv_quals>
	using _Res_type_cv = _Res_type_impl<
	  typename __cv_quals<__dependent<_CallArgs>>::type,
	  _CallArgs,
	  typename __cv_quals<_Bound_args>::type...>;

     public:
      template<typename... _Args>
	explicit _GLIBCXX20_CONSTEXPR
	_Bind(const _Functor& __f, _Args&&... __args)
	: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
	{ }

      template<typename... _Args>
	explicit _GLIBCXX20_CONSTEXPR
	_Bind(_Functor&& __f, _Args&&... __args)
	: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
	{ }

      _Bind(const _Bind&) = default;
      _Bind(_Bind&&) = default;

      // Call unqualified
      template<typename... _Args,
	       typename _Result = _Res_type<tuple<_Args...>>>
	_GLIBCXX20_CONSTEXPR
	_Result
	operator()(_Args&&... __args)
	{
	  return this->__call<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}

      // Call as const
      template<typename... _Args,
	       typename _Result = _Res_type_cv<tuple<_Args...>, add_const>>
	_GLIBCXX20_CONSTEXPR
	_Result
	operator()(_Args&&... __args) const
	{
	  return this->__call_c<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}

#ifdef _GLIBCXX_VOLATILE_BIND
      // Call as volatile
      template<typename... _Args,
	       typename _Result = _Res_type_cv<tuple<_Args...>, add_volatile>>
	_GLIBCXX_DEPR_BIND
	_Result
	operator()(_Args&&... __args) volatile
	{
	  return this->__call_v<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}

      // Call as const volatile
      template<typename... _Args,
	       typename _Result = _Res_type_cv<tuple<_Args...>, add_cv>>
	_GLIBCXX_DEPR_BIND
	_Result
	operator()(_Args&&... __args) const volatile
	{
	  return this->__call_c_v<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}
#endif // volatile
    };

  /// Type of the function object returned from bind<R>().
  template<typename _Result, typename _Signature>
    class _Bind_result;

  template<typename _Result, typename _Functor, typename... _Bound_args>
    class _Bind_result<_Result, _Functor(_Bound_args...)>
    {
      typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
	_Bound_indexes;

      _Functor _M_f;
      tuple<_Bound_args...> _M_bound_args;

      // Call unqualified
      template<typename _Res, typename... _Args, std::size_t... _Indexes>
	_GLIBCXX20_CONSTEXPR
	_Res
	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
	{
	  return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>()
		      (std::get<_Indexes>(_M_bound_args), __args)...);
	}

      // Call as const
      template<typename _Res, typename... _Args, std::size_t... _Indexes>
	_GLIBCXX20_CONSTEXPR
	_Res
	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
	{
	  return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>()
		      (std::get<_Indexes>(_M_bound_args), __args)...);
	}

#ifdef _GLIBCXX_VOLATILE_BIND
      // Call as volatile
      template<typename _Res, typename... _Args, std::size_t... _Indexes>
	_Res
	__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile
	{
	  return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>()
		      (__volget<_Indexes>(_M_bound_args), __args)...);
	}

      // Call as const volatile
      template<typename _Res, typename... _Args, std::size_t... _Indexes>
	_Res
	__call(tuple<_Args...>&& __args,
	       _Index_tuple<_Indexes...>) const volatile
	{
	  return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>()
		      (__volget<_Indexes>(_M_bound_args), __args)...);
	}
#endif // volatile

    public:
      typedef _Result result_type;

      template<typename... _Args>
	explicit _GLIBCXX20_CONSTEXPR
	_Bind_result(const _Functor& __f, _Args&&... __args)
	: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
	{ }

      template<typename... _Args>
	explicit _GLIBCXX20_CONSTEXPR
	_Bind_result(_Functor&& __f, _Args&&... __args)
	: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
	{ }

      _Bind_result(const _Bind_result&) = default;
      _Bind_result(_Bind_result&&) = default;

      // Call unqualified
      template<typename... _Args>
	_GLIBCXX20_CONSTEXPR
	result_type
	operator()(_Args&&... __args)
	{
	  return this->__call<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}

      // Call as const
      template<typename... _Args>
	_GLIBCXX20_CONSTEXPR
	result_type
	operator()(_Args&&... __args) const
	{
	  return this->__call<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}

#ifdef _GLIBCXX_VOLATILE_BIND
      // Call as volatile
      template<typename... _Args>
	_GLIBCXX_DEPR_BIND
	result_type
	operator()(_Args&&... __args) volatile
	{
	  return this->__call<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}

      // Call as const volatile
      template<typename... _Args>
	_GLIBCXX_DEPR_BIND
	result_type
	operator()(_Args&&... __args) const volatile
	{
	  return this->__call<_Result>(
	      std::forward_as_tuple(std::forward<_Args>(__args)...),
	      _Bound_indexes());
	}
#else
      template<typename... _Args>
	void operator()(_Args&&...) const volatile = delete;
#endif // volatile
    };

#undef _GLIBCXX_VOLATILE_BIND
#undef _GLIBCXX_DEPR_BIND

  /**
   *  @brief Class template _Bind is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Signature>
    struct is_bind_expression<_Bind<_Signature> >
    : public true_type { };

  /**
   *  @brief Class template _Bind is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Signature>
    struct is_bind_expression<const _Bind<_Signature> >
    : public true_type { };

  /**
   *  @brief Class template _Bind is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Signature>
    struct is_bind_expression<volatile _Bind<_Signature> >
    : public true_type { };

  /**
   *  @brief Class template _Bind is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Signature>
    struct is_bind_expression<const volatile _Bind<_Signature>>
    : public true_type { };

  /**
   *  @brief Class template _Bind_result is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Result, typename _Signature>
    struct is_bind_expression<_Bind_result<_Result, _Signature>>
    : public true_type { };

  /**
   *  @brief Class template _Bind_result is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Result, typename _Signature>
    struct is_bind_expression<const _Bind_result<_Result, _Signature>>
    : public true_type { };

  /**
   *  @brief Class template _Bind_result is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Result, typename _Signature>
    struct is_bind_expression<volatile _Bind_result<_Result, _Signature>>
    : public true_type { };

  /**
   *  @brief Class template _Bind_result is always a bind expression.
   *  @ingroup binders
   */
  template<typename _Result, typename _Signature>
    struct is_bind_expression<const volatile _Bind_result<_Result, _Signature>>
    : public true_type { };

  template<typename _Func, typename... _BoundArgs>
    struct _Bind_check_arity { };

  template<typename _Ret, typename... _Args, typename... _BoundArgs>
    struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...>
    {
      static_assert(sizeof...(_BoundArgs) == sizeof...(_Args),
                   "Wrong number of arguments for function");
    };

  template<typename _Ret, typename... _Args, typename... _BoundArgs>
    struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...>
    {
      static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args),
                   "Wrong number of arguments for function");
    };

  template<typename _Tp, typename _Class, typename... _BoundArgs>
    struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...>
    {
      using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity;
      using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs;
      static_assert(_Varargs::value
		    ? sizeof...(_BoundArgs) >= _Arity::value + 1
		    : sizeof...(_BoundArgs) == _Arity::value + 1,
		    "Wrong number of arguments for pointer-to-member");
    };

  // Trait type used to remove std::bind() from overload set via SFINAE
  // when first argument has integer type, so that std::bind() will
  // not be a better match than ::bind() from the BSD Sockets API.
  template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type>
    using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>;

  template<bool _SocketLike, typename _Func, typename... _BoundArgs>
    struct _Bind_helper
    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
    {
      typedef typename decay<_Func>::type __func_type;
      typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type;
    };

  // Partial specialization for is_socketlike == true, does not define
  // nested type so std::bind() will not participate in overload resolution
  // when the first argument might be a socket file descriptor.
  template<typename _Func, typename... _BoundArgs>
    struct _Bind_helper<true, _Func, _BoundArgs...>
    { };

  /**
   *  @brief Function template for std::bind.
   *  @ingroup binders
   *  @since C++11
   */
  template<typename _Func, typename... _BoundArgs>
    inline _GLIBCXX20_CONSTEXPR typename
    _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
    bind(_Func&& __f, _BoundArgs&&... __args)
    {
      typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
      return typename __helper_type::type(std::forward<_Func>(__f),
					  std::forward<_BoundArgs>(__args)...);
    }

  template<typename _Result, typename _Func, typename... _BoundArgs>
    struct _Bindres_helper
    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
    {
      typedef typename decay<_Func>::type __functor_type;
      typedef _Bind_result<_Result,
			   __functor_type(typename decay<_BoundArgs>::type...)>
	type;
    };

  /**
   *  @brief Function template for std::bind<R>.
   *  @ingroup binders
   *  @since C++11
   */
  template<typename _Result, typename _Func, typename... _BoundArgs>
    inline _GLIBCXX20_CONSTEXPR
    typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type
    bind(_Func&& __f, _BoundArgs&&... __args)
    {
      typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type;
      return typename __helper_type::type(std::forward<_Func>(__f),
					  std::forward<_BoundArgs>(__args)...);
    }

#if __cplusplus > 201703L
#define __cpp_lib_bind_front 201907L

  template<typename _Fd, typename... _BoundArgs>
    struct _Bind_front
    {
      static_assert(is_move_constructible_v<_Fd>);
      static_assert((is_move_constructible_v<_BoundArgs> && ...));

      // First parameter is to ensure this constructor is never used
      // instead of the copy/move constructor.
      template<typename _Fn, typename... _Args>
	explicit constexpr
	_Bind_front(int, _Fn&& __fn, _Args&&... __args)
	noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>,
			is_nothrow_constructible<_BoundArgs, _Args>...>::value)
	: _M_fd(std::forward<_Fn>(__fn)),
	  _M_bound_args(std::forward<_Args>(__args)...)
	{ static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); }

      _Bind_front(const _Bind_front&) = default;
      _Bind_front(_Bind_front&&) = default;
      _Bind_front& operator=(const _Bind_front&) = default;
      _Bind_front& operator=(_Bind_front&&) = default;
      ~_Bind_front() = default;

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<_Fd&, _BoundArgs&..., _CallArgs...>
	operator()(_CallArgs&&... __call_args) &
	noexcept(is_nothrow_invocable_v<_Fd&, _BoundArgs&..., _CallArgs...>)
	{
	  return _S_call(*this, _BoundIndices(),
	      std::forward<_CallArgs>(__call_args)...);
	}

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<const _Fd&, const _BoundArgs&..., _CallArgs...>
	operator()(_CallArgs&&... __call_args) const &
	noexcept(is_nothrow_invocable_v<const _Fd&, const _BoundArgs&...,
					_CallArgs...>)
	{
	  return _S_call(*this, _BoundIndices(),
	      std::forward<_CallArgs>(__call_args)...);
	}

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<_Fd, _BoundArgs..., _CallArgs...>
	operator()(_CallArgs&&... __call_args) &&
	noexcept(is_nothrow_invocable_v<_Fd, _BoundArgs..., _CallArgs...>)
	{
	  return _S_call(std::move(*this), _BoundIndices(),
	      std::forward<_CallArgs>(__call_args)...);
	}

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<const _Fd, const _BoundArgs..., _CallArgs...>
	operator()(_CallArgs&&... __call_args) const &&
	noexcept(is_nothrow_invocable_v<const _Fd, const _BoundArgs...,
					_CallArgs...>)
	{
	  return _S_call(std::move(*this), _BoundIndices(),
	      std::forward<_CallArgs>(__call_args)...);
	}

    private:
      using _BoundIndices = index_sequence_for<_BoundArgs...>;

      template<typename _Tp, size_t... _Ind, typename... _CallArgs>
	static constexpr
	decltype(auto)
	_S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args)
	{
	  return std::invoke(std::forward<_Tp>(__g)._M_fd,
	      std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...,
	      std::forward<_CallArgs>(__call_args)...);
	}

      _Fd _M_fd;
      std::tuple<_BoundArgs...> _M_bound_args;
    };

  // Avoid the overhead of an empty tuple<> if there are no bound args.
  template<typename _Fd>
    struct _Bind_front0
    {
      static_assert(is_move_constructible_v<_Fd>);

      // First parameter is to ensure this constructor is never used
      // instead of the copy/move constructor.
      template<typename _Fn>
	explicit constexpr
	_Bind_front0(int, _Fn&& __fn)
	noexcept(is_nothrow_constructible_v<_Fd, _Fn>)
	: _M_fd(std::forward<_Fn>(__fn))
	{ }

      _Bind_front0(const _Bind_front0&) = default;
      _Bind_front0(_Bind_front0&&) = default;
      _Bind_front0& operator=(const _Bind_front0&) = default;
      _Bind_front0& operator=(_Bind_front0&&) = default;
      ~_Bind_front0() = default;

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<_Fd&, _CallArgs...>
	operator()(_CallArgs&&... __call_args) &
	noexcept(is_nothrow_invocable_v<_Fd&, _CallArgs...>)
	{ return std::invoke(_M_fd, std::forward<_CallArgs>(__call_args)...); }

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<const _Fd&, _CallArgs...>
	operator()(_CallArgs&&... __call_args) const &
	noexcept(is_nothrow_invocable_v<const _Fd&, _CallArgs...>)
	{ return std::invoke(_M_fd, std::forward<_CallArgs>(__call_args)...); }

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<_Fd, _CallArgs...>
	operator()(_CallArgs&&... __call_args) &&
	noexcept(is_nothrow_invocable_v<_Fd, _CallArgs...>)
	{
	  return std::invoke(std::move(_M_fd),
			     std::forward<_CallArgs>(__call_args)...);
	}

      template<typename... _CallArgs>
	constexpr
	invoke_result_t<const _Fd, _CallArgs...>
	operator()(_CallArgs&&... __call_args) const &&
	noexcept(is_nothrow_invocable_v<const _Fd, _CallArgs...>)
	{
	  return std::invoke(std::move(_M_fd),
			     std::forward<_CallArgs>(__call_args)...);
	}

    private:
      _Fd _M_fd;
    };

  template<typename _Fn, typename... _Args>
    using _Bind_front_t
      = __conditional_t<sizeof...(_Args) == 0, _Bind_front0<decay_t<_Fn>>,
			_Bind_front<decay_t<_Fn>, decay_t<_Args>...>>;

  /** Create call wrapper by partial application of arguments to function.
   *
   * The result of `std::bind_front(f, args...)` is a function object that
   * stores `f` and the bound arguments, `args...`. When that function
   * object is invoked with `call_args...` it returns the result of calling
   * `f(args..., call_args...)`.
   *
   *  @since C++20
   */
  template<typename _Fn, typename... _Args>
    constexpr _Bind_front_t<_Fn, _Args...>
    bind_front(_Fn&& __fn, _Args&&... __args)
    noexcept(is_nothrow_constructible_v<_Bind_front_t<_Fn, _Args...>,
					int, _Fn, _Args...>)
    {
      return _Bind_front_t<_Fn, _Args...>(0, std::forward<_Fn>(__fn),
					  std::forward<_Args>(__args)...);
    }
#endif // C++20

#if __cplusplus >= 201402L
  /// Generalized negator.
  template<typename _Fn>
    class _Not_fn
    {
      template<typename _Fn2, typename... _Args>
	using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type;

      template<typename _Tp>
	static decltype(!std::declval<_Tp>())
	_S_not() noexcept(noexcept(!std::declval<_Tp>()));

    public:
      template<typename _Fn2>
	constexpr
	_Not_fn(_Fn2&& __fn, int)
	: _M_fn(std::forward<_Fn2>(__fn)) { }

      _Not_fn(const _Not_fn& __fn) = default;
      _Not_fn(_Not_fn&& __fn) = default;
      ~_Not_fn() = default;

      // Macro to define operator() with given cv-qualifiers ref-qualifiers,
      // forwarding _M_fn and the function arguments with the same qualifiers,
      // and deducing the return type and exception-specification.
#define _GLIBCXX_NOT_FN_CALL_OP( _QUALS )				\
      template<typename... _Args>					\
	_GLIBCXX20_CONSTEXPR						\
	decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())		\
	operator()(_Args&&... __args) _QUALS				\
	noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value	\
	    && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()))	\
	{								\
	  return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn),	\
				std::forward<_Args>(__args)...);	\
	}
      _GLIBCXX_NOT_FN_CALL_OP( & )
      _GLIBCXX_NOT_FN_CALL_OP( const & )
      _GLIBCXX_NOT_FN_CALL_OP( && )
      _GLIBCXX_NOT_FN_CALL_OP( const && )
#undef _GLIBCXX_NOT_FN_CALL_OP

    private:
      _Fn _M_fn;
    };

  template<typename _Tp, typename _Pred>
    struct __is_byte_like : false_type { };

  template<typename _Tp>
    struct __is_byte_like<_Tp, equal_to<_Tp>>
    : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { };

  template<typename _Tp>
    struct __is_byte_like<_Tp, equal_to<void>>
    : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { };

#if __cplusplus >= 201703L
  // Declare std::byte (full definition is in <cstddef>).
  enum class byte : unsigned char;

  template<>
    struct __is_byte_like<byte, equal_to<byte>>
    : true_type { };

  template<>
    struct __is_byte_like<byte, equal_to<void>>
    : true_type { };

  // [func.not_fn] Function template not_fn
#define __cpp_lib_not_fn 201603L
  /** Wrap a function object to create one that negates its result.
   *
   * The function template `std::not_fn` creates a "forwarding call wrapper",
   * which is a function object that wraps another function object and
   * when called, forwards its arguments to the wrapped function object.
   *
   * The result of invoking the wrapper is the negation (using `!`) of
   * the wrapped function object.
   *
   *  @ingroup functors
   *  @since C++17
   */
  template<typename _Fn>
    _GLIBCXX20_CONSTEXPR
    inline auto
    not_fn(_Fn&& __fn)
    noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
    {
      return _Not_fn<std::decay_t<_Fn>>{std::forward<_Fn>(__fn), 0};
    }

  // Searchers

  template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>>
    class default_searcher
    {
    public:
      _GLIBCXX20_CONSTEXPR
      default_searcher(_ForwardIterator1 __pat_first,
		       _ForwardIterator1 __pat_last,
		       _BinaryPredicate __pred = _BinaryPredicate())
      : _M_m(__pat_first, __pat_last, std::move(__pred))
      { }

      template<typename _ForwardIterator2>
	_GLIBCXX20_CONSTEXPR
	pair<_ForwardIterator2, _ForwardIterator2>
	operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const
	{
	  _ForwardIterator2 __first_ret =
	    std::search(__first, __last, std::get<0>(_M_m), std::get<1>(_M_m),
			std::get<2>(_M_m));
	  auto __ret = std::make_pair(__first_ret, __first_ret);
	  if (__ret.first != __last)
	    std::advance(__ret.second, std::distance(std::get<0>(_M_m),
						     std::get<1>(_M_m)));
	  return __ret;
	}

    private:
      tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m;
    };

#if _GLIBCXX_HOSTED
#define __cpp_lib_boyer_moore_searcher 201603L

  template<typename _Key, typename _Tp, typename _Hash, typename _Pred>
    struct __boyer_moore_map_base
    {
      template<typename _RAIter>
	__boyer_moore_map_base(_RAIter __pat, size_t __patlen,
			       _Hash&& __hf, _Pred&& __pred)
	: _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) }
	{
	  if (__patlen > 0)
	    for (__diff_type __i = 0; __i < __patlen - 1; ++__i)
	      _M_bad_char[__pat[__i]] = __patlen - 1 - __i;
	}

      using __diff_type = _Tp;

      __diff_type
      _M_lookup(_Key __key, __diff_type __not_found) const
      {
	auto __iter = _M_bad_char.find(__key);
	if (__iter == _M_bad_char.end())
	  return __not_found;
	return __iter->second;
      }

      _Pred
      _M_pred() const { return _M_bad_char.key_eq(); }

      _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char;
    };

  template<typename _Tp, size_t _Len, typename _Pred>
    struct __boyer_moore_array_base
    {
      template<typename _RAIter, typename _Unused>
	__boyer_moore_array_base(_RAIter __pat, size_t __patlen,
				 _Unused&&, _Pred&& __pred)
	: _M_bad_char{ array<_Tp, _Len>{}, std::move(__pred) }
	{
	  std::get<0>(_M_bad_char).fill(__patlen);
	  if (__patlen > 0)
	    for (__diff_type __i = 0; __i < __patlen - 1; ++__i)
	      {
		auto __ch = __pat[__i];
		using _UCh = make_unsigned_t<decltype(__ch)>;
		auto __uch = static_cast<_UCh>(__ch);
		std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i;
	      }
	}

      using __diff_type = _Tp;

      template<typename _Key>
	__diff_type
	_M_lookup(_Key __key, __diff_type __not_found) const
	{
	  auto __ukey = static_cast<make_unsigned_t<_Key>>(__key);
	  if (__ukey >= _Len)
	    return __not_found;
	  return std::get<0>(_M_bad_char)[__ukey];
	}

      const _Pred&
      _M_pred() const { return std::get<1>(_M_bad_char); }

      tuple<array<_Tp, _Len>, _Pred> _M_bad_char;
    };

  // Use __boyer_moore_array_base when pattern consists of narrow characters
  // (or std::byte) and uses std::equal_to as the predicate.
  template<typename _RAIter, typename _Hash, typename _Pred,
           typename _Val = typename iterator_traits<_RAIter>::value_type,
	   typename _Diff = typename iterator_traits<_RAIter>::difference_type>
    using __boyer_moore_base_t
      = __conditional_t<__is_byte_like<_Val, _Pred>::value,
			__boyer_moore_array_base<_Diff, 256, _Pred>,
			__boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>;

  template<typename _RAIter, typename _Hash
	     = hash<typename iterator_traits<_RAIter>::value_type>,
	   typename _BinaryPredicate = equal_to<>>
    class boyer_moore_searcher
    : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>
    {
      using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>;
      using typename _Base::__diff_type;

    public:
      boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last,
			   _Hash __hf = _Hash(),
			   _BinaryPredicate __pred = _BinaryPredicate());

      template<typename _RandomAccessIterator2>
        pair<_RandomAccessIterator2, _RandomAccessIterator2>
	operator()(_RandomAccessIterator2 __first,
		   _RandomAccessIterator2 __last) const;

    private:
      bool
      _M_is_prefix(_RAIter __word, __diff_type __len,
		   __diff_type __pos)
      {
	const auto& __pred = this->_M_pred();
	__diff_type __suffixlen = __len - __pos;
	for (__diff_type __i = 0; __i < __suffixlen; ++__i)
	  if (!__pred(__word[__i], __word[__pos + __i]))
	    return false;
	return true;
      }

      __diff_type
      _M_suffix_length(_RAIter __word, __diff_type __len,
		       __diff_type __pos)
      {
	const auto& __pred = this->_M_pred();
	__diff_type __i = 0;
	while (__pred(__word[__pos - __i], __word[__len - 1 - __i])
	       && __i < __pos)
	  {
	    ++__i;
	  }
	return __i;
      }

      template<typename _Tp>
	__diff_type
	_M_bad_char_shift(_Tp __c) const
	{ return this->_M_lookup(__c, _M_pat_end - _M_pat); }

      _RAIter _M_pat;
      _RAIter _M_pat_end;
      _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix;
    };

  template<typename _RAIter, typename _Hash
	     = hash<typename iterator_traits<_RAIter>::value_type>,
	   typename _BinaryPredicate = equal_to<>>
    class boyer_moore_horspool_searcher
    : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>
    {
      using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>;
      using typename _Base::__diff_type;

    public:
      boyer_moore_horspool_searcher(_RAIter __pat,
				    _RAIter __pat_end,
				    _Hash __hf = _Hash(),
				    _BinaryPredicate __pred
				    = _BinaryPredicate())
      : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)),
	_M_pat(__pat), _M_pat_end(__pat_end)
      { }

      template<typename _RandomAccessIterator2>
        pair<_RandomAccessIterator2, _RandomAccessIterator2>
	operator()(_RandomAccessIterator2 __first,
		   _RandomAccessIterator2 __last) const
	{
	  const auto& __pred = this->_M_pred();
	  auto __patlen = _M_pat_end - _M_pat;
	  if (__patlen == 0)
	    return std::make_pair(__first, __first);
	  auto __len = __last - __first;
	  while (__len >= __patlen)
	    {
	      for (auto __scan = __patlen - 1;
		   __pred(__first[__scan], _M_pat[__scan]); --__scan)
		if (__scan == 0)
		  return std::make_pair(__first, __first + __patlen);
	      auto __shift = _M_bad_char_shift(__first[__patlen - 1]);
	      __len -= __shift;
	      __first += __shift;
	    }
	  return std::make_pair(__last, __last);
	}

    private:
      template<typename _Tp>
	__diff_type
	_M_bad_char_shift(_Tp __c) const
	{ return this->_M_lookup(__c, _M_pat_end - _M_pat); }

      _RAIter _M_pat;
      _RAIter _M_pat_end;
    };

  template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
    boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
    boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end,
			 _Hash __hf, _BinaryPredicate __pred)
    : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)),
      _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat)
    {
      auto __patlen = __pat_end - __pat;
      if (__patlen == 0)
	return;
      __diff_type __last_prefix = __patlen - 1;
      for (__diff_type __p = __patlen - 1; __p >= 0; --__p)
	{
	  if (_M_is_prefix(__pat, __patlen, __p + 1))
	    __last_prefix = __p + 1;
	  _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p);
	}
      for (__diff_type __p = 0; __p < __patlen - 1; ++__p)
	{
	  auto __slen = _M_suffix_length(__pat, __patlen, __p);
	  auto __pos = __patlen - 1 - __slen;
	  if (!__pred(__pat[__p - __slen], __pat[__pos]))
	    _M_good_suffix[__pos] = __patlen - 1 - __p + __slen;
	}
    }

  template<typename _RAIter, typename _Hash, typename _BinaryPredicate>
  template<typename _RandomAccessIterator2>
    pair<_RandomAccessIterator2, _RandomAccessIterator2>
    boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>::
    operator()(_RandomAccessIterator2 __first,
	       _RandomAccessIterator2 __last) const
    {
      auto __patlen = _M_pat_end - _M_pat;
      if (__patlen == 0)
	return std::make_pair(__first, __first);
      const auto& __pred = this->_M_pred();
      __diff_type __i = __patlen - 1;
      auto __stringlen = __last - __first;
      while (__i < __stringlen)
	{
	  __diff_type __j = __patlen - 1;
	  while (__j >= 0 && __pred(__first[__i], _M_pat[__j]))
	    {
	      --__i;
	      --__j;
	    }
	  if (__j < 0)
	    {
	      const auto __match = __first + __i + 1;
	      return std::make_pair(__match, __match + __patlen);
	    }
	  __i += std::max(_M_bad_char_shift(__first[__i]),
			  _M_good_suffix[__j]);
	}
      return std::make_pair(__last, __last);
    }
#endif // HOSTED

#endif // C++17
#endif // C++14
#endif // C++11

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // _GLIBCXX_FUNCTIONAL
