// TR1 functional header -*- C++ -*-

// Copyright (C) 2004-2021 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/>.

/** @file tr1/functional
 *  This is a TR1 C++ Library header.
 */

#ifndef _GLIBCXX_TR1_FUNCTIONAL
#define _GLIBCXX_TR1_FUNCTIONAL 1

#pragma GCC system_header

#include <functional> // for std::_Placeholder, std::_Bind, std::_Bind_result

#include <typeinfo>
#include <new>
#include <tr1/tuple>
#include <tr1/type_traits>
#include <bits/stringfwd.h>
#include <tr1/functional_hash.h>
#include <ext/type_traits.h>
#include <bits/move.h> // for std::__addressof

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if __cplusplus < 201103L
  // In C++98 mode, <functional> doesn't declare std::placeholders::_1 etc.
  // because they are not reserved names in C++98. However, they are reserved
  // by <tr1/functional> so we can declare them here, in order to redeclare
  // them in the std::tr1::placeholders namespace below.
  namespace placeholders
  {
    extern const _Placeholder<1> _1;
    extern const _Placeholder<2> _2;
    extern const _Placeholder<3> _3;
    extern const _Placeholder<4> _4;
    extern const _Placeholder<5> _5;
    extern const _Placeholder<6> _6;
    extern const _Placeholder<7> _7;
    extern const _Placeholder<8> _8;
    extern const _Placeholder<9> _9;
    extern const _Placeholder<10> _10;
    extern const _Placeholder<11> _11;
    extern const _Placeholder<12> _12;
    extern const _Placeholder<13> _13;
    extern const _Placeholder<14> _14;
    extern const _Placeholder<15> _15;
    extern const _Placeholder<16> _16;
    extern const _Placeholder<17> _17;
    extern const _Placeholder<18> _18;
    extern const _Placeholder<19> _19;
    extern const _Placeholder<20> _20;
    extern const _Placeholder<21> _21;
    extern const _Placeholder<22> _22;
    extern const _Placeholder<23> _23;
    extern const _Placeholder<24> _24;
    extern const _Placeholder<25> _25;
    extern const _Placeholder<26> _26;
    extern const _Placeholder<27> _27;
    extern const _Placeholder<28> _28;
    extern const _Placeholder<29> _29;
  }
#endif // C++98

namespace tr1
{
  template<typename _MemberPointer>
    class _Mem_fn;
  template<typename _Tp, typename _Class>
    _Mem_fn<_Tp _Class::*>
    mem_fn(_Tp _Class::*);

  /**
   *  Actual implementation of _Has_result_type, which uses SFINAE to
   *  determine if the type _Tp has a publicly-accessible member type
   *  result_type.
  */
  template<typename _Tp>
    class _Has_result_type_helper : __sfinae_types
    {
      template<typename _Up>
        struct _Wrap_type
	{ };

      template<typename _Up>
        static __one __test(_Wrap_type<typename _Up::result_type>*);

      template<typename _Up>
        static __two __test(...);

    public:
      static const bool value = sizeof(__test<_Tp>(0)) == 1;
    };

  template<typename _Tp>
    struct _Has_result_type
    : integral_constant<bool,
	      _Has_result_type_helper<typename remove_cv<_Tp>::type>::value>
    { };

  /**
   *  
  */
  /// If we have found a result_type, extract it.
  template<bool _Has_result_type, typename _Functor>
    struct _Maybe_get_result_type
    { };

  template<typename _Functor>
    struct _Maybe_get_result_type<true, _Functor>
    {
      typedef typename _Functor::result_type result_type;
    };

  /**
   *  Base class for any function object that has a weak result type, as
   *  defined in 3.3/3 of TR1.
  */
  template<typename _Functor>
    struct _Weak_result_type_impl
    : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
    {
    };

  /// Retrieve the result type for a function type.
  template<typename _Res, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res(_ArgTypes...)>
    {
      typedef _Res result_type;
    };

  /// Retrieve the result type for a function reference.
  template<typename _Res, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
    {
      typedef _Res result_type;
    };

  /// Retrieve the result type for a function pointer.
  template<typename _Res, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
    {
      typedef _Res result_type;
    };

  /// Retrieve result type for a member function pointer. 
  template<typename _Res, typename _Class, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
    {
      typedef _Res result_type;
    };

  /// Retrieve result type for a const member function pointer. 
  template<typename _Res, typename _Class, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
    {
      typedef _Res result_type;
    };

  /// Retrieve result type for a volatile member function pointer. 
  template<typename _Res, typename _Class, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
    {
      typedef _Res result_type;
    };

  /// Retrieve result type for a const volatile member function pointer. 
  template<typename _Res, typename _Class, typename... _ArgTypes> 
    struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile>
    {
      typedef _Res result_type;
    };

  /**
   *  Strip top-level cv-qualifiers from the function object and let
   *  _Weak_result_type_impl perform the real work.
  */
  template<typename _Functor>
    struct _Weak_result_type
    : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
    {
    };

  template<typename _Signature>
    class result_of;

  /**
   *  Actual implementation of result_of. When _Has_result_type is
   *  true, gets its result from _Weak_result_type. Otherwise, uses
   *  the function object's member template result to extract the
   *  result type.
  */
  template<bool _Has_result_type, typename _Signature>
    struct _Result_of_impl;

  // Handle member data pointers using _Mem_fn's logic
  template<typename _Res, typename _Class, typename _T1>
    struct _Result_of_impl<false, _Res _Class::*(_T1)>
    {
      typedef typename _Mem_fn<_Res _Class::*>
                ::template _Result_type<_T1>::type type;
    };

  /**
   * Determine whether we can determine a result type from @c Functor 
   * alone.
   */ 
  template<typename _Functor, typename... _ArgTypes>
    class result_of<_Functor(_ArgTypes...)>
    : public _Result_of_impl<
               _Has_result_type<_Weak_result_type<_Functor> >::value,
               _Functor(_ArgTypes...)>
    {
    };

  /// We already know the result type for @c Functor; use it.
  template<typename _Functor, typename... _ArgTypes>
    struct _Result_of_impl<true, _Functor(_ArgTypes...)>
    {
      typedef typename _Weak_result_type<_Functor>::result_type type;
    };

  /**
   * We need to compute the result type for this invocation the hard 
   * way.
   */
  template<typename _Functor, typename... _ArgTypes>
    struct _Result_of_impl<false, _Functor(_ArgTypes...)>
    {
      typedef typename _Functor
                ::template result<_Functor(_ArgTypes...)>::type type;
    };

  /**
   * It is unsafe to access ::result when there are zero arguments, so we 
   * return @c void instead.
   */
  template<typename _Functor>
    struct _Result_of_impl<false, _Functor()>
    {
      typedef void type;
    };

  /// Determines if the type _Tp derives from unary_function.
  template<typename _Tp>
    struct _Derives_from_unary_function : __sfinae_types
    {
    private:
      template<typename _T1, typename _Res>
        static __one __test(const volatile unary_function<_T1, _Res>*);

      // It's tempting to change "..." to const volatile void*, but
      // that fails when _Tp is a function type.
      static __two __test(...);

    public:
      static const bool value = sizeof(__test((_Tp*)0)) == 1;
    };

  /// Determines if the type _Tp derives from binary_function.
  template<typename _Tp>
    struct _Derives_from_binary_function : __sfinae_types
    {
    private:
      template<typename _T1, typename _T2, typename _Res>
        static __one __test(const volatile binary_function<_T1, _T2, _Res>*);

