forked from OSchip/llvm-project
[libc++] Implement shared_ptr methods inline in the class
This patch refactors the shared_ptr methods from being defined out-of-line to being defined inline in the class, like what we do for all new code in the library. The benefits of doing that are that code is not as scattered around and is hence easier to understand, and it avoids a ton of duplication due to SFINAE checks. Defining the method where it is declared also removes the possibility for mismatched attributes. As a fly-by change, this also: - Adds a few _LIBCPP_HIDE_FROM_ABI attributes - Uses __enable_if_t instead of enable_if as a function argument, to match the style that we use everywhere else. Differential Revision: https://reviews.llvm.org/D112478
This commit is contained in:
parent
da1318ccca
commit
b2d25ef2d1
|
@ -430,12 +430,18 @@ private:
|
|||
element_type* __ptr_;
|
||||
__shared_weak_count* __cntrl_;
|
||||
|
||||
struct __nat {int __for_bool_;};
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT
|
||||
: __ptr_(nullptr),
|
||||
__cntrl_(nullptr)
|
||||
{ }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT
|
||||
: __ptr_(nullptr),
|
||||
__cntrl_(nullptr)
|
||||
{ }
|
||||
|
||||
template<class _Yp, class = __enable_if_t<
|
||||
_And<
|
||||
|
@ -457,263 +463,11 @@ public:
|
|||
__enable_weak_this(__p, __p);
|
||||
}
|
||||
|
||||
template<class _Yp, class _Dp>
|
||||
shared_ptr(_Yp* __p, _Dp __d,
|
||||
typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
|
||||
template<class _Yp, class _Dp, class _Alloc>
|
||||
shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
|
||||
typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
|
||||
template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
|
||||
template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
|
||||
template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
shared_ptr(const shared_ptr& __r) _NOEXCEPT;
|
||||
template<class _Yp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
shared_ptr(const shared_ptr<_Yp>& __r,
|
||||
typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat())
|
||||
_NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
shared_ptr(shared_ptr&& __r) _NOEXCEPT;
|
||||
template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r,
|
||||
typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat())
|
||||
_NOEXCEPT;
|
||||
template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
|
||||
typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat());
|
||||
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
|
||||
template<class _Yp>
|
||||
shared_ptr(auto_ptr<_Yp>&& __r,
|
||||
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
|
||||
#endif
|
||||
template <class _Yp, class _Dp>
|
||||
shared_ptr(unique_ptr<_Yp, _Dp>&&,
|
||||
typename enable_if
|
||||
<
|
||||
!is_lvalue_reference<_Dp>::value &&
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||
__nat
|
||||
>::type = __nat());
|
||||
template <class _Yp, class _Dp>
|
||||
shared_ptr(unique_ptr<_Yp, _Dp>&&,
|
||||
typename enable_if
|
||||
<
|
||||
is_lvalue_reference<_Dp>::value &&
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||
__nat
|
||||
>::type = __nat());
|
||||
|
||||
~shared_ptr();
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
|
||||
template<class _Yp>
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
shared_ptr&
|
||||
>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
|
||||
template<class _Yp>
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
shared_ptr&
|
||||
>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
operator=(shared_ptr<_Yp>&& __r);
|
||||
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
|
||||
template<class _Yp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
!is_array<_Yp>::value &&
|
||||
is_convertible<_Yp*, element_type*>::value,
|
||||
shared_ptr
|
||||
>::type&
|
||||
operator=(auto_ptr<_Yp>&& __r);
|
||||
#endif
|
||||
template <class _Yp, class _Dp>
|
||||
typename enable_if
|
||||
<
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||
shared_ptr&
|
||||
>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
operator=(unique_ptr<_Yp, _Dp>&& __r);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void swap(shared_ptr& __r) _NOEXCEPT;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void reset() _NOEXCEPT;
|
||||
template<class _Yp>
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
void
|
||||
>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reset(_Yp* __p);
|
||||
template<class _Yp, class _Dp>
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
void
|
||||
>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reset(_Yp* __p, _Dp __d);
|
||||
template<class _Yp, class _Dp, class _Alloc>
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
void
|
||||
>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
reset(_Yp* __p, _Dp __d, _Alloc __a);
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
element_type* get() const _NOEXCEPT {return __ptr_;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
|
||||
{return *__ptr_;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
element_type* operator->() const _NOEXCEPT
|
||||
{
|
||||
static_assert(!is_array<_Tp>::value,
|
||||
"std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
|
||||
return __ptr_;
|
||||
}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool unique() const _NOEXCEPT {return use_count() == 1;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit operator bool() const _NOEXCEPT {return get() != nullptr;}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
|
||||
{return __cntrl_ < __p.__cntrl_;}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
|
||||
{return __cntrl_ < __p.__cntrl_;}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
__owner_equivalent(const shared_ptr& __p) const
|
||||
{return __cntrl_ == __p.__cntrl_;}
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
typename add_lvalue_reference<element_type>::type
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
operator[](ptrdiff_t __i) const
|
||||
{
|
||||
static_assert(is_array<_Tp>::value,
|
||||
"std::shared_ptr<T>::operator[] is only valid when T is an array type.");
|
||||
return __ptr_[__i];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_NO_RTTI
|
||||
template <class _Dp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Dp* __get_deleter() const _NOEXCEPT
|
||||
{return static_cast<_Dp*>(__cntrl_
|
||||
? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
|
||||
: nullptr);}
|
||||
#endif // _LIBCPP_NO_RTTI
|
||||
|
||||
template<class _Yp, class _CntrlBlk>
|
||||
static shared_ptr<_Tp>
|
||||
__create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
|
||||
{
|
||||
shared_ptr<_Tp> __r;
|
||||
__r.__ptr_ = __p;
|
||||
__r.__cntrl_ = __cntrl;
|
||||
__r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
|
||||
return __r;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class _Yp, bool = is_function<_Yp>::value>
|
||||
struct __shared_ptr_default_allocator
|
||||
{
|
||||
typedef allocator<_Yp> type;
|
||||
};
|
||||
|
||||
template <class _Yp>
|
||||
struct __shared_ptr_default_allocator<_Yp, true>
|
||||
{
|
||||
typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
|
||||
};
|
||||
|
||||
template <class _Yp, class _OrigPtr>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if<is_convertible<_OrigPtr*,
|
||||
const enable_shared_from_this<_Yp>*
|
||||
>::value,
|
||||
void>::type
|
||||
__enable_weak_this(const enable_shared_from_this<_Yp>* __e,
|
||||
_OrigPtr* __ptr) _NOEXCEPT
|
||||
{
|
||||
typedef typename remove_cv<_Yp>::type _RawYp;
|
||||
if (__e && __e->__weak_this_.expired())
|
||||
{
|
||||
__e->__weak_this_ = shared_ptr<_RawYp>(*this,
|
||||
const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
|
||||
|
||||
template <class, class _Yp>
|
||||
struct __shared_ptr_default_delete
|
||||
: default_delete<_Yp> {};
|
||||
|
||||
template <class _Yp, class _Un, size_t _Sz>
|
||||
struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
|
||||
: default_delete<_Yp[]> {};
|
||||
|
||||
template <class _Yp, class _Un>
|
||||
struct __shared_ptr_default_delete<_Yp[], _Un>
|
||||
: default_delete<_Yp[]> {};
|
||||
|
||||
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
|
||||
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
|
||||
};
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
template<class _Tp>
|
||||
shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
|
||||
template<class _Tp, class _Dp>
|
||||
shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
|
||||
#endif
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
_LIBCPP_CONSTEXPR
|
||||
shared_ptr<_Tp>::shared_ptr() _NOEXCEPT
|
||||
: __ptr_(nullptr),
|
||||
__cntrl_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
_LIBCPP_CONSTEXPR
|
||||
shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
|
||||
: __ptr_(nullptr),
|
||||
__cntrl_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp, class _Dp>
|
||||
shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
|
||||
typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
|
||||
template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(_Yp* __p, _Dp __d)
|
||||
: __ptr_(__p)
|
||||
{
|
||||
{
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
|
@ -734,40 +488,13 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
|
|||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Dp>
|
||||
shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
|
||||
: __ptr_(nullptr)
|
||||
{
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
__cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
|
||||
#else
|
||||
__cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
|
||||
#endif // not _LIBCPP_CXX03_LANG
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
__d(__p);
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp, class _Dp, class _Alloc>
|
||||
shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
|
||||
typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
|
||||
template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
|
||||
: __ptr_(__p)
|
||||
{
|
||||
{
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
|
@ -793,13 +520,39 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
|
|||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Dp, class _Alloc>
|
||||
shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
|
||||
template<class _Dp>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(nullptr_t __p, _Dp __d)
|
||||
: __ptr_(nullptr)
|
||||
{
|
||||
{
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
__cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
|
||||
#else
|
||||
__cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
|
||||
#endif // not _LIBCPP_CXX03_LANG
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
__d(__p);
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
template<class _Dp, class _Alloc>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
|
||||
: __ptr_(nullptr)
|
||||
{
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
|
@ -824,90 +577,87 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
|
|||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
|
||||
template<class _Yp>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
|
||||
: __ptr_(__p),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
{
|
||||
if (__cntrl_)
|
||||
__cntrl_->__add_shared();
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(const shared_ptr& __r) _NOEXCEPT
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
{
|
||||
if (__cntrl_)
|
||||
__cntrl_->__add_shared();
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
|
||||
typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type)
|
||||
_NOEXCEPT
|
||||
template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
{
|
||||
if (__cntrl_)
|
||||
__cntrl_->__add_shared();
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(shared_ptr&& __r) _NOEXCEPT
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
{
|
||||
__r.__ptr_ = nullptr;
|
||||
__r.__cntrl_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
|
||||
typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type)
|
||||
_NOEXCEPT
|
||||
template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_)
|
||||
{
|
||||
{
|
||||
__r.__ptr_ = nullptr;
|
||||
__r.__cntrl_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
explicit shared_ptr(const weak_ptr<_Yp>& __r)
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
|
||||
{
|
||||
if (__cntrl_ == nullptr)
|
||||
__throw_bad_weak_ptr();
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
|
||||
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
|
||||
template<class _Yp, class = __enable_if_t<is_convertible<_Yp*, element_type*>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(auto_ptr<_Yp>&& __r)
|
||||
: __ptr_(__r.get())
|
||||
{
|
||||
{
|
||||
typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
|
||||
__cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
|
||||
__enable_weak_this(__r.get(), __r.get());
|
||||
__r.release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class _Tp>
|
||||
template <class _Yp, class _Dp>
|
||||
shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
||||
typename enable_if
|
||||
<
|
||||
template <class _Yp, class _Dp, class = __enable_if_t<
|
||||
!is_lvalue_reference<_Dp>::value &&
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||
__nat
|
||||
>::type)
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
|
||||
: __ptr_(__r.get())
|
||||
{
|
||||
{
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
if (__ptr_ == nullptr)
|
||||
__cntrl_ = nullptr;
|
||||
|
@ -920,19 +670,16 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
|||
__enable_weak_this(__r.get(), __r.get());
|
||||
}
|
||||
__r.release();
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template <class _Yp, class _Dp>
|
||||
shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
||||
typename enable_if
|
||||
<
|
||||
template <class _Yp, class _Dp, class = void, class = __enable_if_t<
|
||||
is_lvalue_reference<_Dp>::value &&
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
|
||||
__nat
|
||||
>::type)
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
|
||||
: __ptr_(__r.get())
|
||||
{
|
||||
{
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
if (__ptr_ == nullptr)
|
||||
__cntrl_ = nullptr;
|
||||
|
@ -947,148 +694,252 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
|
|||
__enable_weak_this(__r.get(), __r.get());
|
||||
}
|
||||
__r.release();
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
shared_ptr<_Tp>::~shared_ptr()
|
||||
{
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
~shared_ptr()
|
||||
{
|
||||
if (__cntrl_)
|
||||
__cntrl_->__release_shared();
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
shared_ptr<_Tp>&
|
||||
shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
|
||||
{
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT
|
||||
{
|
||||
shared_ptr(__r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
shared_ptr<_Tp>&
|
||||
>::type
|
||||
shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
|
||||
{
|
||||
template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
|
||||
{
|
||||
shared_ptr(__r).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
shared_ptr<_Tp>&
|
||||
shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
|
||||
{
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT
|
||||
{
|
||||
shared_ptr(_VSTD::move(__r)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
shared_ptr<_Tp>&
|
||||
>::type
|
||||
shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
|
||||
{
|
||||
template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r)
|
||||
{
|
||||
shared_ptr(_VSTD::move(__r)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
template<class _Yp, class = __enable_if_t<
|
||||
!is_array<_Yp>::value &&
|
||||
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
|
||||
shared_ptr<_Tp>
|
||||
>::type&
|
||||
shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
|
||||
{
|
||||
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp>& operator=(auto_ptr<_Yp>&& __r)
|
||||
{
|
||||
shared_ptr(_VSTD::move(__r)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class _Tp>
|
||||
template <class _Yp, class _Dp>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
|
||||
typename shared_ptr<_Tp>::element_type*>::value,
|
||||
shared_ptr<_Tp>&
|
||||
>::type
|
||||
shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
|
||||
{
|
||||
template <class _Yp, class _Dp, class = __enable_if_t<
|
||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r)
|
||||
{
|
||||
shared_ptr(_VSTD::move(__r)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
void
|
||||
shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
|
||||
{
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void swap(shared_ptr& __r) _NOEXCEPT
|
||||
{
|
||||
_VSTD::swap(__ptr_, __r.__ptr_);
|
||||
_VSTD::swap(__cntrl_, __r.__cntrl_);
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
inline
|
||||
void
|
||||
shared_ptr<_Tp>::reset() _NOEXCEPT
|
||||
{
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void reset() _NOEXCEPT
|
||||
{
|
||||
shared_ptr().swap(*this);
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
void
|
||||
>::type
|
||||
shared_ptr<_Tp>::reset(_Yp* __p)
|
||||
{
|
||||
template<class _Yp, class = __enable_if_t<
|
||||
__compatible_with<_Yp, _Tp>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void reset(_Yp* __p)
|
||||
{
|
||||
shared_ptr(__p).swap(*this);
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp, class _Dp>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
void
|
||||
>::type
|
||||
shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
|
||||
{
|
||||
template<class _Yp, class _Dp, class = __enable_if_t<
|
||||
__compatible_with<_Yp, _Tp>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void reset(_Yp* __p, _Dp __d)
|
||||
{
|
||||
shared_ptr(__p, __d).swap(*this);
|
||||
}
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp, class _Dp, class _Alloc>
|
||||
inline
|
||||
typename enable_if
|
||||
<
|
||||
__compatible_with<_Yp, _Tp>::value,
|
||||
void
|
||||
>::type
|
||||
shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
|
||||
{
|
||||
template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<
|
||||
__compatible_with<_Yp, _Tp>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void reset(_Yp* __p, _Dp __d, _Alloc __a)
|
||||
{
|
||||
shared_ptr(__p, __d, __a).swap(*this);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
element_type* get() const _NOEXCEPT
|
||||
{
|
||||
return __ptr_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
|
||||
{
|
||||
return *__ptr_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
element_type* operator->() const _NOEXCEPT
|
||||
{
|
||||
static_assert(!is_array<_Tp>::value,
|
||||
"std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
|
||||
return __ptr_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
long use_count() const _NOEXCEPT
|
||||
{
|
||||
return __cntrl_ ? __cntrl_->use_count() : 0;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool unique() const _NOEXCEPT
|
||||
{
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
explicit operator bool() const _NOEXCEPT
|
||||
{
|
||||
return get() != nullptr;
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
|
||||
{
|
||||
return __cntrl_ < __p.__cntrl_;
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
|
||||
{
|
||||
return __cntrl_ < __p.__cntrl_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool __owner_equivalent(const shared_ptr& __p) const
|
||||
{
|
||||
return __cntrl_ == __p.__cntrl_;
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
typename add_lvalue_reference<element_type>::type operator[](ptrdiff_t __i) const
|
||||
{
|
||||
static_assert(is_array<_Tp>::value,
|
||||
"std::shared_ptr<T>::operator[] is only valid when T is an array type.");
|
||||
return __ptr_[__i];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_NO_RTTI
|
||||
template <class _Dp>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Dp* __get_deleter() const _NOEXCEPT
|
||||
{
|
||||
return static_cast<_Dp*>(__cntrl_
|
||||
? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
|
||||
: nullptr);
|
||||
}
|
||||
#endif // _LIBCPP_NO_RTTI
|
||||
|
||||
template<class _Yp, class _CntrlBlk>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
|
||||
{
|
||||
shared_ptr<_Tp> __r;
|
||||
__r.__ptr_ = __p;
|
||||
__r.__cntrl_ = __cntrl;
|
||||
__r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
|
||||
return __r;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class _Yp, bool = is_function<_Yp>::value>
|
||||
struct __shared_ptr_default_allocator
|
||||
{
|
||||
typedef allocator<_Yp> type;
|
||||
};
|
||||
|
||||
template <class _Yp>
|
||||
struct __shared_ptr_default_allocator<_Yp, true>
|
||||
{
|
||||
typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
|
||||
};
|
||||
|
||||
template <class _Yp, class _OrigPtr, class = __enable_if_t<
|
||||
is_convertible<_OrigPtr*, const enable_shared_from_this<_Yp>*>::value
|
||||
> >
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void __enable_weak_this(const enable_shared_from_this<_Yp>* __e, _OrigPtr* __ptr) _NOEXCEPT
|
||||
{
|
||||
typedef typename remove_cv<_Yp>::type _RawYp;
|
||||
if (__e && __e->__weak_this_.expired())
|
||||
{
|
||||
__e->__weak_this_ = shared_ptr<_RawYp>(*this,
|
||||
const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void __enable_weak_this(...) _NOEXCEPT { }
|
||||
|
||||
template <class, class _Yp>
|
||||
struct __shared_ptr_default_delete
|
||||
: default_delete<_Yp>
|
||||
{ };
|
||||
|
||||
template <class _Yp, class _Un, size_t _Sz>
|
||||
struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
|
||||
: default_delete<_Yp[]>
|
||||
{ };
|
||||
|
||||
template <class _Yp, class _Un>
|
||||
struct __shared_ptr_default_delete<_Yp[], _Un>
|
||||
: default_delete<_Yp[]>
|
||||
{ };
|
||||
|
||||
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
|
||||
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
|
||||
};
|
||||
|
||||
#if _LIBCPP_STD_VER > 14
|
||||
template<class _Tp>
|
||||
shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
|
||||
template<class _Tp, class _Dp>
|
||||
shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
|
||||
#endif
|
||||
|
||||
//
|
||||
// std::allocate_shared and std::make_shared
|
||||
|
@ -1573,17 +1424,6 @@ weak_ptr<_Tp>::reset() _NOEXCEPT
|
|||
weak_ptr().swap(*this);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
template<class _Yp>
|
||||
shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
|
||||
typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type)
|
||||
: __ptr_(__r.__ptr_),
|
||||
__cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
|
||||
{
|
||||
if (__cntrl_ == nullptr)
|
||||
__throw_bad_weak_ptr();
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
shared_ptr<_Tp>
|
||||
weak_ptr<_Tp>::lock() const _NOEXCEPT
|
||||
|
|
Loading…
Reference in New Issue