1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
13 // template <size_t I, class... Types>
14 // constexpr variant_alternative_t<I, variant<Types...>>&
15 // get(variant<Types...>& v);
16 // template <size_t I, class... Types>
17 // constexpr variant_alternative_t<I, variant<Types...>>&&
18 // get(variant<Types...>&& v);
19 // template <size_t I, class... Types>
20 // constexpr variant_alternative_t<I, variant<Types...>> const& get(const
21 // variant<Types...>& v);
22 // template <size_t I, class... Types>
23 // constexpr variant_alternative_t<I, variant<Types...>> const&& get(const
24 // variant<Types...>&& v);
26 #include "test_macros.h"
27 #include "test_workarounds.h"
28 #include "variant_test_helpers.h"
30 #include <type_traits>
34 void test_const_lvalue_get() {
36 using V
= std::variant
<int, const long>;
38 ASSERT_NOT_NOEXCEPT(std::get
<0>(v
));
39 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), const int &);
40 static_assert(std::get
<0>(v
) == 42, "");
43 using V
= std::variant
<int, const long>;
45 ASSERT_NOT_NOEXCEPT(std::get
<0>(v
));
46 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), const int &);
47 assert(std::get
<0>(v
) == 42);
50 using V
= std::variant
<int, const long>;
52 ASSERT_NOT_NOEXCEPT(std::get
<1>(v
));
53 ASSERT_SAME_TYPE(decltype(std::get
<1>(v
)), const long &);
54 static_assert(std::get
<1>(v
) == 42, "");
57 using V
= std::variant
<int, const long>;
59 ASSERT_NOT_NOEXCEPT(std::get
<1>(v
));
60 ASSERT_SAME_TYPE(decltype(std::get
<1>(v
)), const long &);
61 assert(std::get
<1>(v
) == 42);
63 // FIXME: Remove these once reference support is reinstated
64 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
66 using V
= std::variant
<int &>;
69 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), int &);
70 assert(&std::get
<0>(v
) == &x
);
73 using V
= std::variant
<int &&>;
75 const V
v(std::move(x
));
76 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), int &);
77 assert(&std::get
<0>(v
) == &x
);
80 using V
= std::variant
<const int &&>;
82 const V
v(std::move(x
));
83 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), const int &);
84 assert(&std::get
<0>(v
) == &x
);
89 void test_lvalue_get() {
91 using V
= std::variant
<int, const long>;
93 ASSERT_NOT_NOEXCEPT(std::get
<0>(v
));
94 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), int &);
95 assert(std::get
<0>(v
) == 42);
98 using V
= std::variant
<int, const long>;
100 ASSERT_SAME_TYPE(decltype(std::get
<1>(v
)), const long &);
101 assert(std::get
<1>(v
) == 42);
103 // FIXME: Remove these once reference support is reinstated
104 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
106 using V
= std::variant
<int &>;
109 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), int &);
110 assert(&std::get
<0>(v
) == &x
);
113 using V
= std::variant
<const int &>;
116 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), const int &);
117 assert(&std::get
<0>(v
) == &x
);
120 using V
= std::variant
<int &&>;
123 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), int &);
124 assert(&std::get
<0>(v
) == &x
);
127 using V
= std::variant
<const int &&>;
130 ASSERT_SAME_TYPE(decltype(std::get
<0>(v
)), const int &);
131 assert(&std::get
<0>(v
) == &x
);
136 void test_rvalue_get() {
138 using V
= std::variant
<int, const long>;
140 ASSERT_NOT_NOEXCEPT(std::get
<0>(std::move(v
)));
141 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), int &&);
142 assert(std::get
<0>(std::move(v
)) == 42);
145 using V
= std::variant
<int, const long>;
147 ASSERT_SAME_TYPE(decltype(std::get
<1>(std::move(v
))), const long &&);
148 assert(std::get
<1>(std::move(v
)) == 42);
150 // FIXME: Remove these once reference support is reinstated
151 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
153 using V
= std::variant
<int &>;
156 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), int &);
157 assert(&std::get
<0>(std::move(v
)) == &x
);
160 using V
= std::variant
<const int &>;
163 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), const int &);
164 assert(&std::get
<0>(std::move(v
)) == &x
);
167 using V
= std::variant
<int &&>;
170 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), int &&);
171 int &&xref
= std::get
<0>(std::move(v
));
175 using V
= std::variant
<const int &&>;
178 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), const int &&);
179 const int &&xref
= std::get
<0>(std::move(v
));
185 void test_const_rvalue_get() {
187 using V
= std::variant
<int, const long>;
189 ASSERT_NOT_NOEXCEPT(std::get
<0>(std::move(v
)));
190 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), const int &&);
191 assert(std::get
<0>(std::move(v
)) == 42);
194 using V
= std::variant
<int, const long>;
196 ASSERT_SAME_TYPE(decltype(std::get
<1>(std::move(v
))), const long &&);
197 assert(std::get
<1>(std::move(v
)) == 42);
199 // FIXME: Remove these once reference support is reinstated
200 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
202 using V
= std::variant
<int &>;
205 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), int &);
206 assert(&std::get
<0>(std::move(v
)) == &x
);
209 using V
= std::variant
<const int &>;
212 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), const int &);
213 assert(&std::get
<0>(std::move(v
)) == &x
);
216 using V
= std::variant
<int &&>;
218 const V
v(std::move(x
));
219 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), int &&);
220 int &&xref
= std::get
<0>(std::move(v
));
224 using V
= std::variant
<const int &&>;
226 const V
v(std::move(x
));
227 ASSERT_SAME_TYPE(decltype(std::get
<0>(std::move(v
))), const int &&);
228 const int &&xref
= std::get
<0>(std::move(v
));
234 template <std::size_t I
> using Idx
= std::integral_constant
<std::size_t, I
>;
236 void test_throws_for_all_value_categories() {
237 #ifndef TEST_HAS_NO_EXCEPTIONS
238 using V
= std::variant
<int, long>;
241 assert(v0
.index() == 0);
244 assert(v1
.index() == 1);
245 std::integral_constant
<std::size_t, 0> zero
;
246 std::integral_constant
<std::size_t, 1> one
;
247 auto test
= [](auto idx
, auto &&v
) {
248 using Idx
= decltype(idx
);
250 TEST_IGNORE_NODISCARD
std::get
<Idx::value
>(std::forward
<decltype(v
)>(v
));
251 } catch (const std::bad_variant_access
&) {
253 } catch (...) { /* ... */
257 { // lvalue test cases
258 assert(test(one
, v0
));
259 assert(test(zero
, v1
));
261 { // const lvalue test cases
262 assert(test(one
, cv0
));
263 assert(test(zero
, cv1
));
265 { // rvalue test cases
266 assert(test(one
, std::move(v0
)));
267 assert(test(zero
, std::move(v1
)));
269 { // const rvalue test cases
270 assert(test(one
, std::move(cv0
)));
271 assert(test(zero
, std::move(cv1
)));
276 int main(int, char**) {
277 test_const_lvalue_get();
280 test_const_rvalue_get();
281 test_throws_for_all_value_categories();