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