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 ASSERT_NOT_NOEXCEPT(std::get<0>(v)); 40 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 41 static_assert(std::get<0>(v) == 42, ""); 42 } 43 { 44 using V = std::variant<int, const long>; 45 constexpr V v(42l); 46 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 47 static_assert(std::get<1>(v) == 42, ""); 48 } 49 // FIXME: Remove these once reference support is reinstated 50 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 51 { 52 using V = std::variant<int &>; 53 int x = 42; 54 const V v(x); 55 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 56 assert(&std::get<0>(v) == &x); 57 } 58 { 59 using V = std::variant<int &&>; 60 int x = 42; 61 const V v(std::move(x)); 62 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 63 assert(&std::get<0>(v) == &x); 64 } 65 { 66 using V = std::variant<const int &&>; 67 int x = 42; 68 const V v(std::move(x)); 69 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 70 assert(&std::get<0>(v) == &x); 71 } 72 #endif 73 } 74 75 void test_lvalue_get() { 76 { 77 using V = std::variant<int, const long>; 78 V v(42); 79 ASSERT_NOT_NOEXCEPT(std::get<0>(v)); 80 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 81 assert(std::get<0>(v) == 42); 82 } 83 { 84 using V = std::variant<int, const long>; 85 V v(42l); 86 ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &); 87 assert(std::get<1>(v) == 42); 88 } 89 // FIXME: Remove these once reference support is reinstated 90 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 91 { 92 using V = std::variant<int &>; 93 int x = 42; 94 V v(x); 95 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 96 assert(&std::get<0>(v) == &x); 97 } 98 { 99 using V = std::variant<const int &>; 100 int x = 42; 101 V v(x); 102 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 103 assert(&std::get<0>(v) == &x); 104 } 105 { 106 using V = std::variant<int &&>; 107 int x = 42; 108 V v(std::move(x)); 109 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &); 110 assert(&std::get<0>(v) == &x); 111 } 112 { 113 using V = std::variant<const int &&>; 114 int x = 42; 115 V v(std::move(x)); 116 ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &); 117 assert(&std::get<0>(v) == &x); 118 } 119 #endif 120 } 121 122 void test_rvalue_get() { 123 { 124 using V = std::variant<int, const long>; 125 V v(42); 126 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v))); 127 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 128 assert(std::get<0>(std::move(v)) == 42); 129 } 130 { 131 using V = std::variant<int, const long>; 132 V v(42l); 133 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&); 134 assert(std::get<1>(std::move(v)) == 42); 135 } 136 // FIXME: Remove these once reference support is reinstated 137 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 138 { 139 using V = std::variant<int &>; 140 int x = 42; 141 V v(x); 142 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &); 143 assert(&std::get<0>(std::move(v)) == &x); 144 } 145 { 146 using V = std::variant<const int &>; 147 int x = 42; 148 V v(x); 149 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &); 150 assert(&std::get<0>(std::move(v)) == &x); 151 } 152 { 153 using V = std::variant<int &&>; 154 int x = 42; 155 V v(std::move(x)); 156 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 157 int &&xref = std::get<0>(std::move(v)); 158 assert(&xref == &x); 159 } 160 { 161 using V = std::variant<const int &&>; 162 int x = 42; 163 V v(std::move(x)); 164 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 165 const int &&xref = std::get<0>(std::move(v)); 166 assert(&xref == &x); 167 } 168 #endif 169 } 170 171 void test_const_rvalue_get() { 172 { 173 using V = std::variant<int, const long>; 174 const V v(42); 175 ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v))); 176 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 177 assert(std::get<0>(std::move(v)) == 42); 178 } 179 { 180 using V = std::variant<int, const long>; 181 const V v(42l); 182 ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&); 183 assert(std::get<1>(std::move(v)) == 42); 184 } 185 // FIXME: Remove these once reference support is reinstated 186 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES) 187 { 188 using V = std::variant<int &>; 189 int x = 42; 190 const V v(x); 191 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &); 192 assert(&std::get<0>(std::move(v)) == &x); 193 } 194 { 195 using V = std::variant<const int &>; 196 int x = 42; 197 const V v(x); 198 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &); 199 assert(&std::get<0>(std::move(v)) == &x); 200 } 201 { 202 using V = std::variant<int &&>; 203 int x = 42; 204 const V v(std::move(x)); 205 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&); 206 int &&xref = std::get<0>(std::move(v)); 207 assert(&xref == &x); 208 } 209 { 210 using V = std::variant<const int &&>; 211 int x = 42; 212 const V v(std::move(x)); 213 ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&); 214 const int &&xref = std::get<0>(std::move(v)); 215 assert(&xref == &x); 216 } 217 #endif 218 } 219 220 template <std::size_t I> using Idx = std::integral_constant<size_t, I>; 221 222 void test_throws_for_all_value_categories() { 223 #ifndef TEST_HAS_NO_EXCEPTIONS 224 using V = std::variant<int, long>; 225 V v0(42); 226 const V &cv0 = v0; 227 assert(v0.index() == 0); 228 V v1(42l); 229 const V &cv1 = v1; 230 assert(v1.index() == 1); 231 std::integral_constant<size_t, 0> zero; 232 std::integral_constant<size_t, 1> one; 233 auto test = [](auto idx, auto &&v) { 234 using Idx = decltype(idx); 235 try { 236 std::get<Idx::value>(std::forward<decltype(v)>(v)); 237 } catch (const std::bad_variant_access &) { 238 return true; 239 } catch (...) { /* ... */ 240 } 241 return false; 242 }; 243 { // lvalue test cases 244 assert(test(one, v0)); 245 assert(test(zero, v1)); 246 } 247 { // const lvalue test cases 248 assert(test(one, cv0)); 249 assert(test(zero, cv1)); 250 } 251 { // rvalue test cases 252 assert(test(one, std::move(v0))); 253 assert(test(zero, std::move(v1))); 254 } 255 { // const rvalue test cases 256 assert(test(one, std::move(cv0))); 257 assert(test(zero, std::move(cv1))); 258 } 259 #endif 260 } 261 262 int main() { 263 test_const_lvalue_get(); 264 test_lvalue_get(); 265 test_rvalue_get(); 266 test_const_rvalue_get(); 267 test_throws_for_all_value_categories(); 268 } 269