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