// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_FUNCTIONAL_03
#define _LIBCPP_FUNCTIONAL_03

// manual variadic expansion for <functional>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

template <class _Tp>
class __mem_fn
    : public __weak_result_type<_Tp>
{
public:
    // types
    typedef _Tp type;
private:
    type __f_;

public:
    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}

    // invoke

    typename __invoke_return<type>::type
       operator() () const
       {
           return __invoke(__f_);
       }

    template <class _A0>
       typename __invoke_return0<type, _A0>::type
          operator() (_A0& __a0) const
          {
              return __invoke(__f_, __a0);
          }

    template <class _A0, class _A1>
       typename __invoke_return1<type, _A0, _A1>::type
          operator() (_A0& __a0, _A1& __a1) const
          {
              return __invoke(__f_, __a0, __a1);
          }

    template <class _A0, class _A1, class _A2>
       typename __invoke_return2<type, _A0, _A1, _A2>::type
          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
          {
              return __invoke(__f_, __a0, __a1, __a2);
          }
};

template<class _Rp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp _Tp::*>
mem_fn(_Rp _Tp::* __pm)
{
    return __mem_fn<_Rp _Tp::*>(__pm);
}

template<class _Rp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)()>
mem_fn(_Rp (_Tp::* __pm)())
{
    return __mem_fn<_Rp (_Tp::*)()>(__pm);
}

template<class _Rp, class _Tp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0)>
mem_fn(_Rp (_Tp::* __pm)(_A0))
{
    return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1))
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2))
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
}

template<class _Rp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)() const>
mem_fn(_Rp (_Tp::* __pm)() const)
{
    return __mem_fn<_Rp (_Tp::*)() const>(__pm);
}

template<class _Rp, class _Tp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0) const>
mem_fn(_Rp (_Tp::* __pm)(_A0) const)
{
    return __mem_fn<_Rp (_Tp::*)(_A0) const>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1) const>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const)
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const)
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>(__pm);
}

template<class _Rp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)() volatile>
mem_fn(_Rp (_Tp::* __pm)() volatile)
{
    return __mem_fn<_Rp (_Tp::*)() volatile>(__pm);
}

template<class _Rp, class _Tp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0) volatile>
mem_fn(_Rp (_Tp::* __pm)(_A0) volatile)
{
    return __mem_fn<_Rp (_Tp::*)(_A0) volatile>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) volatile)
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) volatile)
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>(__pm);
}

template<class _Rp, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)() const volatile>
mem_fn(_Rp (_Tp::* __pm)() const volatile)
{
    return __mem_fn<_Rp (_Tp::*)() const volatile>(__pm);
}

template<class _Rp, class _Tp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0) const volatile>
mem_fn(_Rp (_Tp::* __pm)(_A0) const volatile)
{
    return __mem_fn<_Rp (_Tp::*)(_A0) const volatile>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const volatile)
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>(__pm);
}

template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>
mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const volatile)
{
    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>(__pm);
}

// bad_function_call

class _LIBCPP_EXCEPTION_ABI bad_function_call
    : public exception
{
};

template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined

