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
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);
28 #include "test_macros.h"
29 #include "variant_test_helpers.hpp"
31 #include <type_traits>
35 void test_const_lvalue_get() {
37 using V = std::variant<int, const long>;
39 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
40 ASSERT_NOEXCEPT(std::get<0>(v));
42 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
43 static_assert(std::get<0>(v) == 42, "");
46 using V = std::variant<int, const long>;
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);
53 using V = std::variant<int, const long>;
55 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481
56 ASSERT_NOEXCEPT(std::get<1>(v));
58 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
59 static_assert(std::get<1>(v) == 42, "");
62 using V = std::variant<int, const long>;
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);
68 // FIXME: Remove these once reference support is reinstated
69 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
71 using V = std::variant<int &>;
74 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
75 assert(&std::get<0>(v) == &x);
78 using V = std::variant<int &&>;
80 const V v(std::move(x));
81 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
82 assert(&std::get<0>(v) == &x);
85 using V = std::variant<const int &&>;
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);
94 void test_lvalue_get() {
96 using V = std::variant<int, const long>;
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);
103 using V = std::variant<int, const long>;
105 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
106 assert(std::get<1>(v) == 42);
108 // FIXME: Remove these once reference support is reinstated
109 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
111 using V = std::variant<int &>;
114 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
115 assert(&std::get<0>(v) == &x);
118 using V = std::variant<const int &>;
121 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
122 assert(&std::get<0>(v) == &x);
125 using V = std::variant<int &&>;
128 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
129 assert(&std::get<0>(v) == &x);
132 using V = std::variant<const int &&>;
135 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
136 assert(&std::get<0>(v) == &x);
141 void test_rvalue_get() {
143 using V = std::variant<int, const long>;
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);
150 using V = std::variant<int, const long>;
152 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
153 assert(std::get<1>(std::move(v)) == 42);
155 // FIXME: Remove these once reference support is reinstated
156 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
158 using V = std::variant<int &>;
161 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
162 assert(&std::get<0>(std::move(v)) == &x);
165 using V = std::variant<const int &>;
168 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
169 assert(&std::get<0>(std::move(v)) == &x);
172 using V = std::variant<int &&>;
175 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
176 int &&xref = std::get<0>(std::move(v));
180 using V = std::variant<const int &&>;
183 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
184 const int &&xref = std::get<0>(std::move(v));
190 void test_const_rvalue_get() {
192 using V = std::variant<int, const long>;
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);
199 using V = std::variant<int, const long>;
201 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
202 assert(std::get<1>(std::move(v)) == 42);
204 // FIXME: Remove these once reference support is reinstated
205 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
207 using V = std::variant<int &>;
210 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &);
211 assert(&std::get<0>(std::move(v)) == &x);
214 using V = std::variant<const int &>;
217 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &);
218 assert(&std::get<0>(std::move(v)) == &x);
221 using V = std::variant<int &&>;
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));
229 using V = std::variant<const int &&>;
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));
239 template <std::size_t I> using Idx = std::integral_constant<size_t, I>;
241 void test_throws_for_all_value_categories() {
242 #ifndef TEST_HAS_NO_EXCEPTIONS
243 using V = std::variant<int, long>;
246 assert(v0.index() == 0);
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);
255 std::get<Idx::value>(std::forward<decltype(v)>(v));
256 } catch (const std::bad_variant_access &) {
258 } catch (...) { /* ... */
262 { // lvalue test cases
263 assert(test(one, v0));
264 assert(test(zero, v1));
266 { // const lvalue test cases
267 assert(test(one, cv0));
268 assert(test(zero, cv1));
270 { // rvalue test cases
271 assert(test(one, std::move(v0)));
272 assert(test(zero, std::move(v1)));
274 { // const rvalue test cases
275 assert(test(one, std::move(cv0)));
276 assert(test(zero, std::move(cv1)));
282 test_const_lvalue_get();
285 test_const_rvalue_get();
286 test_throws_for_all_value_categories();