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