From 8e84350ebfc8199a9878c7727dedb9f9d19253fe Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sun, 18 Dec 2011 21:19:44 +0000 Subject: [PATCH] Allow unique_ptr to be constructed and assigned from a unique_ptr git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@146853 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 96 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 19 deletions(-) diff --git a/include/memory b/include/memory index 5ec8c7da4..e7fb9d12f 100644 --- a/include/memory +++ b/include/memory @@ -2292,13 +2292,37 @@ struct _LIBCPP_VISIBLE default_delete template struct _LIBCPP_VISIBLE default_delete<_Tp[]> { - _LIBCPP_INLINE_VISIBILITY void operator() (_Tp* __ptr) const _NOEXCEPT +private: + template ::element_type>::type, + typename remove_cv<_Tp>::type>::value> + struct __same_or_less_cv_qualified_imp + : is_convertible<_P1, _Tp*> {}; + template + struct __same_or_less_cv_qualified_imp<_P1, false> + : false_type {}; + + template ::value && !is_pointer<_P1>::value> + struct __same_or_less_cv_qualified + : __same_or_less_cv_qualified_imp<_P1> {}; + + template + struct __same_or_less_cv_qualified<_P1, true> + : false_type {}; + +public: + _LIBCPP_INLINE_VISIBILITY default_delete() _NOEXCEPT {} + template + _LIBCPP_INLINE_VISIBILITY default_delete(const default_delete<_Up[]>&, + typename enable_if<__same_or_less_cv_qualified<_Up*>::value>::type* = 0) _NOEXCEPT {} + template + _LIBCPP_INLINE_VISIBILITY + void operator() (_Up* __ptr, + typename enable_if<__same_or_less_cv_qualified<_Up*>::value>::type* = 0) const _NOEXCEPT { static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type"); delete [] __ptr; } -private: - template void operator() (_Up*) const; }; template > @@ -2499,22 +2523,22 @@ private: unique_ptr(const unique_ptr&); unique_ptr& operator=(const unique_ptr&); -template ::element_type>::type, - typename remove_cv::type>::value> -struct __same_or_less_cv_qualified_imp - : is_convertible<_P1, pointer> {}; -template -struct __same_or_less_cv_qualified_imp<_P1, false> - : false_type {}; - -template ::value && !is_pointer<_P1>::value> -struct __same_or_less_cv_qualified - : __same_or_less_cv_qualified_imp<_P1> {}; - -template -struct __same_or_less_cv_qualified<_P1, true> - : false_type {}; + template ::element_type>::type, + typename remove_cv::type>::value> + struct __same_or_less_cv_qualified_imp + : is_convertible<_P1, pointer> {}; + template + struct __same_or_less_cv_qualified_imp<_P1, false> + : false_type {}; + + template ::value && !is_pointer<_P1>::value> + struct __same_or_less_cv_qualified + : __same_or_less_cv_qualified_imp<_P1> {}; + + template + struct __same_or_less_cv_qualified<_P1, true> + : false_type {}; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES unique_ptr(unique_ptr&); @@ -2597,6 +2621,40 @@ public: __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; } + + template + _LIBCPP_INLINE_VISIBILITY + unique_ptr(unique_ptr<_Up, _Ep>&& __u, + typename enable_if + < + is_array<_Up>::value && + __same_or_less_cv_qualified::pointer>::value + && is_convertible<_Ep, deleter_type>::value && + ( + !is_reference::value || + is_same::value + ), + __nat + >::type = __nat() + ) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) {} + + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + is_array<_Up>::value && + __same_or_less_cv_qualified::pointer>::value && + is_assignable::value, + unique_ptr& + >::type + operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT + { + reset(__u.release()); + __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); + return *this; + } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p)