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 // XFAIL: availability=macosx10.13
14 // XFAIL: availability=macosx10.12
15 // XFAIL: availability=macosx10.11
16 // XFAIL: availability=macosx10.10
17 // XFAIL: availability=macosx10.9
18 // XFAIL: availability=macosx10.8
19 // XFAIL: availability=macosx10.7
20
21 // <variant>
22
23 // template <size_t I, class... Types>
24 // constexpr variant_alternative_t<I, variant<Types...>>&
25 // get(variant<Types...>& v);
26 // template <size_t I, class... Types>
27 // constexpr variant_alternative_t<I, variant<Types...>>&&
28 // get(variant<Types...>&& v);
29 // template <size_t I, class... Types>
30 // constexpr variant_alternative_t<I, variant<Types...>> const& get(const
31 // variant<Types...>& v);
32 // template <size_t I, class... Types>
33 // constexpr variant_alternative_t<I, variant<Types...>> const&& get(const
34 // variant<Types...>&& v);
35
36 #include "test_macros.h"
37 #include "variant_test_helpers.hpp"
38 #include <cassert>
39 #include <type_traits>
40 #include <utility>
41 #include <variant>
42
test_const_lvalue_get()43 void test_const_lvalue_get() {
44 {
45 using V = std::variant<int, const long>;
46 constexpr V v(42);
47 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
48 ASSERT_NOEXCEPT(std::get<0>(v));
49 #endif
50 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
51 static_assert(std::get<0>(v) == 42, "");
52 }
53 {
54 using V = std::variant<int, const long>;
55 const V v(42);
56 ASSERT_NOT_NOEXCEPT(std::get<0>(v));
57 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
58 assert(std::get<0>(v) == 42);
59 }
60 {
61 using V = std::variant<int, const long>;
62 constexpr V v(42l);
63 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
64 ASSERT_NOEXCEPT(std::get<1>(v));
65 #endif
66 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
67 static_assert(std::get<1>(v) == 42, "");
68 }
69 {
70 using V = std::variant<int, const long>;
71 const V v(42l);
72 ASSERT_NOT_NOEXCEPT(std::get<1>(v));
73 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
74 assert(std::get<1>(v) == 42);
75 }
76 // FIXME: Remove these once reference support is reinstated
77 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
78 {
79 using V = std::variant<int &>;
80 int x = 42;
81 const V v(x);
82 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
83 assert(&std::get<0>(v) == &x);
84 }
85 {
86 using V = std::variant<int &&>;
87 int x = 42;
88 const V v(std::move(x));
89 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
90 assert(&std::get<0>(v) == &x);
91 }
92 {
93 using V = std::variant<const int &&>;
94 int x = 42;
95 const V v(std::move(x));
96 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
97 assert(&std::get<0>(v) == &x);
98 }
99 #endif
100 }
101
test_lvalue_get()102 void test_lvalue_get() {
103 {
104 using V = std::variant<int, const long>;
105 V v(42);
106 ASSERT_NOT_NOEXCEPT(std::get<0>(v));
107 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
108 assert(std::get<0>(v) == 42);
109 }
110 {
111 using V = std::variant<int, const long>;
112 V v(42l);
113 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
114 assert(std::get<1>(v) == 42);
115 }
116 // FIXME: Remove these once reference support is reinstated
117 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
118 {
119 using V = std::variant<int &>;
120 int x = 42;
121 V v(x);
122 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
123 assert(&std::get<0>(v) == &x);
124 }
125 {
126 using V = std::variant<const int &>;
127 int x = 42;
128 V v(x);
129 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
130 assert(&std::get<0>(v) == &x);
131 }
132 {
133 using V = std::variant<int &&>;
134 int x = 42;
135 V v(std::move(x));
136 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
137 assert(&std::get<0>(v) == &x);
138 }
139 {
140 using V = std::variant<const int &&>;
141 int x = 42;
142 V v(std::move(x));
143 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
144 assert(&std::get<0>(v) == &x);
145 }
146 #endif
147 }
148
test_rvalue_get()149 void test_rvalue_get() {
150 {
151 using V = std::variant<int, const long>;
152 V v(42);
153 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
154 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
155 assert(std::get<0>(std::move(v)) == 42);
156 }
157 {
158 using V = std::variant<int, const long>;
159 V v(42l);
160 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
161 assert(std::get<1>(std::move(v)) == 42);
162 }
163 // FIXME: Remove these once reference support is reinstated
164 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
165 {
166 using V = std::variant<int &>;
167 int x = 42;
168 V v(x);
169 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
170 assert(&std::get<0>(std::move(v)) == &x);
171 }
172 {
173 using V = std::variant<const int &>;
174 int x = 42;
175 V v(x);
176 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
177 assert(&std::get<0>(std::move(v)) == &x);
178 }
179 {
180 using V = std::variant<int &&>;
181 int x = 42;
182 V v(std::move(x));
183 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
184 int &&xref = std::get<0>(std::move(v));
185 assert(&xref == &x);
186 }
187 {
188 using V = std::variant<const int &&>;
189 int x = 42;
190 V v(std::move(x));
191 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
192 const int &&xref = std::get<0>(std::move(v));
193 assert(&xref == &x);
194 }
195 #endif
196 }
197
test_const_rvalue_get()198 void test_const_rvalue_get() {
199 {
200 using V = std::variant<int, const long>;
201 const V v(42);
202 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
203 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
204 assert(std::get<0>(std::move(v)) == 42);
205 }
206 {
207 using V = std::variant<int, const long>;
208 const V v(42l);
209 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
210 assert(std::get<1>(std::move(v)) == 42);
211 }
212 // FIXME: Remove these once reference support is reinstated
213 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
214 {
215 using V = std::variant<int &>;
216 int x = 42;
217 const V v(x);
218 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
219 assert(&std::get<0>(std::move(v)) == &x);
220 }
221 {
222 using V = std::variant<const int &>;
223 int x = 42;
224 const V v(x);
225 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
226 assert(&std::get<0>(std::move(v)) == &x);
227 }
228 {
229 using V = std::variant<int &&>;
230 int x = 42;
231 const V v(std::move(x));
232 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
233 int &&xref = std::get<0>(std::move(v));
234 assert(&xref == &x);
235 }
236 {
237 using V = std::variant<const int &&>;
238 int x = 42;
239 const V v(std::move(x));
240 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
241 const int &&xref = std::get<0>(std::move(v));
242 assert(&xref == &x);
243 }
244 #endif
245 }
246
247 template <std::size_t I> using Idx = std::integral_constant<size_t, I>;
248
test_throws_for_all_value_categories()249 void test_throws_for_all_value_categories() {
250 #ifndef TEST_HAS_NO_EXCEPTIONS
251 using V = std::variant<int, long>;
252 V v0(42);
253 const V &cv0 = v0;
254 assert(v0.index() == 0);
255 V v1(42l);
256 const V &cv1 = v1;
257 assert(v1.index() == 1);
258 std::integral_constant<size_t, 0> zero;
259 std::integral_constant<size_t, 1> one;
260 auto test = [](auto idx, auto &&v) {
261 using Idx = decltype(idx);
262 try {
263 TEST_IGNORE_NODISCARD std::get<Idx::value>(std::forward<decltype(v)>(v));
264 } catch (const std::bad_variant_access &) {
265 return true;
266 } catch (...) { /* ... */
267 }
268 return false;
269 };
270 { // lvalue test cases
271 assert(test(one, v0));
272 assert(test(zero, v1));
273 }
274 { // const lvalue test cases
275 assert(test(one, cv0));
276 assert(test(zero, cv1));
277 }
278 { // rvalue test cases
279 assert(test(one, std::move(v0)));
280 assert(test(zero, std::move(v1)));
281 }
282 { // const rvalue test cases
283 assert(test(one, std::move(cv0)));
284 assert(test(zero, std::move(cv1)));
285 }
286 #endif
287 }
288
main()289 int main() {
290 test_const_lvalue_get();
291 test_lvalue_get();
292 test_rvalue_get();
293 test_const_rvalue_get();
294 test_throws_for_all_value_categories();
295 }
296