Index: include/utility =================================================================== --- include/utility +++ include/utility @@ -276,6 +276,7 @@ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); #endif + template struct _LIBCPP_TYPE_VIS_ONLY pair { @@ -323,11 +324,20 @@ { } #endif + typedef typename remove_reference<_T1>::type _T1Unref; + typedef typename remove_reference<_T2>::type _T2Unref; + + typedef integral_constant::value || is_reference<_T2>::value) + && is_copy_assignable<_T1Unref>::value + && is_copy_assignable<_T2Unref>::value> _CanCopyAssign; + _LIBCPP_INLINE_VISIBILITY - pair& operator=(const pair& __p) - _NOEXCEPT_(is_nothrow_copy_assignable::value && - is_nothrow_copy_assignable::value) + pair& + operator=(typename conditional<_CanCopyAssign::value == true, pair const&, __nat&>::type __p) + _NOEXCEPT_(is_nothrow_copy_assignable<_T1Unref>::value && + is_nothrow_copy_assignable<_T2Unref>::value) { first = __p.first; second = __p.second; @@ -365,11 +375,16 @@ { } #endif + typedef integral_constant::value || is_reference<_T2>::value) + && is_move_assignable<_T1Unref>::value + && is_move_assignable<_T2Unref>::value> _CanMoveAssign; _LIBCPP_INLINE_VISIBILITY pair& - operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) + operator=(typename conditional<_CanMoveAssign::value, pair&&, __nat&&>::type __p) + _NOEXCEPT_(is_nothrow_move_assignable<_T1Unref>::value && + is_nothrow_move_assignable<_T2Unref>::value) { first = _VSTD::forward(__p.first); second = _VSTD::forward(__p.second); Index: test/test.pass.cpp =================================================================== --- /dev/null +++ test/test.pass.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +struct NonAssignable { + NonAssignable& operator=(NonAssignable const&) = delete; + NonAssignable& operator=(NonAssignable&&) = delete; + +}; + +int main() { + using Ptr = std::unique_ptr; + using NA = NonAssignable; + { + using T = std::pair; + static_assert(!std::is_copy_assignable::value, ""); + static_assert(std::is_move_assignable::value, ""); + } + { + using T = std::pair; + static_assert(!std::is_copy_assignable::value, ""); + static_assert(std::is_move_assignable::value, ""); + } + { + using T = std::pair; + static_assert(!std::is_copy_assignable::value, ""); + static_assert(std::is_move_assignable::value, ""); + } + { + using T = std::pair; + static_assert(!std::is_copy_assignable::value, ""); + static_assert(!std::is_move_assignable::value, ""); + } + { + using T = std::pair; + static_assert(std::is_copy_assignable::value, ""); + static_assert(std::is_move_assignable::value, ""); + } + { + using T = std::tuple; + static_assert(!std::is_copy_assignable::value, ""); + } + { + using T = std::pair; + static_assert(!std::is_copy_assignable::value, ""); + static_assert(!std::is_move_assignable::value, ""); + } + { + using T = std::tuple; + static_assert(!std::is_copy_assignable::value, ""); + static_assert(!std::is_move_assignable::value, ""); + } +} \ No newline at end of file