diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -3921,6 +3921,42 @@ template friend class _LIBCPP_TEMPLATE_VIS shared_ptr; template friend class _LIBCPP_TEMPLATE_VIS weak_ptr; + + template, + class _Alloc = typename __shared_ptr_default_allocator<_Yp>::type> + static __shared_weak_count* + __allocate_shared(_Yp* __p, _Deleter __d = _Deleter(), _Alloc __a = _Alloc()) + { + typedef __shared_ptr_pointer<_Yp*, _Deleter, _Alloc> _CT; + typedef typename __allocator_traits_rebind<_Alloc, _CT>::type _A2; + typedef __allocator_destructor<_A2> _D2; + + _A2 __a2(__a); + unique_ptr<_CT, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); + + ::new(static_cast(_VSTD::addressof(*__hold2.get()))) + _CT(__p, __d, __a); + + return _VSTD::addressof(*__hold2.release()); + } + + template, + class _Alloc = typename __shared_ptr_default_allocator<_Tp>::type> + static __shared_weak_count* + __allocate_shared(nullptr_t __p, _Deleter __d = _Deleter(), _Alloc __a = _Alloc()) + { + typedef __shared_ptr_pointer<_Tp*, _Deleter, _Alloc> _CT; + typedef typename __allocator_traits_rebind<_Alloc, _CT>::type _A2; + typedef __allocator_destructor<_A2> _D2; + + _A2 __a2(__a); + unique_ptr<_CT, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); + + ::new(static_cast(_VSTD::addressof(*__hold2.get()))) + _CT(__p, __d, __a); + + return _VSTD::addressof(*__hold2.release()); + } }; @@ -3929,18 +3965,14 @@ _LIBCPP_CONSTEXPR shared_ptr<_Tp>::shared_ptr() _NOEXCEPT : __ptr_(0), - __cntrl_(0) -{ -} + __cntrl_(0) {} template inline _LIBCPP_CONSTEXPR shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT : __ptr_(0), - __cntrl_(0) -{ -} + __cntrl_(0) {} template template @@ -3948,12 +3980,17 @@ typename enable_if::value, __nat>::type) : __ptr_(__p) { - unique_ptr<_Yp> __hold(__p); - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT()); - __hold.release(); - __enable_weak_this(__p, __p); +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif // _LIBCPP_NO_EXCEPTIONS + __cntrl_ = __allocate_shared(__p); + __enable_weak_this(__p, __p); +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + default_delete<_Yp>()(__p); + throw; + } +#endif // _LIBCPP_NO_EXCEPTIONS } template @@ -3963,17 +4000,12 @@ : __ptr_(__p) { #ifndef _LIBCPP_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_NO_EXCEPTIONS - typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); - __enable_weak_this(__p, __p); + __cntrl_ = __allocate_shared(__p, __d); + __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { + } catch (...) { __d(__p); throw; } @@ -3986,16 +4018,11 @@ : __ptr_(0) { #ifndef _LIBCPP_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_NO_EXCEPTIONS - typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; - typedef __shared_ptr_pointer _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); + __cntrl_ = __allocate_shared(__p, __d); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { + } catch (...) { __d(__p); throw; } @@ -4009,22 +4036,12 @@ : __ptr_(__p) { #ifndef _LIBCPP_NO_EXCEPTIONS - try - { + 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(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__p, __d, __a); - __cntrl_ = _VSTD::addressof(*__hold2.release()); - __enable_weak_this(__p, __p); + __cntrl_ = __allocate_shared(__p, __d, __a); + __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { + } catch (...) { __d(__p); throw; } @@ -4037,21 +4054,11 @@ : __ptr_(0) { #ifndef _LIBCPP_NO_EXCEPTIONS - try - { + 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(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__p, __d, __a); - __cntrl_ = _VSTD::addressof(*__hold2.release()); + __cntrl_ = __allocate_shared(__p, __d, __a); #ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { + } catch (...) { __d(__p); throw; }