namespace __function
{

template<class _Fp>
struct __maybe_derive_from_unary_function
{
};

template<class _Rp, class _A1>
struct __maybe_derive_from_unary_function<_Rp(_A1)>
    : public unary_function<_A1, _Rp>
{
};

template<class _Fp>
struct __maybe_derive_from_binary_function
{
};

template<class _Rp, class _A1, class _A2>
struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
    : public binary_function<_A1, _A2, _Rp>
{
};

template<class _Fp> class __base;

template<class _Rp>
class __base<_Rp()>
{
    __base(const __base&);
    __base& operator=(const __base&);
public:
    __base() {}
    virtual ~__base() {}
    virtual __base* __clone() const = 0;
    virtual void __clone(__base*) const = 0;
    virtual void destroy() = 0;
    virtual void destroy_deallocate() = 0;
    virtual _Rp operator()() = 0;
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const = 0;
    virtual const std::type_info& target_type() const = 0;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp, class _A0>
class __base<_Rp(_A0)>
{
    __base(const __base&);
    __base& operator=(const __base&);
public:
    __base() {}
    virtual ~__base() {}
    virtual __base* __clone() const = 0;
    virtual void __clone(__base*) const = 0;
    virtual void destroy() = 0;
    virtual void destroy_deallocate() = 0;
    virtual _Rp operator()(_A0) = 0;
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const = 0;
    virtual const std::type_info& target_type() const = 0;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp, class _A0, class _A1>
class __base<_Rp(_A0, _A1)>
{
    __base(const __base&);
    __base& operator=(const __base&);
public:
    __base() {}
    virtual ~__base() {}
    virtual __base* __clone() const = 0;
    virtual void __clone(__base*) const = 0;
    virtual void destroy() = 0;
    virtual void destroy_deallocate() = 0;
    virtual _Rp operator()(_A0, _A1) = 0;
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const = 0;
    virtual const std::type_info& target_type() const = 0;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp, class _A0, class _A1, class _A2>
class __base<_Rp(_A0, _A1, _A2)>
{
    __base(const __base&);
    __base& operator=(const __base&);
public:
    __base() {}
    virtual ~__base() {}
    virtual __base* __clone() const = 0;
    virtual void __clone(__base*) const = 0;
    virtual void destroy() = 0;
    virtual void destroy_deallocate() = 0;
    virtual _Rp operator()(_A0, _A1, _A2) = 0;
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const = 0;
    virtual const std::type_info& target_type() const = 0;
#endif  // _LIBCPP_NO_RTTI
};

template<class _FD, class _Alloc, class _FB> class __func;

template<class _Fp, class _Alloc, class _Rp>
class __func<_Fp, _Alloc, _Rp()>
    : public  __base<_Rp()>
{
    __compressed_pair<_Fp, _Alloc> __f_;
public:
    explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
    explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
    virtual __base<_Rp()>* __clone() const;
    virtual void __clone(__base<_Rp()>*) const;
    virtual void destroy();
    virtual void destroy_deallocate();
    virtual _Rp operator()();
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const;
    virtual const std::type_info& target_type() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Fp, class _Alloc, class _Rp>
__base<_Rp()>*
__func<_Fp, _Alloc, _Rp()>::__clone() const
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    typedef __allocator_destructor<_Ap> _Dp;
    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
    return __hold.release();
}

template<class _Fp, class _Alloc, class _Rp>
void
__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
{
    ::new (__p) __func(__f_.first(), __f_.second());
}

template<class _Fp, class _Alloc, class _Rp>
void
__func<_Fp, _Alloc, _Rp()>::destroy()
{
    __f_.~__compressed_pair<_Fp, _Alloc>();
}

template<class _Fp, class _Alloc, class _Rp>
void
__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    __f_.~__compressed_pair<_Fp, _Alloc>();
    __a.deallocate(this, 1);
}

template<class _Fp, class _Alloc, class _Rp>
_Rp
__func<_Fp, _Alloc, _Rp()>::operator()()
{
    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
    return _Invoker::__call(__f_.first());
}

#ifndef _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp>
const void*
__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
{
    if (__ti == typeid(_Fp))
        return &__f_.first();
    return (const void*)0;
}

template<class _Fp, class _Alloc, class _Rp>
const std::type_info&
__func<_Fp, _Alloc, _Rp()>::target_type() const
{
    return typeid(_Fp);
}

#endif  // _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp, class _A0>
class __func<_Fp, _Alloc, _Rp(_A0)>
    : public  __base<_Rp(_A0)>
{
    __compressed_pair<_Fp, _Alloc> __f_;
public:
    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
    virtual __base<_Rp(_A0)>* __clone() const;
    virtual void __clone(__base<_Rp(_A0)>*) const;
    virtual void destroy();
    virtual void destroy_deallocate();
    virtual _Rp operator()(_A0);
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const;
    virtual const std::type_info& target_type() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Fp, class _Alloc, class _Rp, class _A0>
__base<_Rp(_A0)>*
__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    typedef __allocator_destructor<_Ap> _Dp;
    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
    return __hold.release();
}

template<class _Fp, class _Alloc, class _Rp, class _A0>
void
__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
{
    ::new (__p) __func(__f_.first(), __f_.second());
}

template<class _Fp, class _Alloc, class _Rp, class _A0>
void
__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
{
    __f_.~__compressed_pair<_Fp, _Alloc>();
}

template<class _Fp, class _Alloc, class _Rp, class _A0>
void
__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    __f_.~__compressed_pair<_Fp, _Alloc>();
    __a.deallocate(this, 1);
}

template<class _Fp, class _Alloc, class _Rp, class _A0>
_Rp
__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
{
    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
    return _Invoker::__call(__f_.first(), __a0);
}

#ifndef _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp, class _A0>
const void*
__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
{
    if (__ti == typeid(_Fp))
        return &__f_.first();
    return (const void*)0;
}

template<class _Fp, class _Alloc, class _Rp, class _A0>
const std::type_info&
__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
{
    return typeid(_Fp);
}

#endif  // _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
    : public  __base<_Rp(_A0, _A1)>
{
    __compressed_pair<_Fp, _Alloc> __f_;
public:
    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
    virtual __base<_Rp(_A0, _A1)>* __clone() const;
    virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
    virtual void destroy();
    virtual void destroy_deallocate();
    virtual _Rp operator()(_A0, _A1);
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const;
    virtual const std::type_info& target_type() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
__base<_Rp(_A0, _A1)>*
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    typedef __allocator_destructor<_Ap> _Dp;
    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
    return __hold.release();
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
void
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
{
    ::new (__p) __func(__f_.first(), __f_.second());
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
void
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
{
    __f_.~__compressed_pair<_Fp, _Alloc>();
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
void
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    __f_.~__compressed_pair<_Fp, _Alloc>();
    __a.deallocate(this, 1);
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
_Rp
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
{
    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
    return _Invoker::__call(__f_.first(), __a0, __a1);
}

#ifndef _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
const void*
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
{
    if (__ti == typeid(_Fp))
        return &__f_.first();
    return (const void*)0;
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
const std::type_info&
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
{
    return typeid(_Fp);
}

#endif  // _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
    : public  __base<_Rp(_A0, _A1, _A2)>
{
    __compressed_pair<_Fp, _Alloc> __f_;
public:
    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
    virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
    virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
    virtual void destroy();
    virtual void destroy_deallocate();
    virtual _Rp operator()(_A0, _A1, _A2);
#ifndef _LIBCPP_NO_RTTI
    virtual const void* target(const type_info&) const;
    virtual const std::type_info& target_type() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
__base<_Rp(_A0, _A1, _A2)>*
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    typedef __allocator_destructor<_Ap> _Dp;
    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
    return __hold.release();
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
void
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
{
    ::new (__p) __func(__f_.first(), __f_.second());
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
void
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
{
    __f_.~__compressed_pair<_Fp, _Alloc>();
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
void
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
{
    typedef typename _Alloc::template rebind<__func>::other _Ap;
    _Ap __a(__f_.second());
    __f_.~__compressed_pair<_Fp, _Alloc>();
    __a.deallocate(this, 1);
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
_Rp
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
{
    typedef __invoke_void_return_wrapper<_Rp> _Invoker;
    return _Invoker::__call(__f_.first(), __a0, __a1, __a2);
}

#ifndef _LIBCPP_NO_RTTI

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
const void*
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
{
    if (__ti == typeid(_Fp))
        return &__f_.first();
    return (const void*)0;
}

template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
const std::type_info&
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
{
    return typeid(_Fp);
}

#endif  // _LIBCPP_NO_RTTI

}  // __function

template<class _Rp>
class _LIBCPP_TYPE_VIS_ONLY function<_Rp()>
{
    typedef __function::__base<_Rp()> __base;
    aligned_storage<3*sizeof(void*)>::type __buf_;
    __base* __f_;

    template <class _Fp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const _Fp&) {return true;}
    template <class _R2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (*__p)()) {return __p;}
    template <class _R2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const function<_R2()>& __p) {return __p;}
public:
    typedef _Rp result_type;

    // 20.7.16.2.1, construct/copy/destroy:
    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
    function(const function&);
    template<class _Fp>
      function(_Fp,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
    template<class _Alloc>
      function(allocator_arg_t, const _Alloc&, const function&);
    template<class _Fp, class _Alloc>
      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    function& operator=(const function&);
    function& operator=(nullptr_t);
    template<class _Fp>
      typename enable_if
      <
        !is_integral<_Fp>::value,
        function&
      >::type
      operator=(_Fp);

    ~function();

    // 20.7.16.2.2, function modifiers:
    void swap(function&);
    template<class _Fp, class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      void assign(_Fp __f, const _Alloc& __a)
        {function(allocator_arg, __a, __f).swap(*this);}

    // 20.7.16.2.3, function capacity:
    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}

private:
    // deleted overloads close possible hole in the type system
    template<class _R2>
      bool operator==(const function<_R2()>&) const;// = delete;
    template<class _R2>
      bool operator!=(const function<_R2()>&) const;// = delete;
public:
    // 20.7.16.2.4, function invocation:
    _Rp operator()() const;

#ifndef _LIBCPP_NO_RTTI
    // 20.7.16.2.5, function target access:
    const std::type_info& target_type() const;
    template <typename _Tp> _Tp* target();
    template <typename _Tp> const _Tp* target() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp>
function<_Rp()>::function(const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp>
template<class _Alloc>
function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp>
template <class _Fp>
function<_Rp()>::function(_Fp __f,
                                     typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef allocator<_FF> _Ap;
            _Ap __a;
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp>
template <class _Fp, class _Alloc>
function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
                                     typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    typedef allocator_traits<_Alloc> __alloc_traits;
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
            _Ap __a(__a0);
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, _Alloc(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp>
function<_Rp()>&
function<_Rp()>::operator=(const function& __f)
{
    function(__f).swap(*this);
    return *this;
}

template<class _Rp>
function<_Rp()>&
function<_Rp()>::operator=(nullptr_t)
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
    __f_ = 0;
}

template<class _Rp>
template <class _Fp>
typename enable_if
<
    !is_integral<_Fp>::value,
    function<_Rp()>&
>::type
function<_Rp()>::operator=(_Fp __f)
{
    function(_VSTD::move(__f)).swap(*this);
    return *this;
}

template<class _Rp>
function<_Rp()>::~function()
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
}

template<class _Rp>
void
function<_Rp()>::swap(function& __f)
{
    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
    {
        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
        __base* __t = (__base*)&__tempbuf;
        __f_->__clone(__t);
        __f_->destroy();
        __f_ = 0;
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = 0;
        __f_ = (__base*)&__buf_;
        __t->__clone((__base*)&__f.__buf_);
        __t->destroy();
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f_ == (__base*)&__buf_)
    {
        __f_->__clone((__base*)&__f.__buf_);
        __f_->destroy();
        __f_ = __f.__f_;
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f.__f_ == (__base*)&__f.__buf_)
    {
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = __f_;
        __f_ = (__base*)&__buf_;
    }
    else
        _VSTD::swap(__f_, __f.__f_);
}

template<class _Rp>
_Rp
function<_Rp()>::operator()() const
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    if (__f_ == 0)
        throw bad_function_call();
#endif  // _LIBCPP_NO_EXCEPTIONS
    return (*__f_)();
}

#ifndef _LIBCPP_NO_RTTI

template<class _Rp>
const std::type_info&
function<_Rp()>::target_type() const
{
    if (__f_ == 0)
        return typeid(void);
    return __f_->target_type();
}

template<class _Rp>
template <typename _Tp>
_Tp*
function<_Rp()>::target()
{
    if (__f_ == 0)
        return (_Tp*)0;
    return (_Tp*)__f_->target(typeid(_Tp));
}

template<class _Rp>
template <typename _Tp>
const _Tp*
function<_Rp()>::target() const
{
    if (__f_ == 0)
        return (const _Tp*)0;
    return (const _Tp*)__f_->target(typeid(_Tp));
}

#endif  // _LIBCPP_NO_RTTI

template<class _Rp, class _A0>
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)>
    : public unary_function<_A0, _Rp>
{
    typedef __function::__base<_Rp(_A0)> __base;
    aligned_storage<3*sizeof(void*)>::type __buf_;
    __base* __f_;

    template <class _Fp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const _Fp&) {return true;}
    template <class _R2, class _B0>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (*__p)(_B0)) {return __p;}
    template <class _R2, class _Cp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)()) {return __p;}
    template <class _R2, class _Cp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;}
    template <class _R2, class _Cp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;}
    template <class _R2, class _Cp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}
    template <class _R2, class _B0>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}
