
The C++03 version of function tried to default construct the allocator in the uses allocator constructors when no allocation was performed. These constructors would fail to compile when used with allocators that had no default constructor. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@239708 91177308-0d34-0410-b5e6-96231b3b80d8
2128 lines
59 KiB
C++
2128 lines
59 KiB
C++
// -*- 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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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 allocator_traits<_Alloc> __alloc_traits;
|
|
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _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, __a0);
|
|
}
|
|
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;
|
|
return *this;
|
|
}
|
|
|
|
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, __a0);
|
|
}
|
|
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;
|
|
return *this;
|
|
}
|
|
|
|
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, __a0);
|
|
}
|
|
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;
|
|
return *this;
|
|
}
|
|
|
|
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, __a0);
|
|
}
|
|
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;
|
|
return *this;
|
|
}
|
|
|
|
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
|