Index: libcxx/include/memory =================================================================== --- libcxx/include/memory +++ libcxx/include/memory @@ -2446,7 +2446,7 @@ template using _EnableIfDeleterAssignable = typename enable_if< is_assignable<_Dp&, _UDel&&>::value - >::type; + >::type; public: template __d) = delete; + template _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr&& __u) _NOEXCEPT + unique_ptr(unique_ptr&& __u, typename enable_if< + is_move_constructible<_Dummy>::value, + __nat + >::type = __nat()) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { } @@ -2507,8 +2511,13 @@ : __ptr_(__p.release()) {} #endif + template::type>::type> _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + typename enable_if< + is_move_assignable<_Dummy>::value, + unique_ptr& + >::type + operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; @@ -2537,11 +2546,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(); } @@ -2610,6 +2616,8 @@ private: __compressed_pair __ptr_; + struct __nat { int __for_bool_; }; + template struct _CheckArrayPointerConversion : is_same<_From, pointer> {}; @@ -2668,8 +2676,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 _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr&& __u) _NOEXCEPT + unique_ptr(unique_ptr&& __u, typename enable_if< + is_move_constructible<_Dummy>::value, + __nat + >::type = __nat()) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { } + template::type>::type> _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + typename enable_if< + is_move_assignable<_Dummy>::value, + unique_ptr& + >::type + operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; @@ -2760,10 +2777,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 Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp @@ -107,6 +107,15 @@ } } +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**) { { Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp +++ 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 {} }; Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp +++ 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 {} }; Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp +++ 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(); Index: libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp =================================================================== --- libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp +++ 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) Index: libcxx/test/support/deleter_types.h =================================================================== --- libcxx/test/support/deleter_types.h +++ 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_;} Index: libcxx/www/cxx2a_status.html =================================================================== --- libcxx/www/cxx2a_status.html +++ 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