diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -2314,6 +2314,11 @@ : _Base1(_VSTD::forward<_T1>(__t1)), _Base2(_VSTD::forward<_T2>(__t2)) {} #endif + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + __compressed_pair(__compressed_pair && __other) + : _Base1(_VSTD::move(__other.first())), _Base2(_VSTD::move(__other.second())) + {} + _LIBCPP_INLINE_VISIBILITY typename _Base1::reference first() _NOEXCEPT { return static_cast<_Base1&>(*this).__get(); @@ -3669,14 +3674,21 @@ template explicit shared_ptr(_Yp* __p, typename enable_if::value, __nat>::type = __nat()); - template - shared_ptr(_Yp* __p, _Dp __d, - typename enable_if::value, __nat>::type = __nat()); - template - shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, - typename enable_if::value, __nat>::type = __nat()); - template shared_ptr(nullptr_t __p, _Dp __d); - template shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); + template::element_type*>::value && + is_move_constructible<_Dp>::value, int>::type = 0> + shared_ptr(_Yp* __p, _Dp __d); + template::element_type*>::value && + is_move_constructible<_Dp>::value, int>::type = 0> + shared_ptr(_Yp* __p, _Dp __d, _Alloc __a); + template ::value, int>::type = 0> + shared_ptr(nullptr_t __p, _Dp __d); + template ::value, + int>::type = 0> + shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); template _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr& __r) _NOEXCEPT; @@ -3957,9 +3969,10 @@ } template -template -shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, - typename enable_if::value, __nat>::type) +template::element_type*>::value && + is_move_constructible<_Dp>::value, int>::type> +shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -3968,7 +3981,7 @@ #endif // _LIBCPP_NO_EXCEPTIONS typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); + __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT()); __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -3981,7 +3994,7 @@ } template -template +template::value, int>::type> shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) : __ptr_(0) { @@ -3991,7 +4004,7 @@ #endif // _LIBCPP_NO_EXCEPTIONS typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; typedef __shared_ptr_pointer _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); + __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT()); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -4003,9 +4016,10 @@ } template -template -shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, - typename enable_if::value, __nat>::type) +template::element_type*>::value && + is_move_constructible<_Dp>::value, int>::type> +shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -4018,7 +4032,7 @@ _A2 __a2(__a); unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__p, __d, __a); + _CntrlBlk(__p, _VSTD::move(__d), __a); __cntrl_ = _VSTD::addressof(*__hold2.release()); __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -4032,7 +4046,7 @@ } template -template +template::value, int>::type> shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) : __ptr_(0) { @@ -4046,7 +4060,7 @@ _A2 __a2(__a); unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__p, __d, __a); + _CntrlBlk(__p, _VSTD::move(__d), __a); __cntrl_ = _VSTD::addressof(*__hold2.release()); #ifndef _LIBCPP_NO_EXCEPTIONS } diff --git a/libcxx/test/libcxx/utilities/compressed_pair/move_const.pass.cpp b/libcxx/test/libcxx/utilities/compressed_pair/move_const.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/utilities/compressed_pair/move_const.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +#include + +#include "test_macros.h" + +struct NoCopy { + NoCopy(NoCopy const&) = delete; + NoCopy() = delete; + explicit NoCopy(int) {} + + NoCopy(NoCopy &&) = default; +}; + +template +struct Foo { + std::__compressed_pair, int> x; + Foo(T t, int i) : x(std::__compressed_pair(std::move(t), i), 0) {} +}; + +int main(int, char**) +{ + Foo f(NoCopy(0), 1); + + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp @@ -28,6 +28,19 @@ int A::count = 0; +template +class MoveDeleter +{ + MoveDeleter(); + MoveDeleter(MoveDeleter const&); +public: + MoveDeleter(MoveDeleter&&) {}; + + explicit MoveDeleter(int) {} + + void operator()(T*) {} +}; + int main(int, char**) { { @@ -46,5 +59,13 @@ assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); + { + MoveDeleter d(0); + std::shared_ptr p0(new int, std::move(d)); + std::shared_ptr p1(nullptr, std::move(d)); + std::shared_ptr p2(new int, std::move(d), std::allocator()); + std::shared_ptr p3(nullptr, std::move(d), std::allocator()); + } + return 0; } diff --git a/libcxx/www/cxx1z_status.html b/libcxx/www/cxx1z_status.html --- a/libcxx/www/cxx1z_status.html +++ b/libcxx/www/cxx1z_status.html @@ -458,7 +458,7 @@ 2795§[global.functions] provides incorrect example of ADL useKonaComplete 2796tuple should be a literal typeKonaComplete 2801Default-constructibility of unique_ptrKonaComplete - 2802shared_ptr constructor requirements for a deleterKona + 2802shared_ptr constructor requirements for a deleterKonaComplete 2804Unconditional constexpr default constructor for istream_iteratorKonaComplete 2806Base class of bad_optional_accessKonaComplete 2807std::invoke should use std::is_nothrow_callableKonaComplete