2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
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
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);
36 #include "test_macros.h"
37 #include "variant_test_helpers.hpp"
39 #include <type_traits>
43 void test_const_lvalue_get() {
45 using V = std::variant<int, const long>;
47 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
48 ASSERT_NOEXCEPT(std::get<0>(v));
50 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
51 static_assert(std::get<0>(v) == 42, "");
54 using V = std::variant<int, const long>;
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);
61 using V = std::variant<int, const long>;
63 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
64 ASSERT_NOEXCEPT(std::get<1>(v));
66 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
67 static_assert(std::get<1>(v) == 42, "");
70 using V = std::variant<int, const long>;
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);
76 // FIXME: Remove these once reference support is reinstated
77 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
79 using V = std::variant<int &>;
82 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
83 assert(&std::get<0>(v) == &x);
86 using V = std::variant<int &&>;
88 const V v(std::move(x));
89 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
90 assert(&std::get<0>(v) == &x);
93 using V = std::variant<const int &&>;
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);
102 void test_lvalue_get() {
104 using V = std::variant<int, const long>;
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);
111 using V = std::variant<int, const long>;
113 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
114 assert(std::get<1>(v) == 42);
116 // FIXME: Remove these once reference support is reinstated
117 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
119 using V = std::variant<int &>;
122 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
123 assert(&std::get<0>(v) == &x);
126 using V = std::variant<const int &>;
129 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
130 assert(&std::get<0>(v) == &x);
133 using V = std::variant<int &&>;
136 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
137 assert(&std::get<0>(v) == &x);
140 using V = std::variant<const int &&>;
143 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
144 assert(&std::get<0>(v) == &x);
149 void test_rvalue_get() {
151 using V = std::variant<int, const long>;
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);
158 using V = std::variant<int, const long>;
160 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
161 assert(std::get<1>(std::move(v)) == 42);
163 // FIXME: Remove these once reference support is reinstated
164 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
166 using V = std::variant<int &>;
169 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
170 assert(&std::get<0>(std::move(v)) == &x);
173 using V = std::variant<const int &>;
176 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
177 assert(&std::get<0>(std::move(v)) == &x);
180 using V = std::variant<int &&>;
183 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
184 int &&xref = std::get<0>(std::move(v));
188 using V = std::variant<const int &&>;
191 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
192 const int &&xref = std::get<0>(std::move(v));
198 void test_const_rvalue_get() {
200 using V = std::variant<int, const long>;
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);
207 using V = std::variant<int, const long>;
209 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
210 assert(std::get<1>(std::move(v)) == 42);
212 // FIXME: Remove these once reference support is reinstated
213 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
215 using V = std::variant<int &>;
218 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
219 assert(&std::get<0>(std::move(v)) == &x);
222 using V = std::variant<const int &>;
225 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
226 assert(&std::get<0>(std::move(v)) == &x);
229 using V = std::variant<int &&>;
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));
237 using V = std::variant<const int &&>;
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));
247 template <std::size_t I> using Idx = std::integral_constant<size_t, I>;
249 void test_throws_for_all_value_categories() {
250 #ifndef TEST_HAS_NO_EXCEPTIONS
251 using V = std::variant<int, long>;
254 assert(v0.index() == 0);
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);
263 TEST_IGNORE_NODISCARD std::get<Idx::value>(std::forward<decltype(v)>(v));
264 } catch (const std::bad_variant_access &) {
266 } catch (...) { /* ... */
270 { // lvalue test cases
271 assert(test(one, v0));
272 assert(test(zero, v1));
274 { // const lvalue test cases
275 assert(test(one, cv0));
276 assert(test(zero, cv1));
278 { // rvalue test cases
279 assert(test(one, std::move(v0)));
280 assert(test(zero, std::move(v1)));
282 { // const rvalue test cases
283 assert(test(one, std::move(cv0)));
284 assert(test(zero, std::move(cv1)));
290 test_const_lvalue_get();
293 test_const_rvalue_get();
294 test_throws_for_all_value_categories();