1cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// -*- C++ -*- 2cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier//===----------------------------------------------------------------------===// 3cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// 4cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// The LLVM Compiler Infrastructure 5cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// 6cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open 7cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// Source Licenses. See LICENSE.TXT for details. 8cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// 9cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier//===----------------------------------------------------------------------===// 10cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 11cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// UNSUPPORTED: c++98, c++03, c++11, c++14 12cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 13cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// <variant> 14cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 15cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// template <class ...Types> class variant; 16cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 17cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier// variant(variant&&) noexcept(see below); 18cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 19cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier#include <type_traits> 20cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier#include <variant> 21cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 22cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier#include "test_macros.h" 23cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 24cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstruct NTMove { 25cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr NTMove(int v) : value(v) {} 26cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier NTMove(const NTMove &) = delete; 27cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier NTMove(NTMove &&that) : value(that.value) { that.value = -1; } 28cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier int value; 29cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier}; 30cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 31cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstatic_assert(!std::is_trivially_move_constructible<NTMove>::value, ""); 32cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstatic_assert(std::is_move_constructible<NTMove>::value, ""); 33cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 34cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstruct TMove { 35cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr TMove(int v) : value(v) {} 36cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier TMove(const TMove &) = delete; 37cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier TMove(TMove &&) = default; 38cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier int value; 39cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier}; 40cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 41cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstatic_assert(std::is_trivially_move_constructible<TMove>::value, ""); 42cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 43cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstruct TMoveNTCopy { 44cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr TMoveNTCopy(int v) : value(v) {} 45cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier TMoveNTCopy(const TMoveNTCopy& that) : value(that.value) {} 46cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier TMoveNTCopy(TMoveNTCopy&&) = default; 47cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier int value; 48cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier}; 49cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 50cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstatic_assert(std::is_trivially_move_constructible<TMoveNTCopy>::value, ""); 51cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 52cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiseliervoid test_move_ctor_sfinae() { 53cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 54cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier using V = std::variant<int, long>; 55cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier static_assert(std::is_trivially_move_constructible<V>::value, ""); 56cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 57cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 58cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier using V = std::variant<int, NTMove>; 59cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier static_assert(!std::is_trivially_move_constructible<V>::value, ""); 60cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier static_assert(std::is_move_constructible<V>::value, ""); 61cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 62cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 63cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier using V = std::variant<int, TMove>; 64cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier static_assert(std::is_trivially_move_constructible<V>::value, ""); 65cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 66cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 67cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier using V = std::variant<int, TMoveNTCopy>; 68cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier static_assert(std::is_trivially_move_constructible<V>::value, ""); 69cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 70cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier} 71cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 72cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiseliertemplate <typename T> 73cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierstruct Result { size_t index; T value; }; 74cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 75cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiseliervoid test_move_ctor_basic() { 76cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 77cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier struct { 78cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr Result<int> operator()() const { 79cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int> v(std::in_place_index<0>, 42); 80cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int> v2 = std::move(v); 81cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier return {v2.index(), std::get<0>(std::move(v2))}; 82cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 83cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } test; 84cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr auto result = test(); 859c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.index == 0, ""); 869c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.value == 42, ""); 87cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 88cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 89cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier struct { 90cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr Result<long> operator()() const { 91cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int, long> v(std::in_place_index<1>, 42); 92cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int, long> v2 = std::move(v); 93cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier return {v2.index(), std::get<1>(std::move(v2))}; 94cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 95cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } test; 96cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr auto result = test(); 979c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.index == 1, ""); 989c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.value == 42, ""); 99cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 100cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 101cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier struct { 102cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr Result<TMove> operator()() const { 103cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<TMove> v(std::in_place_index<0>, 42); 104cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<TMove> v2(std::move(v)); 105cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier return {v2.index(), std::get<0>(std::move(v2))}; 106cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 107cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } test; 108cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr auto result = test(); 1099c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.index == 0, ""); 1109c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.value.value == 42, ""); 111cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 112cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 113cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier struct { 114cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr Result<TMove> operator()() const { 115cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int, TMove> v(std::in_place_index<1>, 42); 116cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int, TMove> v2(std::move(v)); 117cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier return {v2.index(), std::get<1>(std::move(v2))}; 118cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 119cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } test; 120cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr auto result = test(); 1219c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.index == 1, ""); 1229c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.value.value == 42, ""); 123cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 124cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 125cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier struct { 126cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr Result<TMoveNTCopy> operator()() const { 127cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<TMoveNTCopy> v(std::in_place_index<0>, 42); 128cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<TMoveNTCopy> v2(std::move(v)); 129cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier return {v2.index(), std::get<0>(std::move(v2))}; 130cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 131cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } test; 132cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr auto result = test(); 1339c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.index == 0, ""); 1349c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.value.value == 42, ""); 135cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 136cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier { 137cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier struct { 138cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr Result<TMoveNTCopy> operator()() const { 139cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int, TMoveNTCopy> v(std::in_place_index<1>, 42); 140cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier std::variant<int, TMoveNTCopy> v2(std::move(v)); 141cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier return {v2.index(), std::get<1>(std::move(v2))}; 142cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 143cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } test; 144cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier constexpr auto result = test(); 1459c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.index == 1, ""); 1469c6b70a0afc86ebdcff070ca5020497df5d62889Eric Fiselier static_assert(result.value.value == 42, ""); 147cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier } 148cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier} 149cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier 150cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselierint main() { 151cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier test_move_ctor_basic(); 152cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier test_move_ctor_sfinae(); 153cab2af84188b519bf9ae8ac75641ee06ada49a4eEric Fiselier} 154