public:
    typedef _Rp result_type;

    // 20.7.16.2.1, construct/copy/destroy:
    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
    function(const function&);
    template<class _Fp>
      function(_Fp,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
    template<class _Alloc>
      function(allocator_arg_t, const _Alloc&, const function&);
    template<class _Fp, class _Alloc>
      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    function& operator=(const function&);
    function& operator=(nullptr_t);
    template<class _Fp>
      typename enable_if
      <
        !is_integral<_Fp>::value,
        function&
      >::type
      operator=(_Fp);

    ~function();

    // 20.7.16.2.2, function modifiers:
    void swap(function&);
    template<class _Fp, class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      void assign(_Fp __f, const _Alloc& __a)
        {function(allocator_arg, __a, __f).swap(*this);}

    // 20.7.16.2.3, function capacity:
    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}

private:
    // deleted overloads close possible hole in the type system
    template<class _R2, class _B0>
      bool operator==(const function<_R2(_B0)>&) const;// = delete;
    template<class _R2, class _B0>
      bool operator!=(const function<_R2(_B0)>&) const;// = delete;
public:
    // 20.7.16.2.4, function invocation:
    _Rp operator()(_A0) const;

#ifndef _LIBCPP_NO_RTTI
    // 20.7.16.2.5, function target access:
    const std::type_info& target_type() const;
    template <typename _Tp> _Tp* target();
    template <typename _Tp> const _Tp* target() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp, class _A0>
