[libc++] Make shared_ptr move unique_ptr's deleter
Addresses LWG 3548 which mandates that when shared_ptr is being constructed from a unique_ptr, the unique_ptr's deleter should be moved and not copied. Reviewed By: #libc, philnik, EricWF Differential Revision: https://reviews.llvm.org/D119159
This commit is contained in:
parent
8f108c32bc
commit
34538dba9b
|
@ -90,7 +90,7 @@
|
|||
`3543 <https://wg21.link/LWG3543>`__,"Definition of when ``counted_iterators`` refer to the same sequence isn't quite right","June 2021","|Nothing To Do|","","|ranges|"
|
||||
`3544 <https://wg21.link/LWG3544>`__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","|Complete|","14.0","|format|"
|
||||
`3546 <https://wg21.link/LWG3546>`__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","","","|ranges|"
|
||||
`3548 <https://wg21.link/LWG3548>`__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","",""
|
||||
`3548 <https://wg21.link/LWG3548>`__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","|Complete|","15.0"
|
||||
`3549 <https://wg21.link/LWG3549>`__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","|Complete|","14.0","|ranges|"
|
||||
`3551 <https://wg21.link/LWG3551>`__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","|Nothing To Do|","","|ranges|"
|
||||
`3552 <https://wg21.link/LWG3552>`__,"Parallel specialized memory algorithms should require forward iterators","June 2021","",""
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -457,7 +457,7 @@ public:
|
|||
explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
|
||||
unique_ptr<_Yp> __hold(__p);
|
||||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
|
||||
typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
|
||||
__cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
|
||||
__hold.release();
|
||||
__enable_weak_this(__p, __p);
|
||||
|
@ -473,7 +473,7 @@ public:
|
|||
{
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
|
||||
typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
__cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
|
||||
#else
|
||||
|
@ -532,7 +532,7 @@ public:
|
|||
{
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
|
||||
typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
__cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
|
||||
#else
|
||||
|
@ -665,8 +665,8 @@ public:
|
|||
#endif
|
||||
{
|
||||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk;
|
||||
__cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
|
||||
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk;
|
||||
__cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());
|
||||
__enable_weak_this(__r.get(), __r.get());
|
||||
}
|
||||
__r.release();
|
||||
|
@ -689,7 +689,7 @@ public:
|
|||
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
|
||||
typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
|
||||
reference_wrapper<typename remove_reference<_Dp>::type>,
|
||||
_AllocT > _CntrlBlk;
|
||||
_AllocT> _CntrlBlk;
|
||||
__cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
|
||||
__enable_weak_this(__r.get(), __r.get());
|
||||
}
|
||||
|
|
|
@ -82,6 +82,13 @@ struct StatefulArrayDeleter {
|
|||
}
|
||||
};
|
||||
|
||||
struct MovingDeleter {
|
||||
explicit MovingDeleter(int *moves) : moves_(moves) {}
|
||||
MovingDeleter(MovingDeleter&& rhs) : moves_(rhs.moves_) { *moves_ += 1; }
|
||||
void operator()(int*) const {}
|
||||
int *moves_;
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
|
@ -230,10 +237,39 @@ int main(int, char**)
|
|||
assert(A::count == 0);
|
||||
|
||||
{
|
||||
std::unique_ptr<int[]> ptr(new int[8]);
|
||||
std::shared_ptr<int[]> p(std::move(ptr));
|
||||
int *p = new int[8];
|
||||
std::unique_ptr<int[]> u(p);
|
||||
std::shared_ptr<int[]> s(std::move(u));
|
||||
assert(u == nullptr);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
#endif // TEST_STD_VER > 14
|
||||
|
||||
{ // LWG 3548
|
||||
{
|
||||
int moves = 0;
|
||||
int i = 42;
|
||||
std::unique_ptr<int, MovingDeleter> u(&i, MovingDeleter(&moves));
|
||||
assert(moves == 1);
|
||||
std::shared_ptr<int> s(std::move(u));
|
||||
assert(moves >= 2);
|
||||
assert(u == nullptr);
|
||||
assert(s.get() == &i);
|
||||
}
|
||||
|
||||
#if TEST_STD_VER > 14
|
||||
{
|
||||
int moves = 0;
|
||||
int a[8];
|
||||
std::unique_ptr<int[], MovingDeleter> u(a, MovingDeleter(&moves));
|
||||
assert(moves == 1);
|
||||
std::shared_ptr<int[]> s = std::move(u);
|
||||
assert(moves >= 2);
|
||||
assert(u == nullptr);
|
||||
assert(s.get() == a);
|
||||
}
|
||||
#endif // TEST_STD_VER > 14
|
||||
}
|
||||
#endif // TEST_STD_VER >= 14
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue