1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14
10
11 // <variant>
12
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);
25
26 #include "test_macros.h"
27 #include "test_workarounds.h"
28 #include "variant_test_helpers.h"
29 #include <cassert>
30 #include <type_traits>
31 #include <utility>
32 #include <variant>
33
test_const_lvalue_get()34 void test_const_lvalue_get() {
35 {
36 using V = std::variant<int, const long>;
37 constexpr V v(42);
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, "");
41 }
42 {
43 using V = std::variant<int, const long>;
44 const V v(42);
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);
48 }
49 {
50 using V = std::variant<int, const long>;
51 constexpr V v(42l);
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, "");
55 }
56 {
57 using V = std::variant<int, const long>;
58 const V v(42l);
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);
62 }
63 }
64
test_lvalue_get()65 void test_lvalue_get() {
66 {
67 using V = std::variant<int, const long>;
68 V v(42);
69 ASSERT_NOT_NOEXCEPT(std::get<0>(v));
70 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
71 assert(std::get<0>(v) == 42);
72 }
73 {
74 using V = std::variant<int, const long>;
75 V v(42l);
76 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
77 assert(std::get<1>(v) == 42);
78 }
79 }
80
test_rvalue_get()81 void test_rvalue_get() {
82 {
83 using V = std::variant<int, const long>;
84 V v(42);
85 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
86 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
87 assert(std::get<0>(std::move(v)) == 42);
88 }
89 {
90 using V = std::variant<int, const long>;
91 V v(42l);
92 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
93 assert(std::get<1>(std::move(v)) == 42);
94 }
95 }
96
test_const_rvalue_get()97 void test_const_rvalue_get() {
98 {
99 using V = std::variant<int, const long>;
100 const V v(42);
101 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
102 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
103 assert(std::get<0>(std::move(v)) == 42);
104 }
105 {
106 using V = std::variant<int, const long>;
107 const V v(42l);
108 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
109 assert(std::get<1>(std::move(v)) == 42);
110 }
111 }
112
113 template <std::size_t I> using Idx = std::integral_constant<std::size_t, I>;
114
test_throws_for_all_value_categories()115 void test_throws_for_all_value_categories() {
116 #ifndef TEST_HAS_NO_EXCEPTIONS
117 using V = std::variant<int, long>;
118 V v0(42);
119 const V &cv0 = v0;
120 assert(v0.index() == 0);
121 V v1(42l);
122 const V &cv1 = v1;
123 assert(v1.index() == 1);
124 std::integral_constant<std::size_t, 0> zero;
125 std::integral_constant<std::size_t, 1> one;
126 auto test = [](auto idx, auto &&v) {
127 using Idx = decltype(idx);
128 try {
129 TEST_IGNORE_NODISCARD std::get<Idx::value>(std::forward<decltype(v)>(v));
130 } catch (const std::bad_variant_access &) {
131 return true;
132 } catch (...) { /* ... */
133 }
134 return false;
135 };
136 { // lvalue test cases
137 assert(test(one, v0));
138 assert(test(zero, v1));
139 }
140 { // const lvalue test cases
141 assert(test(one, cv0));
142 assert(test(zero, cv1));
143 }
144 { // rvalue test cases
145 assert(test(one, std::move(v0)));
146 assert(test(zero, std::move(v1)));
147 }
148 { // const rvalue test cases
149 assert(test(one, std::move(cv0)));
150 assert(test(zero, std::move(cv1)));
151 }
152 #endif
153 }
154
main(int,char **)155 int main(int, char**) {
156 test_const_lvalue_get();
157 test_lvalue_get();
158 test_rvalue_get();
159 test_const_rvalue_get();
160 test_throws_for_all_value_categories();
161
162 return 0;
163 }
164