function<_Rp(_A0)>::function(const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp, class _A0>
template<class _Alloc>
function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp, class _A0>
template <class _Fp>
function<_Rp(_A0)>::function(_Fp __f,
                                     typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef allocator<_FF> _Ap;
            _Ap __a;
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp, class _A0>
template <class _Fp, class _Alloc>
function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
                                     typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    typedef allocator_traits<_Alloc> __alloc_traits;
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
            _Ap __a(__a0);
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, _Alloc(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp, class _A0>
function<_Rp(_A0)>&
function<_Rp(_A0)>::operator=(const function& __f)
{
    function(__f).swap(*this);
    return *this;
}

template<class _Rp, class _A0>
function<_Rp(_A0)>&
function<_Rp(_A0)>::operator=(nullptr_t)
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
    __f_ = 0;
}

template<class _Rp, class _A0>
template <class _Fp>
typename enable_if
<
    !is_integral<_Fp>::value,
    function<_Rp(_A0)>&
>::type
function<_Rp(_A0)>::operator=(_Fp __f)
{
    function(_VSTD::move(__f)).swap(*this);
    return *this;
}

template<class _Rp, class _A0>
function<_Rp(_A0)>::~function()
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
}

template<class _Rp, class _A0>
void
function<_Rp(_A0)>::swap(function& __f)
{
    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
    {
        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
        __base* __t = (__base*)&__tempbuf;
        __f_->__clone(__t);
        __f_->destroy();
        __f_ = 0;
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = 0;
        __f_ = (__base*)&__buf_;
        __t->__clone((__base*)&__f.__buf_);
        __t->destroy();
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f_ == (__base*)&__buf_)
    {
        __f_->__clone((__base*)&__f.__buf_);
        __f_->destroy();
        __f_ = __f.__f_;
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f.__f_ == (__base*)&__f.__buf_)
    {
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = __f_;
        __f_ = (__base*)&__buf_;
    }
    else
        _VSTD::swap(__f_, __f.__f_);
}

template<class _Rp, class _A0>
_Rp
function<_Rp(_A0)>::operator()(_A0 __a0) const
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    if (__f_ == 0)
        throw bad_function_call();
#endif  // _LIBCPP_NO_EXCEPTIONS
    return (*__f_)(__a0);
}

