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

// Copyright (C) 2004-2014 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 <bits/c++config.h>
#include <bits/stl_function.h>

#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
#if __cplusplus >= 201103L
#  include <type_traits> // for integral_constant, true_type, false_type
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
#if __cplusplus >= 201103L
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  template<int> struct _Placeholder;
  template<typename> class _Bind;
  template<typename, typename> class _Bind_result;
_GLIBCXX_END_NAMESPACE_VERSION
#endif

namespace tr1
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  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++.
  template<int _Num> struct _Placeholder { };

_GLIBCXX_END_NAMESPACE_VERSION

  /** @namespace std::tr1::placeholders
   *  @brief Sub-namespace for tr1/functional.
   */
  namespace placeholders 
  { 
  _GLIBCXX_BEGIN_NAMESPACE_VERSION
    /*  Define a large number of placeholders. There is no way to
     *  simplify this with variadic templates, because we're introducing
     *  unique names for each.
     */
    namespace 
    {
      _Placeholder<1> _1;
      _Placeholder<2> _2;
      _Placeholder<3> _3;
      _Placeholder<4> _4;
      _Placeholder<5> _5;
      _Placeholder<6> _6;
      _Placeholder<7> _7;
      _Placeholder<8> _8;
      _Placeholder<9> _9;
      _Placeholder<10> _10;
      _Placeholder<11> _11;
      _Placeholder<12> _12;
      _Placeholder<13> _13;
      _Placeholder<14> _14;
      _Placeholder<15> _15;
      _Placeholder<16> _16;
      _Placeholder<17> _17;
      _Placeholder<18> _18;
      _Placeholder<19> _19;
      _Placeholder<20> _20;
      _Placeholder<21> _21;
      _Placeholder<22> _22;
      _Placeholder<23> _23;
      _Placeholder<24> _24;
      _Placeholder<25> _25;
      _Placeholder<26> _26;
      _Placeholder<27> _27;
      _Placeholder<28> _28;
      _Placeholder<29> _29;
    } 
  _GLIBCXX_END_NAMESPACE_VERSION
  }

_GLIBCXX_BEGIN_NAMESPACE_VERSION
  /**
   *  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> >
    { static const int value = _Num; };

  template<int _Num>
    const int is_placeholder<_Placeholder<_Num> >::value;

#if __cplusplus >= 201103L
  template<int _Num>
    struct is_placeholder<std::_Placeholder<_Num>>
    : std::integral_constant<int, _Num>
    { };

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

  /**
   * 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
  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)
	    {
#ifdef __GXX_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)
	    {
#ifdef __GXX_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)
	  {
#ifdef __GXX_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;

#ifdef __GXX_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))
	{
	  _M_invoker = __x._M_invoker;
	  _M_manager = __x._M_manager;
	  __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
	}
    }

  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))
	  {
	    _M_invoker = &_My_handler::_M_invoke;
	    _M_manager = &_My_handler::_M_manager;
	    _My_handler::_M_init_functor(_M_functor, __f);
	  }
      }

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

#ifdef __GXX_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); }

_GLIBCXX_END_NAMESPACE_VERSION
}

#if __cplusplus >= 201103L
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename> struct is_placeholder;

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

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

  template<typename> struct is_bind_expression;

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

_GLIBCXX_END_NAMESPACE_VERSION
#endif
}

#endif // _GLIBCXX_TR1_FUNCTIONAL
