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 13c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert// XFAIL: with_system_cxx_lib=macosx10.12 14c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert// XFAIL: with_system_cxx_lib=macosx10.11 15c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert// XFAIL: with_system_cxx_lib=macosx10.10 16c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert// XFAIL: with_system_cxx_lib=macosx10.9 17c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert// XFAIL: with_system_cxx_lib=macosx10.7 18c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert// XFAIL: with_system_cxx_lib=macosx10.8 19c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// <variant> 210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// template <class ...Types> class variant; 230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier// variant(variant&&) noexcept(see below); 250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <cassert> 270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <string> 280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <type_traits> 290373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include <variant> 300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#include "test_macros.h" 32c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#include "test_workarounds.h" 330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct ThrowsMove { 350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier ThrowsMove(ThrowsMove &&) noexcept(false) {} 360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct NoCopy { 39cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier NoCopy(const NoCopy &) = delete; 400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 410373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveOnly { 430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier int value; 440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnly(int v) : value(v) {} 45cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnly(const MoveOnly &) = delete; 460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnly(MoveOnly &&) = default; 470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 480373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 490373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MoveOnlyNT { 500373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier int value; 510373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnlyNT(int v) : value(v) {} 52cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MoveOnlyNT(const MoveOnlyNT &) = delete; 530373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MoveOnlyNT(MoveOnlyNT &&other) : value(other.value) { other.value = -1; } 540373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 550373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 56c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstruct NTMove { 57c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr NTMove(int v) : value(v) {} 58c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert NTMove(const NTMove &) = delete; 59c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert NTMove(NTMove &&that) : value(that.value) { that.value = -1; } 60c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert int value; 61c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert}; 62c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 63c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstatic_assert(!std::is_trivially_move_constructible<NTMove>::value, ""); 64c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstatic_assert(std::is_move_constructible<NTMove>::value, ""); 65c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 66c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstruct TMove { 67c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr TMove(int v) : value(v) {} 68c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert TMove(const TMove &) = delete; 69c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert TMove(TMove &&) = default; 70c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert int value; 71c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert}; 72c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 73c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstatic_assert(std::is_trivially_move_constructible<TMove>::value, ""); 74c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 75c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstruct TMoveNTCopy { 76c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr TMoveNTCopy(int v) : value(v) {} 77c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert TMoveNTCopy(const TMoveNTCopy& that) : value(that.value) {} 78c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert TMoveNTCopy(TMoveNTCopy&&) = default; 79c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert int value; 80c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert}; 81c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 82c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstatic_assert(std::is_trivially_move_constructible<TMoveNTCopy>::value, ""); 83c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierstruct MakeEmptyT { 860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static int alive; 870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MakeEmptyT() { ++alive; } 88cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MakeEmptyT(const MakeEmptyT &) { 890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier ++alive; 900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier // Don't throw from the copy constructor since variant's assignment 910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier // operator performs a copy before committing to the assignment. 920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MakeEmptyT(MakeEmptyT &&) { throw 42; } 94cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; } 950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; } 960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier ~MakeEmptyT() { --alive; } 970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier}; 980373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint MakeEmptyT::alive = 0; 1000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliertemplate <class Variant> void makeEmpty(Variant &v) { 1020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier Variant v2(std::in_place_type<MakeEmptyT>); 1030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier try { 104c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert v = std::move(v2); 1050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(false); 1060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } catch (...) { 1070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v.valueless_by_exception()); 1080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#endif // TEST_HAS_NO_EXCEPTIONS 1110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_noexcept() { 1130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long>; 1150373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_nothrow_move_constructible<V>::value, ""); 1160373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1170373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1180373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnly>; 1190373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_nothrow_move_constructible<V>::value, ""); 1200373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1210373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1220373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnlyNT>; 1230373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_nothrow_move_constructible<V>::value, ""); 1240373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1250373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1260373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, ThrowsMove>; 1270373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_nothrow_move_constructible<V>::value, ""); 1280373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1290373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 1310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_ctor_sfinae() { 1320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, long>; 1340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_move_constructible<V>::value, ""); 1350373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1370373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnly>; 1380373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_move_constructible<V>::value, ""); 1390373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1400373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1410373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MoveOnlyNT>; 1420373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(std::is_move_constructible<V>::value, ""); 1430373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1440373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1450373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, NoCopy>; 1460373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier static_assert(!std::is_move_constructible<V>::value, ""); 1470373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 148c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 149c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert // The following tests are for not-yet-standardized behavior (P0602): 150c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 151c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert using V = std::variant<int, long>; 152c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_trivially_move_constructible<V>::value, ""); 153c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 154c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 155c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert using V = std::variant<int, NTMove>; 156c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(!std::is_trivially_move_constructible<V>::value, ""); 157c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_move_constructible<V>::value, ""); 158c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 159c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 160c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert using V = std::variant<int, TMove>; 161c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_trivially_move_constructible<V>::value, ""); 162c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 163c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 164c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert using V = std::variant<int, TMoveNTCopy>; 165c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_trivially_move_constructible<V>::value, ""); 166c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 1670373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 1680373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 169c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Alberttemplate <typename T> 170c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albertstruct Result { size_t index; T value; }; 171c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 1720373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_ctor_basic() { 1730373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1740373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int> v(std::in_place_index<0>, 42); 1750373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int> v2 = std::move(v); 1760373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v2.index() == 0); 1770373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<0>(v2) == 42); 1780373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1790373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1800373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, long> v(std::in_place_index<1>, 42); 1810373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, long> v2 = std::move(v); 1820373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v2.index() == 1); 1830373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v2) == 42); 1840373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1850373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1860373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<MoveOnly> v(std::in_place_index<0>, 42); 1870373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v.index() == 0); 1880373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<MoveOnly> v2(std::move(v)); 1890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v2.index() == 0); 1900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<0>(v2).value == 42); 1910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 1930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, MoveOnly> v(std::in_place_index<1>, 42); 1940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v.index() == 1); 1950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, MoveOnly> v2(std::move(v)); 1960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v2.index() == 1); 1970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v2).value == 42); 1980373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 1990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<MoveOnlyNT> v(std::in_place_index<0>, 42); 2010373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v.index() == 0); 2020373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<MoveOnlyNT> v2(std::move(v)); 2030373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v2.index() == 0); 2040373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<0>(v).value == -1); 2050373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<0>(v2).value == 42); 2060373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 2070373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier { 2080373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, MoveOnlyNT> v(std::in_place_index<1>, 42); 2090373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v.index() == 1); 2100373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier std::variant<int, MoveOnlyNT> v2(std::move(v)); 2110373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v2.index() == 1); 2120373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v).value == -1); 2130373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(std::get<1>(v2).value == 42); 2140373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier } 215c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert 216c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert // The following tests are for not-yet-standardized behavior (P0602): 217c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 218c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert struct { 219c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr Result<int> operator()() const { 220c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int> v(std::in_place_index<0>, 42); 221c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int> v2 = std::move(v); 222c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert return {v2.index(), std::get<0>(std::move(v2))}; 223c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 224c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } test; 225c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr auto result = test(); 226c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.index == 0, ""); 227c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.value == 42, ""); 228c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 229c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 230c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert struct { 231c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr Result<long> operator()() const { 232c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int, long> v(std::in_place_index<1>, 42); 233c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int, long> v2 = std::move(v); 234c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert return {v2.index(), std::get<1>(std::move(v2))}; 235c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 236c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } test; 237c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr auto result = test(); 238c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.index == 1, ""); 239c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.value == 42, ""); 240c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 241c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 242c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert struct { 243c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr Result<TMove> operator()() const { 244c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<TMove> v(std::in_place_index<0>, 42); 245c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<TMove> v2(std::move(v)); 246c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert return {v2.index(), std::get<0>(std::move(v2))}; 247c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 248c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } test; 249c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr auto result = test(); 250c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.index == 0, ""); 251c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.value.value == 42, ""); 252c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 253c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 254c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert struct { 255c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr Result<TMove> operator()() const { 256c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int, TMove> v(std::in_place_index<1>, 42); 257c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int, TMove> v2(std::move(v)); 258c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert return {v2.index(), std::get<1>(std::move(v2))}; 259c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 260c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } test; 261c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr auto result = test(); 262c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.index == 1, ""); 263c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.value.value == 42, ""); 264c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 265c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 266c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert struct { 267c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr Result<TMoveNTCopy> operator()() const { 268c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<TMoveNTCopy> v(std::in_place_index<0>, 42); 269c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<TMoveNTCopy> v2(std::move(v)); 270c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert return {v2.index(), std::get<0>(std::move(v2))}; 271c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 272c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } test; 273c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr auto result = test(); 274c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.index == 0, ""); 275c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.value.value == 42, ""); 276c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 277c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert { 278c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert struct { 279c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr Result<TMoveNTCopy> operator()() const { 280c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int, TMoveNTCopy> v(std::in_place_index<1>, 42); 281c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert std::variant<int, TMoveNTCopy> v2(std::move(v)); 282c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert return {v2.index(), std::get<1>(std::move(v2))}; 283c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 284c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } test; 285c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert constexpr auto result = test(); 286c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.index == 1, ""); 287c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(result.value.value == 42, ""); 288c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert } 2890373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 2900373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 2910373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiseliervoid test_move_ctor_valueless_by_exception() { 2920373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS 2930373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier using V = std::variant<int, MakeEmptyT>; 2940373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v1; 2950373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier makeEmpty(v1); 2960373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier V v(std::move(v1)); 2970373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier assert(v.valueless_by_exception()); 298c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#endif // TEST_HAS_NO_EXCEPTIONS 2990373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 3000373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier 30108d07da127849a21a223b1400ed394b3a86ff620Eric Fiseliertemplate <size_t Idx> 30208d07da127849a21a223b1400ed394b3a86ff620Eric Fiselierconstexpr bool test_constexpr_ctor_extension_imp( 30308d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier std::variant<long, void*, const int> const& v) 30408d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier{ 30508d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier auto copy = v; 30608d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier auto v2 = std::move(copy); 30708d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier return v2.index() == v.index() && 30808d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier v2.index() == Idx && 30908d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier std::get<Idx>(v2) == std::get<Idx>(v); 31008d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier} 31108d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier 31208d07da127849a21a223b1400ed394b3a86ff620Eric Fiseliervoid test_constexpr_move_ctor_extension() { 313c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert // NOTE: This test is for not yet standardized behavior. (P0602) 31408d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier using V = std::variant<long, void*, const int>; 315c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE 316c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_trivially_destructible<V>::value, ""); 317c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_trivially_copy_constructible<V>::value, ""); 318c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(std::is_trivially_move_constructible<V>::value, ""); 319c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(!std::is_copy_assignable<V>::value, ""); 320c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert static_assert(!std::is_move_assignable<V>::value, ""); 321c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#else // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE 32208d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier static_assert(std::is_trivially_copyable<V>::value, ""); 323c79549b70e66c251c15dd145c964edb70fa2e2b3Dan Albert#endif // TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE 32408d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier static_assert(std::is_trivially_move_constructible<V>::value, ""); 32508d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier static_assert(test_constexpr_ctor_extension_imp<0>(V(42l)), ""); 32608d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier static_assert(test_constexpr_ctor_extension_imp<1>(V(nullptr)), ""); 32708d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier static_assert(test_constexpr_ctor_extension_imp<2>(V(101)), ""); 32808d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier} 32908d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier 3300373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselierint main() { 3310373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_ctor_basic(); 3320373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_ctor_valueless_by_exception(); 3330373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_noexcept(); 3340373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier test_move_ctor_sfinae(); 33508d07da127849a21a223b1400ed394b3a86ff620Eric Fiselier test_constexpr_move_ctor_extension(); 3360373708cdc6b84bcfac38f4cf8539c6dd794d360Eric Fiselier} 337