#ifndef _LIBCPP_NO_RTTI

template<class _Rp, class _A0>
const std::type_info&
function<_Rp(_A0)>::target_type() const
{
    if (__f_ == 0)
        return typeid(void);
    return __f_->target_type();
}

template<class _Rp, class _A0>
template <typename _Tp>
_Tp*
function<_Rp(_A0)>::target()
{
    if (__f_ == 0)
        return (_Tp*)0;
    return (_Tp*)__f_->target(typeid(_Tp));
}

template<class _Rp, class _A0>
template <typename _Tp>
const _Tp*
function<_Rp(_A0)>::target() const
{
    if (__f_ == 0)
        return (const _Tp*)0;
    return (const _Tp*)__f_->target(typeid(_Tp));
}

#endif  // _LIBCPP_NO_RTTI

template<class _Rp, class _A0, class _A1>
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)>
    : public binary_function<_A0, _A1, _Rp>
{
    typedef __function::__base<_Rp(_A0, _A1)> __base;
    aligned_storage<3*sizeof(void*)>::type __buf_;
    __base* __f_;

    template <class _Fp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const _Fp&) {return true;}
    template <class _R2, class _B0, class _B1>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}
    template <class _R2, class _Cp, class _B1>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;}
    template <class _R2, class _Cp, class _B1>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1) const) {return __p;}
    template <class _R2, class _Cp, class _B1>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1) volatile) {return __p;}
    template <class _R2, class _Cp, class _B1>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}
    template <class _R2, class _B0, class _B1>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}
public:
    typedef _Rp result_type;

    // 20.7.16.2.1, construct/copy/destroy:
    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
    function(const function&);
    template<class _Fp>
      function(_Fp,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
    template<class _Alloc>
      function(allocator_arg_t, const _Alloc&, const function&);
    template<class _Fp, class _Alloc>
      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    function& operator=(const function&);
    function& operator=(nullptr_t);
    template<class _Fp>
      typename enable_if
      <
        !is_integral<_Fp>::value,
        function&
      >::type
      operator=(_Fp);

    ~function();

    // 20.7.16.2.2, function modifiers:
    void swap(function&);
    template<class _Fp, class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      void assign(_Fp __f, const _Alloc& __a)
        {function(allocator_arg, __a, __f).swap(*this);}

    // 20.7.16.2.3, function capacity:
    operator bool() const {return __f_;}

private:
    // deleted overloads close possible hole in the type system
    template<class _R2, class _B0, class _B1>
      bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
    template<class _R2, class _B0, class _B1>
      bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
public:
    // 20.7.16.2.4, function invocation:
    _Rp operator()(_A0, _A1) const;

#ifndef _LIBCPP_NO_RTTI
    // 20.7.16.2.5, function target access:
    const std::type_info& target_type() const;
    template <typename _Tp> _Tp* target();
    template <typename _Tp> const _Tp* target() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp, class _A0, class _A1>
function<_Rp(_A0, _A1)>::function(const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp, class _A0, class _A1>
template<class _Alloc>
function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp, class _A0, class _A1>
template <class _Fp>
function<_Rp(_A0, _A1)>::function(_Fp __f,
                                 typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef allocator<_FF> _Ap;
            _Ap __a;
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp, class _A0, class _A1>
template <class _Fp, class _Alloc>
function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
                                 typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    typedef allocator_traits<_Alloc> __alloc_traits;
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
            _Ap __a(__a0);
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, _Alloc(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp, class _A0, class _A1>
function<_Rp(_A0, _A1)>&
function<_Rp(_A0, _A1)>::operator=(const function& __f)
{
    function(__f).swap(*this);
    return *this;
}

template<class _Rp, class _A0, class _A1>
function<_Rp(_A0, _A1)>&
function<_Rp(_A0, _A1)>::operator=(nullptr_t)
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
    __f_ = 0;
}

template<class _Rp, class _A0, class _A1>
template <class _Fp>
typename enable_if
<
    !is_integral<_Fp>::value,
    function<_Rp(_A0, _A1)>&
>::type
function<_Rp(_A0, _A1)>::operator=(_Fp __f)
{
    function(_VSTD::move(__f)).swap(*this);
    return *this;
}

template<class _Rp, class _A0, class _A1>
function<_Rp(_A0, _A1)>::~function()
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
}

template<class _Rp, class _A0, class _A1>
void
function<_Rp(_A0, _A1)>::swap(function& __f)
{
    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
    {
        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
        __base* __t = (__base*)&__tempbuf;
        __f_->__clone(__t);
        __f_->destroy();
        __f_ = 0;
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = 0;
        __f_ = (__base*)&__buf_;
        __t->__clone((__base*)&__f.__buf_);
        __t->destroy();
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f_ == (__base*)&__buf_)
    {
        __f_->__clone((__base*)&__f.__buf_);
        __f_->destroy();
        __f_ = __f.__f_;
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f.__f_ == (__base*)&__f.__buf_)
    {
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = __f_;
        __f_ = (__base*)&__buf_;
    }
    else
        _VSTD::swap(__f_, __f.__f_);
}

template<class _Rp, class _A0, class _A1>
_Rp
function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    if (__f_ == 0)
        throw bad_function_call();
#endif  // _LIBCPP_NO_EXCEPTIONS
    return (*__f_)(__a0, __a1);
}

#ifndef _LIBCPP_NO_RTTI

template<class _Rp, class _A0, class _A1>
const std::type_info&
function<_Rp(_A0, _A1)>::target_type() const
{
    if (__f_ == 0)
        return typeid(void);
    return __f_->target_type();
}

template<class _Rp, class _A0, class _A1>
template <typename _Tp>
_Tp*
function<_Rp(_A0, _A1)>::target()
{
    if (__f_ == 0)
        return (_Tp*)0;
    return (_Tp*)__f_->target(typeid(_Tp));
}

template<class _Rp, class _A0, class _A1>
template <typename _Tp>
const _Tp*
function<_Rp(_A0, _A1)>::target() const
{
    if (__f_ == 0)
        return (const _Tp*)0;
    return (const _Tp*)__f_->target(typeid(_Tp));
}

#endif  // _LIBCPP_NO_RTTI

template<class _Rp, class _A0, class _A1, class _A2>
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)>
{
    typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
    aligned_storage<3*sizeof(void*)>::type __buf_;
    __base* __f_;

    template <class _Fp>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const _Fp&) {return true;}
    template <class _R2, class _B0, class _B1, class _B2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}
    template <class _R2, class _Cp, class _B1, class _B2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;}
    template <class _R2, class _Cp, class _B1, class _B2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const) {return __p;}
    template <class _R2, class _Cp, class _B1, class _B2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) volatile) {return __p;}
    template <class _R2, class _Cp, class _B1, class _B2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}
    template <class _R2, class _B0, class _B1, class _B2>
        _LIBCPP_INLINE_VISIBILITY
        static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;}
