[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