diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv --- a/libcxx/docs/Status/Cxx20Issues.csv +++ b/libcxx/docs/Status/Cxx20Issues.csv @@ -37,7 +37,7 @@ "`2988 `__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0" "`2993 `__","reference_wrapper conversion from T&&","Albuquerque","|Complete|","13.0" "`2998 `__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|","" -"`3001 `__","weak_ptr::element_type needs remove_extent_t","Albuquerque","","" +"`3001 `__","weak_ptr::element_type needs remove_extent_t","Albuquerque","|Complete|","14.0" "`3024 `__","variant's copies must be deleted instead of disabled via SFINAE","Albuquerque","|Complete|","" "","","","","" "`2164 `__","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 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -375,7 +375,7 @@ template struct __compatible_with -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 17 : is_convertible*, remove_extent_t<_Up>*> {}; #else : is_convertible<_Tp*, _Up*> {}; @@ -419,7 +419,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr { public: -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 17 typedef weak_ptr<_Tp> weak_type; typedef remove_extent_t<_Tp> element_type; #else @@ -471,15 +471,15 @@ template _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 _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 explicit shared_ptr(const weak_ptr<_Yp>& __r, - typename enable_if::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 shared_ptr(auto_ptr<_Yp>&& __r, @@ -509,7 +509,7 @@ template typename enable_if < - __compatible_with<_Yp, element_type>::value, + __compatible_with<_Yp, _Tp>::value, shared_ptr& >::type _LIBCPP_INLINE_VISIBILITY @@ -519,7 +519,7 @@ template typename enable_if < - __compatible_with<_Yp, element_type>::value, + __compatible_with<_Yp, _Tp>::value, shared_ptr& >::type _LIBCPP_INLINE_VISIBILITY @@ -551,7 +551,7 @@ template typename enable_if < - __compatible_with<_Yp, element_type>::value, + __compatible_with<_Yp, _Tp>::value, void >::type _LIBCPP_INLINE_VISIBILITY @@ -559,7 +559,7 @@ template typename enable_if < - __compatible_with<_Yp, element_type>::value, + __compatible_with<_Yp, _Tp>::value, void >::type _LIBCPP_INLINE_VISIBILITY @@ -567,7 +567,7 @@ template typename enable_if < - __compatible_with<_Yp, element_type>::value, + __compatible_with<_Yp, _Tp>::value, void >::type _LIBCPP_INLINE_VISIBILITY @@ -851,7 +851,7 @@ template 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr { public: +#if _LIBCPP_STD_VER >= 20 + 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 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r, - typename enable_if::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 _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r, - typename enable_if::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 _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r, - typename enable_if::value, __nat*>::type = 0) + typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0) _NOEXCEPT; ~weak_ptr(); @@ -1352,7 +1357,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, _Tp>::value, weak_ptr& >::type _LIBCPP_INLINE_VISIBILITY @@ -1363,7 +1368,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, _Tp>::value, weak_ptr& >::type _LIBCPP_INLINE_VISIBILITY @@ -1372,7 +1377,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, _Tp>::value, weak_ptr& >::type _LIBCPP_INLINE_VISIBILITY @@ -1431,7 +1436,7 @@ template inline weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r, - typename enable_if::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 inline weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r, - typename enable_if::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 inline weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r, - typename enable_if::value, __nat*>::type) + typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) @@ -1497,7 +1502,7 @@ 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 @@ 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 @@ 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 @@ template template shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r, - typename enable_if::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 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -405,7 +405,8 @@ class shared_ptr { public: - typedef T element_type; + typedef T element_type; // until C++17 + typedef remove_extent_t element_type; // since C++17 typedef weak_ptr weak_type; // C++17 // constructors: @@ -525,7 +526,8 @@ class weak_ptr { public: - typedef T element_type; + typedef T element_type; // until C++20 + typedef remove_extent_t element_type; // since C++20 // 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 --- 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 shared_ptr // { // public: -// typedef T element_type; +// typedef T element_type; // until C++17 +// typedef remove_extent_t element_type; // since C++17 // typedef weak_ptr weak_type; // C++17 // ... // }; #include +#include #include "test_macros.h" @@ -39,15 +41,13 @@ template void test() { ASSERT_SAME_TYPE(typename std::shared_ptr::element_type, T); -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 17 ASSERT_SAME_TYPE(typename std::shared_ptr::weak_type, std::weak_ptr); static_assert(std::is_copy_constructible >::value, ""); static_assert(std::is_copy_assignable >::value, ""); static_assert(has_less >::value); - static_assert( - std::is_same::element_type, T>::value, ""); - static_assert( - std::is_same::element_type, T>::value, ""); + ASSERT_SAME_TYPE(typename std::shared_ptr::element_type, T); + ASSERT_SAME_TYPE(typename std::shared_ptr::element_type, T); #endif } @@ -57,5 +57,9 @@ test(); test(); +#if TEST_STD_VER >= 17 + ASSERT_SAME_TYPE(typename std::shared_ptr::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 --- 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 @@ assert(A::count == 0); #endif +#if TEST_STD_VER >= 17 + { + std::shared_ptr sp0(new A[8]); + std::weak_ptr wp(sp0); + std::shared_ptr 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 --- 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 weak_ptr // { // public: -// typedef T element_type; +// typedef T element_type; // until C++20 +// typedef remove_extent_t element_type; // since C++20 // ... // }; #include +#include #include "test_macros.h" struct A; // purposefully incomplete +struct B { + int x; + B() = default; +}; + +template +void test() { + ASSERT_SAME_TYPE(typename std::weak_ptr::element_type, T); +#if TEST_STD_VER >= 17 + ASSERT_SAME_TYPE(typename std::weak_ptr::element_type, T); + ASSERT_SAME_TYPE(typename std::weak_ptr::element_type, T); +#endif +} int main(int, char**) { - static_assert((std::is_same::element_type, A>::value), ""); + test(); + test(); + test(); + test(); + +#if TEST_STD_VER >= 17 + ASSERT_SAME_TYPE(typename std::weak_ptr::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 --- 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 @@ assert(B::count == 0); assert(A::count == 0); +#if TEST_STD_VER >= 17 + { + const std::shared_ptr p1(new A[8]); + assert(p1.use_count() == 1); + { + std::weak_ptr 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 --- 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 weak_ptr& operator=(const weak_ptr& r); +// template weak_ptr& operator=(weak_ptr&& r); #include #include +#include #include #include "test_macros.h" @@ -77,5 +79,35 @@ assert(B::count == 0); assert(A::count == 0); +#if TEST_STD_VER >= 17 + { + const std::shared_ptr ps(new A[8]); + const std::weak_ptr p1(ps); + { + std::weak_ptr 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 ps(new A[8]); + std::weak_ptr p1(ps); + { + std::weak_ptr 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 --- 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 @@ assert(B::count == 0); assert(A::count == 0); +#if TEST_STD_VER >= 17 + { + std::shared_ptr p1(new A[8]); + assert(p1.use_count() == 1); + assert(A::count == 8); + { + std::weak_ptr 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 --- 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 weak_ptr(const weak_ptr& r); -// template weak_ptr(weak_ptr &&r); +// template weak_ptr(weak_ptr&& r); #include #include +#include #include #include "test_macros.h" @@ -107,5 +108,23 @@ assert(B::count == 0); assert(A::count == 0); +#if TEST_STD_VER >= 17 + { + std::shared_ptr ps(new A[8]); + std::weak_ptr p1 = source(ps); + std::weak_ptr p2(p1); + assert(p2.use_count() == 1); + } + assert(A::count == 0); + + { + std::shared_ptr ps(new A[8]); + std::weak_ptr p1 = source(ps); + std::weak_ptr p2(std::move(p1)); + assert(p2.use_count() == 1); + } + assert(A::count == 0); +#endif + return 0; }