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 <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);
22 #include "test_macros.h"
23 #include "variant_test_helpers.hpp"
25 #include <type_traits>
29 void test_const_lvalue_get() {
31 using V = std::variant<int, const long>;
33 #ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
34 ASSERT_NOEXCEPT(std::get<int>(v));
36 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
37 static_assert(std::get<int>(v) == 42, "");
40 using V = std::variant<int, const long>;
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);
47 using V = std::variant<int, const long>;
49 #ifndef __clang__ // Avoid https://llvm.org/bugs/show_bug.cgi?id=15481
50 ASSERT_NOEXCEPT(std::get<const long>(v));
52 ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
53 static_assert(std::get<const long>(v) == 42, "");
56 using V = std::variant<int, const long>;
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);
62 // FIXME: Remove these once reference support is reinstated
63 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
65 using V = std::variant<int &>;
68 ASSERT_SAME_TYPE(decltype(std::get<int &>(v)), int &);
69 assert(&std::get<int &>(v) == &x);
72 using V = std::variant<int &&>;
74 const V v(std::move(x));
75 ASSERT_SAME_TYPE(decltype(std::get<int &&>(v)), int &);
76 assert(&std::get<int &&>(v) == &x);
79 using V = std::variant<const int &&>;
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);
88 void test_lvalue_get() {
90 using V = std::variant<int, const long>;
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);
97 using V = std::variant<int, const long>;
99 ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
100 assert(std::get<const long>(v) == 42);
102 // FIXME: Remove these once reference support is reinstated
103 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
105 using V = std::variant<int &>;
108 ASSERT_SAME_TYPE(decltype(std::get<int &>(v)), int &);
109 assert(&std::get<int &>(v) == &x);
112 using V = std::variant<const int &>;
115 ASSERT_SAME_TYPE(decltype(std::get<const int &>(v)), const int &);
116 assert(&std::get<const int &>(v) == &x);
119 using V = std::variant<int &&>;
122 ASSERT_SAME_TYPE(decltype(std::get<int &&>(v)), int &);
123 assert(&std::get<int &&>(v) == &x);
126 using V = std::variant<const int &&>;
129 ASSERT_SAME_TYPE(decltype(std::get<const int &&>(v)), const int &);
130 assert(&std::get<const int &&>(v) == &x);
135 void test_rvalue_get() {
137 using V = std::variant<int, const long>;
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);
144 using V = std::variant<int, const long>;
146 ASSERT_SAME_TYPE(decltype(std::get<const long>(std::move(v))),
148 assert(std::get<const long>(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<int &>(std::move(v))), int &);
157 assert(&std::get<int &>(std::move(v)) == &x);
160 using V = std::variant<const int &>;
163 ASSERT_SAME_TYPE(decltype(std::get<const int &>(std::move(v))),
165 assert(&std::get<const int &>(std::move(v)) == &x);
168 using V = std::variant<int &&>;
171 ASSERT_SAME_TYPE(decltype(std::get<int &&>(std::move(v))), int &&);
172 int &&xref = std::get<int &&>(std::move(v));
176 using V = std::variant<const int &&>;
179 ASSERT_SAME_TYPE(decltype(std::get<const int &&>(std::move(v))),
181 const int &&xref = std::get<const int &&>(std::move(v));
187 void test_const_rvalue_get() {
189 using V = std::variant<int, const long>;
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);
196 using V = std::variant<int, const long>;
198 ASSERT_SAME_TYPE(decltype(std::get<const long>(std::move(v))),
200 assert(std::get<const long>(std::move(v)) == 42);
202 // FIXME: Remove these once reference support is reinstated
203 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
205 using V = std::variant<int &>;
208 ASSERT_SAME_TYPE(decltype(std::get<int &>(std::move(v))), int &);
209 assert(&std::get<int &>(std::move(v)) == &x);
212 using V = std::variant<const int &>;
215 ASSERT_SAME_TYPE(decltype(std::get<const int &>(std::move(v))),
217 assert(&std::get<const int &>(std::move(v)) == &x);
220 using V = std::variant<int &&>;
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));
228 using V = std::variant<const int &&>;
230 const V v(std::move(x));
231 ASSERT_SAME_TYPE(decltype(std::get<const int &&>(std::move(v))),
233 const int &&xref = std::get<const int &&>(std::move(v));
239 template <class Tp> struct identity { using type = Tp; };
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);
252 auto test = [](auto idx, auto &&v) {
253 using Idx = decltype(idx);
255 std::get<typename Idx::type>(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();