      // It's tempting to change "..." to const volatile void*, but
      // that fails when _Tp is a function type.
      static __two __test(...);

    public:
      static const bool value = sizeof(__test((_Tp*)0)) == 1;
    };

  /// Turns a function type into a function pointer type
  template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value>
    struct _Function_to_function_pointer
    {
      typedef _Tp type;
    };

  template<typename _Tp>
    struct _Function_to_function_pointer<_Tp, true>
    {
      typedef _Tp* type;
    };

  /**
   * Invoke a function object, which may be either a member pointer or a
   * function object. The first parameter will tell which.
   */
  template<typename _Functor, typename... _Args>
    inline
    typename __gnu_cxx::__enable_if<
             (!is_member_pointer<_Functor>::value
              && !is_function<_Functor>::value
              && !is_function<typename remove_pointer<_Functor>::type>::value),
             typename result_of<_Functor(_Args...)>::type
           >::__type
    __invoke(_Functor& __f, _Args&... __args)
    {
      return __f(__args...);
    }

  template<typename _Functor, typename... _Args>
    inline
    typename __gnu_cxx::__enable_if<
             (is_member_pointer<_Functor>::value
              && !is_function<_Functor>::value
              && !is_function<typename remove_pointer<_Functor>::type>::value),
             typename result_of<_Functor(_Args...)>::type
           >::__type
    __invoke(_Functor& __f, _Args&... __args)
    {
      return mem_fn(__f)(__args...);
    }

  // To pick up function references (that will become function pointers)
  template<typename _Functor, typename... _Args>
    inline
    typename __gnu_cxx::__enable_if<
             (is_pointer<_Functor>::value
              && is_function<typename remove_pointer<_Functor>::type>::value),
             typename result_of<_Functor(_Args...)>::type
           >::__type
    __invoke(_Functor __f, _Args&... __args)
    {
      return __f(__args...);
    }

  /**
   *  Knowing which of unary_function and binary_function _Tp derives
   *  from, derives from the same and ensures that reference_wrapper
   *  will have a weak result type. See cases below.
   */
  template<bool _Unary, bool _Binary, typename _Tp>
    struct _Reference_wrapper_base_impl;

  // Not a unary_function or binary_function, so try a weak result type.
  template<typename _Tp>
    struct _Reference_wrapper_base_impl<false, false, _Tp>
    : _Weak_result_type<_Tp>
    { };

  // unary_function but not binary_function
  template<typename _Tp>
    struct _Reference_wrapper_base_impl<true, false, _Tp>
    : unary_function<typename _Tp::argument_type,
		     typename _Tp::result_type>
    { };

  // binary_function but not unary_function
  template<typename _Tp>
    struct _Reference_wrapper_base_impl<false, true, _Tp>
    : binary_function<typename _Tp::first_argument_type,
		      typename _Tp::second_argument_type,
		      typename _Tp::result_type>
    { };

  // Both unary_function and binary_function. Import result_type to
  // avoid conflicts.
   template<typename _Tp>
    struct _Reference_wrapper_base_impl<true, true, _Tp>
    : unary_function<typename _Tp::argument_type,
		     typename _Tp::result_type>,
      binary_function<typename _Tp::first_argument_type,
		      typename _Tp::second_argument_type,
		      typename _Tp::result_type>
    {
      typedef typename _Tp::result_type result_type;
    };

  /**
   *  Derives from unary_function or binary_function when it
   *  can. Specializations handle all of the easy cases. The primary
   *  template determines what to do with a class type, which may
   *  derive from both unary_function and binary_function.
  */
  template<typename _Tp>
    struct _Reference_wrapper_base
    : _Reference_wrapper_base_impl<
      _Derives_from_unary_function<_Tp>::value,
      _Derives_from_binary_function<_Tp>::value,
      _Tp>
    { };

  // - a function type (unary)
  template<typename _Res, typename _T1>
    struct _Reference_wrapper_base<_Res(_T1)>
    : unary_function<_T1, _Res>
    { };

  // - a function type (binary)
  template<typename _Res, typename _T1, typename _T2>
    struct _Reference_wrapper_base<_Res(_T1, _T2)>
    : binary_function<_T1, _T2, _Res>
    { };

  // - a function pointer type (unary)
  template<typename _Res, typename _T1>
    struct _Reference_wrapper_base<_Res(*)(_T1)>
    : unary_function<_T1, _Res>
    { };

  // - a function pointer type (binary)
  template<typename _Res, typename _T1, typename _T2>
    struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
    : binary_function<_T1, _T2, _Res>
    { };

  // - a pointer to member function type (unary, no qualifiers)
  template<typename _Res, typename _T1>
    struct _Reference_wrapper_base<_Res (_T1::*)()>
    : unary_function<_T1*, _Res>
    { };

  // - a pointer to member function type (binary, no qualifiers)
  template<typename _Res, typename _T1, typename _T2>
    struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
    : binary_function<_T1*, _T2, _Res>
    { };

  // - a pointer to member function type (unary, const)
  template<typename _Res, typename _T1>
    struct _Reference_wrapper_base<_Res (_T1::*)() const>
    : unary_function<const _T1*, _Res>
    { };

  // - a pointer to member function type (binary, const)
  template<typename _Res, typename _T1, typename _T2>
    struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
    : binary_function<const _T1*, _T2, _Res>
    { };

  // - a pointer to member function type (unary, volatile)
  template<typename _Res, typename _T1>
    struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
    : unary_function<volatile _T1*, _Res>
    { };

  // - a pointer to member function type (binary, volatile)
  template<typename _Res, typename _T1, typename _T2>
    struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
    : binary_function<volatile _T1*, _T2, _Res>
    { };

  // - a pointer to member function type (unary, const volatile)
  template<typename _Res, typename _T1>
    struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
    : unary_function<const volatile _T1*, _Res>
    { };

  // - a pointer to member function type (binary, const volatile)
  template<typename _Res, typename _T1, typename _T2>
    struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
    : binary_function<const volatile _T1*, _T2, _Res>
    { };

  /// reference_wrapper
  template<typename _Tp>
    class reference_wrapper
    : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
    {
      // If _Tp is a function type, we can't form result_of<_Tp(...)>,
      // so turn it into a function pointer type.
      typedef typename _Function_to_function_pointer<_Tp>::type
        _M_func_type;

      _Tp* _M_data;
    public:
      typedef _Tp type;

      explicit
      reference_wrapper(_Tp& __indata)
      : _M_data(std::__addressof(__indata))
      { }

      reference_wrapper(const reference_wrapper<_Tp>& __inref):
      _M_data(__inref._M_data)
      { }

      reference_wrapper&
      operator=(const reference_wrapper<_Tp>& __inref)
      {
        _M_data = __inref._M_data;
        return *this;
      }

      operator _Tp&() const
      { return this->get(); }

      _Tp&
      get() const
      { return *_M_data; }

      template<typename... _Args>
        typename result_of<_M_func_type(_Args...)>::type
        operator()(_Args&... __args) const
        {
	  return __invoke(get(), __args...);
	}
    };


  // Denotes a reference should be taken to a variable.
  template<typename _Tp>
    inline reference_wrapper<_Tp>
    ref(_Tp& __t)
    { return reference_wrapper<_Tp>(__t); }

  // Denotes a const reference should be taken to a variable.
  template<typename _Tp>
    inline reference_wrapper<const _Tp>
    cref(const _Tp& __t)
    { return reference_wrapper<const _Tp>(__t); }

