Implement LWG 2904 for std::variant assignment
authorJonathan Wakely <jwakely@redhat.com>
Tue, 23 Apr 2019 23:01:12 +0000 (00:01 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 23 Apr 2019 23:01:12 +0000 (00:01 +0100)
commit86a57ce103ce429afd7a47dc19fde1bd6fa93742
treeb2c536fee70cd0d7fd4b0f936e13cabc730dc05d
parenta012806011225b46f537c9e1ed8bdcf31f991916
Implement LWG 2904 for std::variant assignment

* include/std/variant (__variant_construct): Use template parameter
type instead of equivalent decltype-specifier.
(_Move_ctor_base<false, Types...>::_Move_ctor_base(_Move_ctor_base&&)):
Replace forward with move.
(_Move_ctor_base<false, Types...>::_M_destructive_move)
(_Move_ctor_base<false, Types...>::_M_destructive_copy)
(_Move_ctor_base<true, Types...>::_M_destructive_move)
(_Move_ctor_base<true, Types...>::_M_destructive_copy): Only set the
index after construction succeeds.
(_Copy_assign_base<false, Types...>::operator=): Remove redundant
if-constexpr checks that are always true. Use __remove_cvref_t instead
of remove_reference so that is_nothrow_move_constructible check
doesn't use a const rvalue parameter. In the potentially-throwing case
construct a temporary and move assign it, as per LWG 2904.
(_Move_assign_base<false, Types...>::operator=): Remove redundant
if-constexpr checks that are always true. Use emplace as per LWG 2904.
(variant::operator=(T&&)): Only use emplace conditionally, otherwise
construct a temporary and move assign from it, as per LWG 2904.
* testsuite/20_util/variant/exception_safety.cc: Check that
assignment operators have strong exception safety guarantee.

From-SVN: r270525
libstdc++-v3/ChangeLog
libstdc++-v3/include/std/variant
libstdc++-v3/testsuite/20_util/variant/exception_safety.cc