[libcxx-commits] [PATCH] D119159: [libc++] Make shared_ptr move unique_ptr's deleter

Asher Mancinelli via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Feb 7 09:58:27 PST 2022


ashermancinelli created this revision.
ashermancinelli added a reviewer: libc++.
ashermancinelli requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added 1 blocking reviewer(s): libc++.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D119159

Files:
  libcxx/include/__memory/shared_ptr.h
  libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp


Index: libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
===================================================================
--- libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
+++ libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
@@ -82,6 +82,14 @@
   }
 };
 
+template <class T>
+struct MoveOnlyDeleter {
+  MoveOnlyDeleter() {}
+  MoveOnlyDeleter(MoveOnlyDeleter&&) {}
+  MoveOnlyDeleter(MoveOnlyDeleter&) = delete;
+  void operator()(T* p) const { delete p; }
+};
+
 int main(int, char**)
 {
     {
@@ -219,5 +227,10 @@
     }
 #endif // TEST_STD_VER >= 14
 
+    { // LWG 3548
+      std::unique_ptr<int, MoveOnlyDeleter<int> > u;
+      std::shared_ptr<int> s(std::move(u));
+    }
+
     return 0;
 }
Index: libcxx/include/__memory/shared_ptr.h
===================================================================
--- libcxx/include/__memory/shared_ptr.h
+++ libcxx/include/__memory/shared_ptr.h
@@ -652,7 +652,8 @@
 
     template <class _Yp, class _Dp, class = __enable_if_t<
         !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 &&
+         is_move_constructible<_Dp>::value
     > >
     _LIBCPP_HIDE_FROM_ABI
     shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
@@ -666,7 +667,7 @@
         {
             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());
+            __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());
             __enable_weak_this(__r.get(), __r.get());
         }
         __r.release();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119159.406515.patch
Type: text/x-patch
Size: 2008 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220207/39a6bce4/attachment-0001.bin>


More information about the libcxx-commits mailing list