public:
    typedef _Rp result_type;

    // 20.7.16.2.1, construct/copy/destroy:
    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
    function(const function&);
    template<class _Fp>
      function(_Fp,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
    template<class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
    template<class _Alloc>
      function(allocator_arg_t, const _Alloc&, const function&);
    template<class _Fp, class _Alloc>
      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
               typename enable_if<!is_integral<_Fp>::value>::type* = 0);

    function& operator=(const function&);
    function& operator=(nullptr_t);
    template<class _Fp>
      typename enable_if
      <
        !is_integral<_Fp>::value,
        function&
      >::type
      operator=(_Fp);

    ~function();

    // 20.7.16.2.2, function modifiers:
    void swap(function&);
    template<class _Fp, class _Alloc>
      _LIBCPP_INLINE_VISIBILITY
      void assign(_Fp __f, const _Alloc& __a)
        {function(allocator_arg, __a, __f).swap(*this);}

    // 20.7.16.2.3, function capacity:
    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}

private:
    // deleted overloads close possible hole in the type system
    template<class _R2, class _B0, class _B1, class _B2>
      bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
    template<class _R2, class _B0, class _B1, class _B2>
      bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
public:
    // 20.7.16.2.4, function invocation:
    _Rp operator()(_A0, _A1, _A2) const;

#ifndef _LIBCPP_NO_RTTI
    // 20.7.16.2.5, function target access:
    const std::type_info& target_type() const;
    template <typename _Tp> _Tp* target();
    template <typename _Tp> const _Tp* target() const;
#endif  // _LIBCPP_NO_RTTI
};

template<class _Rp, class _A0, class _A1, class _A2>
function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp, class _A0, class _A1, class _A2>
template<class _Alloc>
function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
                                      const function& __f)
{
    if (__f.__f_ == 0)
        __f_ = 0;
    else if (__f.__f_ == (const __base*)&__f.__buf_)
    {
        __f_ = (__base*)&__buf_;
        __f.__f_->__clone(__f_);
    }
    else
        __f_ = __f.__f_->__clone();
}

template<class _Rp, class _A0, class _A1, class _A2>
template <class _Fp>
function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
                                     typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef allocator<_FF> _Ap;
            _Ap __a;
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp, class _A0, class _A1, class _A2>
template <class _Fp, class _Alloc>
function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
                                     typename enable_if<!is_integral<_Fp>::value>::type*)
    : __f_(0)
{
    typedef allocator_traits<_Alloc> __alloc_traits;
    if (__not_null(__f))
    {
        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
        if (sizeof(_FF) <= sizeof(__buf_))
        {
            __f_ = (__base*)&__buf_;
            ::new (__f_) _FF(__f);
        }
        else
        {
            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
            _Ap __a(__a0);
            typedef __allocator_destructor<_Ap> _Dp;
            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
            ::new (__hold.get()) _FF(__f, _Alloc(__a));
            __f_ = __hold.release();
        }
    }
}

