Index: libcxx/include/memory =================================================================== --- libcxx/include/memory +++ libcxx/include/memory @@ -3908,6 +3908,52 @@ 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()) + { + try { + 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()); + } catch (...) { + __d(__p); + throw; + } + } + + 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()) + { + try { + 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()); + } catch (...) { + __d(__p); + throw; + } + } }; @@ -3916,30 +3962,22 @@ _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 shared_ptr<_Tp>::shared_ptr(_Yp* __p, typename enable_if::value, __nat>::type) - : __ptr_(__p) + : __ptr_(__p), + __cntrl_(__allocate_shared(__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); } @@ -3947,103 +3985,33 @@ template shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, typename enable_if::value, __nat>::type) - : __ptr_(__p) + : __ptr_(__p), + __cntrl_(__allocate_shared(__p, __d)) { -#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; - __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); - __enable_weak_this(__p, __p); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - __d(__p); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS + __enable_weak_this(__p, __p); } template template shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) - : __ptr_(0) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - 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()); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - __d(__p); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} + : __ptr_(0), + __cntrl_(__allocate_shared(__p, __d)) {} template template shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, typename enable_if::value, __nat>::type) - : __ptr_(__p) + : __ptr_(__p), + __cntrl_(__allocate_shared(__p, __d, __a)) { -#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(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__p, __d, __a); - __cntrl_ = _VSTD::addressof(*__hold2.release()); - __enable_weak_this(__p, __p); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - __d(__p); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS + __enable_weak_this(__p, __p); } template template shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) - : __ptr_(0) -{ -#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(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__p, __d, __a); - __cntrl_ = _VSTD::addressof(*__hold2.release()); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - __d(__p); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} + : __ptr_(0), + __cntrl_(__allocate_shared(__p, __d, __a)) {} template template