diff options
author | Casey Carter <Casey@Carter.net> | 2017-06-07 00:06:04 +0000 |
---|---|---|
committer | Casey Carter <Casey@Carter.net> | 2017-06-07 00:06:04 +0000 |
commit | 708a21bd5faecb88a234b2bd6b598e4ec8a093b4 (patch) | |
tree | 53a9e7123602aacf08db887044cc264f00027941 /libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp | |
parent | 1bfb9f47af8b80d81c48eec71ee3865e3f1b2a68 (diff) | |
download | bcm5719-llvm-708a21bd5faecb88a234b2bd6b598e4ec8a093b4.tar.gz bcm5719-llvm-708a21bd5faecb88a234b2bd6b598e4ec8a093b4.zip |
[test] Test changes to accommodate LWG 2904 "Make variant move-assignment more exception safe"
Also: Move constexpr / triviality extension tests into the std tree and make them conditional on _LIBCPP_VERSION / _MSVC_STL_VERSION.
https://reviews.llvm.org/D32671
llvm-svn: 304847
Diffstat (limited to 'libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp')
-rw-r--r-- | libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp index dd5880ea663..69713662f3a 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp @@ -68,6 +68,28 @@ struct ThrowsCtorT { } }; +struct MoveCrashes { + int value; + MoveCrashes(int v = 0) noexcept : value{v} {} + MoveCrashes(MoveCrashes &&) noexcept { assert(false); } + MoveCrashes &operator=(MoveCrashes &&) noexcept { assert(false); return *this; } + MoveCrashes &operator=(int v) noexcept { + value = v; + return *this; + } +}; + +struct ThrowsCtorTandMove { + int value; + ThrowsCtorTandMove() : value(0) {} + ThrowsCtorTandMove(int) noexcept(false) { throw 42; } + ThrowsCtorTandMove(ThrowsCtorTandMove &&) noexcept(false) { assert(false); } + ThrowsCtorTandMove &operator=(int v) noexcept { + value = v; + return *this; + } +}; + struct ThrowsAssignT { int value; ThrowsAssignT() : value(0) {} @@ -126,7 +148,7 @@ void test_T_assignment_sfinae() { using V = std::variant<int, const int &>; static_assert(!std::is_assignable<V, int>::value, "ambiguous"); } -#endif +#endif // TEST_VARIANT_HAS_NO_REFERENCES } void test_T_assignment_basic() { @@ -163,7 +185,7 @@ void test_T_assignment_basic() { assert(v.index() == 2); assert(std::get<2>(v) == 42); } -#endif +#endif // TEST_VARIANT_HAS_NO_REFERENCES } void test_T_assignment_performs_construction() { @@ -174,9 +196,15 @@ void test_T_assignment_performs_construction() { V v(std::in_place_type<std::string>, "hello"); try { v = 42; + assert(false); } catch (...) { /* ... */ } +#ifdef _LIBCPP_VERSION // LWG2904 assert(v.valueless_by_exception()); +#else // _LIBCPP_VERSION + assert(v.index() == 0); + assert(std::get<0>(v) == "hello"); +#endif // _LIBCPP_VERSION } { using V = std::variant<ThrowsAssignT, std::string>; @@ -185,7 +213,29 @@ void test_T_assignment_performs_construction() { assert(v.index() == 0); assert(std::get<0>(v).value == 42); } -#endif +#ifdef _LIBCPP_VERSION // LWG2904 + { + // Test that nothrow direct construction is preferred to nothrow move. + using V = std::variant<MoveCrashes, std::string>; + V v(std::in_place_type<std::string>, "hello"); + v = 42; + assert(v.index() == 0); + assert(std::get<0>(v).value == 42); + } + { + // Test that throwing direct construction is preferred to copy-and-move when + // move can throw. + using V = std::variant<ThrowsCtorTandMove, std::string>; + V v(std::in_place_type<std::string>, "hello"); + try { + v = 42; + assert(false); + } catch(...) { /* ... */ + } + assert(v.valueless_by_exception()); + } +#endif // _LIBCPP_VERSION // LWG2904 +#endif // TEST_HAS_NO_EXCEPTIONS } void test_T_assignment_performs_assignment() { @@ -227,7 +277,7 @@ void test_T_assignment_performs_assignment() { assert(v.index() == 1); assert(std::get<1>(v).value == 100); } -#endif +#endif // TEST_HAS_NO_EXCEPTIONS } int main() { |