diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -430,12 +430,18 @@ 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 - shared_ptr(_Yp* __p, _Dp __d, - typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); - template - 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 shared_ptr(nullptr_t __p, _Dp __d); - template shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); - template _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 - _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 _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r, - typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat()) - _NOEXCEPT; - template 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 - shared_ptr(auto_ptr<_Yp>&& __r, - typename enable_if::value, __nat>::type = __nat()); -#endif - template - shared_ptr(unique_ptr<_Yp, _Dp>&&, - typename enable_if - < - !is_lvalue_reference<_Dp>::value && - is_convertible::pointer, element_type*>::value, - __nat - >::type = __nat()); - template - shared_ptr(unique_ptr<_Yp, _Dp>&&, - typename enable_if - < - is_lvalue_reference<_Dp>::value && - is_convertible::pointer, element_type*>::value, - __nat - >::type = __nat()); - - ~shared_ptr(); + template::value> > + _LIBCPP_HIDE_FROM_ABI + shared_ptr(_Yp* __p, _Dp __d) + : __ptr_(__p) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer<_Yp*, _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 + __enable_weak_this(__p, __p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __d(__p); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } - _LIBCPP_INLINE_VISIBILITY - shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT; - template - 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 - 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 - _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 - typename enable_if - < - is_convertible::pointer, element_type*>::value, - shared_ptr& - >::type - _LIBCPP_INLINE_VISIBILITY - operator=(unique_ptr<_Yp, _Dp>&& __r); + template::value> > + _LIBCPP_HIDE_FROM_ABI + shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) + : __ptr_(__p) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; + typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; + typedef __allocator_destructor<_A2> _D2; + _A2 __a2(__a); + unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); + ::new ((void*)_VSTD::addressof(*__hold2.get())) +#ifndef _LIBCPP_CXX03_LANG + _CntrlBlk(__p, _VSTD::move(__d), __a); +#else + _CntrlBlk(__p, __d, __a); +#endif // not _LIBCPP_CXX03_LANG + __cntrl_ = _VSTD::addressof(*__hold2.release()); + __enable_weak_this(__p, __p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __d(__p); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } + + template + _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 _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 + _LIBCPP_HIDE_FROM_ABI + shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) + : __ptr_(nullptr) + { +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + typedef __shared_ptr_pointer _CntrlBlk; + typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; + typedef __allocator_destructor<_A2> _D2; + _A2 __a2(__a); + unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); + ::new ((void*)_VSTD::addressof(*__hold2.get())) +#ifndef _LIBCPP_CXX03_LANG + _CntrlBlk(__p, _VSTD::move(__d), __a); +#else + _CntrlBlk(__p, __d, __a); +#endif // not _LIBCPP_CXX03_LANG + __cntrl_ = _VSTD::addressof(*__hold2.release()); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + __d(__p); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS + } - _LIBCPP_INLINE_VISIBILITY - void swap(shared_ptr& __r) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - void reset() _NOEXCEPT; template - typename enable_if - < - __compatible_with<_Yp, _Tp>::value, - void - >::type - _LIBCPP_INLINE_VISIBILITY - reset(_Yp* __p); - template - typename enable_if - < - __compatible_with<_Yp, _Tp>::value, - void - >::type - _LIBCPP_INLINE_VISIBILITY - reset(_Yp* __p, _Dp __d); - template - typename enable_if - < - __compatible_with<_Yp, _Tp>::value, - void - >::type - _LIBCPP_INLINE_VISIBILITY - reset(_Yp* __p, _Dp __d, _Alloc __a); + _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(); + } - _LIBCPP_INLINE_VISIBILITY - element_type* get() const _NOEXCEPT {return __ptr_;} - _LIBCPP_INLINE_VISIBILITY - typename add_lvalue_reference::type operator*() const _NOEXCEPT - {return *__ptr_;} - _LIBCPP_INLINE_VISIBILITY - element_type* operator->() const _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI + shared_ptr(const shared_ptr& __r) _NOEXCEPT + : __ptr_(__r.__ptr_), + __cntrl_(__r.__cntrl_) { - static_assert(!is_array<_Tp>::value, - "std::shared_ptr::operator-> is only valid when T is not an array type."); - return __ptr_; + if (__cntrl_) + __cntrl_->__add_shared(); } - _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 - _LIBCPP_INLINE_VISIBILITY - bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT - {return __cntrl_ < __p.__cntrl_;} - template - _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::type - _LIBCPP_INLINE_VISIBILITY - operator[](ptrdiff_t __i) const + template::value> > + _LIBCPP_HIDE_FROM_ABI + shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT + : __ptr_(__r.__ptr_), + __cntrl_(__r.__cntrl_) { - static_assert(is_array<_Tp>::value, - "std::shared_ptr::operator[] is only valid when T is an array type."); - return __ptr_[__i]; + if (__cntrl_) + __cntrl_->__add_shared(); } -#endif -#ifndef _LIBCPP_NO_RTTI - template - _LIBCPP_INLINE_VISIBILITY - _Dp* __get_deleter() const _NOEXCEPT - {return static_cast<_Dp*>(__cntrl_ - ? const_cast(__cntrl_->__get_deleter(typeid(_Dp))) - : nullptr);} -#endif // _LIBCPP_NO_RTTI + _LIBCPP_HIDE_FROM_ABI + shared_ptr(shared_ptr&& __r) _NOEXCEPT + : __ptr_(__r.__ptr_), + __cntrl_(__r.__cntrl_) + { + __r.__ptr_ = nullptr; + __r.__cntrl_ = nullptr; + } - template - static shared_ptr<_Tp> - __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT + template::value> > + _LIBCPP_HIDE_FROM_ABI + shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT + : __ptr_(__r.__ptr_), + __cntrl_(__r.__cntrl_) { - shared_ptr<_Tp> __r; - __r.__ptr_ = __p; - __r.__cntrl_ = __cntrl; - __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); - return __r; + __r.__ptr_ = nullptr; + __r.__cntrl_ = nullptr; } -private: - template ::value> - struct __shared_ptr_default_allocator - { - typedef allocator<_Yp> type; - }; + template::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(); + } - template - struct __shared_ptr_default_allocator<_Yp, true> +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) + template::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 ::value && + is_convertible::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; + else +#endif { - typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type; - }; + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer::pointer, _Dp, _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); + __enable_weak_this(__r.get(), __r.get()); + } + __r.release(); + } - template - _LIBCPP_INLINE_VISIBILITY - typename enable_if* - >::value, - void>::type - __enable_weak_this(const enable_shared_from_this<_Yp>* __e, - _OrigPtr* __ptr) _NOEXCEPT + template ::value && + is_convertible::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; + else +#endif { - 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(__ptr))); - } + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer::pointer, + reference_wrapper::type>, + _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT()); + __enable_weak_this(__r.get(), __r.get()); } + __r.release(); + } - _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI + ~shared_ptr() + { + if (__cntrl_) + __cntrl_->__release_shared(); + } - template - struct __shared_ptr_default_delete - : default_delete<_Yp> {}; + _LIBCPP_HIDE_FROM_ABI + shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT + { + shared_ptr(__r).swap(*this); + return *this; + } - template - struct __shared_ptr_default_delete<_Yp[_Sz], _Un> - : default_delete<_Yp[]> {}; + template::value> > + _LIBCPP_HIDE_FROM_ABI + shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT + { + shared_ptr(__r).swap(*this); + return *this; + } - template - struct __shared_ptr_default_delete<_Yp[], _Un> - : default_delete<_Yp[]> {}; + _LIBCPP_HIDE_FROM_ABI + shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT + { + shared_ptr(_VSTD::move(__r)).swap(*this); + return *this; + } - template friend class _LIBCPP_TEMPLATE_VIS shared_ptr; - template friend class _LIBCPP_TEMPLATE_VIS weak_ptr; -}; + template::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 -template -shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; -template -shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) + template::value && + 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 -inline -_LIBCPP_CONSTEXPR -shared_ptr<_Tp>::shared_ptr() _NOEXCEPT - : __ptr_(nullptr), - __cntrl_(nullptr) -{ -} - -template -inline -_LIBCPP_CONSTEXPR -shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT - : __ptr_(nullptr), - __cntrl_(nullptr) -{ -} + template ::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 -template -shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, - typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) - : __ptr_(__p) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try + _LIBCPP_HIDE_FROM_ABI + void swap(shared_ptr& __r) _NOEXCEPT { -#endif // _LIBCPP_NO_EXCEPTIONS - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, _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 - __enable_weak_this(__p, __p); -#ifndef _LIBCPP_NO_EXCEPTIONS + _VSTD::swap(__ptr_, __r.__ptr_); + _VSTD::swap(__cntrl_, __r.__cntrl_); } - catch (...) + + _LIBCPP_HIDE_FROM_ABI + void reset() _NOEXCEPT { - __d(__p); - throw; + shared_ptr().swap(*this); } -#endif // _LIBCPP_NO_EXCEPTIONS -} -template -template -shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) - : __ptr_(nullptr) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try + template::value + > > + _LIBCPP_HIDE_FROM_ABI + void reset(_Yp* __p) { -#endif // _LIBCPP_NO_EXCEPTIONS - typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; - typedef __shared_ptr_pointer _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 + shared_ptr(__p).swap(*this); + } + + template::value + > > + _LIBCPP_HIDE_FROM_ABI + void reset(_Yp* __p, _Dp __d) + { + shared_ptr(__p, __d).swap(*this); } - catch (...) + + template::value + > > + _LIBCPP_HIDE_FROM_ABI + void reset(_Yp* __p, _Dp __d, _Alloc __a) { - __d(__p); - throw; + shared_ptr(__p, __d, __a).swap(*this); } -#endif // _LIBCPP_NO_EXCEPTIONS -} -template -template -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) - : __ptr_(__p) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try + _LIBCPP_HIDE_FROM_ABI + element_type* get() const _NOEXCEPT { -#endif // _LIBCPP_NO_EXCEPTIONS - typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; - typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; - typedef __allocator_destructor<_A2> _D2; - _A2 __a2(__a); - unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); - ::new ((void*)_VSTD::addressof(*__hold2.get())) -#ifndef _LIBCPP_CXX03_LANG - _CntrlBlk(__p, _VSTD::move(__d), __a); -#else - _CntrlBlk(__p, __d, __a); -#endif // not _LIBCPP_CXX03_LANG - __cntrl_ = _VSTD::addressof(*__hold2.release()); - __enable_weak_this(__p, __p); -#ifndef _LIBCPP_NO_EXCEPTIONS + return __ptr_; } - catch (...) + + _LIBCPP_HIDE_FROM_ABI + typename add_lvalue_reference::type operator*() const _NOEXCEPT { - __d(__p); - throw; + return *__ptr_; } -#endif // _LIBCPP_NO_EXCEPTIONS -} -template -template -shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) - : __ptr_(nullptr) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try + _LIBCPP_HIDE_FROM_ABI + element_type* operator->() const _NOEXCEPT { -#endif // _LIBCPP_NO_EXCEPTIONS - typedef __shared_ptr_pointer _CntrlBlk; - typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; - typedef __allocator_destructor<_A2> _D2; - _A2 __a2(__a); - unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); - ::new ((void*)_VSTD::addressof(*__hold2.get())) -#ifndef _LIBCPP_CXX03_LANG - _CntrlBlk(__p, _VSTD::move(__d), __a); -#else - _CntrlBlk(__p, __d, __a); -#endif // not _LIBCPP_CXX03_LANG - __cntrl_ = _VSTD::addressof(*__hold2.release()); -#ifndef _LIBCPP_NO_EXCEPTIONS + static_assert(!is_array<_Tp>::value, + "std::shared_ptr::operator-> is only valid when T is not an array type."); + return __ptr_; } - catch (...) + + _LIBCPP_HIDE_FROM_ABI + long use_count() const _NOEXCEPT { - __d(__p); - throw; + return __cntrl_ ? __cntrl_->use_count() : 0; } -#endif // _LIBCPP_NO_EXCEPTIONS -} -template -template -inline -shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT - : __ptr_(__p), - __cntrl_(__r.__cntrl_) -{ - if (__cntrl_) - __cntrl_->__add_shared(); -} + _LIBCPP_HIDE_FROM_ABI + bool unique() const _NOEXCEPT + { + return use_count() == 1; + } -template -inline -shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT - : __ptr_(__r.__ptr_), - __cntrl_(__r.__cntrl_) -{ - if (__cntrl_) - __cntrl_->__add_shared(); -} + _LIBCPP_HIDE_FROM_ABI + explicit operator bool() const _NOEXCEPT + { + return get() != nullptr; + } -template -template -inline -shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, - typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type) - _NOEXCEPT - : __ptr_(__r.__ptr_), - __cntrl_(__r.__cntrl_) -{ - if (__cntrl_) - __cntrl_->__add_shared(); -} + template + _LIBCPP_HIDE_FROM_ABI + bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT + { + return __cntrl_ < __p.__cntrl_; + } -template -inline -shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT - : __ptr_(__r.__ptr_), - __cntrl_(__r.__cntrl_) -{ - __r.__ptr_ = nullptr; - __r.__cntrl_ = nullptr; -} + template + _LIBCPP_HIDE_FROM_ABI + bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT + { + return __cntrl_ < __p.__cntrl_; + } -template -template -inline -shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r, - typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type) - _NOEXCEPT - : __ptr_(__r.__ptr_), - __cntrl_(__r.__cntrl_) -{ - __r.__ptr_ = nullptr; - __r.__cntrl_ = nullptr; -} + _LIBCPP_HIDE_FROM_ABI + bool __owner_equivalent(const shared_ptr& __p) const + { + return __cntrl_ == __p.__cntrl_; + } -#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) -template -template -shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r, - typename enable_if::value, __nat>::type) - : __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(); -} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_HIDE_FROM_ABI + typename add_lvalue_reference::type operator[](ptrdiff_t __i) const + { + static_assert(is_array<_Tp>::value, + "std::shared_ptr::operator[] is only valid when T is an array type."); + return __ptr_[__i]; + } #endif -template -template -shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, - typename enable_if - < - !is_lvalue_reference<_Dp>::value && - is_convertible::pointer, element_type*>::value, - __nat - >::type) - : __ptr_(__r.get()) -{ -#if _LIBCPP_STD_VER > 11 - if (__ptr_ == nullptr) - __cntrl_ = nullptr; - else -#endif +#ifndef _LIBCPP_NO_RTTI + template + _LIBCPP_HIDE_FROM_ABI + _Dp* __get_deleter() const _NOEXCEPT { - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer::pointer, _Dp, _AllocT > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); - __enable_weak_this(__r.get(), __r.get()); + return static_cast<_Dp*>(__cntrl_ + ? const_cast(__cntrl_->__get_deleter(typeid(_Dp))) + : nullptr); } - __r.release(); -} +#endif // _LIBCPP_NO_RTTI -template -template -shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, - typename enable_if - < - is_lvalue_reference<_Dp>::value && - is_convertible::pointer, element_type*>::value, - __nat - >::type) - : __ptr_(__r.get()) -{ -#if _LIBCPP_STD_VER > 11 - if (__ptr_ == nullptr) - __cntrl_ = nullptr; - else -#endif + template + _LIBCPP_HIDE_FROM_ABI + static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT { - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer::pointer, - reference_wrapper::type>, - _AllocT > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT()); - __enable_weak_this(__r.get(), __r.get()); + shared_ptr<_Tp> __r; + __r.__ptr_ = __p; + __r.__cntrl_ = __cntrl; + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); + return __r; } - __r.release(); -} - -template -shared_ptr<_Tp>::~shared_ptr() -{ - if (__cntrl_) - __cntrl_->__release_shared(); -} - -template -inline -shared_ptr<_Tp>& -shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT -{ - shared_ptr(__r).swap(*this); - return *this; -} - -template -template -inline -typename enable_if -< - __compatible_with<_Yp, _Tp>::value, - shared_ptr<_Tp>& ->::type -shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT -{ - shared_ptr(__r).swap(*this); - return *this; -} -template -inline -shared_ptr<_Tp>& -shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT -{ - shared_ptr(_VSTD::move(__r)).swap(*this); - return *this; -} +private: + template ::value> + struct __shared_ptr_default_allocator + { + typedef allocator<_Yp> type; + }; -template -template -inline -typename enable_if -< - __compatible_with<_Yp, _Tp>::value, - shared_ptr<_Tp>& ->::type -shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r) -{ - shared_ptr(_VSTD::move(__r)).swap(*this); - return *this; -} + template + struct __shared_ptr_default_allocator<_Yp, true> + { + typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type; + }; -#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) -template -template -inline -typename enable_if -< - !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) -{ - shared_ptr(_VSTD::move(__r)).swap(*this); - return *this; -} -#endif + template *>::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(__ptr))); + } + } -template -template -inline -typename enable_if -< - is_convertible::pointer, - typename shared_ptr<_Tp>::element_type*>::value, - shared_ptr<_Tp>& ->::type -shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r) -{ - shared_ptr(_VSTD::move(__r)).swap(*this); - return *this; -} + _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(...) _NOEXCEPT { } -template -inline -void -shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT -{ - _VSTD::swap(__ptr_, __r.__ptr_); - _VSTD::swap(__cntrl_, __r.__cntrl_); -} + template + struct __shared_ptr_default_delete + : default_delete<_Yp> + { }; -template -inline -void -shared_ptr<_Tp>::reset() _NOEXCEPT -{ - shared_ptr().swap(*this); -} + template + struct __shared_ptr_default_delete<_Yp[_Sz], _Un> + : default_delete<_Yp[]> + { }; -template -template -inline -typename enable_if -< - __compatible_with<_Yp, _Tp>::value, - void ->::type -shared_ptr<_Tp>::reset(_Yp* __p) -{ - shared_ptr(__p).swap(*this); -} + template + struct __shared_ptr_default_delete<_Yp[], _Un> + : default_delete<_Yp[]> + { }; -template -template -inline -typename enable_if -< - __compatible_with<_Yp, _Tp>::value, - void ->::type -shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) -{ - shared_ptr(__p, __d).swap(*this); -} + template friend class _LIBCPP_TEMPLATE_VIS shared_ptr; + template friend class _LIBCPP_TEMPLATE_VIS weak_ptr; +}; +#if _LIBCPP_STD_VER > 14 template -template -inline -typename enable_if -< - __compatible_with<_Yp, _Tp>::value, - void ->::type -shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) -{ - shared_ptr(__p, __d, __a).swap(*this); -} +shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; +template +shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; +#endif // // std::allocate_shared and std::make_shared @@ -1573,17 +1424,6 @@ weak_ptr().swap(*this); } -template -template -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 shared_ptr<_Tp> weak_ptr<_Tp>::lock() const _NOEXCEPT