  template<typename _Tp>
    inline reference_wrapper<_Tp>
    ref(reference_wrapper<_Tp> __t)
    { return ref(__t.get()); }

  template<typename _Tp>
    inline reference_wrapper<const _Tp>
    cref(reference_wrapper<_Tp> __t)
    { return cref(__t.get()); }

  template<typename _Tp, bool>
    struct _Mem_fn_const_or_non
    {
      typedef const _Tp& type;
    };

  template<typename _Tp>
    struct _Mem_fn_const_or_non<_Tp, false>
    {
      typedef _Tp& type;
    };

  /**
   * Derives from @c unary_function or @c binary_function, or perhaps
   * nothing, depending on the number of arguments provided. The
   * primary template is the basis case, which derives nothing.
   */
  template<typename _Res, typename... _ArgTypes> 
    struct _Maybe_unary_or_binary_function { };

  /// Derives from @c unary_function, as appropriate. 
  template<typename _Res, typename _T1> 
    struct _Maybe_unary_or_binary_function<_Res, _T1>
    : std::unary_function<_T1, _Res> { };

  /// Derives from @c binary_function, as appropriate. 
  template<typename _Res, typename _T1, typename _T2> 
    struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
    : std::binary_function<_T1, _T2, _Res> { };

  /// Implementation of @c mem_fn for member function pointers.
  template<typename _Res, typename _Class, typename... _ArgTypes>
    class _Mem_fn<_Res (_Class::*)(_ArgTypes...)>
    : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>
    {
      typedef _Res (_Class::*_Functor)(_ArgTypes...);

      template<typename _Tp>
        _Res
        _M_call(_Tp& __object, const volatile _Class *, 
                _ArgTypes... __args) const
        { return (__object.*__pmf)(__args...); }

      template<typename _Tp>
        _Res
        _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
        { return ((*__ptr).*__pmf)(__args...); }

    public:
      typedef _Res result_type;

      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }

      // Handle objects
      _Res
      operator()(_Class& __object, _ArgTypes... __args) const
      { return (__object.*__pmf)(__args...); }

      // Handle pointers
      _Res
      operator()(_Class* __object, _ArgTypes... __args) const
      { return (__object->*__pmf)(__args...); }

      // Handle smart pointers, references and pointers to derived
      template<typename _Tp>
        _Res
	operator()(_Tp& __object, _ArgTypes... __args) const
        { return _M_call(__object, &__object, __args...); }

