[libcxx-commits] [libcxx] 065ac30 - [libc++] LWG3001: add `remove_extent_t` to `weak_ptr::element_type`.

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 25 08:16:21 PDT 2021


Author: Konstantin Varlamov
Date: 2021-10-25T11:15:54-04:00
New Revision: 065ac30026d506172994310bd5badd65120f7d74

URL: https://github.com/llvm/llvm-project/commit/065ac30026d506172994310bd5badd65120f7d74
DIFF: https://github.com/llvm/llvm-project/commit/065ac30026d506172994310bd5badd65120f7d74.diff

LOG: [libc++] LWG3001: add `remove_extent_t` to `weak_ptr::element_type`.

Also fix a few places in the `shared_ptr` implementation where
`element_type` was passed to the `__is_compatible` helper. This could
result in `remove_extent` being applied twice to the pointer's template
type (first by the definition of `element_type` and then by the helper),
potentially leading to somewhat less readable error messages for some
incorrect code.

Differential Revision: https://reviews.llvm.org/D112092

Added: 
    

Modified: 
    libcxx/docs/Status/Cxx20Issues.csv
    libcxx/include/__memory/shared_ptr.h
    libcxx/include/memory
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/types.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/weak_ptr_Y.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_Y.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv
index 410cedcaa53d..4f62a9a9d5e8 100644
--- a/libcxx/docs/Status/Cxx20Issues.csv
+++ b/libcxx/docs/Status/Cxx20Issues.csv
@@ -37,7 +37,7 @@
 "`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0"
 "`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","|Complete|","13.0"
 "`2998 <https://wg21.link/LWG2998>`__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|",""
-"`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","",""
+"`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","|Complete|","14.0"
 "`3024 <https://wg21.link/LWG3024>`__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|",""
 "","","","",""
 "`2164 <https://wg21.link/LWG2164>`__","What are the semantics of ``vector.emplace(vector.begin(), vector.back())``\ ?","Jacksonville","|Complete|",""

diff  --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 1b9e01fecad6..0f366794a62d 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -471,15 +471,15 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template<class _Yp>
         _LIBCPP_INLINE_VISIBILITY
         shared_ptr(const shared_ptr<_Yp>& __r,
-                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
+                   typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat())
                        _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     shared_ptr(shared_ptr&& __r) _NOEXCEPT;
     template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
-                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
+                   typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat())
                        _NOEXCEPT;
     template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
-                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
+                   typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type = __nat());
 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
     template<class _Yp>
         shared_ptr(auto_ptr<_Yp>&& __r,
@@ -509,7 +509,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template<class _Yp>
         typename enable_if
         <
-            __compatible_with<_Yp, element_type>::value,
+            __compatible_with<_Yp, _Tp>::value,
             shared_ptr&
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -519,7 +519,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template<class _Yp>
         typename enable_if
         <
-            __compatible_with<_Yp, element_type>::value,
+            __compatible_with<_Yp, _Tp>::value,
             shared_ptr&
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -551,7 +551,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template<class _Yp>
         typename enable_if
         <
-            __compatible_with<_Yp, element_type>::value,
+            __compatible_with<_Yp, _Tp>::value,
             void
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -559,7 +559,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template<class _Yp, class _Dp>
         typename enable_if
         <
-            __compatible_with<_Yp, element_type>::value,
+            __compatible_with<_Yp, _Tp>::value,
             void
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -567,7 +567,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template<class _Yp, class _Dp, class _Alloc>
         typename enable_if
         <
-            __compatible_with<_Yp, element_type>::value,
+            __compatible_with<_Yp, _Tp>::value,
             void
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -683,7 +683,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
 };
 
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
 template<class _Tp>
 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
 template<class _Tp, class _Dp>
@@ -851,7 +851,7 @@ template<class _Tp>
 template<class _Yp>
 inline
 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
-                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
+                            typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type)
          _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -874,7 +874,7 @@ template<class _Tp>
 template<class _Yp>
 inline
 shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
-                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
+                            typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type)
          _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -970,7 +970,7 @@ template<class _Yp>
 inline
 typename enable_if
 <