template<class _Rp, class _A0, class _A1, class _A2>
function<_Rp(_A0, _A1, _A2)>&
function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
{
    function(__f).swap(*this);
    return *this;
}

template<class _Rp, class _A0, class _A1, class _A2>
function<_Rp(_A0, _A1, _A2)>&
function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
    __f_ = 0;
}

template<class _Rp, class _A0, class _A1, class _A2>
template <class _Fp>
typename enable_if
<
    !is_integral<_Fp>::value,
    function<_Rp(_A0, _A1, _A2)>&
>::type
function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
{
    function(_VSTD::move(__f)).swap(*this);
    return *this;
}

template<class _Rp, class _A0, class _A1, class _A2>
function<_Rp(_A0, _A1, _A2)>::~function()
{
    if (__f_ == (__base*)&__buf_)
        __f_->destroy();
    else if (__f_)
        __f_->destroy_deallocate();
}

template<class _Rp, class _A0, class _A1, class _A2>
void
function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
{
    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
    {
        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
        __base* __t = (__base*)&__tempbuf;
        __f_->__clone(__t);
        __f_->destroy();
        __f_ = 0;
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = 0;
        __f_ = (__base*)&__buf_;
        __t->__clone((__base*)&__f.__buf_);
        __t->destroy();
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f_ == (__base*)&__buf_)
    {
        __f_->__clone((__base*)&__f.__buf_);
        __f_->destroy();
        __f_ = __f.__f_;
        __f.__f_ = (__base*)&__f.__buf_;
    }
    else if (__f.__f_ == (__base*)&__f.__buf_)
    {
        __f.__f_->__clone((__base*)&__buf_);
        __f.__f_->destroy();
        __f.__f_ = __f_;
        __f_ = (__base*)&__buf_;
    }
    else
        _VSTD::swap(__f_, __f.__f_);
}

template<class _Rp, class _A0, class _A1, class _A2>
_Rp
function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    if (__f_ == 0)
        throw bad_function_call();
#endif  // _LIBCPP_NO_EXCEPTIONS
    return (*__f_)(__a0, __a1, __a2);
}

#ifndef _LIBCPP_NO_RTTI

template<class _Rp, class _A0, class _A1, class _A2>
const std::type_info&
function<_Rp(_A0, _A1, _A2)>::target_type() const
{
    if (__f_ == 0)
        return typeid(void);
    return __f_->target_type();
}

template<class _Rp, class _A0, class _A1, class _A2>
template <typename _Tp>
_Tp*
function<_Rp(_A0, _A1, _A2)>::target()
{
    if (__f_ == 0)
        return (_Tp*)0;
    return (_Tp*)__f_->target(typeid(_Tp));
}

template<class _Rp, class _A0, class _A1, class _A2>
template <typename _Tp>
const _Tp*
function<_Rp(_A0, _A1, _A2)>::target() const
{
    if (__f_ == 0)
        return (const _Tp*)0;
    return (const _Tp*)__f_->target(typeid(_Tp));
}

#endif  // _LIBCPP_NO_RTTI

template <class _Fp>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}

template <class _Fp>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}

template <class _Fp>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}

template <class _Fp>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}

template <class _Fp>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(function<_Fp>& __x, function<_Fp>& __y)
{return __x.swap(__y);}

template<class _Tp> struct __is_bind_expression : public false_type {};
template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};

template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
    : public __is_placeholder<typename remove_cv<_Tp>::type> {};

namespace placeholders
{

template <int _Np> struct __ph {};

extern __ph<1>   _1;
extern __ph<2>   _2;
extern __ph<3>   _3;
extern __ph<4>   _4;
extern __ph<5>   _5;
extern __ph<6>   _6;
extern __ph<7>   _7;
extern __ph<8>   _8;
extern __ph<9>   _9;
extern __ph<10> _10;

}  // placeholders

template<int _Np>
struct __is_placeholder<placeholders::__ph<_Np> >
    : public integral_constant<int, _Np> {};

