[libcxx] r348778 - Refactor std::function to more easily support alternative implementations.
Eric Fiselier
eric at efcs.ca
Mon Dec 10 10:14:09 PST 2018
Author: ericwf
Date: Mon Dec 10 10:14:09 2018
New Revision: 348778
URL: http://llvm.org/viewvc/llvm-project?rev=348778&view=rev
Log:
Refactor std::function to more easily support alternative implementations.
Patch from Jordan Soyke (jsoyke at google.com)
Reviewed as D55520
This change adds a new internal class, called __value_func, that adds
a minimal subset of value-type semantics to the internal __func interface.
The change is NFC, and is cleanup for the upcoming ABI v2 function implementation (D55045).
Modified:
libcxx/trunk/include/functional
Modified: libcxx/trunk/include/functional
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/functional?rev=348778&r1=348777&r2=348778&view=diff
==============================================================================
--- libcxx/trunk/include/functional (original)
+++ libcxx/trunk/include/functional Mon Dec 10 10:14:09 2018
@@ -1473,6 +1473,81 @@ bool __not_null(function<_Fp> const& __f
namespace __function {
+// __alloc_func holds a functor and an allocator.
+
+template <class _Fp, class _Ap, class _FB> class __alloc_func;
+
+template <class _Fp, class _Ap, class _Rp, class... _ArgTypes>
+class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
+{
+ __compressed_pair<_Fp, _Ap> __f_;
+
+ public:
+ typedef _Fp _Target;
+ typedef _Ap _Alloc;
+
+ _LIBCPP_INLINE_VISIBILITY
+ const _Target& __target() const { return __f_.first(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ const _Alloc& __allocator() const { return __f_.second(); }
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __alloc_func(_Target&& __f)
+ : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
+ _VSTD::forward_as_tuple())
+ {
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __alloc_func(const _Target& __f, const _Alloc& __a)
+ : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
+ _VSTD::forward_as_tuple(__a))
+ {
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __alloc_func(const _Target& __f, _Alloc&& __a)
+ : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
+ _VSTD::forward_as_tuple(_VSTD::move(__a)))
+ {
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __alloc_func(_Target&& __f, _Alloc&& __a)
+ : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
+ _VSTD::forward_as_tuple(_VSTD::move(__a)))
+ {
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ _Rp operator()(_ArgTypes&&... __arg)
+ {
+ typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+ return _Invoker::__call(__f_.first(),
+ _VSTD::forward<_ArgTypes>(__arg)...);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __alloc_func* __clone() const
+ {
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef
+ typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
+ _AA;
+ _AA __a(__f_.second());
+ typedef __allocator_destructor<_AA> _Dp;
+ unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+ ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a));
+ return __hold.release();
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); }
+};
+
+// __base provides an abstract interface for copyable functors.
+
template<class _Fp> class __base;
template<class _Rp, class ..._ArgTypes>
@@ -1494,37 +1569,37 @@ public:
#endif // _LIBCPP_NO_RTTI
};
+// __func implements __base for a given functor type.
+
template<class _FD, class _Alloc, class _FB> class __func;
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
: public __base<_Rp(_ArgTypes...)>
{
- __compressed_pair<_Fp, _Alloc> __f_;
+ __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_;
public:
_LIBCPP_INLINE_VISIBILITY
explicit __func(_Fp&& __f)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
- _VSTD::forward_as_tuple()) {}
+ : __f_(_VSTD::move(__f)) {}
+
_LIBCPP_INLINE_VISIBILITY
explicit __func(const _Fp& __f, const _Alloc& __a)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
- _VSTD::forward_as_tuple(__a)) {}
+ : __f_(__f, __a) {}
_LIBCPP_INLINE_VISIBILITY
explicit __func(const _Fp& __f, _Alloc&& __a)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
- _VSTD::forward_as_tuple(_VSTD::move(__a))) {}
+ : __f_(__f, _VSTD::move(__a)) {}
_LIBCPP_INLINE_VISIBILITY
explicit __func(_Fp&& __f, _Alloc&& __a)
- : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
- _VSTD::forward_as_tuple(_VSTD::move(__a))) {}
+ : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+
virtual __base<_Rp(_ArgTypes...)>* __clone() const;
virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
virtual void destroy() _NOEXCEPT;
virtual void destroy_deallocate() _NOEXCEPT;
- virtual _Rp operator()(_ArgTypes&& ... __arg);
+ virtual _Rp operator()(_ArgTypes&&... __arg);
#ifndef _LIBCPP_NO_RTTI
virtual const void* target(const type_info&) const _NOEXCEPT;
virtual const std::type_info& target_type() const _NOEXCEPT;
@@ -1537,10 +1612,10 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::
{
typedef allocator_traits<_Alloc> __alloc_traits;
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
- _Ap __a(__f_.second());
+ _Ap __a(__f_.__allocator());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
- ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+ ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a));
return __hold.release();
}
@@ -1548,14 +1623,14 @@ template<class _Fp, class _Alloc, class
void
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
{
- ::new (__p) __func(__f_.first(), __f_.second());
+ ::new (__p) __func(__f_.__target(), __f_.__allocator());
}
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
void
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
{
- __f_.~__compressed_pair<_Fp, _Alloc>();
+ __f_.destroy();
}
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
@@ -1564,8 +1639,8 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::
{
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>();
+ _Ap __a(__f_.__allocator());
+ __f_.destroy();
__a.deallocate(this, 1);
}
@@ -1573,8 +1648,7 @@ template<class _Fp, class _Alloc, class
_Rp
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
{
- typedef __invoke_void_return_wrapper<_Rp> _Invoker;
- return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
+ return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
#ifndef _LIBCPP_NO_RTTI
@@ -1584,7 +1658,7 @@ const void*
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
{
if (__ti == typeid(_Fp))
- return &__f_.first();
+ return &__f_.__target();
return (const void*)0;
}
@@ -1597,6 +1671,194 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::
#endif // _LIBCPP_NO_RTTI
+// __value_func creates a value-type from a __func.
+
+template <class _Fp> class __value_func;
+
+template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
+{
+ typename aligned_storage<3 * sizeof(void*)>::type __buf_;
+
+ typedef __base<_Rp(_ArgTypes...)> __func;
+ __func* __f_;
+
+ _LIBCPP_NO_CFI static __func* __as_base(void* p)
+ {
+ return reinterpret_cast<__func*>(p);
+ }
+
+ public:
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func() _NOEXCEPT : __f_(0) {}
+
+ template <class _Fp, class _Alloc>
+ _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc __a)
+ : __f_(0)
+ {
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
+ _FunAlloc;
+
+ if (__function::__not_null(__f))
+ {
+ _FunAlloc __af(__a);
+ if (sizeof(_Fun) <= sizeof(__buf_) &&
+ is_nothrow_copy_constructible<_Fp>::value &&
+ is_nothrow_copy_constructible<_FunAlloc>::value)
+ {
+ __f_ =
+ ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af));
+ }
+ else
+ {
+ typedef __allocator_destructor<_FunAlloc> _Dp;
+ unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1));
+ ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a));
+ __f_ = __hold.release();
+ }
+ }
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func(const __value_func& __f)
+ {
+ if (__f.__f_ == 0)
+ __f_ = 0;
+ else if ((void*)__f.__f_ == &__f.__buf_)
+ {
+ __f_ = __as_base(&__buf_);
+ __f.__f_->__clone(__f_);
+ }
+ else
+ __f_ = __f.__f_->__clone();
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func(__value_func&& __f) _NOEXCEPT
+ {
+ if (__f.__f_ == 0)
+ __f_ = 0;
+ else if ((void*)__f.__f_ == &__f.__buf_)
+ {
+ __f_ = __as_base(&__buf_);
+ __f.__f_->__clone(__f_);
+ }
+ else
+ {
+ __f_ = __f.__f_;
+ __f.__f_ = 0;
+ }
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ ~__value_func()
+ {
+ if ((void*)__f_ == &__buf_)
+ __f_->destroy();
+ else if (__f_)
+ __f_->destroy_deallocate();
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func& operator=(__value_func&& __f)
+ {
+ *this = nullptr;
+ if (__f.__f_ == 0)
+ __f_ = 0;
+ else if ((void*)__f.__f_ == &__f.__buf_)
+ {
+ __f_ = __as_base(&__buf_);
+ __f.__f_->__clone(__f_);
+ }
+ else
+ {
+ __f_ = __f.__f_;
+ __f.__f_ = 0;
+ }
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ __value_func& operator=(nullptr_t)
+ {
+ __func* __f = __f_;
+ __f_ = 0;
+ if ((void*)__f == &__buf_)
+ __f->destroy();
+ else if (__f)
+ __f->destroy_deallocate();
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ _Rp operator()(_ArgTypes&&... __args) const
+ {
+ if (__f_ == 0)
+ __throw_bad_function_call();
+ return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(__value_func& __f) _NOEXCEPT
+ {
+ if (&__f == this)
+ return;
+ if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
+ {
+ typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+ __func* __t = __as_base(&__tempbuf);
+ __f_->__clone(__t);
+ __f_->destroy();
+ __f_ = 0;
+ __f.__f_->__clone(__as_base(&__buf_));
+ __f.__f_->destroy();
+ __f.__f_ = 0;
+ __f_ = __as_base(&__buf_);
+ __t->__clone(__as_base(&__f.__buf_));
+ __t->destroy();
+ __f.__f_ = __as_base(&__f.__buf_);
+ }
+ else if ((void*)__f_ == &__buf_)
+ {
+ __f_->__clone(__as_base(&__f.__buf_));
+ __f_->destroy();
+ __f_ = __f.__f_;
+ __f.__f_ = __as_base(&__f.__buf_);
+ }
+ else if ((void*)__f.__f_ == &__f.__buf_)
+ {
+ __f.__f_->__clone(__as_base(&__buf_));
+ __f.__f_->destroy();
+ __f.__f_ = __f_;
+ __f_ = __as_base(&__buf_);
+ }
+ else
+ _VSTD::swap(__f_, __f.__f_);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != 0; }
+
+#ifndef _LIBCPP_NO_RTTI
+ _LIBCPP_INLINE_VISIBILITY
+ const std::type_info& target_type() const _NOEXCEPT
+ {
+ if (__f_ == 0)
+ return typeid(void);
+ return __f_->target_type();
+ }
+
+ template <typename _Tp>
+ _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT
+ {
+ if (__f_ == 0)
+ return 0;
+ return (const _Tp*)__f_->target(typeid(_Tp));
+ }
+#endif // _LIBCPP_NO_RTTI
+};
+
} // __function
template<class _Rp, class ..._ArgTypes>
@@ -1604,13 +1866,9 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(
: public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
{
- typedef __function::__base<_Rp(_ArgTypes...)> __base;
- typename aligned_storage<3*sizeof(void*)>::type __buf_;
- __base* __f_;
+ typedef __function::__value_func<_Rp(_ArgTypes...)> __func;
- _LIBCPP_NO_CFI static __base *__as_base(void *p) {
- return reinterpret_cast<__base*>(p);
- }
+ __func __f_;
template <class _Fp, bool = __lazy_and<
integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
@@ -1637,9 +1895,9 @@ public:
// construct/copy/destroy:
_LIBCPP_INLINE_VISIBILITY
- function() _NOEXCEPT : __f_(0) {}
+ function() _NOEXCEPT { }
_LIBCPP_INLINE_VISIBILITY
- function(nullptr_t) _NOEXCEPT : __f_(0) {}
+ function(nullptr_t) _NOEXCEPT {}
function(const function&);
function(function&&) _NOEXCEPT;
template<class _Fp, class = _EnableIfCallable<_Fp>>
@@ -1648,10 +1906,10 @@ public:
#if _LIBCPP_STD_VER <= 14
template<class _Alloc>
_LIBCPP_INLINE_VISIBILITY
- function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {}
+ function(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
template<class _Alloc>
_LIBCPP_INLINE_VISIBILITY
- function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {}
+ function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
template<class _Alloc>
function(allocator_arg_t, const _Alloc&, const function&);
template<class _Alloc>
@@ -1680,7 +1938,9 @@ public:
// function capacity:
_LIBCPP_INLINE_VISIBILITY
- _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;}
+ _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
+ return static_cast<bool>(__f_);
+ }
// deleted overloads close possible hole in the type system
template<class _R2, class... _ArgTypes2>
@@ -1700,125 +1960,38 @@ public:
};
template<class _Rp, class ..._ArgTypes>
-function<_Rp(_ArgTypes...)>::function(const function& __f)
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- __f_ = __f.__f_->__clone();
-}
+function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
#if _LIBCPP_STD_VER <= 14
template<class _Rp, class ..._ArgTypes>
template <class _Alloc>
function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
- const function& __f)
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- __f_ = __f.__f_->__clone();
-}
+ const function& __f) : __f_(__f.__f_) {}
#endif
-template<class _Rp, class ..._ArgTypes>
+template <class _Rp, class... _ArgTypes>
function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- {
- __f_ = __f.__f_;
- __f.__f_ = 0;
- }
-}
+ : __f_(_VSTD::move(__f.__f_)) {}
#if _LIBCPP_STD_VER <= 14
template<class _Rp, class ..._ArgTypes>
template <class _Alloc>
function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
- function&& __f)
-{
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- {
- __f_ = __f.__f_;
- __f.__f_ = 0;
- }
-}
+ function&& __f)
+ : __f_(_VSTD::move(__f.__f_)) {}
#endif
-template<class _Rp, class ..._ArgTypes>
+template <class _Rp, class... _ArgTypes>
template <class _Fp, class>
function<_Rp(_ArgTypes...)>::function(_Fp __f)
- : __f_(0)
-{
- if (__function::__not_null(__f))
- {
- typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF;
- if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value)
- {
- __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__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(_VSTD::move(__f), allocator<_Fp>(__a));
- __f_ = __hold.release();
- }
- }
-}
+ : __f_(_VSTD::move(__f), allocator<_Fp>()) {}
#if _LIBCPP_STD_VER <= 14
-template<class _Rp, class ..._ArgTypes>
+template <class _Rp, class... _ArgTypes>
template <class _Fp, class _Alloc, class>
-function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f)
- : __f_(0)
-{
- typedef allocator_traits<_Alloc> __alloc_traits;
- if (__function::__not_null(__f))
- {
- typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
- typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
- _Ap __a(__a0);
- if (sizeof(_FF) <= sizeof(__buf_) &&
- is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
- {
- __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a));
- }
- else
- {
- typedef __allocator_destructor<_Ap> _Dp;
- unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
- ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a));
- __f_ = __hold.release();
- }
- }
-}
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a,
+ _Fp __f)
+ : __f_(_VSTD::move(__f), __a) {}
#endif
template<class _Rp, class ..._ArgTypes>
@@ -1833,19 +2006,7 @@ template<class _Rp, class ..._ArgTypes>
function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
{
- *this = nullptr;
- if (__f.__f_ == 0)
- __f_ = 0;
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f_ = __as_base(&__buf_);
- __f.__f_->__clone(__f_);
- }
- else
- {
- __f_ = __f.__f_;
- __f.__f_ = 0;
- }
+ __f_ = std::move(__f.__f_);
return *this;
}
@@ -1853,12 +2014,7 @@ template<class _Rp, class ..._ArgTypes>
function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
{
- __base* __t = __f_;
- __f_ = 0;
- if ((void *)__t == &__buf_)
- __t->destroy();
- else if (__t)
- __t->destroy_deallocate();
+ __f_ = nullptr;
return *this;
}
@@ -1872,60 +2028,20 @@ function<_Rp(_ArgTypes...)>::operator=(_
}
template<class _Rp, class ..._ArgTypes>
-function<_Rp(_ArgTypes...)>::~function()
-{
- if ((void *)__f_ == &__buf_)
- __f_->destroy();
- else if (__f_)
- __f_->destroy_deallocate();
-}
+function<_Rp(_ArgTypes...)>::~function() {}
template<class _Rp, class ..._ArgTypes>
void
function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
{
- if (_VSTD::addressof(__f) == this)
- return;
- if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_)
- {
- typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
- __base* __t = __as_base(&__tempbuf);
- __f_->__clone(__t);
- __f_->destroy();
- __f_ = 0;
- __f.__f_->__clone(__as_base(&__buf_));
- __f.__f_->destroy();
- __f.__f_ = 0;
- __f_ = __as_base(&__buf_);
- __t->__clone(__as_base(&__f.__buf_));
- __t->destroy();
- __f.__f_ = __as_base(&__f.__buf_);
- }
- else if ((void *)__f_ == &__buf_)
- {
- __f_->__clone(__as_base(&__f.__buf_));
- __f_->destroy();
- __f_ = __f.__f_;
- __f.__f_ = __as_base(&__f.__buf_);
- }
- else if ((void *)__f.__f_ == &__f.__buf_)
- {
- __f.__f_->__clone(__as_base(&__buf_));
- __f.__f_->destroy();
- __f.__f_ = __f_;
- __f_ = __as_base(&__buf_);
- }
- else
- _VSTD::swap(__f_, __f.__f_);
+ __f_.swap(__f.__f_);
}
template<class _Rp, class ..._ArgTypes>
_Rp
function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
{
- if (__f_ == 0)
- __throw_bad_function_call();
- return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
+ return __f_(_VSTD::forward<_ArgTypes>(__arg)...);
}
#ifndef _LIBCPP_NO_RTTI
@@ -1934,9 +2050,7 @@ template<class _Rp, class ..._ArgTypes>
const std::type_info&
function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
{
- if (__f_ == 0)
- return typeid(void);
- return __f_->target_type();
+ return __f_.target_type();
}
template<class _Rp, class ..._ArgTypes>
@@ -1944,9 +2058,7 @@ template <typename _Tp>
_Tp*
function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
{
- if (__f_ == 0)
- return nullptr;
- return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
+ return (_Tp*)(__f_.template target<_Tp>());
}
template<class _Rp, class ..._ArgTypes>
@@ -1954,9 +2066,7 @@ template <typename _Tp>
const _Tp*
function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
{
- if (__f_ == 0)
- return nullptr;
- return (const _Tp*)__f_->target(typeid(_Tp));
+ return __f_.template target<_Tp>();
}
#endif // _LIBCPP_NO_RTTI
More information about the libcxx-commits
mailing list