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 // XFAIL: availability=macosx10.13 14 // XFAIL: availability=macosx10.12 15 // XFAIL: availability=macosx10.11 16 // XFAIL: availability=macosx10.10 17 // XFAIL: availability=macosx10.9 18 // XFAIL: availability=macosx10.8 19 // XFAIL: availability=macosx10.7 20 21 // <variant> 22 23 // template <size_t I, class... Types> 24 // constexpr variant_alternative_t<I, variant<Types...>>& 25 // get(variant<Types...>& v); 26 // template <size_t I, class... Types> 27 // constexpr variant_alternative_t<I, variant<Types...>>&& 28 // get(variant<Types...>&& v); 29 // template <size_t I, class... Types> 30 // constexpr variant_alternative_t<I, variant<Types...>> const& get(const 31 // variant<Types...>& v); 32 // template <size_t I, class... Types> 33 // constexpr variant_alternative_t<I, variant<Types...>> const&& get(const 34 // variant<Types...>&& v); 35 36 #include "test_macros.h" 37 #include "variant_test_helpers.hpp" 38 #include <cassert> 39 #include <type_traits> 40 #include <utility> 41 #include <variant> 42 43 void test_const_lvalue_get() { 44 { 45 using V = std::variant<int, const long>; 46 constexpr V v(42); 47 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481 48 ASSERT_NOEXCEPT(std::get<0>(v)); 49 #endif 50 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 51 static_assert(std::get<0>(v) == 42, ""); 52 } 53 { 54 using V = std::variant<int, const long>; 55 const V v(42); 56 ASSERT_NOT_NOEXCEPT(std::get<0>(v)); 57 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 58 assert(std::get<0>(v) == 42); 59 } 60 { 61 using V = std::variant<int, const long>; 62 constexpr V v(42l); 63 #ifndef __clang__ // Avoid https://bugs.llvm.org/show_bug.cgi?id=15481 64 ASSERT_NOEXCEPT(std::get<1>(v)); 65 #endif 66 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 67 static_assert(std::get<1>(v) == 42, ""); 68 } 69 { 70 using V = std::variant<int, const long>; 71 const V v(42l); 72 ASSERT_NOT_NOEXCEPT(std::get<1>(v)); 73 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 74 assert(std::get<1>(v) == 42); 75 } 76 // FIXME: Remove these once reference support is reinstated 77 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 78 { 79 using V = std::variant<int &>; 80 int x = 42; 81 const V v(x); 82 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 83 assert(&std::get<0>(v) == &x); 84 } 85 { 86 using V = std::variant<int &&>; 87 int x = 42; 88 const V v(std::move(x)); 89 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 90 assert(&std::get<0>(v) == &x); 91 } 92 { 93 using V = std::variant<const int &&>; 94 int x = 42; 95 const V v(std::move(x)); 96 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 97 assert(&std::get<0>(v) == &x); 98 } 99 #endif 100 } 101 102 void test_lvalue_get() { 103 { 104 using V = std::variant<int, const long>; 105 V v(42); 106 ASSERT_NOT_NOEXCEPT(std::get<0>(v)); 107 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 108 assert(std::get<0>(v) == 42); 109 } 110 { 111 using V = std::variant<int, const long>; 112 V v(42l); 113 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 114 assert(std::get<1>(v) == 42); 115 } 116 // FIXME: Remove these once reference support is reinstated 117 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 118 { 119 using V = std::variant<int &>; 120 int x = 42; 121 V v(x); 122 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 123 assert(&std::get<0>(v) == &x); 124 } 125 { 126 using V = std::variant<const int &>; 127 int x = 42; 128 V v(x); 129 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 130 assert(&std::get<0>(v) == &x); 131 } 132 { 133 using V = std::variant<int &&>; 134 int x = 42; 135 V v(std::move(x)); 136 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 137 assert(&std::get<0>(v) == &x); 138 } 139 { 140 using V = std::variant<const int &&>; 141 int x = 42; 142 V v(std::move(x)); 143 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 144 assert(&std::get<0>(v) == &x); 145 } 146 #endif 147 } 148 149 void test_rvalue_get() { 150 { 151 using V = std::variant<int, const long>; 152 V v(42); 153 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v))); 154 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 155 assert(std::get<0>(std::move(v)) == 42); 156 } 157 { 158 using V = std::variant<int, const long>; 159 V v(42l); 160 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&); 161 assert(std::get<1>(std::move(v)) == 42); 162 } 163 // FIXME: Remove these once reference support is reinstated 164 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 165 { 166 using V = std::variant<int &>; 167 int x = 42; 168 V v(x); 169 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &); 170 assert(&std::get<0>(std::move(v)) == &x); 171 } 172 { 173 using V = std::variant<const int &>; 174 int x = 42; 175 V v(x); 176 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &); 177 assert(&std::get<0>(std::move(v)) == &x); 178 } 179 { 180 using V = std::variant<int &&>; 181 int x = 42; 182 V v(std::move(x)); 183 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 184 int &&xref = std::get<0>(std::move(v)); 185 assert(&xref == &x); 186 } 187 { 188 using V = std::variant<const int &&>; 189 int x = 42; 190 V v(std::move(x)); 191 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 192 const int &&xref = std::get<0>(std::move(v)); 193 assert(&xref == &x); 194 } 195 #endif 196 } 197 198 void test_const_rvalue_get() { 199 { 200 using V = std::variant<int, const long>; 201 const V v(42); 202 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v))); 203 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 204 assert(std::get<0>(std::move(v)) == 42); 205 } 206 { 207 using V = std::variant<int, const long>; 208 const V v(42l); 209 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&); 210 assert(std::get<1>(std::move(v)) == 42); 211 } 212 // FIXME: Remove these once reference support is reinstated 213 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 214 { 215 using V = std::variant<int &>; 216 int x = 42; 217 const V v(x); 218 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &); 219 assert(&std::get<0>(std::move(v)) == &x); 220 } 221 { 222 using V = std::variant<const int &>; 223 int x = 42; 224 const V v(x); 225 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &); 226 assert(&std::get<0>(std::move(v)) == &x); 227 } 228 { 229 using V = std::variant<int &&>; 230 int x = 42; 231 const V v(std::move(x)); 232 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 233 int &&xref = std::get<0>(std::move(v)); 234 assert(&xref == &x); 235 } 236 { 237 using V = std::variant<const int &&>; 238 int x = 42; 239 const V v(std::move(x)); 240 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 241 const int &&xref = std::get<0>(std::move(v)); 242 assert(&xref == &x); 243 } 244 #endif 245 } 246 247 template <std::size_t I> using Idx = std::integral_constant<size_t, I>; 248 249 void test_throws_for_all_value_categories() { 250 #ifndef TEST_HAS_NO_EXCEPTIONS 251 using V = std::variant<int, long>; 252 V v0(42); 253 const V &cv0 = v0; 254 assert(v0.index() == 0); 255 V v1(42l); 256 const V &cv1 = v1; 257 assert(v1.index() == 1); 258 std::integral_constant<size_t, 0> zero; 259 std::integral_constant<size_t, 1> one; 260 auto test = [](auto idx, auto &&v) { 261 using Idx = decltype(idx); 262 try { 263 TEST_IGNORE_NODISCARD std::get<Idx::value>(std::forward<decltype(v)>(v)); 264 } catch (const std::bad_variant_access &) { 265 return true; 266 } catch (...) { /* ... */ 267 } 268 return false; 269 }; 270 { // lvalue test cases 271 assert(test(one, v0)); 272 assert(test(zero, v1)); 273 } 274 { // const lvalue test cases 275 assert(test(one, cv0)); 276 assert(test(zero, cv1)); 277 } 278 { // rvalue test cases 279 assert(test(one, std::move(v0))); 280 assert(test(zero, std::move(v1))); 281 } 282 { // const rvalue test cases 283 assert(test(one, std::move(cv0))); 284 assert(test(zero, std::move(cv1))); 285 } 286 #endif 287 } 288 289 int main() { 290 test_const_lvalue_get(); 291 test_lvalue_get(); 292 test_rvalue_get(); 293 test_const_rvalue_get(); 294 test_throws_for_all_value_categories(); 295 } 296