    private:
      _Functor __pmf;
    };

  /// Implementation of @c mem_fn for const member function pointers.
  template<typename _Res, typename _Class, typename... _ArgTypes>
    class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const>
    : public _Maybe_unary_or_binary_function<_Res, const _Class*, 
					     _ArgTypes...>
    {
      typedef _Res (_Class::*_Functor)(_ArgTypes...) const;

      template<typename _Tp>
        _Res
        _M_call(_Tp& __object, const volatile _Class *, 
                _ArgTypes... __args) const
        { return (__object.*__pmf)(__args...); }

      template<typename _Tp>
        _Res
        _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
        { return ((*__ptr).*__pmf)(__args...); }

    public:
      typedef _Res result_type;

      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }

      // Handle objects
      _Res
      operator()(const _Class& __object, _ArgTypes... __args) const
      { return (__object.*__pmf)(__args...); }

      // Handle pointers
      _Res
      operator()(const _Class* __object, _ArgTypes... __args) const
      { return (__object->*__pmf)(__args...); }

      // Handle smart pointers, references and pointers to derived
      template<typename _Tp>
        _Res operator()(_Tp& __object, _ArgTypes... __args) const
        { return _M_call(__object, &__object, __args...); }

    private:
      _Functor __pmf;
    };

  /// Implementation of @c mem_fn for volatile member function pointers.
  template<typename _Res, typename _Class, typename... _ArgTypes>
    class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile>
    : public _Maybe_unary_or_binary_function<_Res, volatile _Class*, 
					     _ArgTypes...>
    {
      typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;

      template<typename _Tp>
        _Res
        _M_call(_Tp& __object, const volatile _Class *, 
                _ArgTypes... __args) const
        { return (__object.*__pmf)(__args...); }

      template<typename _Tp>
        _Res
        _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
        { return ((*__ptr).*__pmf)(__args...); }

    public:
      typedef _Res result_type;

      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }

      // Handle objects
      _Res
      operator()(volatile _Class& __object, _ArgTypes... __args) const
      { return (__object.*__pmf)(__args...); }

      // Handle pointers
      _Res
      operator()(volatile _Class* __object, _ArgTypes... __args) const
      { return (__object->*__pmf)(__args...); }

      // Handle smart pointers, references and pointers to derived
      template<typename _Tp>
        _Res
	operator()(_Tp& __object, _ArgTypes... __args) const
        { return _M_call(__object, &__object, __args...); }

    private:
      _Functor __pmf;
    };

  /// Implementation of @c mem_fn for const volatile member function pointers.
  template<typename _Res, typename _Class, typename... _ArgTypes>
    class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile>
    : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*, 
					     _ArgTypes...>
    {
      typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;

      template<typename _Tp>
        _Res
        _M_call(_Tp& __object, const volatile _Class *, 
                _ArgTypes... __args) const
        { return (__object.*__pmf)(__args...); }

      template<typename _Tp>
        _Res
        _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
        { return ((*__ptr).*__pmf)(__args...); }

    public:
      typedef _Res result_type;

      explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }

      // Handle objects
      _Res 
      operator()(const volatile _Class& __object, _ArgTypes... __args) const
      { return (__object.*__pmf)(__args...); }

      // Handle pointers
      _Res 
      operator()(const volatile _Class* __object, _ArgTypes... __args) const
      { return (__object->*__pmf)(__args...); }

      // Handle smart pointers, references and pointers to derived
      template<typename _Tp>
        _Res operator()(_Tp& __object, _ArgTypes... __args) const
        { return _M_call(__object, &__object, __args...); }

    private:
      _Functor __pmf;
    };


  template<typename _Res, typename _Class>
    class _Mem_fn<_Res _Class::*>
    {
      // This bit of genius is due to Peter Dimov, improved slightly by
      // Douglas Gregor.
      template<typename _Tp>
        _Res&
        _M_call(_Tp& __object, _Class *) const
        { return __object.*__pm; }

      template<typename _Tp, typename _Up>
        _Res&
        _M_call(_Tp& __object, _Up * const *) const
        { return (*__object).*__pm; }

      template<typename _Tp, typename _Up>
        const _Res&
        _M_call(_Tp& __object, const _Up * const *) const
        { return (*__object).*__pm; }

      template<typename _Tp>
        const _Res&
        _M_call(_Tp& __object, const _Class *) const
        { return __object.*__pm; }

      template<typename _Tp>
        const _Res&
        _M_call(_Tp& __ptr, const volatile void*) const
        { return (*__ptr).*__pm; }

      template<typename _Tp> static _Tp& __get_ref();

      template<typename _Tp>
        static __sfinae_types::__one __check_const(_Tp&, _Class*);
      template<typename _Tp, typename _Up>
        static __sfinae_types::__one __check_const(_Tp&, _Up * const *);
      template<typename _Tp, typename _Up>
        static __sfinae_types::__two __check_const(_Tp&, const _Up * const *);
      template<typename _Tp>
        static __sfinae_types::__two __check_const(_Tp&, const _Class*);
      template<typename _Tp>
        static __sfinae_types::__two __check_const(_Tp&, const volatile void*);

    public:
      template<typename _Tp>
        struct _Result_type
	: _Mem_fn_const_or_non<_Res,
	  (sizeof(__sfinae_types::__two)
	   == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
        { };

      template<typename _Signature>
        struct result;

      template<typename _CVMem, typename _Tp>
        struct result<_CVMem(_Tp)>
	: public _Result_type<_Tp> { };

      template<typename _CVMem, typename _Tp>
        struct result<_CVMem(_Tp&)>
	: public _Result_type<_Tp> { };

      explicit
      _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { }

      // Handle objects
      _Res&
      operator()(_Class& __object) const
      { return __object.*__pm; }

      const _Res&
      operator()(const _Class& __object) const
      { return __object.*__pm; }

      // Handle pointers
      _Res&
      operator()(_Class* __object) const
      { return __object->*__pm; }

      const _Res&
      operator()(const _Class* __object) const
      { return __object->*__pm; }

      // Handle smart pointers and derived
      template<typename _Tp>
        typename _Result_type<_Tp>::type
        operator()(_Tp& __unknown) const
        { return _M_call(__unknown, &__unknown); }

    private:
      _Res _Class::*__pm;
    };

  /**
   *  @brief Returns a function object that forwards to the member
   *  pointer @a pm.
   */
  template<typename _Tp, typename _Class>
    inline _Mem_fn<_Tp _Class::*>
    mem_fn(_Tp _Class::* __pm)
    {
      return _Mem_fn<_Tp _Class::*>(__pm);
    }

  /**
   *  @brief Determines if the given type _Tp is a function object
   *  should be treated as a subexpression when evaluating calls to
   *  function objects returned by bind(). [TR1 3.6.1]
   */
  template<typename _Tp>
    struct is_bind_expression
    { static const bool value = false; };

  template<typename _Tp>
    const bool is_bind_expression<_Tp>::value;

  /**
   *  @brief Determines if the given type _Tp is a placeholder in a
   *  bind() expression and, if so, which placeholder it is. [TR1 3.6.2]
   */
  template<typename _Tp>
    struct is_placeholder
    { static const int value = 0; };

  template<typename _Tp>
    const int is_placeholder<_Tp>::value;

  /// The type of placeholder objects defined by libstdc++.
  using ::std::_Placeholder;

  /** @namespace std::tr1::placeholders
   *  @brief Sub-namespace for tr1/functional.
   */
  namespace placeholders
  {
    // The C++11 std::placeholders are already exported from the library.
    // Reusing them here avoids needing to export additional symbols for
    // the TR1 placeholders, and avoids ODR violations due to defining
    // them with internal linkage (as we used to do).
    using namespace ::std::placeholders;
  }

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

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

  /**
   * Stores a tuple of indices. Used by bind() to extract the elements
   * in a tuple. 
   */
  template<int... _Indexes>
    struct _Index_tuple { };

  /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
  template<std::size_t _Num, typename _Tuple = _Index_tuple<> >
    struct _Build_index_tuple;
 
  template<std::size_t _Num, int... _Indexes> 
    struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> >
    : _Build_index_tuple<_Num - 1, 
                         _Index_tuple<_Indexes..., sizeof...(_Indexes)> >
    {
    };

  template<int... _Indexes>
    struct _Build_index_tuple<0, _Index_tuple<_Indexes...> >
    {
      typedef _Index_tuple<_Indexes...> __type;
    };

  /** 
   * Used by _Safe_tuple_element to indicate that there is no tuple
   * element at this position.
   */
  struct _No_tuple_element;

  /**
   * Implementation helper for _Safe_tuple_element. This primary
   * template handles the case where it is safe to use @c
   * tuple_element.
   */
  template<int __i, typename _Tuple, bool _IsSafe>
    struct _Safe_tuple_element_impl
    : tuple_element<__i, _Tuple> { };

  /**
   * Implementation helper for _Safe_tuple_element. This partial
   * specialization handles the case where it is not safe to use @c
   * tuple_element. We just return @c _No_tuple_element.
   */
  template<int __i, typename _Tuple>
    struct _Safe_tuple_element_impl<__i, _Tuple, false>
    {
      typedef _No_tuple_element type;
    };

  /**
   * Like tuple_element, but returns @c _No_tuple_element when
   * tuple_element would return an error.
   */
 template<int __i, typename _Tuple>
   struct _Safe_tuple_element
   : _Safe_tuple_element_impl<__i, _Tuple, 
                              (__i >= 0 && __i < tuple_size<_Tuple>::value)>
   {
   };

  /**
   *  Maps an argument to bind() into an actual argument to the bound
   *  function object [TR1 3.6.3/5]. 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. [TR1 3.6.3/5 bullet 1]
   */
  template<typename _Tp>
    class _Mu<reference_wrapper<_Tp>, false, false>
    {
    public:
      typedef _Tp& result_type;

      /* 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>
        result_type
        operator()(_CVRef& __arg, const _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). [TR1 3.6.3/5 bullet 2]
   */
  template<typename _Arg>
    class _Mu<_Arg, true, false>
    {
    public:
      template<typename _Signature> class result;

      // Determine the result type when we pass the arguments along. This
      // involves passing along the cv-qualifiers placed on _Mu and
      // unwrapping the argument bundle.
      template<typename _CVMu, typename _CVArg, typename... _Args>
        class result<_CVMu(_CVArg, tuple<_Args...>)>
	: public result_of<_CVArg(_Args...)> { };

      template<typename _CVArg, typename... _Args>
        typename result_of<_CVArg(_Args...)>::type
        operator()(_CVArg& __arg,
		   const tuple<_Args...>& __tuple) const volatile
        {
	  // 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, int... _Indexes>
        typename result_of<_CVArg(_Args...)>::type
        __call(_CVArg& __arg, const tuple<_Args...>& __tuple,
	       const _Index_tuple<_Indexes...>&) const volatile
        {
	  return __arg(tr1::get<_Indexes>(__tuple)...);
	}
    };

  /**
   *  If the argument is a placeholder for the Nth argument, returns
   *  a reference to the Nth argument to the bind function object.
   *  [TR1 3.6.3/5 bullet 3]
   */
  template<typename _Arg>
    class _Mu<_Arg, false, true>
    {
    public:
      template<typename _Signature> class result;

      template<typename _CVMu, typename _CVArg, typename _Tuple>
        class result<_CVMu(_CVArg, _Tuple)>
        {
	  // Add a reference, if it hasn't already been done for us.
	  // This allows us to be a little bit sloppy in constructing
	  // the tuple that we pass to result_of<...>.
	  typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value
						- 1), _Tuple>::type
	    __base_type;

	public:
	  typedef typename add_reference<__base_type>::type type;
	};

      template<typename _Tuple>
        typename result<_Mu(_Arg, _Tuple)>::type
        operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile
        {
	  return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple);
	}
    };

  /**
   *  If the argument is just a value, returns a reference to that
   *  value. The cv-qualifiers on the reference are the same as the
   *  cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4]
   */
  template<typename _Arg>
    class _Mu<_Arg, false, false>
    {
    public:
      template<typename _Signature> struct result;

      template<typename _CVMu, typename _CVArg, typename _Tuple>
        struct result<_CVMu(_CVArg, _Tuple)>
        {
	  typedef typename add_reference<_CVArg>::type type;
	};

      // Pick up the cv-qualifiers of the argument
      template<typename _CVArg, typename _Tuple>
        _CVArg&
        operator()(_CVArg& __arg, const _Tuple&) const volatile
        { return __arg; }
    };

  /**
   *  Maps member pointers into instances of _Mem_fn but leaves all
   *  other function objects untouched. Used by tr1::bind(). The
   *  primary template handles the non--member-pointer case.
   */
  template<typename _Tp>
    struct _Maybe_wrap_member_pointer
    {
      typedef _Tp type;
      
      static const _Tp&
      __do_wrap(const _Tp& __x)
      { return __x; }
    };

  /**
   *  Maps member pointers into instances of _Mem_fn but leaves all
   *  other function objects untouched. Used by tr1::bind(). This
   *  partial specialization handles the member pointer case.
   */
  template<typename _Tp, typename _Class>
    struct _Maybe_wrap_member_pointer<_Tp _Class::*>
    {
      typedef _Mem_fn<_Tp _Class::*> type;
      
      static type
      __do_wrap(_Tp _Class::* __pm)
      { return type(__pm); }
    };

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

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

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

      // Call unqualified
      template<typename... _Args, int... _Indexes>
        typename result_of<
                   _Functor(typename result_of<_Mu<_Bound_args> 
                            (_Bound_args, tuple<_Args...>)>::type...)
                 >::type
        __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

      // Call as const
      template<typename... _Args, int... _Indexes>
        typename result_of<
                   const _Functor(typename result_of<_Mu<_Bound_args> 
                                    (const _Bound_args, tuple<_Args...>)
                                  >::type...)>::type
        __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

      // Call as volatile
      template<typename... _Args, int... _Indexes>
        typename result_of<
                   volatile _Functor(typename result_of<_Mu<_Bound_args> 
                                    (volatile _Bound_args, tuple<_Args...>)
                                  >::type...)>::type
        __call(const tuple<_Args...>& __args, 
               _Index_tuple<_Indexes...>) volatile
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

      // Call as const volatile
      template<typename... _Args, int... _Indexes>
        typename result_of<
                   const volatile _Functor(typename result_of<_Mu<_Bound_args> 
                                    (const volatile _Bound_args, 
                                     tuple<_Args...>)
                                  >::type...)>::type
        __call(const tuple<_Args...>& __args, 
               _Index_tuple<_Indexes...>) const volatile
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

     public:
      explicit _Bind(_Functor __f, _Bound_args... __bound_args)
        : _M_f(__f), _M_bound_args(__bound_args...) { }

      // Call unqualified
      template<typename... _Args>
        typename result_of<
                   _Functor(typename result_of<_Mu<_Bound_args> 
                            (_Bound_args, tuple<_Args...>)>::type...)
                 >::type
        operator()(_Args&... __args)
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }

      // Call as const
      template<typename... _Args>
        typename result_of<
                   const _Functor(typename result_of<_Mu<_Bound_args> 
                            (const _Bound_args, tuple<_Args...>)>::type...)
                 >::type
        operator()(_Args&... __args) const
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }


      // Call as volatile
      template<typename... _Args>
        typename result_of<
                   volatile _Functor(typename result_of<_Mu<_Bound_args> 
                            (volatile _Bound_args, tuple<_Args...>)>::type...)
                 >::type
        operator()(_Args&... __args) volatile
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }


      // Call as const volatile
      template<typename... _Args>
        typename result_of<
                   const volatile _Functor(typename result_of<_Mu<_Bound_args> 
                            (const volatile _Bound_args, 
                             tuple<_Args...>)>::type...)
                 >::type
        operator()(_Args&... __args) const volatile
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }
    };

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

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

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

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

      // Call as const
      template<typename... _Args, int... _Indexes>
        _Result
        __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

      // Call as volatile
      template<typename... _Args, int... _Indexes>
        _Result
        __call(const tuple<_Args...>& __args, 
               _Index_tuple<_Indexes...>) volatile
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

      // Call as const volatile
      template<typename... _Args, int... _Indexes>
        _Result
        __call(const tuple<_Args...>& __args, 
               _Index_tuple<_Indexes...>) const volatile
        {
          return _M_f(_Mu<_Bound_args>()
                      (tr1::get<_Indexes>(_M_bound_args), __args)...);
        }

    public:
      typedef _Result result_type;

      explicit
      _Bind_result(_Functor __f, _Bound_args... __bound_args)
      : _M_f(__f), _M_bound_args(__bound_args...) { }

      // Call unqualified
      template<typename... _Args>
        result_type
        operator()(_Args&... __args)
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }

      // Call as const
      template<typename... _Args>
        result_type
        operator()(_Args&... __args) const
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }

      // Call as volatile
      template<typename... _Args>
        result_type
        operator()(_Args&... __args) volatile
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }

      // Call as const volatile
      template<typename... _Args>
        result_type
        operator()(_Args&... __args) const volatile
        {
          return this->__call(tr1::tie(__args...), _Bound_indexes());
        }
    };

  /// Class template _Bind is always a bind expression.
  template<typename _Signature>
    struct is_bind_expression<_Bind<_Signature> >
    { static const bool value = true; };

  template<typename _Signature>
    const bool is_bind_expression<_Bind<_Signature> >::value;

  /// Class template _Bind is always a bind expression.
  template<typename _Signature>
    struct is_bind_expression<const _Bind<_Signature> >
    { static const bool value = true; };

  template<typename _Signature>
    const bool is_bind_expression<const _Bind<_Signature> >::value;

  /// Class template _Bind is always a bind expression.
  template<typename _Signature>
    struct is_bind_expression<volatile _Bind<_Signature> >
    { static const bool value = true; };

  template<typename _Signature>
    const bool is_bind_expression<volatile _Bind<_Signature> >::value;

  /// Class template _Bind is always a bind expression.
  template<typename _Signature>
    struct is_bind_expression<const volatile _Bind<_Signature> >
    { static const bool value = true; };

  template<typename _Signature>
    const bool is_bind_expression<const volatile _Bind<_Signature> >::value;

  /// Class template _Bind_result is always a bind expression.
  template<typename _Result, typename _Signature>
    struct is_bind_expression<_Bind_result<_Result, _Signature> >
    { static const bool value = true; };

  template<typename _Result, typename _Signature>
    const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value;

  /// Class template _Bind_result is always a bind expression.
  template<typename _Result, typename _Signature>
    struct is_bind_expression<const _Bind_result<_Result, _Signature> >
    { static const bool value = true; };

  template<typename _Result, typename _Signature>
    const bool
    is_bind_expression<const _Bind_result<_Result, _Signature> >::value;

  /// Class template _Bind_result is always a bind expression.
  template<typename _Result, typename _Signature>
    struct is_bind_expression<volatile _Bind_result<_Result, _Signature> >
    { static const bool value = true; };

  template<typename _Result, typename _Signature>
    const bool
    is_bind_expression<volatile _Bind_result<_Result, _Signature> >::value;

  /// Class template _Bind_result is always a bind expression.
  template<typename _Result, typename _Signature>
    struct
    is_bind_expression<const volatile _Bind_result<_Result, _Signature> >
    { static const bool value = true; };

  template<typename _Result, typename _Signature>
    const bool
    is_bind_expression<const volatile _Bind_result<_Result,
                                                   _Signature> >::value;

