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