diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -2458,7 +2458,7 @@ template using _EnableIfDeleterAssignable = typename enable_if< is_assignable<_Dp&, _UDel&&>::value - >::type; + >::type; public: template __d) = delete; + template::value>> _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { @@ -2519,8 +2520,10 @@ : __ptr_(__p.release()) {} #endif + template::value>> _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + unique_ptr& + operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; @@ -2549,11 +2552,8 @@ } #endif -#ifdef _LIBCPP_CXX03_LANG unique_ptr(unique_ptr const&) = delete; unique_ptr& operator=(unique_ptr const&) = delete; -#endif - _LIBCPP_INLINE_VISIBILITY ~unique_ptr() { reset(); } @@ -2680,8 +2680,8 @@ template using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE = typename enable_if< - is_assignable<_Dp&, _UDel&&>::value - >::type; + is_assignable<_Dp&, _UDel&&>::value + >::type; public: template __d) = delete; + template::value>> _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { } + template::value>> _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + unique_ptr& + operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; @@ -2772,10 +2775,8 @@ return *this; } -#ifdef _LIBCPP_CXX03_LANG unique_ptr(unique_ptr const&) = delete; unique_ptr& operator=(unique_ptr const&) = delete; -#endif public: _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp @@ -91,22 +91,17 @@ static_assert(!std::is_assignable::value, ""); static_assert(std::is_nothrow_assignable::value, ""); } - { - typedef std::unique_ptr&> U; - static_assert(!std::is_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); - static_assert(std::is_nothrow_assignable::value, ""); - } - { - typedef std::unique_ptr&> U; - static_assert(!std::is_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); - static_assert(std::is_nothrow_assignable::value, ""); - } } +template +struct NonMoveableDeleter : std::default_delete { + NonMoveableDeleter() = default; + NonMoveableDeleter& operator=(NonMoveableDeleter&&) = delete; +}; + +typedef std::unique_ptr > NonMoveableUniquePtr; +static_assert(!std::is_assignable::value, ""); + int main(int, char**) { { diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp @@ -214,14 +214,9 @@ using U2 = std::unique_ptr >; using U3 = std::unique_ptr &>; using U4 = std::unique_ptr >; - using U5 = std::unique_ptr const&>; static_assert(!std::is_assignable::value, ""); static_assert(!std::is_assignable::value, ""); static_assert(!std::is_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); - - using U1C = std::unique_ptr const&>; - static_assert(std::is_nothrow_assignable::value, ""); } { // Test that if the deleter assignment is not valid the assignment operator // SFINAEs. @@ -295,16 +290,6 @@ typedef std::unique_ptr > BPtr; static_assert(std::is_nothrow_assignable::value, ""); } - { - typedef std::unique_ptr&> APtr; - typedef std::unique_ptr&> BPtr; - static_assert(std::is_nothrow_assignable::value, ""); - } - { - typedef std::unique_ptr&> APtr; - typedef std::unique_ptr&> BPtr; - static_assert(std::is_nothrow_assignable::value, ""); - } } template diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp @@ -43,10 +43,14 @@ NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; NCConvertingDeleter(NCConvertingDeleter&&) = default; + NCConvertingDeleter& operator=(NCConvertingDeleter&&) = default; template NCConvertingDeleter(NCConvertingDeleter&&) {} + template + NCConvertingDeleter& operator=(NCConvertingDeleter&&) {} + void operator()(T*) const {} }; @@ -55,10 +59,14 @@ NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; NCConvertingDeleter(NCConvertingDeleter&&) = default; + NCConvertingDeleter& operator=(NCConvertingDeleter&&) = default; template NCConvertingDeleter(NCConvertingDeleter&&) {} + template + NCConvertingDeleter& operator=(NCConvertingDeleter&&) {} + void operator()(T*) const {} }; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp @@ -44,10 +44,14 @@ NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; NCConvertingDeleter(NCConvertingDeleter&&) = default; + NCConvertingDeleter& operator=(NCConvertingDeleter&&) = default; template NCConvertingDeleter(NCConvertingDeleter&&) {} + template + NCConvertingDeleter& operator=(NCConvertingDeleter&&) {} + void operator()(T*) const {} }; @@ -56,10 +60,14 @@ NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; NCConvertingDeleter(NCConvertingDeleter&&) = default; + NCConvertingDeleter& operator=(NCConvertingDeleter&&) = default; template NCConvertingDeleter(NCConvertingDeleter&&) {} + template + NCConvertingDeleter& operator=(NCConvertingDeleter&&) {} + void operator()(T*) const {} }; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp @@ -159,6 +159,15 @@ #endif } +template +struct NonMoveableDeleter : std::default_delete { + NonMoveableDeleter() = default; + NonMoveableDeleter& operator=(NonMoveableDeleter&&) = delete; +}; + +typedef std::unique_ptr > NonMoveableUniquePtr; +static_assert(!std::is_constructible::value, ""); + int main(int, char**) { { test_basic(); diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp @@ -48,6 +48,12 @@ int value; }; +// is_move_constructible_v = false here +struct no_move_const { + no_move_const(no_move_const const&) = delete; + no_move_const(no_move_const&&) = delete; +}; + template void test_sfinae() { using Tup = std::tuple; @@ -110,6 +116,19 @@ assert(std::get<1>(t) == 1); assert(std::get<2>(t) == 2); } + // Issue 2899: + // Constraints: is_move_constructible_v is true for all i. + { + typedef std::tuple T1; + typedef std::tuple T2; + typedef std::tuple T3; + typedef std::tuple T4; + + static_assert(!std::is_constructible::value, ""); + static_assert(!std::is_constructible::value, ""); + static_assert(!std::is_constructible::value, ""); + static_assert(!std::is_constructible::value, ""); + } // A bug in tuple caused __tuple_leaf to use its explicit converting constructor // as its move constructor. This tests that ConstructsWithTupleLeaf is not called // (w/ __tuple_leaf) diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp @@ -28,7 +28,7 @@ void test_bad_return_type() { typedef std::unique_ptr upint; std::tuple t; - upint p = std::get(t); // expected-error{{deleted copy constructor}} + upint p = std::get(t); // expected-error{{call to deleted constructor of 'upint' (aka 'unique_ptr')}} } int main(int, char**) diff --git a/libcxx/test/support/deleter_types.h b/libcxx/test/support/deleter_types.h --- a/libcxx/test/support/deleter_types.h +++ b/libcxx/test/support/deleter_types.h @@ -223,6 +223,7 @@ public: NCDeleter() : state_(0) {} + NCDeleter& operator=(NCDeleter&& other) { return NCDeleter(std::move(other.state_)); } explicit NCDeleter(int s) : state_(s) {} ~NCDeleter() {assert(state_ >= 0); state_ = -1;} @@ -242,6 +243,7 @@ public: NCDeleter() : state_(0) {} + NCDeleter& operator=(NCDeleter&& other) { return NCDeleter(std::move(other.state_)); } explicit NCDeleter(int s) : state_(s) {} ~NCDeleter() {assert(state_ >= 0); state_ = -1;} @@ -263,6 +265,11 @@ NCConstDeleter() : state_(0) {} explicit NCConstDeleter(int s) : state_(s) {} + NCConstDeleter& operator=(NCConstDeleter&& other) + { + return NCConstDeleter(std::move(other.state_)); + } + ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} int state() const {return state_;} @@ -282,6 +289,11 @@ NCConstDeleter() : state_(0) {} explicit NCConstDeleter(int s) : state_(s) {} + NCConstDeleter& operator=(NCConstDeleter&& other) + { + return NCConstDeleter(std::move(other.state_)); + } + ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} int state() const {return state_;} diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -358,7 +358,7 @@ 3182Specification of Same could be clearerKona - 2899is_(nothrow_)move_constructible and tuple, optional and unique_ptrCologne + 2899is_(nothrow_)move_constructible and tuple, optional and unique_ptrCologneComplete 3055path::operator+=(single-character) misspecifiedCologne 3158tuple(allocator_arg_t, const Alloc&) should be conditionally explicitCologne 3169ranges permutation generators discard useful informationCologne