diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -2701,7 +2701,6 @@ typename enable_if < !is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible::pointer, element_type*>::value, __nat >::type = __nat()); @@ -2710,7 +2709,6 @@ typename enable_if < is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible::pointer, element_type*>::value, __nat >::type = __nat()); @@ -3131,7 +3129,6 @@ typename enable_if < !is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible::pointer, element_type*>::value, __nat >::type) @@ -3144,7 +3141,7 @@ #endif { typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; + typedef __shared_ptr_pointer::pointer, _Dp, _AllocT > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); __enable_weak_this(__r.get(), __r.get()); } @@ -3157,7 +3154,6 @@ typename enable_if < is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible::pointer, element_type*>::value, __nat >::type) @@ -3170,7 +3166,7 @@ #endif { typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, + typedef __shared_ptr_pointer::pointer, reference_wrapper::type>, _AllocT > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT()); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -69,6 +69,19 @@ } }; +template +struct StatefulArrayDeleter { + int state = 0; + + StatefulArrayDeleter(int val = 0) : state(val) {} + StatefulArrayDeleter(StatefulArrayDeleter const&) { assert(false); } + + void operator()(T* ptr) { + assert(state == 42); + delete []ptr; + } +}; + int main(int, char**) { { @@ -135,5 +148,76 @@ std::shared_ptr s = std::move(u); } - return 0; + assert(A::count == 0); + { + std::unique_ptr ptr(new A[8]); + A* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 8); + assert(B::count == 8); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + assert(B::count == 0); + + { + std::unique_ptr ptr(new A[8]); + A* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 8); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + + { + std::unique_ptr ptr(new int[8]); + std::shared_ptr p(std::move(ptr)); + } + +#if TEST_STD_VER >= 14 + { + StatefulArrayDeleter d; + std::unique_ptr&> u(new A[4], d); + std::shared_ptr p(std::move(u)); + d.state = 42; + assert(A::count == 4); + } + assert(A::count == 0); + assert(B::count == 0); + + { + std::unique_ptr ptr(new A[8]); + A* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 8); + assert(B::count == 8); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + assert(B::count == 0); + + { + std::unique_ptr ptr(new A[8]); + A* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 8); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + + { + std::unique_ptr ptr(new int[8]); + std::shared_ptr p(std::move(ptr)); + } +#endif // TEST_STD_VER >= 14 + + return 0; }