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

// Copyright (C) 2001-2025 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

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#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_algobase.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

#define __glibcxx_want_boyer_moore_searcher
#define __glibcxx_want_bind_front
#define __glibcxx_want_bind_back
#define __glibcxx_want_constexpr_functional
#define __glibcxx_want_invoke
#define __glibcxx_want_invoke_r
#define __glibcxx_want_move_only_function
#define __glibcxx_want_not_fn
#define __glibcxx_want_ranges
#define __glibcxx_want_reference_wrapper
#define __glibcxx_want_transparent_operators
#include <bits/version.h>

#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 { };

#ifdef __cpp_lib_invoke // C++ >= 17

  /** 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)...);
    }
#endif

#ifdef __cpp_lib_invoke_r // C++ >= 23

  /** 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 // __cpp_lib_invoke_r

  /// @cond undocumented

#if __cplusplus >= 201103L
  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
	  = __invoke_result_t<_Fn&, _Mu_type<_BArgs, _CallArgs>&&...>;

      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)...);
    }

#ifdef __cpp_lib_bind_front // C++ >= 20

  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)); }

#if __cpp_explicit_this_parameter
      template<typename _Self, typename... _CallArgs>
	constexpr
	invoke_result_t<__like_t<_Self, _Fd>, __like_t<_Self, _BoundArgs>..., _CallArgs...>
	operator()(this _Self&& __self, _CallArgs&&... __call_args)
	noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>,
					__like_t<_Self, _BoundArgs>..., _CallArgs...>)
	{
	  return _S_call(__like_t<_Self, _Bind_front>(__self), _BoundIndices(),
			 std::forward<_CallArgs>(__call_args)...);
	}
#else
      template<typename... _CallArgs>
	requires true
	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>
	requires true
	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>
	requires true
	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>
	requires true
	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)...);
	}

      template<typename... _CallArgs>
	void operator()(_CallArgs&&...) & = delete;

      template<typename... _CallArgs>
	void operator()(_CallArgs&&...) const & = delete;

      template<typename... _CallArgs>
	void operator()(_CallArgs&&...) && = delete;

      template<typename... _CallArgs>
	void operator()(_CallArgs&&...) const && = delete;
#endif

    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)...);
	}

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

  template<typename _Fn, typename... _Args>
    using _Bind_front_t = _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 // __cpp_lib_bind_front

#ifdef __cpp_lib_bind_back // C++ >= 23
  template<typename _Fd, typename... _BoundArgs>
    struct _Bind_back
    {
      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_back(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)); }

      template<typename _Self, typename... _CallArgs>
	constexpr
	invoke_result_t<__like_t<_Self, _Fd>, _CallArgs..., __like_t<_Self, _BoundArgs>...>
	operator()(this _Self&& __self, _CallArgs&&... __call_args)
	noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>,
					_CallArgs..., __like_t<_Self, _BoundArgs>...>)
	{
	  return _S_call(__like_t<_Self, _Bind_back>(__self), _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::forward<_CallArgs>(__call_args)...,
	      std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...);
	}

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

  template<typename _Fn, typename... _Args>
    using _Bind_back_t = _Bind_back<decay_t<_Fn>, decay_t<_Args>...>;

  /** Create call wrapper by partial application of arguments to function.
   *
   * The result of `std::bind_back(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(call_args..., args...)`.
   *
   *  @since C++23
   */
  template<typename _Fn, typename... _Args>
    constexpr _Bind_back_t<_Fn, _Args...>
    bind_back(_Fn&& __fn, _Args&&... __args)
    noexcept(is_nothrow_constructible_v<_Bind_back_t<_Fn, _Args...>,
					int, _Fn, _Args...>)
    {
      return _Bind_back_t<_Fn, _Args...>(0, std::forward<_Fn>(__fn),
					 std::forward<_Args>(__args)...);
    }
#endif // __cpp_lib_bind_back

#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,					\
	       typename = enable_if_t<__is_invocable<_Fn _QUALS, _Args...>::value>> \
	_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)...);	\
	}								\
									\
      template<typename... _Args,					\
	       typename = enable_if_t<!__is_invocable<_Fn _QUALS, _Args...>::value>> \
	void operator()(_Args&&... __args) _QUALS = delete;

      _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 { };
#endif

  // [func.not_fn] Function template not_fn
#ifdef __cpp_lib_not_fn // C++ >= 17
  /** 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};
    }
#endif

#if __cplusplus >= 201703L
  // 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;
    };

#ifdef __cpp_lib_boyer_moore_searcher // C++ >= 17 && HOSTED

  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 // __cpp_lib_boyer_moore_searcher

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

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // _GLIBCXX_FUNCTIONAL
