1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 // UNSUPPORTED: c++98, c++03, c++11, c++14 12 13 // <variant> 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); 27 28 #include "test_macros.h" 29 #include "variant_test_helpers.hpp" 30 #include <cassert> 31 #include <type_traits> 32 #include <utility> 33 #include <variant> 34 35 void test_const_lvalue_get() { 36 { 37 using V = std::variant<int, const long>; 38 constexpr V v(42); 39 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481 40 ASSERT_NOEXCEPT(std::get<0>(v)); 41 #endif 42 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 43 static_assert(std::get<0>(v) == 42, ""); 44 } 45 { 46 using V = std::variant<int, const long>; 47 const V v(42); 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); 51 } 52 { 53 using V = std::variant<int, const long>; 54 constexpr V v(42l); 55 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481 56 ASSERT_NOEXCEPT(std::get<1>(v)); 57 #endif 58 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 59 static_assert(std::get<1>(v) == 42, ""); 60 } 61 { 62 using V = std::variant<int, const long>; 63 const V v(42l); 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); 67 } 68 // FIXME: Remove these once reference support is reinstated 69 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 70 { 71 using V = std::variant<int &>; 72 int x = 42; 73 const V v(x); 74 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 75 assert(&std::get<0>(v) == &x); 76 } 77 { 78 using V = std::variant<int &&>; 79 int x = 42; 80 const V v(std::move(x)); 81 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 82 assert(&std::get<0>(v) == &x); 83 } 84 { 85 using V = std::variant<const int &&>; 86 int x = 42; 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); 90 } 91 #endif 92 } 93 94 void test_lvalue_get() { 95 { 96 using V = std::variant<int, const long>; 97 V v(42); 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); 101 } 102 { 103 using V = std::variant<int, const long>; 104 V v(42l); 105 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 106 assert(std::get<1>(v) == 42); 107 } 108 // FIXME: Remove these once reference support is reinstated 109 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 110 { 111 using V = std::variant<int &>; 112 int x = 42; 113 V v(x); 114 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 115 assert(&std::get<0>(v) == &x); 116 } 117 { 118 using V = std::variant<const int &>; 119 int x = 42; 120 V v(x); 121 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 122 assert(&std::get<0>(v) == &x); 123 } 124 { 125 using V = std::variant<int &&>; 126 int x = 42; 127 V v(std::move(x)); 128 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 129 assert(&std::get<0>(v) == &x); 130 } 131 { 132 using V = std::variant<const int &&>; 133 int x = 42; 134 V v(std::move(x)); 135 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 136 assert(&std::get<0>(v) == &x); 137 } 138 #endif 139 } 140 141 void test_rvalue_get() { 142 { 143 using V = std::variant<int, const long>; 144 V v(42); 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); 148 } 149 { 150 using V = std::variant<int, const long>; 151 V v(42l); 152 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&); 153 assert(std::get<1>(std::move(v)) == 42); 154 } 155 // FIXME: Remove these once reference support is reinstated 156 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 157 { 158 using V = std::variant<int &>; 159 int x = 42; 160 V v(x); 161 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &); 162 assert(&std::get<0>(std::move(v)) == &x); 163 } 164 { 165 using V = std::variant<const int &>; 166 int x = 42; 167 V v(x); 168 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &); 169 assert(&std::get<0>(std::move(v)) == &x); 170 } 171 { 172 using V = std::variant<int &&>; 173 int x = 42; 174 V v(std::move(x)); 175 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 176 int &&xref = std::get<0>(std::move(v)); 177 assert(&xref == &x); 178 } 179 { 180 using V = std::variant<const int &&>; 181 int x = 42; 182 V v(std::move(x)); 183 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 184 const int &&xref = std::get<0>(std::move(v)); 185 assert(&xref == &x); 186 } 187 #endif 188 } 189 190 void test_const_rvalue_get() { 191 { 192 using V = std::variant<int, const long>; 193 const V v(42); 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); 197 } 198 { 199 using V = std::variant<int, const long>; 200 const V v(42l); 201 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&); 202 assert(std::get<1>(std::move(v)) == 42); 203 } 204 // FIXME: Remove these once reference support is reinstated 205 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 206 { 207 using V = std::variant<int &>; 208 int x = 42; 209 const V v(x); 210 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &); 211 assert(&std::get<0>(std::move(v)) == &x); 212 } 213 { 214 using V = std::variant<const int &>; 215 int x = 42; 216 const V v(x); 217 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &); 218 assert(&std::get<0>(std::move(v)) == &x); 219 } 220 { 221 using V = std::variant<int &&>; 222 int x = 42; 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)); 226 assert(&xref == &x); 227 } 228 { 229 using V = std::variant<const int &&>; 230 int x = 42; 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)); 234 assert(&xref == &x); 235 } 236 #endif 237 } 238 239 template <std::size_t I> using Idx = std::integral_constant<size_t, I>; 240 241 void test_throws_for_all_value_categories() { 242 #ifndef TEST_HAS_NO_EXCEPTIONS 243 using V = std::variant<int, long>; 244 V v0(42); 245 const V &cv0 = v0; 246 assert(v0.index() == 0); 247 V v1(42l); 248 const V &cv1 = v1; 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); 254 try { 255 std::get<Idx::value>(std::forward<decltype(v)>(v)); 256 } catch (const std::bad_variant_access &) { 257 return true; 258 } catch (...) { /* ... */ 259 } 260 return false; 261 }; 262 { // lvalue test cases 263 assert(test(one, v0)); 264 assert(test(zero, v1)); 265 } 266 { // const lvalue test cases 267 assert(test(one, cv0)); 268 assert(test(zero, cv1)); 269 } 270 { // rvalue test cases 271 assert(test(one, std::move(v0))); 272 assert(test(zero, std::move(v1))); 273 } 274 { // const rvalue test cases 275 assert(test(one, std::move(cv0))); 276 assert(test(zero, std::move(cv1))); 277 } 278 #endif 279 } 280 281 int main() { 282 test_const_lvalue_get(); 283 test_lvalue_get(); 284 test_rvalue_get(); 285 test_const_rvalue_get(); 286 test_throws_for_all_value_categories(); 287 } 288