EricWF created this revision.
EricWF added a reviewer: mclow.lists.
EricWF added a subscriber: cfe-commits.

See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0033r1.html

http://reviews.llvm.org/D19254

Files:
  include/memory
  
test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
  www/cxx1z_status.html

Index: www/cxx1z_status.html
===================================================================
--- www/cxx1z_status.html
+++ www/cxx1z_status.html
@@ -82,7 +82,7 @@
 	<tr><td><a href="http://wg21.link/P0226R1";>P0226R1</a></td><td>LWG</td><td>Mathematical Special Functions for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
 	<tr><td><a href="http://wg21.link/P0220R1";>P0220R1</a></td><td>LWG</td><td>Adopt Library Fundamentals V1 TS Components for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
 	<tr><td><a href="http://wg21.link/P0218R1";>P0218R1</a></td><td>LWG</td><td>Adopt the File System TS for C++17</td><td>Jacksonville</td><td></td><td></td></tr>	
-	<tr><td><a href="http://wg21.link/P0033R1";>P0033R1</a></td><td>LWG</td><td>Re-enabling shared_from_this</td><td>Jacksonville</td><td></td><td></td></tr>
+	<tr><td><a href="http://wg21.link/P0033R1";>P0033R1</a></td><td>LWG</td><td>Re-enabling shared_from_this</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
 	<tr><td><a href="http://wg21.link/P0005R4";>P0005R4</a></td><td>LWG</td><td>Adopt not_fn from Library Fundamentals 2 for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
 	<tr><td><a href="http://wg21.link/P0152R1";>P0152R1</a></td><td>LWG</td><td>constexpr atomic::is_always_lock_free</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
 	<tr><td><a href="http://wg21.link/P0185R1";>P0185R1</a></td><td>LWG</td><td>Adding [nothrow-]swappable traits</td><td>Jacksonville</td><td></td><td></td></tr>
Index: test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
===================================================================
--- test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
+++ test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
@@ -18,11 +18,15 @@
 // public:
 //     shared_ptr<T> shared_from_this();
 //     shared_ptr<T const> shared_from_this() const;
+//     weak_ptr<T> weak_from_this() noexcept;                         // C++17
+//     weak_ptr<T const> weak_from_this() const noexecpt;             // C++17
 // };
 
 #include <memory>
 #include <cassert>
 
+#include "test_macros.h"
+
 struct T
     : public std::enable_shared_from_this<T>
 {
@@ -32,6 +36,8 @@
 
 struct Z : Y {};
 
+void nullDeleter(void*) {}
+
 int main()
 {
     {  // https://llvm.org/bugs/show_bug.cgi?id=18843
@@ -50,4 +56,40 @@
     assert(p == q);
     assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
     }
+    // Test weak_from_this_methods
+    {
+        T* ptr = new T;
+        const T* cptr = ptr;
+
+#if TEST_STD_VER >= 11
+        static_assert(noexcept(ptr->weak_from_this()), "Operation must be noexcept");
+        static_assert(noexcept(cptr->weak_from_this()), "Operation must be noexcept");
+#endif
+        std::weak_ptr<T> my_weak = ptr->weak_from_this();
+        assert(my_weak.expired());
+
+        std::weak_ptr<T const> my_const_weak = cptr->weak_from_this();
+        assert(my_const_weak.expired());
+
+        // Enable shared_from_this with ptr.
+        std::shared_ptr<T> sptr(ptr);
+        my_weak = ptr->weak_from_this();
+        assert(!my_weak.expired());
+        assert(my_weak.lock().get() == ptr);
+    }
+    // Test LWG issue 2529. Only reset '__weak_ptr_' when it's already expired.
+    // http://cplusplus.github.io/LWG/lwg-active.html#2529
+    {
+        T* ptr = new T;
+        std::shared_ptr<T> s(ptr);
+        {
+            // Don't re-initialize the "enabled_shared_from_this" base
+            // because it already references a non-expired shared_ptr.
+            std::shared_ptr<T> s2(ptr, &nullDeleter);
+        }
+        // The enabled_shared_from_this base should still be referencing
+        // the original shared_ptr.
+        assert(!ptr->weak_from_this().expired());
+
+    }
 }
Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -4124,7 +4124,7 @@
         void
         __enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT
         {
-            if (__e)
+            if (__e && __e->__weak_this_.expired())
             {
                 __e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e));
                 __e->__weak_this_.__cntrl_ = __cntrl_;
@@ -5436,6 +5436,14 @@
     shared_ptr<_Tp const> shared_from_this() const
         {return shared_ptr<const _Tp>(__weak_this_);}
 
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
+       { return __weak_this_; }
+
+    _LIBCPP_INLINE_VISIBILITY
+    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
+        { return __weak_this_; }
+
     template <class _Up> friend class shared_ptr;
 };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to