#if __cplusplus >= 201103L
  // Specialize tr1::is_bind_expression for std::bind closure types,
  // so that they can also work with tr1::bind.

  template<typename _Signature>
    struct is_bind_expression<std::_Bind<_Signature>>
    : true_type { };

  template<typename _Signature>
    struct is_bind_expression<const std::_Bind<_Signature>>
    : true_type { };

  template<typename _Signature>
    struct is_bind_expression<volatile std::_Bind<_Signature>>
    : true_type { };

  template<typename _Signature>
    struct is_bind_expression<const volatile std::_Bind<_Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<std::_Bind_result<_Result, _Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<const std::_Bind_result<_Result, _Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<volatile std::_Bind_result<_Result, _Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<const volatile std::_Bind_result<_Result,
                                                               _Signature>>
    : true_type { };
#endif

  /// bind
  template<typename _Functor, typename... _ArgTypes>
    inline
    _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type(_ArgTypes...)>
    bind(_Functor __f, _ArgTypes... __args)
    {
      typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
      typedef typename __maybe_type::type __functor_type;
      typedef _Bind<__functor_type(_ArgTypes...)> __result_type;
      return __result_type(__maybe_type::__do_wrap(__f), __args...);
    } 

  template<typename _Result, typename _Functor, typename... _ArgTypes>
    inline
    _Bind_result<_Result,
		 typename _Maybe_wrap_member_pointer<_Functor>::type
                            (_ArgTypes...)>
    bind(_Functor __f, _ArgTypes... __args)
    {
      typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
      typedef typename __maybe_type::type __functor_type;
      typedef _Bind_result<_Result, __functor_type(_ArgTypes...)>
	__result_type;
      return __result_type(__maybe_type::__do_wrap(__f), __args...);
    }

  /**
   *  @brief Exception class thrown when class template function's
   *  operator() is called with an empty target.
   *  @ingroup exceptions
   */
  class bad_function_call : public std::exception { };

  /**
   *  The integral constant expression 0 can be converted into a
   *  pointer to this type. It is used by the function template to
   *  accept NULL pointers.
   */
  struct _M_clear_type;

  /**
   *  Trait identifying @a location-invariant types, meaning that the
   *  address of the object (or any of its members) will not escape.
   *  Also implies a trivial copy constructor and assignment operator.
   */
  template<typename _Tp>
    struct __is_location_invariant
    : integral_constant<bool,
                        (is_pointer<_Tp>::value
                         || is_member_pointer<_Tp>::value)>
    {
    };

  class _Undefined_class;

  union _Nocopy_types
  {
    void*       _M_object;
    const void* _M_const_object;
    void (*_M_function_pointer)();
    void (_Undefined_class::*_M_member_pointer)();
  };

  union _Any_data
  {
    void*       _M_access()       { return &_M_pod_data[0]; }
    const void* _M_access() const { return &_M_pod_data[0]; }

    template<typename _Tp>
      _Tp&
      _M_access()
      { return *static_cast<_Tp*>(_M_access()); }

    template<typename _Tp>
      const _Tp&
      _M_access() const
      { return *static_cast<const _Tp*>(_M_access()); }

    _Nocopy_types _M_unused;
    char _M_pod_data[sizeof(_Nocopy_types)];
  };

  enum _Manager_operation
  {
    __get_type_info,
    __get_functor_ptr,
    __clone_functor,
    __destroy_functor
  };

  // Simple type wrapper that helps avoid annoying const problems
  // when casting between void pointers and pointers-to-pointers.
  template<typename _Tp>
    struct _Simple_type_wrapper
    {
      _Simple_type_wrapper(_Tp __value) : __value(__value) { }

      _Tp __value;
    };

  template<typename _Tp>
    struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
    : __is_location_invariant<_Tp>
    {
    };

  // Converts a reference to a function object into a callable
  // function object.
  template<typename _Functor>
    inline _Functor&
    __callable_functor(_Functor& __f)
    { return __f; }

  template<typename _Member, typename _Class>
    inline _Mem_fn<_Member _Class::*>
    __callable_functor(_Member _Class::* &__p)
    { return mem_fn(__p); }

  template<typename _Member, typename _Class>
    inline _Mem_fn<_Member _Class::*>
    __callable_functor(_Member _Class::* const &__p)
    { return mem_fn(__p); }

  template<typename _Signature>
    class function;

  /// Base class of all polymorphic function object wrappers.
  class _Function_base
  {
  public:
    static const std::size_t _M_max_size = sizeof(_Nocopy_types);
    static const std::size_t _M_max_align = __alignof__(_Nocopy_types);

    template<typename _Functor>
      class _Base_manager
      {
      protected:
	static const bool __stored_locally =
        (__is_location_invariant<_Functor>::value
         && sizeof(_Functor) <= _M_max_size
         && __alignof__(_Functor) <= _M_max_align
         && (_M_max_align % __alignof__(_Functor) == 0));
	
	typedef integral_constant<bool, __stored_locally> _Local_storage;

	// Retrieve a pointer to the function object
	static _Functor*
	_M_get_pointer(const _Any_data& __source)
	{
	  const _Functor* __ptr =
	    __stored_locally? std::__addressof(__source._M_access<_Functor>())
	    /* have stored a pointer */ : __source._M_access<_Functor*>();
	  return const_cast<_Functor*>(__ptr);
	}

	// Clone a location-invariant function object that fits within
	// an _Any_data structure.
	static void
	_M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
	{
	  new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
	}

	// Clone a function object that is not location-invariant or
	// that cannot fit into an _Any_data structure.
	static void
	_M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
	{
	  __dest._M_access<_Functor*>() =
	    new _Functor(*__source._M_access<_Functor*>());
	}

	// Destroying a location-invariant object may still require
	// destruction.
	static void
	_M_destroy(_Any_data& __victim, true_type)
	{
	  __victim._M_access<_Functor>().~_Functor();
	}
	
	// Destroying an object located on the heap.
	static void
	_M_destroy(_Any_data& __victim, false_type)
	{
	  delete __victim._M_access<_Functor*>();
	}
	
      public:
	static bool
	_M_manager(_Any_data& __dest, const _Any_data& __source,
		   _Manager_operation __op)
	{
	  switch (__op)
	    {
#if __cpp_rtti
	    case __get_type_info:
	      __dest._M_access<const type_info*>() = &typeid(_Functor);
	      break;
#endif
	    case __get_functor_ptr:
	      __dest._M_access<_Functor*>() = _M_get_pointer(__source);
	      break;
	      
	    case __clone_functor:
	      _M_clone(__dest, __source, _Local_storage());
	      break;

	    case __destroy_functor:
	      _M_destroy(__dest, _Local_storage());
	      break;
	    }
	  return false;
	}

	static void
	_M_init_functor(_Any_data& __functor, const _Functor& __f)
	{ _M_init_functor(__functor, __f, _Local_storage()); }
	
	template<typename _Signature>
	  static bool
	  _M_not_empty_function(const function<_Signature>& __f)
          { return static_cast<bool>(__f); }

	template<typename _Tp>
	  static bool
	  _M_not_empty_function(const _Tp*& __fp)
	  { return __fp; }

	template<typename _Class, typename _Tp>
	  static bool
	  _M_not_empty_function(_Tp _Class::* const& __mp)
	  { return __mp; }

	template<typename _Tp>
	  static bool
	  _M_not_empty_function(const _Tp&)
	  { return true; }

      private:
	static void
	_M_init_functor(_Any_data& __functor, const _Functor& __f, true_type)
	{ new (__functor._M_access()) _Functor(__f); }

	static void
	_M_init_functor(_Any_data& __functor, const _Functor& __f, false_type)
	{ __functor._M_access<_Functor*>() = new _Functor(__f); }
      };

    template<typename _Functor>
      class _Ref_manager : public _Base_manager<_Functor*>
      {
	typedef _Function_base::_Base_manager<_Functor*> _Base;

    public:
	static bool
	_M_manager(_Any_data& __dest, const _Any_data& __source,
		   _Manager_operation __op)
	{
	  switch (__op)
	    {
#if __cpp_rtti
	    case __get_type_info:
	      __dest._M_access<const type_info*>() = &typeid(_Functor);
	      break;
#endif
	    case __get_functor_ptr:
	      __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
	      return is_const<_Functor>::value;
	      break;
	      
	    default:
	      _Base::_M_manager(__dest, __source, __op);
	    }
	  return false;
	}

	static void
	_M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
	{
	  _Base::_M_init_functor(__functor, std::__addressof(__f.get()));
	}
      };

    _Function_base() : _M_manager(0) { }
    
    ~_Function_base()
    {
      if (_M_manager)
	_M_manager(_M_functor, _M_functor, __destroy_functor);
    }


    bool _M_empty() const { return !_M_manager; }

    typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
                                  _Manager_operation);

    _Any_data     _M_functor;
    _Manager_type _M_manager;
  };

  template<typename _Signature, typename _Functor>
    class _Function_handler;

  template<typename _Res, typename _Functor, typename... _ArgTypes>
    class _Function_handler<_Res(_ArgTypes...), _Functor>
    : public _Function_base::_Base_manager<_Functor>
    {
      typedef _Function_base::_Base_manager<_Functor> _Base;

    public:
      static _Res
      _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
      {
        return (*_Base::_M_get_pointer(__functor))(__args...);
      }
    };

  template<typename _Functor, typename... _ArgTypes>
    class _Function_handler<void(_ArgTypes...), _Functor>
    : public _Function_base::_Base_manager<_Functor>
    {
      typedef _Function_base::_Base_manager<_Functor> _Base;

     public:
      static void
      _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
      {
        (*_Base::_M_get_pointer(__functor))(__args...);
      }
    };

  template<typename _Res, typename _Functor, typename... _ArgTypes>
    class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >
    : public _Function_base::_Ref_manager<_Functor>
    {
      typedef _Function_base::_Ref_manager<_Functor> _Base;

     public:
      static _Res
      _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
      {
        return 
          __callable_functor(**_Base::_M_get_pointer(__functor))(__args...);
      }
    };

  template<typename _Functor, typename... _ArgTypes>
    class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >
    : public _Function_base::_Ref_manager<_Functor>
    {
      typedef _Function_base::_Ref_manager<_Functor> _Base;

     public:
      static void
      _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
      {
        __callable_functor(**_Base::_M_get_pointer(__functor))(__args...);
      }
    };

  template<typename _Class, typename _Member, typename _Res, 
           typename... _ArgTypes>
    class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
    : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
    {
      typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
        _Base;

     public:
      static _Res
      _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
      {
        return tr1::
	  mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...);
      }
    };

  template<typename _Class, typename _Member, typename... _ArgTypes>
    class _Function_handler<void(_ArgTypes...), _Member _Class::*>
    : public _Function_base::_Base_manager<
                 _Simple_type_wrapper< _Member _Class::* > >
    {
      typedef _Member _Class::* _Functor;
      typedef _Simple_type_wrapper<_Functor> _Wrapper;
      typedef _Function_base::_Base_manager<_Wrapper> _Base;

     public:
      static bool
      _M_manager(_Any_data& __dest, const _Any_data& __source,
                 _Manager_operation __op)
      {
        switch (__op)
	  {
#if __cpp_rtti
	  case __get_type_info:
	    __dest._M_access<const type_info*>() = &typeid(_Functor);
	    break;
#endif	    
	  case __get_functor_ptr:
	    __dest._M_access<_Functor*>() =
	      &_Base::_M_get_pointer(__source)->__value;
	    break;
	    
	  default:
	    _Base::_M_manager(__dest, __source, __op);
	  }
        return false;
      }

      static void
      _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
      {
	tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...);
      }
    };

  /// class function
  template<typename _Res, typename... _ArgTypes>
    class function<_Res(_ArgTypes...)>
    : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
      private _Function_base
    {
#if __cplusplus < 201103L
      /// This class is used to implement the safe_bool idiom.
      struct _Hidden_type
      {
	_Hidden_type* _M_bool;
      };

      /// This typedef is used to implement the safe_bool idiom.
      typedef _Hidden_type* _Hidden_type::* _Safe_bool;
#endif

      typedef _Res _Signature_type(_ArgTypes...);
      
      struct _Useless { };
      
    public:
      typedef _Res result_type;
      
      // [3.7.2.1] construct/copy/destroy
      
      /**
       *  @brief Default construct creates an empty function call wrapper.
       *  @post @c !(bool)*this
       */
      function() : _Function_base() { }
      
      /**
       *  @brief Default construct creates an empty function call wrapper.
       *  @post @c !(bool)*this
       */
      function(_M_clear_type*) : _Function_base() { }
      
      /**
       *  @brief %Function copy constructor.
       *  @param x A %function object with identical call signature.
       *  @post @c (bool)*this == (bool)x
       *
       *  The newly-created %function contains a copy of the target of @a
       *  x (if it has one).
       */
      function(const function& __x);

      /**
       *  @brief Builds a %function that targets a copy of the incoming
       *  function object.
       *  @param f A %function object that is callable with parameters of
       *  type @c T1, @c T2, ..., @c TN and returns a value convertible
       *  to @c Res.
       *
       *  The newly-created %function object will target a copy of @a
       *  f. If @a f is @c reference_wrapper<F>, then this function
       *  object will contain a reference to the function object @c
       *  f.get(). If @a f is a NULL function pointer or NULL
       *  pointer-to-member, the newly-created object will be empty.
       *
       *  If @a f is a non-NULL function pointer or an object of type @c
       *  reference_wrapper<F>, this function will not throw.
       */
      template<typename _Functor>
        function(_Functor __f,
                 typename __gnu_cxx::__enable_if<
                           !is_integral<_Functor>::value, _Useless>::__type
                   = _Useless());

      /**
       *  @brief %Function assignment operator.
       *  @param x A %function with identical call signature.
       *  @post @c (bool)*this == (bool)x
       *  @returns @c *this
       *
       *  The target of @a x is copied to @c *this. If @a x has no
       *  target, then @c *this will be empty.
       *
       *  If @a x targets a function pointer or a reference to a function
       *  object, then this operation will not throw an %exception.
       */
      function&
      operator=(const function& __x)
      {
        function(__x).swap(*this);
        return *this;
      }

      /**
       *  @brief %Function assignment to zero.
       *  @post @c !(bool)*this
       *  @returns @c *this
       *
       *  The target of @c *this is deallocated, leaving it empty.
       */
      function&
      operator=(_M_clear_type*)
      {
        if (_M_manager)
	  {
	    _M_manager(_M_functor, _M_functor, __destroy_functor);
	    _M_manager = 0;
	    _M_invoker = 0;
	  }
        return *this;
      }

      /**
       *  @brief %Function assignment to a new target.
       *  @param f A %function object that is callable with parameters of
       *  type @c T1, @c T2, ..., @c TN and returns a value convertible
       *  to @c Res.
       *  @return @c *this
       *
       *  This  %function object wrapper will target a copy of @a
       *  f. If @a f is @c reference_wrapper<F>, then this function
       *  object will contain a reference to the function object @c
       *  f.get(). If @a f is a NULL function pointer or NULL
       *  pointer-to-member, @c this object will be empty.
       *
       *  If @a f is a non-NULL function pointer or an object of type @c
       *  reference_wrapper<F>, this function will not throw.
       */
      template<typename _Functor>
        typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value,
	                                function&>::__type
	operator=(_Functor __f)
	{
	  function(__f).swap(*this);
	  return *this;
	}

      // [3.7.2.2] function modifiers
      
      /**
       *  @brief Swap the targets of two %function objects.
       *  @param f A %function with identical call signature.
       *
       *  Swap the targets of @c this function object and @a f. This
       *  function will not throw an %exception.
       */
      void swap(function& __x)
      {
	std::swap(_M_functor, __x._M_functor);
	std::swap(_M_manager, __x._M_manager);
	std::swap(_M_invoker, __x._M_invoker);
      }

      // [3.7.2.3] function capacity

      /**
       *  @brief Determine if the %function wrapper has a target.
       *
       *  @return @c true when this %function object contains a target,
       *  or @c false when it is empty.
       *
       *  This function will not throw an %exception.
       */
#if __cplusplus >= 201103L
      explicit operator bool() const
      { return !_M_empty(); }
#else
      operator _Safe_bool() const
      {
        if (_M_empty())
	  return 0;
	else
	  return &_Hidden_type::_M_bool;
      }
#endif

      // [3.7.2.4] function invocation

      /**
       *  @brief Invokes the function targeted by @c *this.
       *  @returns the result of the target.
       *  @throws bad_function_call when @c !(bool)*this
       *
       *  The function call operator invokes the target function object
       *  stored by @c this.
       */
      _Res operator()(_ArgTypes... __args) const;

#if __cpp_rtti
      // [3.7.2.5] function target access
      /**
       *  @brief Determine the type of the target of this function object
       *  wrapper.
       *
       *  @returns the type identifier of the target function object, or
       *  @c typeid(void) if @c !(bool)*this.
       *
       *  This function will not throw an %exception.
       */
      const type_info& target_type() const;
      
      /**
       *  @brief Access the stored target function object.
       *
       *  @return Returns a pointer to the stored target function object,
       *  if @c typeid(Functor).equals(target_type()); otherwise, a NULL
       *  pointer.
       *
       * This function will not throw an %exception.
       */
      template<typename _Functor>       _Functor* target();
      
      /// @overload
      template<typename _Functor> const _Functor* target() const;
#endif

    private:
      // [3.7.2.6] undefined operators
      template<typename _Function>
	void operator==(const function<_Function>&) const;
      template<typename _Function>
	void operator!=(const function<_Function>&) const;

      typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
      _Invoker_type _M_invoker;
  };

  template<typename _Res, typename... _ArgTypes>
    function<_Res(_ArgTypes...)>::
    function(const function& __x)
    : _Function_base()
    {
      if (static_cast<bool>(__x))
	{
	  __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
	  _M_invoker = __x._M_invoker;
	  _M_manager = __x._M_manager;
	}
    }

  template<typename _Res, typename... _ArgTypes>
    template<typename _Functor>
      function<_Res(_ArgTypes...)>::
      function(_Functor __f,
	       typename __gnu_cxx::__enable_if<
                       !is_integral<_Functor>::value, _Useless>::__type)
      : _Function_base()
      {
	typedef _Function_handler<_Signature_type, _Functor> _My_handler;

	if (_My_handler::_M_not_empty_function(__f))
	  {
	    _My_handler::_M_init_functor(_M_functor, __f);
	    _M_invoker = &_My_handler::_M_invoke;
	    _M_manager = &_My_handler::_M_manager;
	  }
      }

  template<typename _Res, typename... _ArgTypes>
    _Res
    function<_Res(_ArgTypes...)>::
    operator()(_ArgTypes... __args) const
    {
      if (_M_empty())
	_GLIBCXX_THROW_OR_ABORT(bad_function_call());
      return _M_invoker(_M_functor, __args...);
    }

