These tests will not pass with the current implementation of variant, but should give the implementor of LWG2904 a head start.
Details:
test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp:
- Make CopyAssign's move operations noexcept so uses in variants continue to prefer copy-and-move over direct construction.
- Fix makeEmpty: Copy assignment syntax no longer invokes MakeEmptyT's throwing move constructor, move assignment syntax still does.
- test_copy_assignment_sfinae: variant<int, CopyOnly> is now copy assignable.
- test_copy_assignment_different_index:
- CopyThrows and MoveThrows have potentially-throwing move construction, so they are now copy constructed directly into variants instead of via indirect copy-and-move.
- implement new CopyCannotThrow and verify that direct copy construction of such in variants is preferred over indirect copy-and-move when neither method throws.
test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp:
- test_move_assignment_sfinae: variant<int, MoveOnly> is now move assignable.
test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp:
- test_T_assignment_performs_construction:
- assigning ThrowsCtorT into a variant now constructs a temporary and moves into the variant; the variant keeps its old value if the temporary construction throws.
- test that direct construction is preferred to temporary-and-move when neither can throw.
- test that direct construction is preferred to temporary-and-move when both can throw.
test/support/variant_test_helpers.hpp:
test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp:
test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp:
- Fix makeEmpty: Copy assignment syntax no longer invokes MakeEmptyT's throwing move constructor, move assignment syntax still does.
Reviewer note: After LWG 2904, the assignment on 191 uses a new "emplace from temporary" path. The temporary creation now throws *before* v becomes valueless.