template <class _Tp, class _Uj>
inline _LIBCPP_INLINE_VISIBILITY
_Tp&
__mu(reference_wrapper<_Tp> __t, _Uj&)
{
    return __t.get();
}
/*
template <bool _IsBindExpr, class _Ti, class ..._Uj>
struct __mu_return1 {};

template <class _Ti, class ..._Uj>
struct __mu_return1<true, _Ti, _Uj...>
{
    typedef typename result_of<_Ti(_Uj...)>::type type;
};

template <class _Ti, class ..._Uj, size_t ..._Indx>
inline _LIBCPP_INLINE_VISIBILITY
typename __mu_return1<true, _Ti, _Uj...>::type
__mu_expand(_Ti& __ti, tuple<_Uj...>&& __uj, __tuple_indices<_Indx...>)
{
    __ti(_VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj))...);
}

template <class _Ti, class ..._Uj>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    is_bind_expression<_Ti>::value,
    typename __mu_return1<is_bind_expression<_Ti>::value, _Ti, _Uj...>::type
>::type
__mu(_Ti& __ti, tuple<_Uj...>& __uj)
{
    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
    return  __mu_expand(__ti, __uj, __indices());
}

template <bool IsPh, class _Ti, class _Uj>
struct __mu_return2 {};

template <class _Ti, class _Uj>
struct __mu_return2<true, _Ti, _Uj>
{
    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
};

template <class _Ti, class _Uj>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    0 < is_placeholder<_Ti>::value,
    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
>::type
__mu(_Ti&, _Uj& __uj)
{
    const size_t _Indx = is_placeholder<_Ti>::value - 1;
    // compiler bug workaround
    typename tuple_element<_Indx, _Uj>::type __t = _VSTD::get<_Indx>(__uj);
    return __t;
//    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
}

template <class _Ti, class _Uj>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
    !is_bind_expression<_Ti>::value &&
    is_placeholder<_Ti>::value == 0 &&
    !__is_reference_wrapper<_Ti>::value,
    _Ti&
>::type
__mu(_Ti& __ti, _Uj& __uj)
{
    return __ti;
}

template <class _Ti, bool IsBindEx, bool IsPh, class _TupleUj>
struct ____mu_return;

template <class _Ti, class ..._Uj>
struct ____mu_return<_Ti, true, false, tuple<_Uj...> >
{
    typedef typename result_of<_Ti(_Uj...)>::type type;
};

template <class _Ti, class _TupleUj>
struct ____mu_return<_Ti, false, true, _TupleUj>
{
    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
                                   _TupleUj>::type&& type;
};

template <class _Ti, class _TupleUj>
struct ____mu_return<_Ti, false, false, _TupleUj>
{
    typedef _Ti& type;
};

template <class _Ti, class _TupleUj>
struct __mu_return
    : public ____mu_return<_Ti,
                           is_bind_expression<_Ti>::value,
                           0 < is_placeholder<_Ti>::value,
                           _TupleUj>
{
};

template <class _Ti, class _TupleUj>
struct __mu_return<reference_wrapper<_Ti>, _TupleUj>
{
    typedef _Ti& type;
};

template <class _Fp, class _BoundArgs, class _TupleUj>
struct __bind_return;

template <class _Fp, class ..._BoundArgs, class _TupleUj>
struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
{
    typedef typename __ref_return
    <
        _Fp&,
        typename __mu_return
        <
            _BoundArgs,
            _TupleUj
        >::type...
    >::type type;
};

template <class _Fp, class ..._BoundArgs, class _TupleUj>
struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
{
    typedef typename __ref_return
    <
        _Fp&,
        typename __mu_return
        <
            const _BoundArgs,
            _TupleUj
        >::type...
    >::type type;
};

template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
inline _LIBCPP_INLINE_VISIBILITY
typename __bind_return<_Fp, _BoundArgs, _Args>::type
__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
                _Args&& __args)
{
    return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);
}

template<class _Fp, class ..._BoundArgs>
class __bind
{
    _Fp __f_;
    tuple<_BoundArgs...> __bound_args_;

    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
public:
    template <class _Gp, class ..._BA>
      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
        : __f_(_VSTD::forward<_Gp>(__f)),
          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}

    template <class ..._Args>
        typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
        operator()(_Args&& ...__args)
        {
            // compiler bug workaround
            return __apply_functor(__f_, __bound_args_, __indices(),
                                  tuple<_Args&&...>(__args...));
        }

    template <class ..._Args>
        typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
        operator()(_Args&& ...__args) const
        {
            return __apply_functor(__f_, __bound_args_, __indices(),
                                   tuple<_Args&&...>(__args...));
        }
};

template<class _Fp, class ..._BoundArgs>
struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};

template<class _Rp, class _Fp, class ..._BoundArgs>
class __bind_r
    : public __bind<_Fp, _BoundArgs...>
{
    typedef __bind<_Fp, _BoundArgs...> base;
public:
    typedef _Rp result_type;

    template <class _Gp, class ..._BA>
      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
        : base(_VSTD::forward<_Gp>(__f),
               _VSTD::forward<_BA>(__bound_args)...) {}

    template <class ..._Args>
        result_type
        operator()(_Args&& ...__args)
        {
            return base::operator()(_VSTD::forward<_Args>(__args)...);
        }

    template <class ..._Args>
        result_type
        operator()(_Args&& ...__args) const
        {
            return base::operator()(_VSTD::forward<_Args>(__args)...);
        }
};

template<class _Rp, class _Fp, class ..._BoundArgs>
struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};

template<class _Fp, class ..._BoundArgs>
inline _LIBCPP_INLINE_VISIBILITY
__bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
bind(_Fp&& __f, _BoundArgs&&... __bound_args)
{
    typedef __bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
}

template<class _Rp, class _Fp, class ..._BoundArgs>
inline _LIBCPP_INLINE_VISIBILITY
__bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
bind(_Fp&& __f, _BoundArgs&&... __bound_args)
{
    typedef __bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
}
*/

#endif  // _LIBCPP_FUNCTIONAL_03