-    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    __compatible_with<_Yp, _Tp>::value,
     shared_ptr<_Tp>&
 >::type
 shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
@@ -993,7 +993,7 @@ template<class _Yp>
 inline
 typename enable_if
 <
-    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    __compatible_with<_Yp, _Tp>::value,
     shared_ptr<_Tp>&
 >::type
 shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
@@ -1056,7 +1056,7 @@ template<class _Yp>
 inline
 typename enable_if
 <
-    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    __compatible_with<_Yp, _Tp>::value,
     void
 >::type
 shared_ptr<_Tp>::reset(_Yp* __p)
@@ -1069,7 +1069,7 @@ template<class _Yp, class _Dp>
 inline
 typename enable_if
 <
-    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    __compatible_with<_Yp, _Tp>::value,
     void
 >::type
 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
@@ -1082,7 +1082,7 @@ template<class _Yp, class _Dp, class _Alloc>
 inline
 typename enable_if
 <
-    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
+    __compatible_with<_Yp, _Tp>::value,
     void
 >::type
 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
@@ -1323,7 +1323,12 @@ template<class _Tp>
 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
 {
 public:
+#if _LIBCPP_STD_VER > 14
+    typedef remove_extent_t<_Tp> element_type;
+#else
     typedef _Tp element_type;
+#endif
+
 private:
     element_type*        __ptr_;
     __shared_weak_count* __cntrl_;
@@ -1332,18 +1337,18 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
-                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                   typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
                         _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     weak_ptr(weak_ptr const& __r) _NOEXCEPT;
     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
-                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                   typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
                          _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     weak_ptr(weak_ptr&& __r) _NOEXCEPT;
     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
-                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                   typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
                          _NOEXCEPT;
     ~weak_ptr();
 
@@ -1352,7 +1357,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
     template<class _Yp>
         typename enable_if
         <
-            is_convertible<_Yp*, element_type*>::value,
+            __compatible_with<_Yp, _Tp>::value,
             weak_ptr&
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -1363,7 +1368,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
     template<class _Yp>
         typename enable_if
         <
-            is_convertible<_Yp*, element_type*>::value,
+            __compatible_with<_Yp, _Tp>::value,
             weak_ptr&
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -1372,7 +1377,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
     template<class _Yp>
         typename enable_if
         <
-            is_convertible<_Yp*, element_type*>::value,
+            __compatible_with<_Yp, _Tp>::value,
             weak_ptr&
         >::type
         _LIBCPP_INLINE_VISIBILITY
@@ -1403,7 +1408,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
 };
 
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
 template<class _Tp>
 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
 #endif
@@ -1431,7 +1436,7 @@ template<class _Tp>
 template<class _Yp>
 inline
 weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
-                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+                        typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
                          _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -1444,7 +1449,7 @@ template<class _Tp>
 template<class _Yp>
 inline
 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
-                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+                        typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
          _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -1467,7 +1472,7 @@ template<class _Tp>
 template<class _Yp>
 inline
 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
-                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+                        typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
          _NOEXCEPT
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_)
@@ -1497,7 +1502,7 @@ template<class _Yp>
 inline
 typename enable_if
 <
-    is_convertible<_Yp*, _Tp*>::value,
+    __compatible_with<_Yp, _Tp>::value,
     weak_ptr<_Tp>&
 >::type
 weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
@@ -1520,7 +1525,7 @@ template<class _Yp>
 inline
 typename enable_if
 <
-    is_convertible<_Yp*, _Tp*>::value,
+    __compatible_with<_Yp, _Tp>::value,
     weak_ptr<_Tp>&
 >::type
 weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
@@ -1534,7 +1539,7 @@ template<class _Yp>
 inline
 typename enable_if
 <
-    is_convertible<_Yp*, _Tp*>::value,
+    __compatible_with<_Yp, _Tp>::value,
     weak_ptr<_Tp>&
 >::type
 weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
@@ -1571,7 +1576,7 @@ weak_ptr<_Tp>::reset() _NOEXCEPT
 template<class _Tp>
 template<class _Yp>
 shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