#if __cpp_rtti
  template<typename _Res, typename... _ArgTypes>
    const type_info&
    function<_Res(_ArgTypes...)>::
    target_type() const
    {
      if (_M_manager)
        {
          _Any_data __typeinfo_result;
          _M_manager(__typeinfo_result, _M_functor, __get_type_info);
          return *__typeinfo_result._M_access<const type_info*>();
        }
      else
	return typeid(void);
    }

  template<typename _Res, typename... _ArgTypes>
    template<typename _Functor>
      _Functor*
      function<_Res(_ArgTypes...)>::
      target()
      {
	if (typeid(_Functor) == target_type() && _M_manager)
	  {
	    _Any_data __ptr;
	    if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
		&& !is_const<_Functor>::value)
	      return 0;
	    else
	      return __ptr._M_access<_Functor*>();
	  }
	else
	  return 0;
      }

  template<typename _Res, typename... _ArgTypes>
    template<typename _Functor>
      const _Functor*
      function<_Res(_ArgTypes...)>::
      target() const
      {
	if (typeid(_Functor) == target_type() && _M_manager)
	  {
	    _Any_data __ptr;
	    _M_manager(__ptr, _M_functor, __get_functor_ptr);
	    return __ptr._M_access<const _Functor*>();
	  }
	else
	  return 0;
      }
