Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -3737,15 +3737,33 @@ template class _LIBCPP_TEMPLATE_VIS enable_shared_from_this; +template +struct __ref_not_void +{ typedef _Tp& type; }; + +template<> +struct __ref_not_void +{ typedef void type; }; + +template +struct __compatible_with +#if _LIBCPP_STD_VER > 14 + : is_convertible*, remove_extent_t<_Up>*> {}; +#else + : is_convertible<_Tp*, _Up*> {}; +#endif // _LIBCPP_STD_VER > 14 + template class _LIBCPP_TEMPLATE_VIS shared_ptr { public: - typedef _Tp element_type; - #if _LIBCPP_STD_VER > 14 typedef weak_ptr<_Tp> weak_type; + typedef remove_extent_t<_Tp> element_type; +#else + typedef _Tp element_type; #endif + private: element_type* __ptr_; __shared_weak_count* __cntrl_; @@ -3758,13 +3776,13 @@ _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT; template explicit shared_ptr(_Yp* __p, - typename enable_if::value, __nat>::type = __nat()); + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()); template shared_ptr(_Yp* __p, _Dp __d, - typename enable_if::value, __nat>::type = __nat()); + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()); template shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, - typename enable_if::value, __nat>::type = __nat()); + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()); template shared_ptr(nullptr_t __p, _Dp __d); template shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); template _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT; @@ -3773,13 +3791,13 @@ template _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, - typename enable_if::value, __nat>::type = __nat()) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) _NOEXCEPT; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr&& __r) _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r, - typename enable_if::value, __nat>::type = __nat()) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) _NOEXCEPT; #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template explicit shared_ptr(const weak_ptr<_Yp>& __r, @@ -3831,7 +3849,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, element_type>::value, shared_ptr& >::type _LIBCPP_INLINE_VISIBILITY @@ -3842,8 +3860,8 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, - shared_ptr<_Tp>& + __compatible_with<_Yp, element_type>::value, + shared_ptr& >::type _LIBCPP_INLINE_VISIBILITY operator=(shared_ptr<_Yp>&& __r); @@ -3893,7 +3911,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, element_type>::value, void >::type _LIBCPP_INLINE_VISIBILITY @@ -3901,7 +3919,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, element_type>::value, void >::type _LIBCPP_INLINE_VISIBILITY @@ -3909,7 +3927,7 @@ template typename enable_if < - is_convertible<_Yp*, element_type*>::value, + __compatible_with<_Yp, element_type>::value, void >::type _LIBCPP_INLINE_VISIBILITY @@ -3941,6 +3959,13 @@ __owner_equivalent(const shared_ptr& __p) const {return __cntrl_ == __p.__cntrl_;} +#if _LIBCPP_STD_VER > 14 + typename __ref_not_void::type + _LIBCPP_INLINE_VISIBILITY + operator[](ptrdiff_t __i) const + {return __ptr_[__i];} +#endif + #ifndef _LIBCPP_NO_RTTI template _LIBCPP_INLINE_VISIBILITY @@ -3991,12 +4016,24 @@ } } + template + struct __shared_ptr_default_delete + : default_delete<_Yp> {}; + + template + struct __shared_ptr_default_delete<_Yp[_Sz]> + : default_delete<_Yp[]> {}; + + template + struct __shared_ptr_default_delete<_Yp[]> + : default_delete<_Yp[]> {}; + _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {} template friend class _LIBCPP_TEMPLATE_VIS shared_ptr; template friend class _LIBCPP_TEMPLATE_VIS weak_ptr; - template, + template, class _Alloc = typename __shared_ptr_default_allocator<_Yp>::type> static __shared_weak_count* __allocate_shared(_Yp* __p, _Deleter __d = _Deleter(), _Alloc __a = _Alloc()) @@ -4019,7 +4056,7 @@ } } - template, + template, class _Alloc = typename __shared_ptr_default_allocator<_Tp>::type> static __shared_weak_count* __allocate_shared(nullptr_t __p, _Deleter __d = _Deleter(), _Alloc __a = _Alloc()) @@ -4061,7 +4098,7 @@ template template shared_ptr<_Tp>::shared_ptr(_Yp* __p, - typename enable_if::value, __nat>::type) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) : __ptr_(__p), __cntrl_(__allocate_shared(__p)) { @@ -4071,7 +4108,7 @@ template template shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, - typename enable_if::value, __nat>::type) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) : __ptr_(__p), __cntrl_(__allocate_shared(__p, __d)) { @@ -4087,7 +4124,7 @@ template template shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, - typename enable_if::value, __nat>::type) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) : __ptr_(__p), __cntrl_(__allocate_shared(__p, __d, __a)) { @@ -4125,7 +4162,7 @@ template inline shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, - typename enable_if::value, __nat>::type) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) @@ -4150,7 +4187,7 @@ template inline shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r, - typename enable_if::value, __nat>::type) + typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) @@ -4262,7 +4299,7 @@ inline typename enable_if < - is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, + __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, shared_ptr<_Tp>& >::type shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT @@ -4287,7 +4324,7 @@ inline typename enable_if < - is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, + __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, shared_ptr<_Tp>& >::type shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r) @@ -4388,7 +4425,7 @@ inline typename enable_if < - is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, + __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, void >::type shared_ptr<_Tp>::reset(_Yp* __p) @@ -4401,7 +4438,7 @@ inline typename enable_if < - is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, + __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, void >::type shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) @@ -4414,7 +4451,7 @@ inline typename enable_if < - is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, + __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, void >::type shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) @@ -4758,41 +4795,41 @@ template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - !is_array<_Tp>::value && !is_array<_Up>::value, - shared_ptr<_Tp> ->::type +shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { - return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); + return shared_ptr<_Tp>(__r, + static_cast< + typename shared_ptr<_Tp>::element_type*>(__r.get())); } template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - !is_array<_Tp>::value && !is_array<_Up>::value, - shared_ptr<_Tp> ->::type +shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { - _Tp* __p = dynamic_cast<_Tp*>(__r.get()); + typedef typename shared_ptr<_Tp>::element_type _ET; + _ET* __p = dynamic_cast<_ET*>(__r.get()); return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); } template -typename enable_if -< - is_array<_Tp>::value == is_array<_Up>::value, - shared_ptr<_Tp> ->::type +shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { - typedef typename remove_extent<_Tp>::type _RTp; + typedef typename shared_ptr<_Tp>::element_type _RTp; return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); } +template +shared_ptr<_Tp> +reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT +{ + return shared_ptr<_Tp>(__r, + reinterpret_cast< + typename shared_ptr<_Tp>::element_type*>(__r.get())); +} + #ifndef _LIBCPP_NO_RTTI template @@ -5191,7 +5228,7 @@ _LIBCPP_INLINE_VISIBILITY result_type operator()(const argument_type& __ptr) const _NOEXCEPT { - return hash<_Tp*>()(__ptr.get()); + return hash::element_type*>()(__ptr.get()); } }; Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp @@ -20,14 +20,45 @@ #include "test_macros.h" +#if TEST_STD_VER > 14 +template> +struct has_less + : std::false_type +{}; + +template +struct has_less() < std::declval())>> + : std::true_type +{}; +#endif + struct A; // purposefully incomplete +struct B +{ + int x; + B() = default; +}; -int main(int, char**) +template +void test() { - static_assert((std::is_same::element_type, A>::value), ""); + static_assert((std::is_same::element_type, T>::value), ""); #if TEST_STD_VER > 14 - static_assert((std::is_same::weak_type, std::weak_ptr>::value), ""); + static_assert(std::is_same::weak_type, std::weak_ptr>::value, ""); + 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, ""); #endif +} + +int main(int, char**) +{ + test(); + test(); + test(); + test(); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/const_pointer_cast.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/const_pointer_cast.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/const_pointer_cast.pass.cpp @@ -55,6 +55,14 @@ assert(pB.get() == pA.get()); assert(!pB.owner_before(pA) && !pA.owner_before(pB)); } +#if TEST_STD_VER > 14 + { + const std::shared_ptr pA; + std::shared_ptr pB = std::const_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } +#endif // TEST_STD_VER > 14 - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/dynamic_pointer_cast.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/dynamic_pointer_cast.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/dynamic_pointer_cast.pass.cpp @@ -55,6 +55,14 @@ assert(pA.get() == 0); assert(pA.use_count() == 0); } +#if TEST_STD_VER > 14 + { + const std::shared_ptr pB(new B[8]); + std::shared_ptr pA = std::dynamic_pointer_cast(pB); + assert(pA.get() == 0); + assert(pA.use_count() == 0); + } +#endif // TEST_STD_VER > 14 return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/reinterpret_pointer_cast.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/reinterpret_pointer_cast.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// shared_ptr + +// template +// shared_ptr reinterpret_pointer_cast(const shared_ptr& r) noexcept; + +#include "test_macros.h" + +#include +#include +#include + +struct A { int x; }; + +int main(int, char**) +{ + { + const std::shared_ptr pA(new A); + std::shared_ptr pi = std::reinterpret_pointer_cast(pA); + std::shared_ptr pA2 = std::reinterpret_pointer_cast(pi); + assert(pA2.get() == pA.get()); + assert(!pi.owner_before(pA) && !pA.owner_before(pi)); + } + { + const std::shared_ptr pA; + std::shared_ptr pi = std::reinterpret_pointer_cast(pA); + std::shared_ptr pA2 = std::reinterpret_pointer_cast(pi); + assert(pA2.get() == pA.get()); + assert(!pi.owner_before(pA) && !pA.owner_before(pi)); + } +#if TEST_STD_VER > 14 + { + const std::shared_ptr pA; + std::shared_ptr pi = std::reinterpret_pointer_cast(pA); + std::shared_ptr pA2 = std::reinterpret_pointer_cast(pi); + assert(pA2.get() == pA.get()); + assert(!pi.owner_before(pA) && !pA.owner_before(pi)); + } +#endif // TEST_STD_VER > 14 + + return 0; +} Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/static_pointer_cast.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/static_pointer_cast.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/static_pointer_cast.pass.cpp @@ -67,6 +67,20 @@ assert(pB.get() == pA.get()); assert(!pB.owner_before(pA) && !pA.owner_before(pB)); } +#if TEST_STD_VER > 14 + { + const std::shared_ptr pA; + std::shared_ptr pB = std::static_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } + { + const std::shared_ptr pA; + std::shared_ptr pB = std::static_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } +#endif // TEST_STD_VER > 14 return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp @@ -15,11 +15,32 @@ #include #include +struct A { }; + +template +void test() +{ + { + std::shared_ptr p; + assert(p.use_count() == 0); + assert(p.get() == 0); + } + { +#if TEST_STD_VER >= 11 + std::shared_ptr p {}; + assert(p.use_count() == 0); + assert(p.get() == 0); +#endif + } +} + int main(int, char**) { - std::shared_ptr p; - assert(p.use_count() == 0); - assert(p.get() == 0); + test(); + test(); + test(); + test(); + test(); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp @@ -15,6 +15,8 @@ #include #include +#include "test_macros.h" + struct A { static int count; @@ -37,13 +39,29 @@ } assert(A::count == 0); { - A* ptr = new A; - std::shared_ptr p(ptr); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); +// A* ptr = new A; +// std::shared_ptr p(ptr); +// assert(A::count == 1); +// assert(p.use_count() == 1); +// assert(p.get() == ptr); + } + assert(A::count == 0); + +#if TEST_STD_VER > 14 + { + std::shared_ptr pA(new A[8]); + assert(pA.use_count() == 1); + assert(A::count == 8); + } + assert(A::count == 0); + + { + std::shared_ptr pA(new A[8]); + assert(pA.use_count() == 1); + assert(A::count == 8); } assert(A::count == 0); +#endif return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp @@ -93,6 +93,7 @@ { std::shared_ptr pA; assert(pA.use_count() == 0); + assert(pA.get() == nullptr); assert(B::count == 0); assert(A::count == 0); { @@ -102,6 +103,7 @@ assert(pB.use_count() == 0); assert(pA.use_count() == 0); assert(pA.get() == pB.get()); + assert(pB.get() == nullptr); } assert(pA.use_count() == 0); assert(B::count == 0); Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_copy_move.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_copy_move.fail.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// shared_ptr + +// template shared_ptr(const shared_ptr& r); + +#include +#include + +struct A { int x = 42; }; + +struct ADel : std::default_delete +{ + typedef A* pointer; +}; + +int main(int, char**) +{ + static_assert(!(std::is_convertible::value), ""); + + { + std::shared_ptr pA; + std::shared_ptr pi(pA); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + { + std::shared_ptr pA; + std::shared_ptr pi(std::move(pA)); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + { + std::weak_ptr pA; + std::shared_ptr pi(std::move(pA)); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + +#if TEST_STD_VER > 14 + { + std::unique_ptr ui; + std::shared_ptr pi(std::move(ui)); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } +#endif + + return 0; +} Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp @@ -44,6 +44,7 @@ { std::shared_ptr pA(new A); assert(pA.use_count() == 1); + { B b; std::shared_ptr pB(pA, &b); @@ -60,5 +61,38 @@ assert(A::count == 0); assert(B::count == 0); - return 0; + { + std::shared_ptr p1(nullptr); + std::shared_ptr p2(p1, new int); + assert(p2.get() != nullptr); + } + { + std::shared_ptr p1(new int); + std::shared_ptr p2(p1, nullptr); + assert(p2.get() == nullptr); + } + +#if TEST_STD_VER > 14 + { + std::shared_ptr pA(new A); + assert(pA.use_count() == 1); + + { + B b; + std::shared_ptr pB(std::move(pA), &b); + assert(A::count == 1); + assert(B::count == 1); + assert(pA.use_count() == 2); + assert(pB.use_count() == 2); + assert(pB.get() == &b); + } + assert(pA.use_count() == 1); + assert(A::count == 1); + assert(B::count == 0); + } + assert(A::count == 0); + assert(B::count == 0); +#endif + + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -49,6 +49,20 @@ template void assert_deleter ( T * ) { assert(false); } +template +struct StatefulDeleter +{ + int state = 0; + + StatefulDeleter(int val = 0) : state(val) {} + StatefulDeleter(StatefulDeleter const&) { assert(false); } + + void operator()(T* ptr) { + assert(state == 42); + delete ptr; + } +}; + int main(int, char**) { { @@ -83,11 +97,29 @@ assert(A::count == 0); assert(B::count == 0); assert(ptr.get() == 0); -#endif +#endif // TEST_STD_VER >= 11 } } #endif + +#if TEST_STD_VER > 14 + { + std::unique_ptr ptr; + std::shared_ptr p(std::move(ptr)); + assert(p.get() == 0); + assert(p.use_count() == 0); + } +#endif + + { + StatefulDeleter d; + std::unique_ptr&> u(new A, d); + std::shared_ptr p(std::move(u)); + d.state = 42; + assert(A::count == 1); + } assert(A::count == 0); + { // LWG 2399 fn(std::unique_ptr(new int)); } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.private.fail.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.private.fail.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.private.fail.cpp @@ -26,5 +26,5 @@ { std::shared_ptr p = std::make_shared(); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp @@ -24,7 +24,7 @@ int main(int, char**) { - std::shared_ptr p = std::make_shared(); // expected-error-re@memory:* {{static_assert failed{{.*}} "Can't construct object in make_shared"}} + std::shared_ptr p = std::make_shared(); // expected-error@memory:* {{static_assert failed due to requirement 'is_constructible::value' "Can't construct object in make_shared"}} return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp @@ -17,16 +17,28 @@ #include #include +struct A +{ + int a; + virtual ~A() {}; +}; +struct B : A { }; + int main(int, char**) { { - const std::shared_ptr p(new int(32)); - assert(p); + const std::shared_ptr p(new int(32)); + assert(p); + } + { + const std::shared_ptr p; + assert(!p); } { - const std::shared_ptr p; - assert(!p); + std::shared_ptr basePtr = std::make_shared(); + std::shared_ptr sp = std::dynamic_pointer_cast(basePtr); + assert(sp); } - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bracket.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bracket.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// shared_ptr + +// element_type& operator[](ptrdiff_t i) const; + +#include "test_macros.h" + +#include +#include + +int main(int, char**) +{ + { + const std::shared_ptr p(new int[8]); + + for (int i = 0; i < 8; ++i) + p[i] = i; + for (int i = 0; i < 8; ++i) + assert(p[i] == i); + } + { + int *iptr = new int[8]; + for (int i = 0; i < 8; ++i) + iptr[i] = i; + + const std::shared_ptr p(iptr); + + for (int i = 0; i < 8; ++i) + assert(p[i] == i); + } + { + const std::shared_ptr p(new int[8]); + + for (int i = 0; i < 8; ++i) + p[i] = i; + for (int i = 0; i < 8; ++i) + assert(p[i] == i); + } + + return 0; +} Index: test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp @@ -45,6 +45,7 @@ { { const std::shared_ptr pA(new A); + assert(pA.use_count() == 1); { std::weak_ptr pB; pB = pA; Index: test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp @@ -107,5 +107,5 @@ assert(B::count == 0); assert(A::count == 0); - return 0; + return 0; } Index: www/cxx1z_status.html =================================================================== --- www/cxx1z_status.html +++ www/cxx1z_status.html @@ -128,7 +128,7 @@ P0003R5LWGRemoving Deprecated Exception Specifications from C++17IssaquahComplete5.0 P0067R5LWGElementary string conversions, revision 5IssaquahPartially done P0403R1LWGLiteral suffixes for basic_string_viewIssaquahComplete4.0 - P0414R2LWGMerging shared_ptr changes from Library Fundamentals to C++17Issaquah + P0414R2LWGMerging shared_ptr changes from Library Fundamentals to C++17IssaquahComplete P0418R2LWGFail or succeed: there is no atomic latticeIssaquah P0426R1LWGConstexpr for std::char_traitsIssaquahComplete4.0 P0435R1LWGResolving LWG Issues re common_typeIssaquahComplete4.0