-                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+                            typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat>::type)
     : __ptr_(__r.__ptr_),
       __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
 {

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 0fb36b5c7173..b1d16ef082aa 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -405,7 +405,8 @@ template<class T>
 class shared_ptr
 {
 public:
-    typedef T element_type;
+    typedef T element_type; // until C++17
+    typedef remove_extent_t<T> element_type; // since C++17
     typedef weak_ptr<T> weak_type; // C++17
 
     // constructors:
@@ -525,7 +526,8 @@ template<class T>
 class weak_ptr
 {
 public:
-    typedef T element_type;
+    typedef T element_type; // until C++17
+    typedef remove_extent_t<T> element_type; // since C++17
 
     // constructors
     constexpr weak_ptr() noexcept;

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp
index b33f4043e1e0..c71765891d55 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp
@@ -11,12 +11,14 @@
 // template<class T> class shared_ptr
 // {
 // public:
-//     typedef T element_type;
+//     typedef T element_type; // until C++17
+//     typedef remove_extent_t<T> element_type; // since C++17
 //     typedef weak_ptr<T> weak_type; // C++17
 //     ...
 // };
 
 #include <memory>
+#include <type_traits>
 
 #include "test_macros.h"
 
@@ -44,10 +46,8 @@ void test() {
   static_assert(std::is_copy_constructible<std::shared_ptr<T> >::value, "");
   static_assert(std::is_copy_assignable<std::shared_ptr<T> >::value, "");
   static_assert(has_less<std::shared_ptr<T> >::value);
-  static_assert(
-      std::is_same<typename std::shared_ptr<T[]>::element_type, T>::value, "");
-  static_assert(
-      std::is_same<typename std::shared_ptr<T[8]>::element_type, T>::value, "");
+  ASSERT_SAME_TYPE(typename std::shared_ptr<T[]>::element_type, T);
+  ASSERT_SAME_TYPE(typename std::shared_ptr<T[8]>::element_type, T);
 #endif
 }
 
@@ -57,5 +57,9 @@ int main(int, char**) {
   test<int>();
   test<char*>();
 
+#if TEST_STD_VER > 14
+  ASSERT_SAME_TYPE(typename std::shared_ptr<int[][2]>::element_type, int[2]);
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
index 4859f8104933..30fa6ccd1806 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp
@@ -82,5 +82,17 @@ int main(int, char**)
     assert(A::count == 0);
 #endif
 
+#if TEST_STD_VER > 14
+    {
+        std::shared_ptr<A[]> sp0(new A[8]);
+        std::weak_ptr<A[]> wp(sp0);
+        std::shared_ptr<const A[]> sp(wp);
+        assert(sp.use_count() == 2);
+        assert(sp.get() == sp0.get());
+        assert(A::count == 8);
+    }
+    assert(A::count == 0);
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/types.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/types.pass.cpp
index 0666a98828d9..017876c9fd00 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/types.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/types.pass.cpp
@@ -11,19 +11,41 @@
 // template<class T> class weak_ptr
 // {
 // public:
-//     typedef T element_type;
+//     typedef T element_type; // until C++17
+//     typedef remove_extent_t<T> element_type; // since C++17
 //     ...
 // };
 
 #include <memory>
+#include <type_traits>
 
 #include "test_macros.h"
 
 struct A;  // purposefully incomplete
+struct B {
+  int x;
+  B() = default;
+};
+
+template <class T>
+void test() {
+  ASSERT_SAME_TYPE(typename std::weak_ptr<T>::element_type, T);
+#if TEST_STD_VER > 14
+  ASSERT_SAME_TYPE(typename std::weak_ptr<T[]>::element_type, T);
+  ASSERT_SAME_TYPE(typename std::weak_ptr<T[8]>::element_type, T);
+#endif
+}
 
 int main(int, char**)
 {
-    static_assert((std::is_same<std::weak_ptr<A>::element_type, A>::value), "");
+  test<A>();
+  test<B>();
+  test<int>();
+  test<char*>();
+
+#if TEST_STD_VER > 14
+  ASSERT_SAME_TYPE(typename std::weak_ptr<int[][2]>::element_type, int[2]);
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp
index 86624478f40f..97994e6ff397 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp
@@ -61,5 +61,22 @@ int main(int, char**)
     assert(B::count == 0);
     assert(A::count == 0);
 
+#if TEST_STD_VER > 14
+    {
+        const std::shared_ptr<A[]> p1(new A[8]);
+        assert(p1.use_count() == 1);
+        {
+            std::weak_ptr<const A[]> p2;
+            p2 = p1;
+            assert(A::count == 8);
+            assert(p2.use_count() == 1);
+            assert(p1.use_count() == 1);
+        }
+        assert(p1.use_count() == 1);
+        assert(A::count == 8);
+    }
+    assert(A::count == 0);
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/weak_ptr_Y.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/weak_ptr_Y.pass.cpp
index 9da2fd75fbf2..035e6e51e786 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/weak_ptr_Y.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/weak_ptr_Y.pass.cpp
@@ -11,9 +11,11 @@
 // weak_ptr
 
 // template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r);
+// template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r);
 
 #include <memory>
 #include <type_traits>
+#include <utility>
 #include <cassert>
 
 #include "test_macros.h"
@@ -77,5 +79,35 @@ int main(int, char**)
     assert(B::count == 0);
     assert(A::count == 0);
 
+#if TEST_STD_VER > 14
+    {
+        const std::shared_ptr<A[]> ps(new A[8]);
+        const std::weak_ptr<A[]> p1(ps);
+        {
+            std::weak_ptr<const A[]> p2;
+            p2 = p1;
+            assert(A::count == 8);
+            assert(p2.use_count() == 1);
+            assert(p1.use_count() == 1);
+        }
+        assert(p1.use_count() == 1);
+        assert(A::count == 8);
+    }
+    assert(A::count == 0);
+
+    {
+        const std::shared_ptr<A[]> ps(new A[8]);
+        std::weak_ptr<A[]> p1(ps);
+        {
+            std::weak_ptr<const A[]> p2;
+            p2 = std::move(p1);
+            assert(A::count == 8);
+            assert(p2.use_count() == 1);
+        }
+        assert(A::count == 8);
+    }
+    assert(A::count == 0);
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_Y.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_Y.pass.cpp
index 3b66e9ae27fa..d9b405a48180 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_Y.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_Y.pass.cpp
@@ -94,5 +94,22 @@ int main(int, char**)
     assert(B::count == 0);
     assert(A::count == 0);
 
+#if TEST_STD_VER > 14
+    {
+        std::shared_ptr<A[]> p1(new A[8]);
+        assert(p1.use_count() == 1);
+        assert(A::count == 8);
+        {
+            std::weak_ptr<const A[]> p2(p1);
+            assert(A::count == 8);
+            assert(p2.use_count() == 1);
+            assert(p1.use_count() == 1);
+        }
+        assert(p1.use_count() == 1);
+        assert(A::count == 8);
+    }
+    assert(A::count == 0);
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp
index 3fd447356cd7..7167701861ad 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp
@@ -11,10 +11,11 @@
 // weak_ptr
 
 // template<class Y> weak_ptr(const weak_ptr<Y>& r);
-// template<class Y> weak_ptr(weak_ptr<Y> &&r);
+// template<class Y> weak_ptr(weak_ptr<Y>&& r);
 
 #include <memory>
 #include <type_traits>
+#include <utility>
 #include <cassert>
 
 #include "test_macros.h"
@@ -107,5 +108,23 @@ int main(int, char**)
     assert(B::count == 0);
     assert(A::count == 0);
 
+#if TEST_STD_VER > 14
+    {
+        std::shared_ptr<A[]> ps(new A[8]);
+        std::weak_ptr<A[]> p1 = source(ps);
+        std::weak_ptr<const A[]> p2(p1);
+        assert(p2.use_count() == 1);
+    }
+    assert(A::count == 0);
+
+    {
+        std::shared_ptr<A[]> ps(new A[8]);
+        std::weak_ptr<A[]> p1 = source(ps);
+        std::weak_ptr<const A[]> p2(std::move(p1));
+        assert(p2.use_count() == 1);
+    }
+    assert(A::count == 0);
+#endif
+
   return 0;
 }


        


More information about the libcxx-commits mailing list