#endif

  // [3.7.2.7] null pointer comparisons

  /**
   *  @brief Compares a polymorphic function object wrapper against 0
   *  (the NULL pointer).
   *  @returns @c true if the wrapper has no target, @c false otherwise
   *
   *  This function will not throw an %exception.
   */
  template<typename _Signature>
    inline bool
    operator==(const function<_Signature>& __f, _M_clear_type*)
    { return !static_cast<bool>(__f); }

  /// @overload
  template<typename _Signature>
    inline bool
    operator==(_M_clear_type*, const function<_Signature>& __f)
    { return !static_cast<bool>(__f); }

  /**
   *  @brief Compares a polymorphic function object wrapper against 0
   *  (the NULL pointer).
   *  @returns @c false if the wrapper has no target, @c true otherwise
   *
   *  This function will not throw an %exception.
   */
  template<typename _Signature>
    inline bool
    operator!=(const function<_Signature>& __f, _M_clear_type*)
    { return static_cast<bool>(__f); }

  /// @overload
  template<typename _Signature>
    inline bool
    operator!=(_M_clear_type*, const function<_Signature>& __f)
    { return static_cast<bool>(__f); }

  // [3.7.2.8] specialized algorithms

  /**
   *  @brief Swap the targets of two polymorphic function object wrappers.
   *
   *  This function will not throw an %exception.
   */
  template<typename _Signature>
    inline void
    swap(function<_Signature>& __x, function<_Signature>& __y)
    { __x.swap(__y); }
}

#if __cplusplus >= 201103L
  // Specialize std::is_bind_expression for tr1::bind closure types,
  // so that they can also work with std::bind.

  template<typename _Signature>
    struct is_bind_expression<tr1::_Bind<_Signature>>
    : true_type { };

  template<typename _Signature>
    struct is_bind_expression<const tr1::_Bind<_Signature>>
    : true_type { };

  template<typename _Signature>
    struct is_bind_expression<volatile tr1::_Bind<_Signature>>
    : true_type { };

  template<typename _Signature>
    struct is_bind_expression<const volatile tr1::_Bind<_Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<tr1::_Bind_result<_Result, _Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<const tr1::_Bind_result<_Result, _Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<volatile tr1::_Bind_result<_Result, _Signature>>
    : true_type { };

  template<typename _Result, typename _Signature>
    struct is_bind_expression<const volatile tr1::_Bind_result<_Result,
                                                               _Signature>>
    : true_type { };

#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
}

#endif // _GLIBCXX_TR1_FUNCTIONAL
