[libcxx-commits] [libcxx] 34538db - [libc++] Make shared_ptr move unique_ptr's deleter
Asher Mancinelli via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Mar 18 10:54:42 PDT 2022
Author: Asher Mancinelli
Date: 2022-03-18T11:50:31-06:00
New Revision: 34538dba9be69f69ef8df088485447b278470020
URL: https://github.com/llvm/llvm-project/commit/34538dba9be69f69ef8df088485447b278470020
DIFF: https://github.com/llvm/llvm-project/commit/34538dba9be69f69ef8df088485447b278470020.diff
LOG: [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
Added:
Modified:
libcxx/docs/Status/Cxx2bIssues.csv
libcxx/include/__memory/shared_ptr.h
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index 0b2dbf4eef9e2..a9c67cf0714c1 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -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","",""
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 7401d3a891c1d..8560d3079758a 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -457,7 +457,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
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 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
{
#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 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
{
#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 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
#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 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
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());
}
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
index a86bff84435f9..203659bf4b632 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
@@ -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;
}
More information about the libcxx-commits
mailing list