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
34void 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: v));
39 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
40 static_assert(std::get<0>(v: 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: 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: v));
53 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
54 static_assert(std::get<1>(v: 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: v));
60 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
61 assert(std::get<1>(v) == 42);
62 }
63}
64
65void test_lvalue_get() {
66 {
67 using V = std::variant<int, const long>;
68 V v(42);
69 ASSERT_NOT_NOEXCEPT(std::get<0>(v&: 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
81void test_rvalue_get() {
82 {
83 using V = std::variant<int, const long>;
84 V v(42);
85 ASSERT_NOT_NOEXCEPT(std::get<0>(v: 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
97void 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>(v: 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
113template <std::size_t I> using Idx = std::integral_constant<std::size_t, I>;
114
115void 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
155int 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

source code of libcxx/test/std/utilities/variant/variant.get/get_index.pass.cpp