Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Standalone View
libcxx/include/__memory/shared_ptr.h
Show First 20 Lines • Show All 585 Lines • ▼ Show 20 Lines | #endif // _LIBCPP_NO_EXCEPTIONS | ||||||||||
shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT | shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT | ||||||||||
: __ptr_(__p), | : __ptr_(__p), | ||||||||||
__cntrl_(__r.__cntrl_) | __cntrl_(__r.__cntrl_) | ||||||||||
{ | { | ||||||||||
if (__cntrl_) | if (__cntrl_) | ||||||||||
__cntrl_->__add_shared(); | __cntrl_->__add_shared(); | ||||||||||
} | } | ||||||||||
// LWG-2996 | |||||||||||
Mordante: Please update the synopsis too. | |||||||||||
We (and other vendors) typically backport LWG-issue, can you do that for this issue too. Mordante: We (and other vendors) typically backport LWG-issue, can you do that for this issue too. | |||||||||||
I think back-porting to c++17 will break code that does a std::move() but relies on the fact that no move happens. Arguable this a just a bug in user code, but probably still something we don't want to change? pateldeev: I think back-porting to c++17 will break code that does a `std::move()` but relies on the fact… | |||||||||||
I don't feel that we should guard against users doing bad things; updating their code to C++20 will break that scenario. I see MSVC STL applied this change unconditionally, but libstdc++ limits it to C++20 and newer. @jwakely is there a reason for not backporting LWG-2996 to older versions? Mordante: I don't feel that we should guard against users doing bad things; updating their code to C++20… | |||||||||||
I don't remember why I only added it for C++20, but probably because it's questionable whether there was a defect. It seems more like an evolutionary change (which is why it went through LEWG) than a defect fix. jwakely: I don't remember why I only added it for C++20, but probably because it's questionable whether… | |||||||||||
Thanks for the information. Then it makes sense to me to do the same in libc++. @pateldeev please leave a comment why this LWG issue isn't backported to earlier language versions. Mordante: > I don't remember why I only added it for C++20, but probably because it's questionable… | |||||||||||
Or remove it entirely. Mordante: Or remove it entirely. | |||||||||||
// We don't backport because it is an evolutionary change. | |||||||||||
#if _LIBCPP_STD_VER > 20 | |||||||||||
Mordante: | |||||||||||
philnikUnsubmitted
The LWG issue is against C++20. Same for the other changes. philnik: The LWG issue is against C++20. Same for the other changes. | |||||||||||
template <class _Yp> | |||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept | |||||||||||
: __ptr_(__p), | |||||||||||
__cntrl_(__r.__cntrl_) { | |||||||||||
__r.__ptr_ = nullptr; | |||||||||||
__r.__cntrl_ = nullptr; | |||||||||||
} | |||||||||||
#endif | |||||||||||
_LIBCPP_HIDE_FROM_ABI | _LIBCPP_HIDE_FROM_ABI | ||||||||||
shared_ptr(const shared_ptr& __r) _NOEXCEPT | shared_ptr(const shared_ptr& __r) _NOEXCEPT | ||||||||||
: __ptr_(__r.__ptr_), | : __ptr_(__r.__ptr_), | ||||||||||
__cntrl_(__r.__cntrl_) | __cntrl_(__r.__cntrl_) | ||||||||||
{ | { | ||||||||||
if (__cntrl_) | if (__cntrl_) | ||||||||||
__cntrl_->__add_shared(); | __cntrl_->__add_shared(); | ||||||||||
} | } | ||||||||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||||||||
#if _LIBCPP_STD_VER > 11 | #if _LIBCPP_STD_VER > 11 | ||||||||||
if (__ptr_ == nullptr) | if (__ptr_ == nullptr) | ||||||||||
__cntrl_ = nullptr; | __cntrl_ = nullptr; | ||||||||||
else | else | ||||||||||
#endif | #endif | ||||||||||
{ | { | ||||||||||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; | ||||||||||
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk; | typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk; | ||||||||||
__cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT()); | __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT()); | ||||||||||
Please undo this change. In the past we used _VSTD instead of std. We don't change all existing code to avoid breaking too much work in progress, but we use it when changing code. Mordante: Please undo this change. In the past we used `_VSTD` instead of `std`. We don't change all… | |||||||||||
__enable_weak_this(__r.get(), __r.get()); | __enable_weak_this(__r.get(), __r.get()); | ||||||||||
} | } | ||||||||||
__r.release(); | __r.release(); | ||||||||||
} | } | ||||||||||
template <class _Yp, class _Dp, class = void, class = __enable_if_t< | template <class _Yp, class _Dp, class = void, class = __enable_if_t< | ||||||||||
is_lvalue_reference<_Dp>::value && | is_lvalue_reference<_Dp>::value && | ||||||||||
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value | ||||||||||
▲ Show 20 Lines • Show All 688 Lines • ▼ Show 20 Lines | |||||||||||
shared_ptr<_Tp> | shared_ptr<_Tp> | ||||||||||
static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | ||||||||||
{ | { | ||||||||||
return shared_ptr<_Tp>(__r, | return shared_ptr<_Tp>(__r, | ||||||||||
static_cast< | static_cast< | ||||||||||
typename shared_ptr<_Tp>::element_type*>(__r.get())); | typename shared_ptr<_Tp>::element_type*>(__r.get())); | ||||||||||
} | } | ||||||||||
// LWG-2996 | |||||||||||
// We don't backport because it is an evolutionary change. | |||||||||||
#if _LIBCPP_STD_VER > 20 | |||||||||||
_LIBCPP_HIDE_FROM_ABI is the new name for _LIBCPP_INLINE_VISIBILITY. Mordante: `_LIBCPP_HIDE_FROM_ABI` is the new name for `_LIBCPP_INLINE_VISIBILITY`. | |||||||||||
template <class _Tp, class _Up> | |||||||||||
Mordante: | |||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |||||||||||
return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); | |||||||||||
} | |||||||||||
#endif | |||||||||||
template<class _Tp, class _Up> | template<class _Tp, class _Up> | ||||||||||
inline _LIBCPP_INLINE_VISIBILITY | inline _LIBCPP_INLINE_VISIBILITY | ||||||||||
shared_ptr<_Tp> | shared_ptr<_Tp> | ||||||||||
dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | ||||||||||
{ | { | ||||||||||
typedef typename shared_ptr<_Tp>::element_type _ET; | typedef typename shared_ptr<_Tp>::element_type _ET; | ||||||||||
_ET* __p = dynamic_cast<_ET*>(__r.get()); | _ET* __p = dynamic_cast<_ET*>(__r.get()); | ||||||||||
return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); | return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); | ||||||||||
} | } | ||||||||||
// LWG-2996 | |||||||||||
// We don't backport because it is an evolutionary change. | |||||||||||
#if _LIBCPP_STD_VER > 20 | |||||||||||
See above. Mordante: See above. | |||||||||||
template <class _Tp, class _Up> | |||||||||||
In new code we prefer using over typedef. Mordante: In new code we prefer `using` over `typedef`. | |||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |||||||||||
auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()); | |||||||||||
return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>(); | |||||||||||
} | |||||||||||
#endif | |||||||||||
template<class _Tp, class _Up> | template<class _Tp, class _Up> | ||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> | ||||||||||
const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | ||||||||||
{ | { | ||||||||||
typedef typename shared_ptr<_Tp>::element_type _RTp; | typedef typename shared_ptr<_Tp>::element_type _RTp; | ||||||||||
return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); | return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); | ||||||||||
} | } | ||||||||||
// LWG-2996 | |||||||||||
// We don't backport because it is an evolutionary change. | |||||||||||
#if _LIBCPP_STD_VER > 20 | |||||||||||
template <class _Tp, class _Up> | |||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |||||||||||
return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); | |||||||||||
} | |||||||||||
#endif | |||||||||||
template<class _Tp, class _Up> | template<class _Tp, class _Up> | ||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> | ||||||||||
reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT | ||||||||||
{ | { | ||||||||||
return shared_ptr<_Tp>(__r, | return shared_ptr<_Tp>(__r, | ||||||||||
reinterpret_cast< | reinterpret_cast< | ||||||||||
typename shared_ptr<_Tp>::element_type*>(__r.get())); | typename shared_ptr<_Tp>::element_type*>(__r.get())); | ||||||||||
} | } | ||||||||||
// LWG-2996 | |||||||||||
// We don't backport because it is an evolutionary change. | |||||||||||
#if _LIBCPP_STD_VER > 20 | |||||||||||
template <class _Tp, class _Up> | |||||||||||
The extra space isn't fixed by clang-format due to C++03 compatibility. Mordante: The extra space isn't fixed by clang-format due to C++03 compatibility. | |||||||||||
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |||||||||||
return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); | |||||||||||
} | |||||||||||
#endif | |||||||||||
#ifndef _LIBCPP_NO_RTTI | #ifndef _LIBCPP_NO_RTTI | ||||||||||
template<class _Dp, class _Tp> | template<class _Dp, class _Tp> | ||||||||||
inline _LIBCPP_INLINE_VISIBILITY | inline _LIBCPP_INLINE_VISIBILITY | ||||||||||
_Dp* | _Dp* | ||||||||||
get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT | get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT | ||||||||||
{ | { | ||||||||||
return __p.template __get_deleter<_Dp>(); | return __p.template __get_deleter<_Dp>(); | ||||||||||
▲ Show 20 Lines • Show All 533 Lines • Show Last 20 Lines |
Please update the synopsis too.