10373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// -*- C++ -*- 20373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//===----------------------------------------------------------------------===// 30373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// 40373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// The LLVM Compiler Infrastructure 50373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// 60373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open 70373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// Source Licenses. See LICENSE.TXT for details. 80373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// 90373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier//===----------------------------------------------------------------------===// 100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// UNSUPPORTED: c++98, c++03, c++11, c++14 120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// <variant> 140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// template <class ...Types> class variant; 160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// variant& operator=(variant&&) noexcept(see below); 180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <cassert> 200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <string> 210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <type_traits> 220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <utility> 230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <variant> 240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "test_macros.h" 260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "variant_test_helpers.hpp" 270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct NoCopy { 29cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier NoCopy(const NoCopy &) = delete; 30cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier NoCopy &operator=(const NoCopy &) = default; 310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct CopyOnly { 34cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier CopyOnly(const CopyOnly &) = default; 350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier CopyOnly(CopyOnly &&) = delete; 36cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier CopyOnly &operator=(const CopyOnly &) = default; 370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier CopyOnly &operator=(CopyOnly &&) = delete; 380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 390373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveOnly { 41cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnly(const MoveOnly &) = delete; 420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnly(MoveOnly &&) = default; 43cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnly &operator=(const MoveOnly &) = delete; 440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnly &operator=(MoveOnly &&) = default; 450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveOnlyNT { 48cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnlyNT(const MoveOnlyNT &) = delete; 490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnlyNT(MoveOnlyNT &&) {} 50cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnlyNT &operator=(const MoveOnlyNT &) = delete; 510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnlyNT &operator=(MoveOnlyNT &&) = default; 520373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveOnlyOddNothrow { 550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnlyOddNothrow(MoveOnlyOddNothrow &&) noexcept(false) {} 56cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnlyOddNothrow(const MoveOnlyOddNothrow &) = delete; 570373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnlyOddNothrow &operator=(MoveOnlyOddNothrow &&) noexcept = default; 58cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnlyOddNothrow &operator=(const MoveOnlyOddNothrow &) = delete; 590373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 600373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 610373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveAssignOnly { 620373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssignOnly(MoveAssignOnly &&) = delete; 630373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssignOnly &operator=(MoveAssignOnly &&) = default; 640373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 650373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 660373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveAssign { 670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static int move_construct; 680373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static int move_assign; 690373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static void reset() { move_construct = move_assign = 0; } 700373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssign(int v) : value(v) {} 710373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssign(MoveAssign &&o) : value(o.value) { 720373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier ++move_construct; 730373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier o.value = -1; 740373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 750373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssign &operator=(MoveAssign &&o) { 760373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier value = o.value; 770373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier ++move_assign; 780373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier o.value = -1; 790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier return *this; 800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier int value; 820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint MoveAssign::move_construct = 0; 850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint MoveAssign::move_assign = 0; 860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_noexcept() { 880373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int>; 900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_nothrow_move_assignable<V>::value, ""); 910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<MoveOnly>; 940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_nothrow_move_assignable<V>::value, ""); 950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long>; 980373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_nothrow_move_assignable<V>::value, ""); 990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnly>; 1020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_nothrow_move_assignable<V>::value, ""); 1030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1040373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<MoveOnlyNT>; 1060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_nothrow_move_assignable<V>::value, ""); 1070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<MoveOnlyOddNothrow>; 1100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_nothrow_move_assignable<V>::value, ""); 1110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_sfinae() { 1150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long>; 1170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_move_assignable<V>::value, ""); 1180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier // variant only provides move assignment when both the move constructor 1210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier // and move assignment operator are well formed. 1220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, CopyOnly>; 1230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_move_assignable<V>::value, ""); 1240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, NoCopy>; 1270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_move_assignable<V>::value, ""); 1280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1290373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnly>; 1310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_move_assignable<V>::value, ""); 1320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnlyNT>; 1350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_move_assignable<V>::value, ""); 1360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier // variant only provides move assignment when the types also provide 1390373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier // a move constructor. 1400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveAssignOnly>; 1410373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_move_assignable<V>::value, ""); 1420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_empty_empty() { 1460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 1470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using MET = MakeEmptyT; 1480373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long, MET>; 1500373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_index<0>); 1510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v1); 1520373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_index<0>); 1530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v2); 1540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 1550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 1560373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.valueless_by_exception()); 1570373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == std::variant_npos); 1580373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1590373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif 1600373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1610373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1620373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_non_empty_empty() { 1630373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 1640373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using MET = MakeEmptyT; 1650373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1660373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET>; 1670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_index<0>, 42); 1680373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_index<0>); 1690373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v2); 1700373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 1710373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 1720373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.valueless_by_exception()); 1730373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == std::variant_npos); 1740373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1750373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1760373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET, std::string>; 1770373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_index<2>, "hello"); 1780373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_index<0>); 1790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v2); 1800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 1810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 1820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.valueless_by_exception()); 1830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == std::variant_npos); 1840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif 1860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1880373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_empty_non_empty() { 1890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 1900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using MET = MakeEmptyT; 1910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET>; 1930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_index<0>); 1940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v1); 1950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_index<0>, 42); 1960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 1970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 1980373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 0); 1990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<0>(v1) == 42); 2000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET, std::string>; 2030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_index<0>); 2040373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v1); 2050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_type<std::string>, "hello"); 2060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 2070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 2080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 2); 2090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<2>(v1) == "hello"); 2100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif 2120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 2130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 2140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_same_index() { 2150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int>; 2170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(43); 2180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(42); 2190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 2200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 2210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 0); 2220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<0>(v1) == 42); 2230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long, unsigned>; 2260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(43l); 2270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(42l); 2280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 2290373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 2300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 1); 2310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v1) == 42); 2320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveAssign, unsigned>; 2350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_type<MoveAssign>, 43); 2360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_type<MoveAssign>, 42); 2370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssign::reset(); 2380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 2390373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 2400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 1); 2410373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v1).value == 42); 2420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(MoveAssign::move_construct == 0); 2430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(MoveAssign::move_assign == 1); 2440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 2460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using MET = MakeEmptyT; 2470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2480373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET, std::string>; 2490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_type<MET>); 2500373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MET &mref = std::get<1>(v1); 2510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_type<MET>); 2520373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier try { 2530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier v1 = std::move(v2); 2540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(false); 2550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } catch (...) { 2560373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2570373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 1); 2580373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&std::get<1>(v1) == &mref); 2590373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2600373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif 2610373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 2620373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 2630373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_assignment_different_index() { 2640373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2650373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long, unsigned>; 2660373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(43); 2670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(42l); 2680373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 2690373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 2700373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 1); 2710373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v1) == 42); 2720373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2730373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2740373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveAssign, unsigned>; 2750373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_type<unsigned>, 43); 2760373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_type<MoveAssign>, 42); 2770373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveAssign::reset(); 2780373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 2790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 2800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 1); 2810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v1).value == 42); 2820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(MoveAssign::move_construct == 1); 2830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(MoveAssign::move_assign == 0); 2840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 2860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using MET = MakeEmptyT; 2870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2880373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET, std::string>; 2890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_type<int>); 2900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_type<MET>); 2910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier try { 2920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier v1 = std::move(v2); 2930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(false); 2940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } catch (...) { 2950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.valueless_by_exception()); 2970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == std::variant_npos); 2980373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 3000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MET, std::string>; 3010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1(std::in_place_type<MET>); 3020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v2(std::in_place_type<std::string>, "hello"); 3030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V &vref = (v1 = std::move(v2)); 3040373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(&vref == &v1); 3050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v1.index() == 2); 3060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<2>(v1) == "hello"); 3070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 3080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif 3090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 3100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 3110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint main() { 3120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_empty_empty(); 3130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_non_empty_empty(); 3140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_empty_non_empty(); 3150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_same_index(); 3160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_different_index(); 3170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_sfinae(); 3180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_assignment_noexcept(); 3190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 320