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 {
NTMoveNTMove25 constexpr NTMove(int v) : value(v) {}
26 NTMove(const NTMove &) = delete;
NTMoveNTMove27 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 {
TMoveTMove35 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 {
TMoveNTCopyTMoveNTCopy44 constexpr TMoveNTCopy(int v) : value(v) {}
TMoveNTCopyTMoveNTCopy45 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
test_move_ctor_sfinae()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
test_move_ctor_basic()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
main()150 int main() {
151 test_move_ctor_basic();
152 test_move_ctor_sfinae();
153 }
154