Implement LWG 2904.

Summary:
- Removed the move-constructibe requirement from copy-assignable.
- Updated `__assign_alt` such that we direct initialize if
  `_Tp` can be `nothrow`-constructible from `_Arg`, or `_Tp`'s
  move construction can throw. Otherwise, construct a temporary and move it.
- Updated the tests to remove the pre-LWG2904 path.

Depends on D32671.

Reviewers: EricWF, CaseyCarter

Reviewed By: EricWF

Differential Revision: https://reviews.llvm.org/D33965

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@304891 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael Park
2017-06-07 10:22:43 +00:00
parent 7457967300
commit 3762fe69d2
4 changed files with 8 additions and 76 deletions

View File

@@ -358,7 +358,6 @@ struct __traits {
static constexpr _Trait __copy_assignable_trait = __common_trait(
{__copy_constructible_trait,
__move_constructible_trait,
__trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
static constexpr _Trait __move_assignable_trait = __common_trait(
@@ -877,25 +876,24 @@ public:
}
protected:
template <bool _CopyAssign, size_t _Ip, class _Tp, class _Arg>
template <size_t _Ip, class _Tp, class _Arg>
inline _LIBCPP_INLINE_VISIBILITY
void __assign_alt(__alt<_Ip, _Tp>& __a,
_Arg&& __arg,
bool_constant<_CopyAssign> __tag) {
void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
if (this->index() == _Ip) {
__a.__value = _VSTD::forward<_Arg>(__arg);
} else {
struct {
void operator()(true_type) const {
__this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
__this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
}
void operator()(false_type) const {
__this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
__this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
}
__assignment* __this;
_Arg&& __arg;
} __impl{this, _VSTD::forward<_Arg>(__arg)};
__impl(__tag);
__impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
!is_nothrow_move_constructible_v<_Tp>>{});
}
}
@@ -912,8 +910,7 @@ protected:
[this](auto& __this_alt, auto&& __that_alt) {
this->__assign_alt(
__this_alt,
_VSTD::forward<decltype(__that_alt)>(__that_alt).__value,
is_lvalue_reference<_That>{});
_VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
},
*this, _VSTD::forward<_That>(__that));
}
@@ -1013,8 +1010,7 @@ public:
inline _LIBCPP_INLINE_VISIBILITY
void __assign(_Arg&& __arg) {
this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
_VSTD::forward<_Arg>(__arg),
false_type{});
_VSTD::forward<_Arg>(__arg));
}
inline _LIBCPP_INLINE_VISIBILITY
@@ -1088,7 +1084,6 @@ class _LIBCPP_TEMPLATE_VIS variant
__all<is_move_constructible_v<_Types>...>::value>,
private __sfinae_assign_base<
__all<(is_copy_constructible_v<_Types> &&
is_move_constructible_v<_Types> &&
is_copy_assignable_v<_Types>)...>::value,
__all<(is_move_constructible_v<_Types> &&
is_move_assignable_v<_Types>)...>::value> {