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