| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2015, Just Software Solutions Ltd |
| 2 // All rights reserved. |
| 3 // |
| 4 // Redistribution and use in source and binary forms, with or |
| 5 // without modification, are permitted provided that the |
| 6 // following conditions are met: |
| 7 // |
| 8 // 1. Redistributions of source code must retain the above |
| 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer. |
| 11 // |
| 12 // 2. Redistributions in binary form must reproduce the above |
| 13 // copyright notice, this list of conditions and the following |
| 14 // disclaimer in the documentation and/or other materials |
| 15 // provided with the distribution. |
| 16 // |
| 17 // 3. Neither the name of the copyright holder nor the names of |
| 18 // its contributors may be used to endorse or promote products |
| 19 // derived from this software without specific prior written |
| 20 // permission. |
| 21 // |
| 22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
| 23 // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
| 24 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 25 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 26 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| 27 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 29 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 31 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 32 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 33 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| 34 // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 35 |
| 36 // Copied from https://bitbucket.org/anthonyw/variant/src |
| 37 // (5bce47fa788648f79e5ea1d77b0eef2e8f0b2999) |
| 38 |
| 39 // Modified to make it compile with exceptions disabled. |
| 40 |
| 41 #ifndef WTF_VARIANT_H |
| 42 #define WTF_VARIANT_H |
| 43 |
| 44 #include <limits.h> |
| 45 #include <stddef.h> |
| 46 #include <wtf/Compiler.h> |
| 47 #include <wtf/StdLibExtras.h> |
| 48 #include <functional> |
| 49 #include <new> |
| 50 #include <stdexcept> |
| 51 #include <string> |
| 52 #include <type_traits> |
| 53 #include <utility> |
| 54 |
| 55 #if COMPILER(MSVC) |
| 56 #pragma warning(push) |
| 57 #pragma warning(disable : 4245) |
| 58 #pragma warning(disable : 4521) |
| 59 #pragma warning(disable : 4522) |
| 60 #pragma warning(disable : 4814) |
| 61 #endif |
| 62 |
| 63 namespace std { |
| 64 |
| 65 template <class T> |
| 66 using add_const_t = typename std::add_const<T>::type; |
| 67 |
| 68 template <class T> |
| 69 using add_pointer_t = typename std::add_pointer<T>::type; |
| 70 |
| 71 template <class T> |
| 72 using add_volatile_t = typename std::add_volatile<T>::type; |
| 73 } |
| 74 |
| 75 namespace WTF { |
| 76 |
| 77 #define __THROW_EXCEPTION(__exception) \ |
| 78 do { \ |
| 79 (void)__exception; \ |
| 80 CRASH(); \ |
| 81 } while (0); |
| 82 #define __NOEXCEPT |
| 83 #define __NOEXCEPT_(...) |
| 84 |
| 85 struct __variant_in_place_private { |
| 86 template <typename> |
| 87 struct __type_holder; |
| 88 |
| 89 template <size_t> |
| 90 struct __value_holder; |
| 91 }; |
| 92 |
| 93 struct variant_in_place_tag { |
| 94 variant_in_place_tag() = delete; |
| 95 }; |
| 96 |
| 97 using variant_in_place_t = |
| 98 variant_in_place_tag (&)(__variant_in_place_private&); |
| 99 |
| 100 template <class _Type> |
| 101 using variant_in_place_type_t = |
| 102 variant_in_place_tag (&)(__variant_in_place_private::__type_holder<_Type>&); |
| 103 |
| 104 template <size_t _Index> |
| 105 using variant_in_place_index_t = variant_in_place_tag (&)( |
| 106 __variant_in_place_private::__value_holder<_Index>&); |
| 107 |
| 108 variant_in_place_tag variant_in_place(__variant_in_place_private&); |
| 109 |
| 110 template <class _Type> |
| 111 variant_in_place_tag variant_in_place( |
| 112 __variant_in_place_private::__type_holder<_Type>&) { |
| 113 __THROW_EXCEPTION(__variant_in_place_private()); |
| 114 } |
| 115 |
| 116 template <size_t _Index> |
| 117 variant_in_place_tag variant_in_place( |
| 118 __variant_in_place_private::__value_holder<_Index>&) { |
| 119 __THROW_EXCEPTION(__variant_in_place_private()); |
| 120 } |
| 121 |
| 122 class bad_variant_access : public std::logic_error { |
| 123 public: |
| 124 explicit bad_variant_access(const std::string& what_arg) |
| 125 : std::logic_error(what_arg) {} |
| 126 explicit bad_variant_access(const char* what_arg) |
| 127 : std::logic_error(what_arg) {} |
| 128 }; |
| 129 |
| 130 template <typename T> |
| 131 inline T __throw_bad_variant_access(const char* what_arg) { |
| 132 __THROW_EXCEPTION(bad_variant_access(what_arg)) |
| 133 } |
| 134 |
| 135 template <ptrdiff_t _Offset, typename _Type, typename... _Types> |
| 136 struct __type_index_helper; |
| 137 |
| 138 template <ptrdiff_t _Offset, typename _Type, typename _Head, typename... _Rest> |
| 139 struct __type_index_helper<_Offset, _Type, _Head, _Rest...> { |
| 140 static constexpr ptrdiff_t __value = |
| 141 __type_index_helper<_Offset + 1, _Type, _Rest...>::__value; |
| 142 }; |
| 143 |
| 144 template <ptrdiff_t _Offset, typename _Type, typename... _Rest> |
| 145 struct __type_index_helper<_Offset, _Type, _Type, _Rest...> { |
| 146 static constexpr ptrdiff_t __value = _Offset; |
| 147 }; |
| 148 |
| 149 template <typename _Type, typename... _Types> |
| 150 struct __type_index { |
| 151 static constexpr ptrdiff_t __value = |
| 152 __type_index_helper<0, _Type, _Types...>::__value; |
| 153 }; |
| 154 |
| 155 template <ptrdiff_t _Index, typename... _Types> |
| 156 struct __indexed_type; |
| 157 |
| 158 template <typename _Head, typename... _Rest> |
| 159 struct __indexed_type<0, _Head, _Rest...> { |
| 160 typedef _Head __type; |
| 161 }; |
| 162 |
| 163 template <typename _Head, typename... _Rest> |
| 164 struct __indexed_type<-1, _Head, _Rest...> { |
| 165 typedef void __type; |
| 166 }; |
| 167 |
| 168 template <ptrdiff_t _Index, typename _Head, typename... _Rest> |
| 169 struct __indexed_type<_Index, _Head, _Rest...> { |
| 170 typedef typename __indexed_type<_Index - 1, _Rest...>::__type __type; |
| 171 }; |
| 172 |
| 173 template <ptrdiff_t _Index, typename... _Types> |
| 174 struct __next_index { |
| 175 static constexpr ptrdiff_t __value = |
| 176 (_Index >= ptrdiff_t(sizeof...(_Types) - 1)) ? -1 : _Index + 1; |
| 177 }; |
| 178 |
| 179 template <typename... _Types> |
| 180 class Variant; |
| 181 |
| 182 template <typename> |
| 183 struct variant_size; |
| 184 |
| 185 template <typename _Type> |
| 186 struct variant_size<const _Type> : variant_size<_Type> {}; |
| 187 |
| 188 template <typename _Type> |
| 189 struct variant_size<volatile _Type> : variant_size<_Type> {}; |
| 190 |
| 191 template <typename _Type> |
| 192 struct variant_size<const volatile _Type> : variant_size<_Type> {}; |
| 193 |
| 194 template <typename... _Types> |
| 195 struct variant_size<Variant<_Types...>> |
| 196 : std::integral_constant<size_t, sizeof...(_Types)> {}; |
| 197 |
| 198 template <size_t _Index, typename _Type> |
| 199 struct variant_alternative; |
| 200 |
| 201 template <size_t _Index, typename _Type> |
| 202 using variant_alternative_t = typename variant_alternative<_Index, _Type>::type; |
| 203 |
| 204 template <size_t _Index, typename _Type> |
| 205 struct variant_alternative<_Index, const _Type> { |
| 206 using type = std::add_const_t<variant_alternative_t<_Index, _Type>>; |
| 207 }; |
| 208 |
| 209 template <size_t _Index, typename _Type> |
| 210 struct variant_alternative<_Index, volatile _Type> { |
| 211 using type = std::add_volatile_t<variant_alternative_t<_Index, _Type>>; |
| 212 }; |
| 213 |
| 214 template <size_t _Index, typename _Type> |
| 215 struct variant_alternative<_Index, volatile const _Type> { |
| 216 using type = std::add_volatile_t< |
| 217 std::add_const_t<variant_alternative_t<_Index, _Type>>>; |
| 218 }; |
| 219 |
| 220 template <size_t _Index, typename... _Types> |
| 221 struct variant_alternative<_Index, Variant<_Types...>> { |
| 222 using type = typename __indexed_type<_Index, _Types...>::__type; |
| 223 }; |
| 224 |
| 225 constexpr size_t variant_npos = -1; |
| 226 |
| 227 template <typename _Type, typename... _Types> |
| 228 constexpr _Type& get(Variant<_Types...>&); |
| 229 |
| 230 template <typename _Type, typename... _Types> |
| 231 constexpr _Type const& get(Variant<_Types...> const&); |
| 232 |
| 233 template <typename _Type, typename... _Types> |
| 234 constexpr _Type&& get(Variant<_Types...>&&); |
| 235 |
| 236 template <typename _Type, typename... _Types> |
| 237 constexpr const _Type&& get(Variant<_Types...> const&&); |
| 238 |
| 239 template <ptrdiff_t _Index, typename... _Types> |
| 240 constexpr typename __indexed_type<_Index, _Types...>::__type& get( |
| 241 Variant<_Types...>&); |
| 242 |
| 243 template <ptrdiff_t _Index, typename... _Types> |
| 244 constexpr typename __indexed_type<_Index, _Types...>::__type&& get( |
| 245 Variant<_Types...>&&); |
| 246 |
| 247 template <ptrdiff_t _Index, typename... _Types> |
| 248 constexpr typename __indexed_type<_Index, _Types...>::__type const& get( |
| 249 Variant<_Types...> const&); |
| 250 |
| 251 template <ptrdiff_t _Index, typename... _Types> |
| 252 constexpr const typename __indexed_type<_Index, _Types...>::__type&& get( |
| 253 Variant<_Types...> const&&); |
| 254 |
| 255 template <typename _Type, typename... _Types> |
| 256 constexpr std::add_pointer_t<_Type> get_if(Variant<_Types...>&); |
| 257 |
| 258 template <typename _Type, typename... _Types> |
| 259 constexpr std::add_pointer_t<_Type const> get_if(Variant<_Types...> const&); |
| 260 |
| 261 template <ptrdiff_t _Index, typename... _Types> |
| 262 constexpr std::add_pointer_t<typename __indexed_type<_Index, _Types...>::__type> |
| 263 get_if(Variant<_Types...>&); |
| 264 |
| 265 template <ptrdiff_t _Index, typename... _Types> |
| 266 constexpr std::add_pointer_t< |
| 267 typename __indexed_type<_Index, _Types...>::__type const> |
| 268 get_if(Variant<_Types...> const&); |
| 269 |
| 270 template <ptrdiff_t _Index, typename... _Types> |
| 271 struct __variant_accessor; |
| 272 |
| 273 template <size_t __count, |
| 274 bool __larger_than_char = (__count > SCHAR_MAX), |
| 275 bool __larger_than_short = (__count > SHRT_MAX), |
| 276 bool __larger_than_int = (__count > INT_MAX)> |
| 277 struct __discriminator_type { |
| 278 typedef signed char __type; |
| 279 }; |
| 280 |
| 281 template <size_t __count> |
| 282 struct __discriminator_type<__count, true, false, false> { |
| 283 typedef signed short __type; |
| 284 }; |
| 285 |
| 286 template <size_t __count> |
| 287 struct __discriminator_type<__count, true, true, false> { |
| 288 typedef int __type; |
| 289 }; |
| 290 template <size_t __count> |
| 291 struct __discriminator_type<__count, true, true, true> { |
| 292 typedef signed long __type; |
| 293 }; |
| 294 |
| 295 template <typename _Type> |
| 296 struct __stored_type { |
| 297 typedef _Type __type; |
| 298 }; |
| 299 |
| 300 template <typename _Type> |
| 301 struct __stored_type<_Type&> { |
| 302 typedef _Type* __type; |
| 303 }; |
| 304 |
| 305 template <typename... _Types> |
| 306 struct __all_trivially_destructible; |
| 307 |
| 308 template <> |
| 309 struct __all_trivially_destructible<> { |
| 310 static constexpr bool __value = true; |
| 311 }; |
| 312 |
| 313 template <typename _Type> |
| 314 struct __all_trivially_destructible<_Type> { |
| 315 static constexpr bool __value = std::is_trivially_destructible< |
| 316 typename __stored_type<_Type>::__type>::value; |
| 317 }; |
| 318 |
| 319 template <typename _Head, typename... _Rest> |
| 320 struct __all_trivially_destructible<_Head, _Rest...> { |
| 321 static constexpr bool __value = |
| 322 __all_trivially_destructible<_Head>::__value && |
| 323 __all_trivially_destructible<_Rest...>::__value; |
| 324 }; |
| 325 |
| 326 template <typename _Target, typename... _Args> |
| 327 struct __storage_nothrow_constructible { |
| 328 static const bool __value = |
| 329 std::is_nothrow_constructible<_Target, _Args...>::value; |
| 330 }; |
| 331 |
| 332 template <typename... _Types> |
| 333 struct __storage_nothrow_move_constructible; |
| 334 |
| 335 template <> |
| 336 struct __storage_nothrow_move_constructible<> { |
| 337 static constexpr bool __value = true; |
| 338 }; |
| 339 |
| 340 template <typename _Type> |
| 341 struct __storage_nothrow_move_constructible<_Type> { |
| 342 static constexpr bool __value = std::is_nothrow_move_constructible< |
| 343 typename __stored_type<_Type>::__type>::value; |
| 344 }; |
| 345 |
| 346 template <typename _Head, typename... _Rest> |
| 347 struct __storage_nothrow_move_constructible<_Head, _Rest...> { |
| 348 static constexpr bool __value = |
| 349 __storage_nothrow_move_constructible<_Head>::__value && |
| 350 __storage_nothrow_move_constructible<_Rest...>::__value; |
| 351 }; |
| 352 |
| 353 template <ptrdiff_t _Index, typename... _Types> |
| 354 struct __other_storage_nothrow_move_constructible; |
| 355 |
| 356 template <typename _Head, typename... _Rest> |
| 357 struct __other_storage_nothrow_move_constructible<0, _Head, _Rest...> { |
| 358 static const bool __value = |
| 359 __storage_nothrow_move_constructible<_Rest...>::__value; |
| 360 }; |
| 361 |
| 362 template <typename _Head, typename... _Rest> |
| 363 struct __other_storage_nothrow_move_constructible<-1, _Head, _Rest...> { |
| 364 static const bool __value = |
| 365 __storage_nothrow_move_constructible<_Head, _Rest...>::__value; |
| 366 }; |
| 367 |
| 368 template <ptrdiff_t _Index, typename _Head, typename... _Rest> |
| 369 struct __other_storage_nothrow_move_constructible<_Index, _Head, _Rest...> { |
| 370 static const bool __value = |
| 371 __storage_nothrow_move_constructible<_Head>::__value && |
| 372 __other_storage_nothrow_move_constructible<_Index - 1, _Rest...>::__value; |
| 373 }; |
| 374 |
| 375 template <ptrdiff_t _Index, typename... _Types> |
| 376 struct __backup_storage_required { |
| 377 static const bool __value = |
| 378 !__storage_nothrow_move_constructible< |
| 379 typename __indexed_type<_Index, _Types...>::__type>::__value && |
| 380 !__other_storage_nothrow_move_constructible<_Index, _Types...>::__value; |
| 381 }; |
| 382 |
| 383 template <ptrdiff_t _Index, ptrdiff_t _Count, typename... _Types> |
| 384 struct __any_backup_storage_required_impl { |
| 385 static const bool __value = |
| 386 __backup_storage_required<_Index, _Types...>::__value || |
| 387 __any_backup_storage_required_impl<_Index + 1, _Count - 1, _Types...>:: |
| 388 __value; |
| 389 }; |
| 390 |
| 391 template <ptrdiff_t _Index, typename... _Types> |
| 392 struct __any_backup_storage_required_impl<_Index, 0, _Types...> { |
| 393 static const bool __value = false; |
| 394 }; |
| 395 |
| 396 template <typename _Variant> |
| 397 struct __any_backup_storage_required; |
| 398 |
| 399 template <typename... _Types> |
| 400 struct __any_backup_storage_required<Variant<_Types...>> { |
| 401 static const bool __value = |
| 402 __any_backup_storage_required_impl<0, sizeof...(_Types), _Types...>:: |
| 403 __value; |
| 404 }; |
| 405 |
| 406 template <typename... _Types> |
| 407 union __variant_data; |
| 408 |
| 409 template <typename _Type, bool = std::is_literal_type<_Type>::value> |
| 410 struct __variant_storage { |
| 411 typedef _Type __type; |
| 412 |
| 413 static constexpr _Type& __get(__type& __val) { return __val; } |
| 414 static constexpr _Type&& __get_rref(__type& __val) { |
| 415 return std::move(__val); |
| 416 } |
| 417 static constexpr const _Type& __get(__type const& __val) { return __val; } |
| 418 static constexpr const _Type&& __get_rref(__type const& __val) { |
| 419 return std::move(__val); |
| 420 } |
| 421 static void __destroy(__type&) {} |
| 422 }; |
| 423 |
| 424 template <typename _Type> |
| 425 struct __storage_wrapper { |
| 426 typename std::aligned_storage<sizeof(_Type), alignof(_Type)>::type __storage; |
| 427 |
| 428 template <typename... _Args> |
| 429 static constexpr void* __construct(void* __p, _Args&&... __args) { |
| 430 return new (__p) _Type(std::forward<_Args>(__args)...); |
| 431 } |
| 432 |
| 433 template <typename _Dummy = _Type> |
| 434 __storage_wrapper( |
| 435 typename std::enable_if<std::is_default_constructible<_Dummy>::value, |
| 436 void (__storage_wrapper::*)()>::type = nullptr) { |
| 437 __construct(&__storage); |
| 438 } |
| 439 |
| 440 template <typename _Dummy = _Type> |
| 441 __storage_wrapper( |
| 442 typename std::enable_if<!std::is_default_constructible<_Dummy>::value, |
| 443 void (__storage_wrapper::*)()>::type = nullptr) {} |
| 444 |
| 445 template <typename _First, typename... _Args> |
| 446 __storage_wrapper(_First&& __first, _Args&&... __args) { |
| 447 __construct(&__storage, std::forward<_First>(__first), |
| 448 std::forward<_Args>(__args)...); |
| 449 } |
| 450 |
| 451 _Type& __get() { |
| 452 return *static_cast<_Type*>(static_cast<void*>(&__storage)); |
| 453 } |
| 454 constexpr _Type const& __get() const { |
| 455 return *static_cast<_Type const*>(static_cast<void const*>(&__storage)); |
| 456 } |
| 457 void __destroy() { __get().~_Type(); } |
| 458 }; |
| 459 |
| 460 template <typename _Type> |
| 461 struct __storage_wrapper<_Type&> { |
| 462 _Type* __storage; |
| 463 |
| 464 template <typename _Arg> |
| 465 constexpr __storage_wrapper(_Arg& __arg) : __storage(&__arg) {} |
| 466 |
| 467 _Type& __get() { return *__storage; } |
| 468 constexpr _Type const& __get() const { return *__storage; } |
| 469 }; |
| 470 |
| 471 template <typename _Type> |
| 472 struct __variant_storage<_Type, false> { |
| 473 typedef __storage_wrapper<_Type> __type; |
| 474 |
| 475 static constexpr _Type& __get(__type& __val) { return __val.__get(); } |
| 476 static constexpr _Type&& __get_rref(__type& __val) { |
| 477 return std::move(__val.__get()); |
| 478 } |
| 479 static constexpr const _Type& __get(__type const& __val) { |
| 480 return __val.__get(); |
| 481 } |
| 482 static constexpr const _Type&& __get_rref(__type const& __val) { |
| 483 return std::move(__val.__get()); |
| 484 } |
| 485 static void __destroy(__type& __val) { __val.__destroy(); } |
| 486 }; |
| 487 |
| 488 template <typename _Type, bool __b> |
| 489 struct __variant_storage<_Type&, __b> { |
| 490 typedef _Type* __type; |
| 491 |
| 492 static constexpr _Type& __get(__type& __val) { return *__val; } |
| 493 static constexpr _Type& __get_rref(__type& __val) { return *__val; } |
| 494 static constexpr _Type& __get(__type const& __val) { return *__val; } |
| 495 static constexpr _Type& __get_rref(__type const& __val) { return *__val; } |
| 496 static void __destroy(__type&) {} |
| 497 }; |
| 498 |
| 499 template <typename _Type, bool __b> |
| 500 struct __variant_storage<_Type&&, __b> { |
| 501 typedef _Type* __type; |
| 502 |
| 503 static constexpr _Type&& __get(__type& __val) { |
| 504 return static_cast<_Type&&>(*__val); |
| 505 } |
| 506 static constexpr _Type&& __get_rref(__type& __val) { |
| 507 return static_cast<_Type&&>(*__val); |
| 508 } |
| 509 static constexpr _Type&& __get(__type const& __val) { |
| 510 return static_cast<_Type&&>(*__val); |
| 511 } |
| 512 static constexpr _Type&& __get_rref(__type const& __val) { |
| 513 return static_cast<_Type&&>(*__val); |
| 514 } |
| 515 static void __destroy(__type&) {} |
| 516 }; |
| 517 |
| 518 template <> |
| 519 union __variant_data<> { |
| 520 constexpr __variant_data() {} |
| 521 }; |
| 522 |
| 523 template <typename _Type> |
| 524 union __variant_data<_Type> { |
| 525 typename __variant_storage<_Type>::__type __val; |
| 526 struct __dummy_type { |
| 527 } __dummy; |
| 528 |
| 529 constexpr __variant_data() : __dummy() {} |
| 530 |
| 531 template <typename... _Args> |
| 532 constexpr __variant_data(variant_in_place_index_t<0>, _Args&&... __args) |
| 533 : __val(std::forward<_Args>(__args)...) {} |
| 534 |
| 535 _Type& __get(variant_in_place_index_t<0>) { |
| 536 return __variant_storage<_Type>::__get(__val); |
| 537 } |
| 538 /*constexpr*/ _Type&& __get_rref(variant_in_place_index_t<0>) { |
| 539 return __variant_storage<_Type>::__get_rref(__val); |
| 540 } |
| 541 constexpr const _Type& __get(variant_in_place_index_t<0>) const { |
| 542 return __variant_storage<_Type>::__get(__val); |
| 543 } |
| 544 constexpr const _Type&& __get_rref(variant_in_place_index_t<0>) const { |
| 545 return __variant_storage<_Type>::__get_rref(__val); |
| 546 } |
| 547 void __destroy(variant_in_place_index_t<0>) { |
| 548 __variant_storage<_Type>::__destroy(__val); |
| 549 } |
| 550 }; |
| 551 |
| 552 template <typename _Type> |
| 553 union __variant_data<_Type&> { |
| 554 typename __variant_storage<_Type&>::__type __val; |
| 555 struct __dummy_type { |
| 556 } __dummy; |
| 557 |
| 558 constexpr __variant_data() : __dummy() {} |
| 559 |
| 560 template <typename... _Args> |
| 561 constexpr __variant_data(variant_in_place_index_t<0>, _Args&&... __args) |
| 562 : __val(&std::forward<_Args>(__args)...) {} |
| 563 |
| 564 _Type& __get(variant_in_place_index_t<0>) { |
| 565 return __variant_storage<_Type&>::__get(__val); |
| 566 } |
| 567 constexpr _Type& __get(variant_in_place_index_t<0>) const { |
| 568 return __variant_storage<_Type&>::__get(__val); |
| 569 } |
| 570 |
| 571 _Type& __get_rref(variant_in_place_index_t<0>) { |
| 572 return __variant_storage<_Type&>::__get_rref(__val); |
| 573 } |
| 574 constexpr _Type& __get_rref(variant_in_place_index_t<0>) const { |
| 575 return __variant_storage<_Type&>::__get_rref(__val); |
| 576 } |
| 577 |
| 578 void __destroy(variant_in_place_index_t<0>) { |
| 579 __variant_storage<_Type&>::__destroy(__val); |
| 580 } |
| 581 }; |
| 582 |
| 583 template <typename _Type> |
| 584 union __variant_data<_Type&&> { |
| 585 typename __variant_storage<_Type&&>::__type __val; |
| 586 struct __dummy_type { |
| 587 } __dummy; |
| 588 |
| 589 constexpr __variant_data() : __dummy() {} |
| 590 |
| 591 template <typename _Arg> |
| 592 __variant_data(variant_in_place_index_t<0>, _Arg&& __arg) : __val(&__arg) {} |
| 593 |
| 594 _Type&& __get(variant_in_place_index_t<0>) { |
| 595 return __variant_storage<_Type&&>::__get(__val); |
| 596 } |
| 597 constexpr _Type&& __get(variant_in_place_index_t<0>) const { |
| 598 return __variant_storage<_Type&&>::__get(__val); |
| 599 } |
| 600 _Type&& __get_rref(variant_in_place_index_t<0>) { |
| 601 return __variant_storage<_Type&&>::__get_rref(__val); |
| 602 } |
| 603 constexpr _Type&& __get_rref(variant_in_place_index_t<0>) const { |
| 604 return __variant_storage<_Type&&>::__get_rref(__val); |
| 605 } |
| 606 void __destroy(variant_in_place_index_t<0>) { |
| 607 __variant_storage<_Type&&>::__destroy(__val); |
| 608 } |
| 609 }; |
| 610 |
| 611 template <typename _Head, typename... _Rest> |
| 612 union __variant_data<_Head, _Rest...> { |
| 613 __variant_data<_Head> __head; |
| 614 __variant_data<_Rest...> __rest; |
| 615 |
| 616 constexpr __variant_data() : __head() {} |
| 617 |
| 618 template <typename... _Args> |
| 619 constexpr __variant_data(variant_in_place_index_t<0>, _Args&&... __args) |
| 620 : __head(variant_in_place<0>, std::forward<_Args>(__args)...) {} |
| 621 template <size_t _Index, typename... _Args> |
| 622 constexpr __variant_data(variant_in_place_index_t<_Index>, _Args&&... __args) |
| 623 : __rest(variant_in_place<_Index - 1>, std::forward<_Args>(__args)...) {} |
| 624 |
| 625 _Head& __get(variant_in_place_index_t<0>) { |
| 626 return __head.__get(variant_in_place<0>); |
| 627 } |
| 628 |
| 629 /*constexpr*/ _Head&& __get_rref(variant_in_place_index_t<0>) { |
| 630 return __head.__get_rref(variant_in_place<0>); |
| 631 } |
| 632 |
| 633 constexpr const _Head& __get(variant_in_place_index_t<0>) const { |
| 634 return __head.__get(variant_in_place<0>); |
| 635 } |
| 636 |
| 637 constexpr const _Head&& __get_rref(variant_in_place_index_t<0>) const { |
| 638 return __head.__get_rref(variant_in_place<0>); |
| 639 } |
| 640 |
| 641 template <size_t _Index> |
| 642 typename __indexed_type<_Index - 1, _Rest...>::__type& __get( |
| 643 variant_in_place_index_t<_Index>) { |
| 644 return __rest.__get(variant_in_place<_Index - 1>); |
| 645 } |
| 646 |
| 647 template <size_t _Index> |
| 648 /*constexpr*/ typename __indexed_type<_Index - 1, _Rest...>::__type&& |
| 649 __get_rref(variant_in_place_index_t<_Index>) { |
| 650 return __rest.__get_rref(variant_in_place<_Index - 1>); |
| 651 } |
| 652 |
| 653 template <size_t _Index> |
| 654 constexpr const typename __indexed_type<_Index - 1, _Rest...>::__type& __get( |
| 655 variant_in_place_index_t<_Index>) const { |
| 656 return __rest.__get(variant_in_place<_Index - 1>); |
| 657 } |
| 658 |
| 659 template <size_t _Index> |
| 660 constexpr const typename __indexed_type<_Index - 1, _Rest...>::__type&& |
| 661 __get_rref(variant_in_place_index_t<_Index>) const { |
| 662 return __rest.__get_rref(variant_in_place<_Index - 1>); |
| 663 } |
| 664 |
| 665 void __destroy(variant_in_place_index_t<0>) { |
| 666 __head.__destroy(variant_in_place<0>); |
| 667 } |
| 668 template <size_t _Index> |
| 669 void __destroy(variant_in_place_index_t<_Index>) { |
| 670 __rest.__destroy(variant_in_place<_Index - 1>); |
| 671 } |
| 672 }; |
| 673 |
| 674 template <ptrdiff_t... _Indices> |
| 675 struct __index_sequence { |
| 676 typedef __index_sequence<_Indices..., sizeof...(_Indices)> __next; |
| 677 static constexpr size_t __length = sizeof...(_Indices); |
| 678 }; |
| 679 |
| 680 template <typename... _Types> |
| 681 struct __type_indices; |
| 682 |
| 683 template <> |
| 684 struct __type_indices<> { |
| 685 typedef __index_sequence<> __type; |
| 686 }; |
| 687 |
| 688 template <typename _Type> |
| 689 struct __type_indices<_Type> { |
| 690 typedef __index_sequence<0> __type; |
| 691 }; |
| 692 |
| 693 template <typename _Type, typename... _Rest> |
| 694 struct __type_indices<_Type, _Rest...> { |
| 695 typedef typename __type_indices<_Rest...>::__type::__next __type; |
| 696 }; |
| 697 |
| 698 template <typename _Variant> |
| 699 struct __variant_indices; |
| 700 |
| 701 template <typename... _Types> |
| 702 struct __variant_indices<Variant<_Types...>> { |
| 703 typedef typename __type_indices<_Types...>::__type __type; |
| 704 }; |
| 705 |
| 706 template <typename _Variant, |
| 707 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 708 struct __move_construct_op_table; |
| 709 |
| 710 template <typename _Variant, ptrdiff_t... _Indices> |
| 711 struct __move_construct_op_table<_Variant, __index_sequence<_Indices...>> { |
| 712 typedef void (*const __func_type)(_Variant*, _Variant&); |
| 713 |
| 714 template <ptrdiff_t _Index> |
| 715 static void __move_construct_func(_Variant* __lhs, _Variant& __rhs) { |
| 716 __lhs->template __emplace_construct<_Index>(std::move(get<_Index>(__rhs))); |
| 717 } |
| 718 |
| 719 static const __func_type __apply[sizeof...(_Indices)]; |
| 720 }; |
| 721 |
| 722 template <typename _Variant, ptrdiff_t... _Indices> |
| 723 const typename __move_construct_op_table< |
| 724 _Variant, |
| 725 __index_sequence<_Indices...>>::__func_type |
| 726 __move_construct_op_table<_Variant, __index_sequence<_Indices...>>::__apply |
| 727 [sizeof...(_Indices)] = {&__move_construct_func<_Indices>...}; |
| 728 |
| 729 template <typename _Variant, |
| 730 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 731 struct __move_assign_op_table; |
| 732 |
| 733 template <typename _Variant, ptrdiff_t... _Indices> |
| 734 struct __move_assign_op_table<_Variant, __index_sequence<_Indices...>> { |
| 735 typedef void (*const __func_type)(_Variant*, _Variant&); |
| 736 |
| 737 template <ptrdiff_t _Index> |
| 738 static void __move_assign_func(_Variant* __lhs, _Variant& __rhs) { |
| 739 get<_Index>(*__lhs) = std::move(get<_Index>(__rhs)); |
| 740 } |
| 741 |
| 742 static const __func_type __apply[sizeof...(_Indices)]; |
| 743 }; |
| 744 |
| 745 template <typename _Variant, ptrdiff_t... _Indices> |
| 746 const typename __move_assign_op_table<_Variant, __index_sequence<_Indices...>>:: |
| 747 __func_type __move_assign_op_table< |
| 748 _Variant, |
| 749 __index_sequence<_Indices...>>::__apply[sizeof...(_Indices)] = { |
| 750 &__move_assign_func<_Indices>...}; |
| 751 |
| 752 template <typename _Variant, |
| 753 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 754 struct __copy_construct_op_table; |
| 755 |
| 756 template <typename _Variant, ptrdiff_t... _Indices> |
| 757 struct __copy_construct_op_table<_Variant, __index_sequence<_Indices...>> { |
| 758 typedef void (*const __func_type)(_Variant*, _Variant const&); |
| 759 |
| 760 template <ptrdiff_t _Index> |
| 761 static void __copy_construct_func(_Variant* __lhs, _Variant const& __rhs) { |
| 762 __lhs->template __emplace_construct<_Index>(get<_Index>(__rhs)); |
| 763 } |
| 764 |
| 765 static const __func_type __apply[sizeof...(_Indices)]; |
| 766 }; |
| 767 |
| 768 template <typename _Variant, ptrdiff_t... _Indices> |
| 769 const typename __copy_construct_op_table< |
| 770 _Variant, |
| 771 __index_sequence<_Indices...>>::__func_type |
| 772 __copy_construct_op_table<_Variant, __index_sequence<_Indices...>>::__apply |
| 773 [sizeof...(_Indices)] = {&__copy_construct_func<_Indices>...}; |
| 774 |
| 775 template <typename _Variant, |
| 776 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 777 struct __copy_assign_op_table; |
| 778 |
| 779 template <typename _Variant, ptrdiff_t... _Indices> |
| 780 struct __copy_assign_op_table<_Variant, __index_sequence<_Indices...>> { |
| 781 typedef void (*const __func_type)(_Variant*, _Variant const&); |
| 782 |
| 783 template <ptrdiff_t _Index> |
| 784 static void __copy_assign_func(_Variant* __lhs, _Variant const& __rhs) { |
| 785 get<_Index>(*__lhs) = get<_Index>(__rhs); |
| 786 } |
| 787 |
| 788 static const __func_type __apply[sizeof...(_Indices)]; |
| 789 }; |
| 790 |
| 791 template <typename _Variant, ptrdiff_t... _Indices> |
| 792 const typename __copy_assign_op_table<_Variant, __index_sequence<_Indices...>>:: |
| 793 __func_type __copy_assign_op_table< |
| 794 _Variant, |
| 795 __index_sequence<_Indices...>>::__apply[sizeof...(_Indices)] = { |
| 796 &__copy_assign_func<_Indices>...}; |
| 797 |
| 798 template <typename _Variant, |
| 799 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 800 struct __destroy_op_table; |
| 801 |
| 802 template <typename _Variant, ptrdiff_t... _Indices> |
| 803 struct __destroy_op_table<_Variant, __index_sequence<_Indices...>> { |
| 804 typedef void (*const __func_type)(_Variant*); |
| 805 |
| 806 template <ptrdiff_t _Index> |
| 807 static void __destroy_func(_Variant* __self) { |
| 808 if (__self->__index >= 0) { |
| 809 __self->__storage.__destroy(variant_in_place<_Index>); |
| 810 } |
| 811 } |
| 812 |
| 813 static const __func_type __apply[sizeof...(_Indices)]; |
| 814 }; |
| 815 |
| 816 template <typename _Variant, ptrdiff_t... _Indices> |
| 817 const typename __destroy_op_table<_Variant, |
| 818 __index_sequence<_Indices...>>::__func_type |
| 819 __destroy_op_table<_Variant, __index_sequence<_Indices...>>::__apply |
| 820 [sizeof...(_Indices)] = {&__destroy_func<_Indices>...}; |
| 821 |
| 822 template <typename _Variant, |
| 823 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 824 struct __swap_op_table; |
| 825 |
| 826 template <typename _Variant, ptrdiff_t... _Indices> |
| 827 struct __swap_op_table<_Variant, __index_sequence<_Indices...>> { |
| 828 typedef void (*const __func_type)(_Variant&, _Variant&); |
| 829 |
| 830 template <ptrdiff_t _Index> |
| 831 static void __swap_func(_Variant& __lhs, _Variant& __rhs) { |
| 832 swap(get<_Index>(__lhs), get<_Index>(__rhs)); |
| 833 } |
| 834 |
| 835 static const __func_type __apply[sizeof...(_Indices)]; |
| 836 }; |
| 837 |
| 838 template <typename _Variant, ptrdiff_t... _Indices> |
| 839 const typename __swap_op_table<_Variant, |
| 840 __index_sequence<_Indices...>>::__func_type |
| 841 __swap_op_table<_Variant, __index_sequence<_Indices...>>::__apply[sizeof...( |
| 842 _Indices)] = {&__swap_func<_Indices>...}; |
| 843 |
| 844 template <typename _Variant, |
| 845 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 846 struct __equality_op_table; |
| 847 |
| 848 template <typename _Variant, ptrdiff_t... _Indices> |
| 849 struct __equality_op_table<_Variant, __index_sequence<_Indices...>> { |
| 850 typedef bool (*const __compare_func_type)(_Variant const&, _Variant const&); |
| 851 |
| 852 template <ptrdiff_t _Index> |
| 853 static constexpr bool __equality_compare_func(_Variant const& __lhs, |
| 854 _Variant const& __rhs) { |
| 855 return get<_Index>(__lhs) == get<_Index>(__rhs); |
| 856 } |
| 857 |
| 858 static constexpr __compare_func_type __equality_compare[sizeof...(_Indices)] = |
| 859 {&__equality_compare_func<_Indices>...}; |
| 860 }; |
| 861 |
| 862 template <typename _Variant, ptrdiff_t... _Indices> |
| 863 constexpr |
| 864 typename __equality_op_table<_Variant, __index_sequence<_Indices...>>:: |
| 865 __compare_func_type |
| 866 __equality_op_table<_Variant, __index_sequence<_Indices...>>:: |
| 867 __equality_compare[sizeof...(_Indices)]; |
| 868 |
| 869 template <typename _Variant, |
| 870 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 871 struct __less_than_op_table; |
| 872 |
| 873 template <typename _Variant, ptrdiff_t... _Indices> |
| 874 struct __less_than_op_table<_Variant, __index_sequence<_Indices...>> { |
| 875 typedef bool (*const __compare_func_type)(_Variant const&, _Variant const&); |
| 876 |
| 877 template <ptrdiff_t _Index> |
| 878 static constexpr bool __less_than_compare_func(_Variant const& __lhs, |
| 879 _Variant const& __rhs) { |
| 880 return get<_Index>(__lhs) < get<_Index>(__rhs); |
| 881 } |
| 882 |
| 883 static constexpr __compare_func_type __less_than_compare[sizeof...( |
| 884 _Indices)] = {&__less_than_compare_func<_Indices>...}; |
| 885 }; |
| 886 |
| 887 template <typename _Variant, ptrdiff_t... _Indices> |
| 888 constexpr |
| 889 typename __less_than_op_table<_Variant, __index_sequence<_Indices...>>:: |
| 890 __compare_func_type |
| 891 __less_than_op_table<_Variant, __index_sequence<_Indices...>>:: |
| 892 __less_than_compare[sizeof...(_Indices)]; |
| 893 |
| 894 template <typename _Derived, bool __trivial_destructor> |
| 895 struct __variant_base { |
| 896 ~__variant_base() { static_cast<_Derived*>(this)->__destroy_self(); } |
| 897 }; |
| 898 |
| 899 template <typename _Derived> |
| 900 struct __variant_base<_Derived, true> {}; |
| 901 |
| 902 template <ptrdiff_t _Offset, |
| 903 typename _CurrentSequence, |
| 904 typename _Type, |
| 905 typename... _Types> |
| 906 struct __all_indices_helper; |
| 907 |
| 908 template <ptrdiff_t _Offset, |
| 909 ptrdiff_t... _Indices, |
| 910 typename _Type, |
| 911 typename... _Rest> |
| 912 struct __all_indices_helper<_Offset, |
| 913 __index_sequence<_Indices...>, |
| 914 _Type, |
| 915 _Type, |
| 916 _Rest...> { |
| 917 typedef typename __all_indices_helper<_Offset + 1, |
| 918 __index_sequence<_Indices..., _Offset>, |
| 919 _Type, |
| 920 _Rest...>::__type __type; |
| 921 }; |
| 922 |
| 923 template <ptrdiff_t _Offset, |
| 924 typename _CurrentSequence, |
| 925 typename _Type, |
| 926 typename _Head, |
| 927 typename... _Rest> |
| 928 struct __all_indices_helper<_Offset, _CurrentSequence, _Type, _Head, _Rest...> { |
| 929 typedef typename __all_indices_helper<_Offset + 1, |
| 930 _CurrentSequence, |
| 931 _Type, |
| 932 _Rest...>::__type __type; |
| 933 }; |
| 934 |
| 935 template <ptrdiff_t _Offset, typename _CurrentSequence, typename _Type> |
| 936 struct __all_indices_helper<_Offset, _CurrentSequence, _Type> { |
| 937 typedef _CurrentSequence __type; |
| 938 }; |
| 939 |
| 940 template <typename _Type, typename... _Types> |
| 941 struct __all_indices { |
| 942 typedef |
| 943 typename __all_indices_helper<0, __index_sequence<>, _Type, _Types...>:: |
| 944 __type __type; |
| 945 }; |
| 946 |
| 947 template <typename... _Sequences> |
| 948 struct __combine_sequences; |
| 949 |
| 950 template <ptrdiff_t... _Indices1, ptrdiff_t... _Indices2> |
| 951 struct __combine_sequences<__index_sequence<_Indices1...>, |
| 952 __index_sequence<_Indices2...>> { |
| 953 typedef __index_sequence<_Indices1..., _Indices2...> __type; |
| 954 }; |
| 955 |
| 956 template <typename _Sequence, typename... _Rest> |
| 957 struct __combine_sequences<_Sequence, _Rest...> { |
| 958 typedef typename __combine_sequences< |
| 959 _Sequence, |
| 960 typename __combine_sequences<_Rest...>::__type>::__type __type; |
| 961 }; |
| 962 |
| 963 template <typename _Indices> |
| 964 struct __first_index; |
| 965 |
| 966 template <ptrdiff_t _FirstIndex, ptrdiff_t... _Rest> |
| 967 struct __first_index<__index_sequence<_FirstIndex, _Rest...>> { |
| 968 static constexpr ptrdiff_t __value = _FirstIndex; |
| 969 }; |
| 970 |
| 971 template <ptrdiff_t _Offset, |
| 972 typename _CurrentSequence, |
| 973 typename _Type, |
| 974 typename... _Types> |
| 975 struct __constructible_matches_helper; |
| 976 |
| 977 template <ptrdiff_t _Offset, typename _Sequence, typename _Type> |
| 978 struct __constructible_matches_helper<_Offset, _Sequence, _Type> { |
| 979 typedef _Sequence __type; |
| 980 }; |
| 981 |
| 982 template <bool _Accept, ptrdiff_t _Entry> |
| 983 struct __sequence_or_empty { |
| 984 typedef __index_sequence<> __type; |
| 985 }; |
| 986 |
| 987 template <ptrdiff_t _Entry> |
| 988 struct __sequence_or_empty<true, _Entry> { |
| 989 typedef __index_sequence<_Entry> __type; |
| 990 }; |
| 991 |
| 992 template <ptrdiff_t _Offset, |
| 993 typename _CurrentSequence, |
| 994 typename _Type, |
| 995 typename _Head, |
| 996 typename... _Rest> |
| 997 struct __constructible_matches_helper<_Offset, |
| 998 _CurrentSequence, |
| 999 _Type, |
| 1000 _Head, |
| 1001 _Rest...> { |
| 1002 typedef typename __constructible_matches_helper< |
| 1003 _Offset + 1, |
| 1004 typename __combine_sequences< |
| 1005 _CurrentSequence, |
| 1006 typename __sequence_or_empty< |
| 1007 std::is_constructible<_Head, _Type>::value, |
| 1008 _Offset>::__type>::__type, |
| 1009 _Type, |
| 1010 _Rest...>::__type __type; |
| 1011 }; |
| 1012 |
| 1013 template <typename _Type, typename... _Types> |
| 1014 struct __constructible_matches { |
| 1015 typedef typename __constructible_matches_helper<0, |
| 1016 __index_sequence<>, |
| 1017 _Type, |
| 1018 _Types...>::__type __type; |
| 1019 }; |
| 1020 |
| 1021 template <typename _Type, typename... _Types> |
| 1022 struct __type_index_to_construct { |
| 1023 typedef typename __all_indices<_Type, _Types...>::__type __direct_matches; |
| 1024 typedef typename __all_indices< |
| 1025 typename std::remove_const< |
| 1026 typename std::remove_reference<_Type>::type>::type, |
| 1027 _Types...>::__type __value_matches; |
| 1028 typedef typename __all_indices< |
| 1029 _Type, |
| 1030 typename std::remove_const<typename std::remove_reference<_Types>::type>:: |
| 1031 type...>::__type __rref_matches; |
| 1032 |
| 1033 typedef typename __constructible_matches<_Type, _Types...>::__type |
| 1034 __constructibles; |
| 1035 |
| 1036 static_assert((__direct_matches::__length > 0) || |
| 1037 (__value_matches::__length > 0) || |
| 1038 (__rref_matches::__length > 0) || |
| 1039 (__constructibles::__length == 1), |
| 1040 "For conversion construction of variants, exactly one type " |
| 1041 "must be constructible"); |
| 1042 |
| 1043 typedef typename __combine_sequences<__direct_matches, |
| 1044 __value_matches, |
| 1045 __rref_matches, |
| 1046 __constructibles>::__type __all_matches; |
| 1047 |
| 1048 static constexpr ptrdiff_t __value = __first_index<__all_matches>::__value; |
| 1049 }; |
| 1050 |
| 1051 struct __replace_construct_helper { |
| 1052 template <ptrdiff_t _Index, |
| 1053 bool __construct_directly, |
| 1054 bool __indexed_type_has_nothrow_move, |
| 1055 bool __other_types_have_nothrow_move> |
| 1056 struct __helper; |
| 1057 |
| 1058 template <typename _Variant, |
| 1059 typename _Indices = typename __variant_indices<_Variant>::__type> |
| 1060 struct __op_table; |
| 1061 }; |
| 1062 |
| 1063 template <ptrdiff_t _Index, bool __other_types_have_nothrow_move> |
| 1064 struct __replace_construct_helper:: |
| 1065 __helper<_Index, false, true, __other_types_have_nothrow_move> { |
| 1066 template <typename _Variant, typename... _Args> |
| 1067 static void __trampoline(_Variant& __v, _Args&&... __args) { |
| 1068 __v.template __two_stage_replace<_Index>(__args...); |
| 1069 } |
| 1070 }; |
| 1071 |
| 1072 template <ptrdiff_t _Index, |
| 1073 bool __indexed_type_has_nothrow_move, |
| 1074 bool __other_types_have_nothrow_move> |
| 1075 struct __replace_construct_helper::__helper<_Index, |
| 1076 true, |
| 1077 __indexed_type_has_nothrow_move, |
| 1078 __other_types_have_nothrow_move> { |
| 1079 template <typename _Variant, typename... _Args> |
| 1080 static void __trampoline(_Variant& __v, _Args&&... __args) { |
| 1081 __v.template __direct_replace<_Index>(std::forward<_Args>(__args)...); |
| 1082 } |
| 1083 }; |
| 1084 |
| 1085 template <ptrdiff_t _Index> |
| 1086 struct __replace_construct_helper::__helper<_Index, false, false, true> { |
| 1087 template <typename _Variant, typename... _Args> |
| 1088 static void __trampoline(_Variant& __v, _Args&&... __args) { |
| 1089 __v.template __local_backup_replace<_Index>(std::forward<_Args>(__args)...); |
| 1090 } |
| 1091 }; |
| 1092 |
| 1093 template <ptrdiff_t _Index> |
| 1094 struct __replace_construct_helper::__helper<_Index, false, false, false> { |
| 1095 template <typename _Variant, typename... _Args> |
| 1096 static void __trampoline(_Variant& __v, _Args&&... __args) { |
| 1097 __v.template __direct_replace<_Index>(std::forward<_Args>(__args)...); |
| 1098 } |
| 1099 }; |
| 1100 |
| 1101 template <typename _Variant, ptrdiff_t... _Indices> |
| 1102 struct __replace_construct_helper::__op_table<_Variant, |
| 1103 __index_sequence<_Indices...>> { |
| 1104 typedef void (*const __move_func_type)(_Variant*, _Variant&); |
| 1105 typedef void (*const __copy_func_type)(_Variant*, _Variant const&); |
| 1106 |
| 1107 template <ptrdiff_t _Index> |
| 1108 static void __move_assign_func(_Variant* __lhs, _Variant& __rhs) { |
| 1109 __lhs->template __replace_construct<_Index>(std::move(get<_Index>(__rhs))); |
| 1110 __rhs.__destroy_self(); |
| 1111 } |
| 1112 |
| 1113 template <ptrdiff_t _Index> |
| 1114 static void __copy_assign_func(_Variant* __lhs, _Variant const& __rhs) { |
| 1115 __lhs->template __replace_construct<_Index>(get<_Index>(__rhs)); |
| 1116 } |
| 1117 |
| 1118 static const __move_func_type __move_assign[sizeof...(_Indices)]; |
| 1119 static const __copy_func_type __copy_assign[sizeof...(_Indices)]; |
| 1120 }; |
| 1121 |
| 1122 template <typename _Variant, ptrdiff_t... _Indices> |
| 1123 const typename __replace_construct_helper:: |
| 1124 __op_table<_Variant, __index_sequence<_Indices...>>::__move_func_type |
| 1125 __replace_construct_helper::__op_table< |
| 1126 _Variant, |
| 1127 __index_sequence<_Indices...>>::__move_assign[sizeof...(_Indices)] = |
| 1128 {&__move_assign_func<_Indices>...}; |
| 1129 |
| 1130 template <typename _Variant, ptrdiff_t... _Indices> |
| 1131 const typename __replace_construct_helper:: |
| 1132 __op_table<_Variant, __index_sequence<_Indices...>>::__copy_func_type |
| 1133 __replace_construct_helper::__op_table< |
| 1134 _Variant, |
| 1135 __index_sequence<_Indices...>>::__copy_assign[sizeof...(_Indices)] = |
| 1136 {&__copy_assign_func<_Indices>...}; |
| 1137 |
| 1138 template <ptrdiff_t _Index, ptrdiff_t _MaskIndex, typename _Storage> |
| 1139 struct __backup_storage_ops { |
| 1140 static void __move_construct_func(_Storage* __dest, _Storage& __source) { |
| 1141 new (__dest) _Storage(variant_in_place<_Index>, |
| 1142 std::move(__source.__get(variant_in_place<_Index>))); |
| 1143 } |
| 1144 static void __destroy_func(_Storage* __obj) { |
| 1145 __obj->__destroy(variant_in_place<_Index>); |
| 1146 }; |
| 1147 }; |
| 1148 |
| 1149 template <ptrdiff_t _Index, typename _Storage> |
| 1150 struct __backup_storage_ops<_Index, _Index, _Storage> { |
| 1151 static void __move_construct_func(_Storage*, _Storage&) { |
| 1152 __THROW_EXCEPTION(std::bad_alloc()); |
| 1153 }; |
| 1154 static void __destroy_func(_Storage*) { |
| 1155 __THROW_EXCEPTION(std::bad_alloc()); |
| 1156 }; |
| 1157 }; |
| 1158 |
| 1159 template <ptrdiff_t _MaskIndex, typename _Storage, typename _Indices> |
| 1160 struct __backup_storage_op_table; |
| 1161 |
| 1162 template <ptrdiff_t _MaskIndex, typename _Storage, ptrdiff_t... _Indices> |
| 1163 struct __backup_storage_op_table<_MaskIndex, |
| 1164 _Storage, |
| 1165 __index_sequence<_Indices...>> { |
| 1166 typedef void (*__move_func_type)(_Storage* __dest, _Storage& __source); |
| 1167 typedef void (*__destroy_func_type)(_Storage* __obj); |
| 1168 |
| 1169 template <size_t _Index> |
| 1170 struct __helper { |
| 1171 typedef __backup_storage_ops<_Index, _MaskIndex, _Storage> __ops; |
| 1172 }; |
| 1173 |
| 1174 static const __move_func_type __move_ops[sizeof...(_Indices)]; |
| 1175 static const __destroy_func_type __destroy_ops[sizeof...(_Indices)]; |
| 1176 }; |
| 1177 |
| 1178 template <ptrdiff_t _MaskIndex, typename _Storage, ptrdiff_t... _Indices> |
| 1179 const typename __backup_storage_op_table<_MaskIndex, |
| 1180 _Storage, |
| 1181 __index_sequence<_Indices...>>:: |
| 1182 __move_func_type __backup_storage_op_table< |
| 1183 _MaskIndex, |
| 1184 _Storage, |
| 1185 __index_sequence<_Indices...>>::__move_ops[sizeof...(_Indices)] = { |
| 1186 &__helper<_Indices>::__ops::__move_construct_func...}; |
| 1187 |
| 1188 template <ptrdiff_t _MaskIndex, typename _Storage, ptrdiff_t... _Indices> |
| 1189 const typename __backup_storage_op_table<_MaskIndex, |
| 1190 _Storage, |
| 1191 __index_sequence<_Indices...>>:: |
| 1192 __destroy_func_type __backup_storage_op_table< |
| 1193 _MaskIndex, |
| 1194 _Storage, |
| 1195 __index_sequence<_Indices...>>::__destroy_ops[sizeof...(_Indices)] = { |
| 1196 &__helper<_Indices>::__ops::__destroy_func...}; |
| 1197 |
| 1198 template <ptrdiff_t _Index, typename... _Types> |
| 1199 struct __backup_storage { |
| 1200 typedef __variant_data<_Types...> __storage_type; |
| 1201 |
| 1202 typedef __backup_storage_op_table<_Index, |
| 1203 __storage_type, |
| 1204 typename __type_indices<_Types...>::__type> |
| 1205 __op_table_type; |
| 1206 |
| 1207 ptrdiff_t __backup_index; |
| 1208 __storage_type& __live_storage; |
| 1209 __storage_type __backup; |
| 1210 |
| 1211 __backup_storage(ptrdiff_t __live_index_, __storage_type& __live_storage_) |
| 1212 : __backup_index(__live_index_), __live_storage(__live_storage_) { |
| 1213 if (__backup_index >= 0) { |
| 1214 __op_table_type::__move_ops[__backup_index](&__backup, __live_storage); |
| 1215 __op_table_type::__destroy_ops[__backup_index](&__live_storage); |
| 1216 } |
| 1217 } |
| 1218 void __destroy() { |
| 1219 if (__backup_index >= 0) |
| 1220 __op_table_type::__destroy_ops[__backup_index](&__backup); |
| 1221 __backup_index = -1; |
| 1222 } |
| 1223 |
| 1224 ~__backup_storage() { |
| 1225 if (__backup_index >= 0) { |
| 1226 __op_table_type::__move_ops[__backup_index](&__live_storage, __backup); |
| 1227 __destroy(); |
| 1228 } |
| 1229 } |
| 1230 }; |
| 1231 |
| 1232 template <typename... _Types> |
| 1233 struct __all_move_constructible; |
| 1234 |
| 1235 template <typename _Head, typename... _Rest> |
| 1236 struct __all_move_constructible<_Head, _Rest...> { |
| 1237 static constexpr bool value = std::is_move_constructible<_Head>::value && |
| 1238 __all_move_constructible<_Rest...>::value; |
| 1239 }; |
| 1240 |
| 1241 template <> |
| 1242 struct __all_move_constructible<> : std::true_type {}; |
| 1243 |
| 1244 template <typename... _Types> |
| 1245 struct __all_move_assignable; |
| 1246 |
| 1247 template <typename _Head, typename... _Rest> |
| 1248 struct __all_move_assignable<_Head, _Rest...> { |
| 1249 static constexpr bool value = std::is_move_assignable<_Head>::value && |
| 1250 __all_move_assignable<_Rest...>::value; |
| 1251 }; |
| 1252 |
| 1253 template <> |
| 1254 struct __all_move_assignable<> : std::true_type {}; |
| 1255 |
| 1256 template <typename... _Types> |
| 1257 struct __all_copy_assignable; |
| 1258 |
| 1259 template <typename _Head, typename... _Rest> |
| 1260 struct __all_copy_assignable<_Head, _Rest...> { |
| 1261 static constexpr bool value = std::is_copy_assignable<_Head>::value && |
| 1262 __all_copy_assignable<_Rest...>::value; |
| 1263 }; |
| 1264 |
| 1265 template <> |
| 1266 struct __all_copy_assignable<> : std::true_type {}; |
| 1267 |
| 1268 namespace __swap_test_detail { |
| 1269 using std::swap; |
| 1270 |
| 1271 template <typename _Other> |
| 1272 struct __swap_result {}; |
| 1273 |
| 1274 template <typename> |
| 1275 static char __test(...); |
| 1276 template <typename _Other> |
| 1277 static std::pair< |
| 1278 char, |
| 1279 std::pair<char, |
| 1280 __swap_result<decltype(swap(std::declval<_Other&>(), |
| 1281 std::declval<_Other&>()))>>> |
| 1282 __test(_Other*); |
| 1283 } |
| 1284 |
| 1285 template <typename _Type> |
| 1286 struct __is_swappable { |
| 1287 static constexpr bool value = |
| 1288 sizeof(__swap_test_detail::__test<_Type>(0)) != 1; |
| 1289 }; |
| 1290 |
| 1291 template <typename... _Types> |
| 1292 struct __all_swappable; |
| 1293 |
| 1294 template <typename _Head, typename... _Rest> |
| 1295 struct __all_swappable<_Head, _Rest...> { |
| 1296 static constexpr bool value = |
| 1297 __is_swappable<_Head>::value && __all_swappable<_Rest...>::value; |
| 1298 }; |
| 1299 |
| 1300 template <> |
| 1301 struct __all_swappable<> : std::true_type {}; |
| 1302 |
| 1303 template <bool _MoveConstructible, typename... _Types> |
| 1304 struct __noexcept_variant_move_construct_impl {}; |
| 1305 |
| 1306 template <typename _Head, typename... _Rest> |
| 1307 struct __noexcept_variant_move_construct_impl<true, _Head, _Rest...> { |
| 1308 static constexpr bool value = |
| 1309 noexcept(_Head(std::declval<_Head&&>())) && |
| 1310 __noexcept_variant_move_construct_impl<true, _Rest...>::value; |
| 1311 }; |
| 1312 |
| 1313 template <> |
| 1314 struct __noexcept_variant_move_construct_impl<true> { |
| 1315 static constexpr bool value = true; |
| 1316 }; |
| 1317 |
| 1318 template <typename... _Types> |
| 1319 struct __noexcept_variant_move_construct |
| 1320 : __noexcept_variant_move_construct_impl< |
| 1321 __all_move_constructible<_Types...>::value, |
| 1322 _Types...> {}; |
| 1323 |
| 1324 template <bool _MoveAssignable, typename... _Types> |
| 1325 struct __noexcept_variant_move_assign_impl {}; |
| 1326 |
| 1327 template <typename _Head, typename... _Rest> |
| 1328 struct __noexcept_variant_move_assign_impl<true, _Head, _Rest...> { |
| 1329 static constexpr bool value = |
| 1330 std::is_nothrow_move_assignable<_Head>::value && |
| 1331 std::is_nothrow_move_constructible<_Head>::value && |
| 1332 __noexcept_variant_move_assign_impl<true, _Rest...>::value; |
| 1333 }; |
| 1334 |
| 1335 template <> |
| 1336 struct __noexcept_variant_move_assign_impl<true> { |
| 1337 static constexpr bool value = true; |
| 1338 }; |
| 1339 |
| 1340 template <typename... _Types> |
| 1341 struct __noexcept_variant_move_assign |
| 1342 : __noexcept_variant_move_assign_impl< |
| 1343 __all_move_assignable<_Types...>::value && |
| 1344 __all_move_constructible<_Types...>::value, |
| 1345 _Types...> {}; |
| 1346 |
| 1347 template <typename... _Types> |
| 1348 struct __all_copy_constructible; |
| 1349 |
| 1350 template <typename _Head, typename... _Rest> |
| 1351 struct __all_copy_constructible<_Head, _Rest...> { |
| 1352 static constexpr bool value = std::is_copy_constructible<_Head>::value && |
| 1353 __all_copy_constructible<_Rest...>::value; |
| 1354 }; |
| 1355 |
| 1356 template <> |
| 1357 struct __all_copy_constructible<> : std::true_type {}; |
| 1358 |
| 1359 template <bool _CopyConstructible, typename... _Types> |
| 1360 struct __noexcept_variant_const_copy_construct_impl {}; |
| 1361 |
| 1362 template <typename _Head, typename... _Rest> |
| 1363 struct __noexcept_variant_const_copy_construct_impl<true, _Head, _Rest...> { |
| 1364 static constexpr bool value = |
| 1365 noexcept(_Head(std::declval<_Head const&>())) && |
| 1366 __noexcept_variant_const_copy_construct_impl<true, _Rest...>::value; |
| 1367 }; |
| 1368 |
| 1369 template <> |
| 1370 struct __noexcept_variant_const_copy_construct_impl<true> { |
| 1371 static constexpr bool value = true; |
| 1372 }; |
| 1373 |
| 1374 template <typename... _Types> |
| 1375 struct __noexcept_variant_const_copy_construct |
| 1376 : __noexcept_variant_const_copy_construct_impl< |
| 1377 __all_copy_constructible<_Types...>::value, |
| 1378 _Types...> {}; |
| 1379 |
| 1380 template <bool _CopyNon_Constructible, typename... _Types> |
| 1381 struct __noexcept_variant_non_const_copy_construct_impl {}; |
| 1382 |
| 1383 template <typename _Head, typename... _Rest> |
| 1384 struct __noexcept_variant_non_const_copy_construct_impl<true, _Head, _Rest...> { |
| 1385 static constexpr bool value = |
| 1386 noexcept(_Head(std::declval<_Head&>())) && |
| 1387 __noexcept_variant_non_const_copy_construct_impl<true, _Rest...>::value; |
| 1388 }; |
| 1389 |
| 1390 template <> |
| 1391 struct __noexcept_variant_non_const_copy_construct_impl<true> { |
| 1392 static constexpr bool value = true; |
| 1393 }; |
| 1394 |
| 1395 template <typename... _Types> |
| 1396 struct __noexcept_variant_non_const_copy_construct |
| 1397 : __noexcept_variant_non_const_copy_construct_impl< |
| 1398 __all_copy_constructible<_Types...>::value, |
| 1399 _Types...> {}; |
| 1400 |
| 1401 template <bool _Swappable, typename... _Types> |
| 1402 struct __noexcept_variant_swap_impl {}; |
| 1403 |
| 1404 template <typename _Head, typename... _Rest> |
| 1405 struct __noexcept_variant_swap_impl<true, _Head, _Rest...> { |
| 1406 static constexpr bool value = |
| 1407 noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>())) && |
| 1408 __noexcept_variant_swap_impl<true, _Rest...>::value; |
| 1409 }; |
| 1410 |
| 1411 template <> |
| 1412 struct __noexcept_variant_swap_impl<true> { |
| 1413 static constexpr bool value = true; |
| 1414 }; |
| 1415 |
| 1416 template <typename... _Types> |
| 1417 struct __noexcept_variant_swap |
| 1418 : __noexcept_variant_swap_impl<__all_swappable<_Types...>::value, |
| 1419 _Types...> {}; |
| 1420 |
| 1421 template <typename... _Types> |
| 1422 class Variant |
| 1423 : private __variant_base<Variant<_Types...>, |
| 1424 __all_trivially_destructible<_Types...>::__value> { |
| 1425 typedef __variant_base<Variant<_Types...>, |
| 1426 __all_trivially_destructible<_Types...>::__value> |
| 1427 __base_type; |
| 1428 friend __base_type; |
| 1429 friend struct __copy_construct_op_table<Variant>; |
| 1430 friend struct __copy_assign_op_table<Variant>; |
| 1431 friend struct __move_construct_op_table<Variant>; |
| 1432 friend struct __move_assign_op_table<Variant>; |
| 1433 friend struct __destroy_op_table<Variant>; |
| 1434 |
| 1435 template <ptrdiff_t _Index, typename... _Types2> |
| 1436 friend struct __variant_accessor; |
| 1437 |
| 1438 friend struct __replace_construct_helper; |
| 1439 |
| 1440 typedef __variant_data<_Types...> __storage_type; |
| 1441 __storage_type __storage; |
| 1442 typename __discriminator_type<sizeof...(_Types)>::__type __index; |
| 1443 |
| 1444 template <size_t _Index, typename... _Args> |
| 1445 size_t __emplace_construct(_Args&&... __args) { |
| 1446 new (&__storage) __storage_type(variant_in_place<_Index>, |
| 1447 std::forward<_Args>(__args)...); |
| 1448 return _Index; |
| 1449 } |
| 1450 |
| 1451 void __destroy_self() { |
| 1452 if (valueless_by_exception()) |
| 1453 return; |
| 1454 __destroy_op_table<Variant>::__apply[index()](this); |
| 1455 __index = -1; |
| 1456 } |
| 1457 |
| 1458 ptrdiff_t __move_construct(Variant& __other) { |
| 1459 ptrdiff_t const __other_index = __other.index(); |
| 1460 if (__other_index == -1) |
| 1461 return -1; |
| 1462 __move_construct_op_table<Variant>::__apply[__other_index](this, __other); |
| 1463 __other.__destroy_self(); |
| 1464 return __other_index; |
| 1465 } |
| 1466 |
| 1467 ptrdiff_t __copy_construct(Variant const& __other) { |
| 1468 ptrdiff_t const __other_index = __other.index(); |
| 1469 if (__other_index == -1) |
| 1470 return -1; |
| 1471 __copy_construct_op_table<Variant>::__apply[__other_index](this, __other); |
| 1472 return __other_index; |
| 1473 } |
| 1474 |
| 1475 template <size_t _Index, typename... _Args> |
| 1476 void __replace_construct(_Args&&... __args) { |
| 1477 typedef typename __indexed_type<_Index, _Types...>::__type __this_type; |
| 1478 __replace_construct_helper::__helper< |
| 1479 _Index, |
| 1480 __storage_nothrow_constructible<__this_type, _Args...>::__value || |
| 1481 (sizeof...(_Types) == 1), |
| 1482 __storage_nothrow_move_constructible<__this_type>::__value, |
| 1483 __other_storage_nothrow_move_constructible<_Index, _Types...>:: |
| 1484 __value>::__trampoline(*this, std::forward<_Args>(__args)...); |
| 1485 } |
| 1486 |
| 1487 template <size_t _Index, typename... _Args> |
| 1488 void __two_stage_replace(_Args&&... __args) { |
| 1489 typedef typename __indexed_type<_Index, _Types...>::__type __type; |
| 1490 __variant_data<__type> __local(variant_in_place<0>, |
| 1491 std::forward<_Args>(__args)...); |
| 1492 __destroy_self(); |
| 1493 __emplace_construct<_Index>(std::move(__local.__get(variant_in_place<0>))); |
| 1494 __index = _Index; |
| 1495 __local.__destroy(variant_in_place<0>); |
| 1496 } |
| 1497 |
| 1498 template <size_t _Index, typename... _Args> |
| 1499 void __local_backup_replace(_Args&&... __args) { |
| 1500 __backup_storage<_Index, _Types...> __backup(__index, __storage); |
| 1501 __emplace_construct<_Index>(std::forward<_Args>(__args)...); |
| 1502 __index = _Index; |
| 1503 __backup.__destroy(); |
| 1504 } |
| 1505 |
| 1506 template <size_t _Index, typename... _Args> |
| 1507 void __direct_replace(_Args&&... __args) { |
| 1508 __destroy_self(); |
| 1509 __emplace_construct<_Index>(std::forward<_Args>(__args)...); |
| 1510 __index = _Index; |
| 1511 } |
| 1512 |
| 1513 struct __private_type {}; |
| 1514 |
| 1515 public: |
| 1516 constexpr Variant() |
| 1517 __NOEXCEPT_(noexcept(typename __indexed_type<0, _Types...>::__type())) |
| 1518 : __storage(variant_in_place<0>), __index(0) {} |
| 1519 |
| 1520 constexpr Variant( |
| 1521 typename std::conditional<__all_move_constructible<_Types...>::value, |
| 1522 Variant, |
| 1523 __private_type>::type&& __other) |
| 1524 __NOEXCEPT_(__noexcept_variant_move_construct<_Types...>::value) |
| 1525 : __index(__move_construct(__other)) {} |
| 1526 |
| 1527 constexpr Variant( |
| 1528 typename std::conditional<!__all_move_constructible<_Types...>::value, |
| 1529 Variant, |
| 1530 __private_type>::type&& __other) = delete; |
| 1531 |
| 1532 constexpr Variant( |
| 1533 typename std::conditional<__all_copy_constructible<_Types...>::value, |
| 1534 Variant, |
| 1535 __private_type>::type& __other) |
| 1536 __NOEXCEPT_(__noexcept_variant_non_const_copy_construct<_Types...>::value) |
| 1537 : __index(__copy_construct(__other)) {} |
| 1538 |
| 1539 constexpr Variant( |
| 1540 typename std::conditional<!__all_copy_constructible<_Types...>::value, |
| 1541 Variant, |
| 1542 __private_type>::type& __other) = delete; |
| 1543 |
| 1544 constexpr Variant( |
| 1545 typename std::conditional<__all_copy_constructible<_Types...>::value, |
| 1546 Variant, |
| 1547 __private_type>::type const& __other) |
| 1548 __NOEXCEPT_(__noexcept_variant_const_copy_construct<_Types...>::value) |
| 1549 : __index(__copy_construct(__other)) {} |
| 1550 |
| 1551 constexpr Variant( |
| 1552 typename std::conditional<!__all_copy_constructible<_Types...>::value, |
| 1553 Variant, |
| 1554 __private_type>::type const& __other) = delete; |
| 1555 |
| 1556 template <typename _Type, typename... _Args> |
| 1557 explicit constexpr Variant(variant_in_place_type_t<_Type>, _Args&&... __args) |
| 1558 : __storage(variant_in_place<__type_index<_Type, _Types...>::__value>, |
| 1559 std::forward<_Args>(__args)...), |
| 1560 __index(__type_index<_Type, _Types...>::__value) { |
| 1561 static_assert(std::is_constructible<_Type, _Args...>::value, |
| 1562 "Type must be constructible from args"); |
| 1563 } |
| 1564 |
| 1565 template <size_t _Index, typename... _Args> |
| 1566 explicit constexpr Variant(variant_in_place_index_t<_Index>, |
| 1567 _Args&&... __args) |
| 1568 : __storage(variant_in_place<_Index>, std::forward<_Args>(__args)...), |
| 1569 __index(_Index) { |
| 1570 static_assert(std::is_constructible< |
| 1571 typename __indexed_type<_Index, _Types...>::__type, |
| 1572 _Args...>::value, |
| 1573 "Type must be constructible from args"); |
| 1574 } |
| 1575 |
| 1576 template <typename _Type> |
| 1577 constexpr Variant(_Type&& __x) |
| 1578 : __storage(variant_in_place< |
| 1579 __type_index_to_construct<_Type, _Types...>::__value>, |
| 1580 std::forward<_Type>(__x)), |
| 1581 __index(__type_index_to_construct<_Type, _Types...>::__value) {} |
| 1582 |
| 1583 template < |
| 1584 typename _Type, |
| 1585 typename _Enable = typename std::enable_if< |
| 1586 (__constructible_matches<std::initializer_list<_Type>, |
| 1587 _Types...>::__type::__length > 0)>::type> |
| 1588 constexpr Variant(std::initializer_list<_Type> __x) |
| 1589 : __storage(variant_in_place< |
| 1590 __type_index_to_construct<std::initializer_list<_Type>, |
| 1591 _Types...>::__value>, |
| 1592 __x), |
| 1593 __index(__type_index_to_construct<std::initializer_list<_Type>, |
| 1594 _Types...>::__value) {} |
| 1595 |
| 1596 template <typename _Type> |
| 1597 Variant& operator=(_Type&& __x) { |
| 1598 constexpr size_t _Index = |
| 1599 __type_index_to_construct<_Type, _Types...>::__value; |
| 1600 if (_Index == __index) { |
| 1601 get<_Index>(*this) = std::forward<_Type>(__x); |
| 1602 } else { |
| 1603 __replace_construct<_Index>(std::forward<_Type>(__x)); |
| 1604 } |
| 1605 return *this; |
| 1606 } |
| 1607 |
| 1608 Variant& operator=( |
| 1609 typename std::conditional<!(__all_copy_constructible<_Types...>::value && |
| 1610 __all_move_constructible<_Types...>::value && |
| 1611 __all_copy_assignable<_Types...>::value), |
| 1612 Variant, |
| 1613 __private_type>::type const& __other) = delete; |
| 1614 |
| 1615 Variant& operator=(typename std::conditional< |
| 1616 __all_copy_constructible<_Types...>::value && |
| 1617 __all_move_constructible<_Types...>::value && |
| 1618 __all_copy_assignable<_Types...>::value, |
| 1619 Variant, |
| 1620 __private_type>::type const& __other) { |
| 1621 if (__other.valueless_by_exception()) { |
| 1622 __destroy_self(); |
| 1623 } else if (__other.index() == index()) { |
| 1624 __copy_assign_op_table<Variant>::__apply[index()](this, __other); |
| 1625 } else { |
| 1626 __replace_construct_helper::__op_table< |
| 1627 Variant>::__copy_assign[__other.index()](this, __other); |
| 1628 } |
| 1629 return *this; |
| 1630 } |
| 1631 Variant& operator=( |
| 1632 typename std::conditional<!(__all_copy_constructible<_Types...>::value && |
| 1633 __all_move_constructible<_Types...>::value && |
| 1634 __all_copy_assignable<_Types...>::value), |
| 1635 Variant, |
| 1636 __private_type>::type& __other) = delete; |
| 1637 |
| 1638 Variant& operator=(typename std::conditional< |
| 1639 __all_copy_constructible<_Types...>::value && |
| 1640 __all_move_constructible<_Types...>::value && |
| 1641 __all_copy_assignable<_Types...>::value, |
| 1642 Variant, |
| 1643 __private_type>::type& __other) { |
| 1644 if (__other.valueless_by_exception()) { |
| 1645 __destroy_self(); |
| 1646 } else if (__other.index() == index()) { |
| 1647 __copy_assign_op_table<Variant>::__apply[index()](this, __other); |
| 1648 } else { |
| 1649 __replace_construct_helper::__op_table< |
| 1650 Variant>::__copy_assign[__other.index()](this, __other); |
| 1651 } |
| 1652 return *this; |
| 1653 } |
| 1654 Variant& operator=( |
| 1655 typename std::conditional<!(__all_move_constructible<_Types...>::value && |
| 1656 __all_move_assignable<_Types...>::value), |
| 1657 Variant, |
| 1658 __private_type>::type&& __other) = delete; |
| 1659 |
| 1660 Variant& operator=( |
| 1661 typename std::conditional<__all_move_constructible<_Types...>::value && |
| 1662 __all_move_assignable<_Types...>::value, |
| 1663 Variant, |
| 1664 __private_type>::type&& __other) |
| 1665 __NOEXCEPT_(__noexcept_variant_move_assign<_Types...>::value) { |
| 1666 if (__other.valueless_by_exception()) { |
| 1667 __destroy_self(); |
| 1668 } else if (__other.index() == index()) { |
| 1669 __move_assign_op_table<Variant>::__apply[index()](this, __other); |
| 1670 __other.__destroy_self(); |
| 1671 } else { |
| 1672 __replace_construct_helper::__op_table< |
| 1673 Variant>::__move_assign[__other.index()](this, __other); |
| 1674 } |
| 1675 return *this; |
| 1676 } |
| 1677 |
| 1678 template <typename _Type, typename... _Args> |
| 1679 void emplace(_Args&&... __args) { |
| 1680 __direct_replace<__type_index<_Type, _Types...>::__value>( |
| 1681 std::forward<_Args>(__args)...); |
| 1682 } |
| 1683 |
| 1684 template <size_t _Index, typename... _Args> |
| 1685 void emplace(_Args&&... __args) { |
| 1686 __direct_replace<_Index>(std::forward<_Args>(__args)...); |
| 1687 } |
| 1688 |
| 1689 constexpr bool valueless_by_exception() const __NOEXCEPT { |
| 1690 return __index == -1; |
| 1691 } |
| 1692 constexpr ptrdiff_t index() const __NOEXCEPT { return __index; } |
| 1693 |
| 1694 void swap( |
| 1695 typename std::conditional<__all_swappable<_Types...>::value && |
| 1696 __all_move_constructible<_Types...>::value, |
| 1697 Variant, |
| 1698 __private_type>::type& __other) |
| 1699 __NOEXCEPT_(__noexcept_variant_swap<_Types...>::value) { |
| 1700 if (__other.index() == index()) { |
| 1701 if (!valueless_by_exception()) |
| 1702 __swap_op_table<Variant>::__apply[index()](*this, __other); |
| 1703 } else { |
| 1704 Variant __temp(std::move(__other)); |
| 1705 __other.__index = __other.__move_construct(*this); |
| 1706 __index = __move_construct(__temp); |
| 1707 } |
| 1708 } |
| 1709 }; |
| 1710 |
| 1711 template <> |
| 1712 class Variant<> { |
| 1713 public: |
| 1714 Variant() = delete; |
| 1715 |
| 1716 constexpr bool valueless_by_exception() const __NOEXCEPT { return true; } |
| 1717 constexpr ptrdiff_t index() const __NOEXCEPT { return -1; } |
| 1718 |
| 1719 void swap(Variant&) {} |
| 1720 }; |
| 1721 |
| 1722 template <typename... _Types> |
| 1723 typename std::enable_if<__all_swappable<_Types...>::value && |
| 1724 __all_move_constructible<_Types...>::value, |
| 1725 void>::type |
| 1726 swap(Variant<_Types...>& __lhs, Variant<_Types...>& __rhs) |
| 1727 __NOEXCEPT_(__noexcept_variant_swap<_Types...>::value) { |
| 1728 __lhs.swap(__rhs); |
| 1729 } |
| 1730 |
| 1731 template <ptrdiff_t _Index, typename... _Types> |
| 1732 struct __variant_accessor { |
| 1733 typedef typename __indexed_type<_Index, _Types...>::__type __type; |
| 1734 static constexpr __type& get(Variant<_Types...>& __v) { |
| 1735 return __v.__storage.__get(variant_in_place<_Index>); |
| 1736 } |
| 1737 static constexpr __type const& get(Variant<_Types...> const& __v) { |
| 1738 return __v.__storage.__get(variant_in_place<_Index>); |
| 1739 } |
| 1740 static constexpr __type&& get(Variant<_Types...>&& __v) { |
| 1741 return __v.__storage.__get_rref(variant_in_place<_Index>); |
| 1742 } |
| 1743 static constexpr const __type&& get(Variant<_Types...> const&& __v) { |
| 1744 return __v.__storage.__get_rref(variant_in_place<_Index>); |
| 1745 } |
| 1746 }; |
| 1747 |
| 1748 template <typename _Type, typename... _Types> |
| 1749 constexpr _Type& get(Variant<_Types...>& __v) { |
| 1750 return get<__type_index<_Type, _Types...>::__value>(__v); |
| 1751 } |
| 1752 |
| 1753 template <typename _Type, typename... _Types> |
| 1754 constexpr _Type&& get(Variant<_Types...>&& __v) { |
| 1755 return get<__type_index<_Type, _Types...>::__value>(std::move(__v)); |
| 1756 } |
| 1757 |
| 1758 template <typename _Type, typename... _Types> |
| 1759 constexpr _Type const& get(Variant<_Types...> const& __v) { |
| 1760 return get<__type_index<_Type, _Types...>::__value>(__v); |
| 1761 } |
| 1762 |
| 1763 template <typename _Type, typename... _Types> |
| 1764 constexpr const _Type&& get(Variant<_Types...> const&& __v) { |
| 1765 return get<__type_index<_Type, _Types...>::__value>(std::move(__v)); |
| 1766 } |
| 1767 |
| 1768 template <ptrdiff_t _Index, typename... _Types> |
| 1769 constexpr typename __indexed_type<_Index, _Types...>::__type const& get( |
| 1770 Variant<_Types...> const& __v) { |
| 1771 return *((_Index != __v.index()) |
| 1772 ? &__throw_bad_variant_access< |
| 1773 typename __indexed_type<_Index, _Types...>::__type const&>( |
| 1774 "Bad Variant index in get") |
| 1775 : &__variant_accessor<_Index, _Types...>::get(__v)); |
| 1776 } |
| 1777 |
| 1778 template <ptrdiff_t _Index, typename... _Types> |
| 1779 constexpr typename __indexed_type<_Index, _Types...>::__type& get( |
| 1780 Variant<_Types...>& __v) { |
| 1781 return *((_Index != __v.index()) |
| 1782 ? &__throw_bad_variant_access< |
| 1783 typename __indexed_type<_Index, _Types...>::__type&>( |
| 1784 "Bad Variant index in get") |
| 1785 : &__variant_accessor<_Index, _Types...>::get(__v)); |
| 1786 } |
| 1787 |
| 1788 template <ptrdiff_t _Index, typename... _Types> |
| 1789 constexpr typename __indexed_type<_Index, _Types...>::__type&& get( |
| 1790 Variant<_Types...>&& __v) { |
| 1791 return __variant_accessor<_Index, _Types...>::get( |
| 1792 (((_Index != __v.index()) |
| 1793 ? __throw_bad_variant_access<int>("Bad Variant index in get") |
| 1794 : 0), |
| 1795 std::move(__v))); |
| 1796 } |
| 1797 |
| 1798 template <ptrdiff_t _Index, typename... _Types> |
| 1799 constexpr const typename __indexed_type<_Index, _Types...>::__type&& get( |
| 1800 Variant<_Types...> const&& __v) { |
| 1801 return __variant_accessor<_Index, _Types...>::get( |
| 1802 (((_Index != __v.index()) |
| 1803 ? __throw_bad_variant_access<int>("Bad Variant index in get") |
| 1804 : 0), |
| 1805 std::move(__v))); |
| 1806 } |
| 1807 |
| 1808 template <typename _Type, typename... _Types> |
| 1809 constexpr std::add_pointer_t<_Type> get_if(Variant<_Types...>& __v) { |
| 1810 return (__type_index<_Type, _Types...>::__value != __v.index()) |
| 1811 ? nullptr |
| 1812 : &get<_Type>(__v); |
| 1813 } |
| 1814 |
| 1815 template <typename _Type, typename... _Types> |
| 1816 constexpr std::add_pointer_t<_Type const> get_if( |
| 1817 Variant<_Types...> const& __v) { |
| 1818 return (__type_index<_Type, _Types...>::__value != __v.index()) |
| 1819 ? nullptr |
| 1820 : &get<_Type>(__v); |
| 1821 } |
| 1822 |
| 1823 template <ptrdiff_t _Index, typename... _Types> |
| 1824 constexpr std::add_pointer_t<typename __indexed_type<_Index, _Types...>::__type> |
| 1825 get_if(Variant<_Types...>& __v) { |
| 1826 return ((_Index != __v.index()) |
| 1827 ? nullptr |
| 1828 : &__variant_accessor<_Index, _Types...>::get(__v)); |
| 1829 } |
| 1830 |
| 1831 template <ptrdiff_t _Index, typename... _Types> |
| 1832 constexpr std::add_pointer_t< |
| 1833 typename __indexed_type<_Index, _Types...>::__type const> |
| 1834 get_if(Variant<_Types...> const& __v) { |
| 1835 return ((_Index != __v.index()) |
| 1836 ? nullptr |
| 1837 : &__variant_accessor<_Index, _Types...>::get(__v)); |
| 1838 } |
| 1839 |
| 1840 template <typename _Type, typename... _Types> |
| 1841 constexpr bool holds_alternative(Variant<_Types...> const& __v) __NOEXCEPT { |
| 1842 return __v.index() == __type_index<_Type, _Types...>::__value; |
| 1843 } |
| 1844 |
| 1845 template <typename _Visitor, typename... _Types> |
| 1846 struct __visitor_return_type; |
| 1847 |
| 1848 template <typename _Visitor> |
| 1849 struct __visitor_return_type<_Visitor> { |
| 1850 typedef decltype(std::declval<_Visitor&>()()) __type; |
| 1851 }; |
| 1852 |
| 1853 template <typename _Visitor, typename _Head, typename... _Rest> |
| 1854 struct __visitor_return_type<_Visitor, _Head, _Rest...> { |
| 1855 typedef decltype(std::declval<_Visitor&>()(std::declval<_Head&>())) __type; |
| 1856 }; |
| 1857 |
| 1858 template <typename _Visitor, typename... _Types> |
| 1859 struct __visitor_table { |
| 1860 typedef Variant<_Types...> __variant_type; |
| 1861 typedef |
| 1862 typename __visitor_return_type<_Visitor, _Types...>::__type __return_type; |
| 1863 typedef __return_type (*__func_type)(_Visitor&, __variant_type&); |
| 1864 |
| 1865 template <typename _Type> |
| 1866 static __return_type __trampoline_func(_Visitor& __visitor, |
| 1867 __variant_type& __v) { |
| 1868 return __visitor(get<_Type>(__v)); |
| 1869 } |
| 1870 |
| 1871 static const __func_type __trampoline[sizeof...(_Types)]; |
| 1872 }; |
| 1873 |
| 1874 template <typename _Visitor, typename... _Types> |
| 1875 const typename __visitor_table<_Visitor, _Types...>::__func_type |
| 1876 __visitor_table<_Visitor, _Types...>::__trampoline[sizeof...(_Types)] = { |
| 1877 &__trampoline_func<_Types>...}; |
| 1878 |
| 1879 template <typename _Visitor, typename... _Types> |
| 1880 constexpr typename __visitor_return_type<_Visitor, _Types...>::__type visit( |
| 1881 _Visitor&& __visitor, |
| 1882 Variant<_Types...>& __v) { |
| 1883 return (__v.valueless_by_exception()) |
| 1884 ? __throw_bad_variant_access< |
| 1885 typename __visitor_return_type<_Visitor, _Types...>::__type>( |
| 1886 "Visiting of empty Variant") |
| 1887 : __visitor_table<_Visitor, _Types...>::__trampoline[__v.index()]( |
| 1888 __visitor, __v); |
| 1889 } |
| 1890 |
| 1891 template <typename _Visitor, typename... _Variants> |
| 1892 struct __multi_visitor_return_type { |
| 1893 typedef decltype( |
| 1894 std::declval<_Visitor&>()(get<0>(std::declval<_Variants>())...)) __type; |
| 1895 }; |
| 1896 |
| 1897 template <size_t _VariantIndex, typename _Indices> |
| 1898 struct __visit_helper; |
| 1899 |
| 1900 template <ptrdiff_t... _Indices> |
| 1901 struct __visit_helper<0, __index_sequence<_Indices...>> { |
| 1902 template <typename _Visitor, typename... _Variants> |
| 1903 static constexpr |
| 1904 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type |
| 1905 __visit(_Visitor& __visitor, _Variants&... __v) { |
| 1906 return __visitor(get<_Indices>(__v)...); |
| 1907 } |
| 1908 }; |
| 1909 |
| 1910 template <size_t _Index, typename... _Args> |
| 1911 struct __arg_selector_t; |
| 1912 |
| 1913 template <typename _Head, typename... _Rest> |
| 1914 struct __arg_selector_t<0, _Head, _Rest...> { |
| 1915 typedef _Head __type; |
| 1916 |
| 1917 static constexpr __type& __select(_Head& __head, _Rest&...) { return __head; } |
| 1918 }; |
| 1919 |
| 1920 template <size_t _Index, typename _Head, typename... _Rest> |
| 1921 struct __arg_selector_t<_Index, _Head, _Rest...> { |
| 1922 typedef typename __arg_selector_t<_Index - 1, _Rest...>::__type __type; |
| 1923 static constexpr __type& __select(_Head&, _Rest&... __rest) { |
| 1924 return __arg_selector_t<_Index - 1, _Rest...>::__select(__rest...); |
| 1925 } |
| 1926 }; |
| 1927 |
| 1928 template <size_t _Index, typename... _Args> |
| 1929 constexpr typename __arg_selector_t<_Index, _Args...>::__type&& __arg_selector( |
| 1930 _Args&&... __args) { |
| 1931 return std::forward<typename __arg_selector_t<_Index, _Args...>::__type>( |
| 1932 __arg_selector_t<_Index, _Args...>::__select(__args...)); |
| 1933 } |
| 1934 |
| 1935 template <ptrdiff_t _Index, size_t _VariantIndex, ptrdiff_t... _Indices> |
| 1936 struct __visit_helper2 { |
| 1937 template <typename _Visitor, typename... _Variants> |
| 1938 static constexpr |
| 1939 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type |
| 1940 __visit(_Visitor& __visitor, _Variants&&... __v) { |
| 1941 return (__arg_selector<_VariantIndex - 1>(__v...).index() == _Index) |
| 1942 ? __visit_helper<_VariantIndex - 1, |
| 1943 __index_sequence<_Index, _Indices...>>:: |
| 1944 __visit(__visitor, std::forward<_Variants>(__v)...) |
| 1945 : __visit_helper2<_Index - 1, _VariantIndex, |
| 1946 _Indices...>::__visit(__visitor, |
| 1947 std::forward<_Variants>( |
| 1948 __v)...); |
| 1949 } |
| 1950 }; |
| 1951 |
| 1952 template <size_t _VariantIndex, ptrdiff_t... _Indices> |
| 1953 struct __visit_helper2<-1, _VariantIndex, _Indices...> { |
| 1954 template <typename _Visitor, typename... _Variants> |
| 1955 static constexpr |
| 1956 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type |
| 1957 __visit(_Visitor&, _Variants&&...) { |
| 1958 return __throw_bad_variant_access< |
| 1959 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type>( |
| 1960 "Visiting of empty Variant"); |
| 1961 } |
| 1962 }; |
| 1963 |
| 1964 template <typename _Variant> |
| 1965 struct __variant_type_count; |
| 1966 |
| 1967 template <typename... _Types> |
| 1968 struct __variant_type_count<Variant<_Types...>> { |
| 1969 static constexpr size_t __value = sizeof...(_Types); |
| 1970 }; |
| 1971 |
| 1972 template <typename _Variant> |
| 1973 struct __variant_type_count<_Variant&> { |
| 1974 static constexpr size_t __value = __variant_type_count<_Variant>::__value; |
| 1975 }; |
| 1976 |
| 1977 template <typename _Variant> |
| 1978 struct __variant_type_count<_Variant const&> { |
| 1979 static constexpr size_t __value = __variant_type_count<_Variant>::__value; |
| 1980 }; |
| 1981 |
| 1982 template <size_t _VariantIndex, ptrdiff_t... _Indices> |
| 1983 struct __visit_helper<_VariantIndex, __index_sequence<_Indices...>> { |
| 1984 template <typename _Visitor, typename... _Variants> |
| 1985 static constexpr |
| 1986 typename __multi_visitor_return_type<_Visitor, _Variants...>::__type |
| 1987 __visit(_Visitor& __visitor, _Variants&&... __v) { |
| 1988 return __visit_helper2< |
| 1989 __variant_type_count<typename __arg_selector_t< |
| 1990 _VariantIndex - 1, _Variants...>::__type>::__value - |
| 1991 1, |
| 1992 _VariantIndex, _Indices...>::__visit(__visitor, |
| 1993 std::forward<_Variants&&>(__v)...); |
| 1994 } |
| 1995 }; |
| 1996 |
| 1997 template <typename _Visitor, typename... _Variants> |
| 1998 constexpr typename __multi_visitor_return_type<_Visitor, _Variants...>::__type |
| 1999 visit(_Visitor&& __visitor, _Variants&&... __v) { |
| 2000 return __visit_helper<sizeof...(_Variants), __index_sequence<>>::__visit( |
| 2001 __visitor, std::forward<_Variants>(__v)...); |
| 2002 } |
| 2003 |
| 2004 template <typename... _Types> |
| 2005 constexpr bool operator==(Variant<_Types...> const& __lhs, |
| 2006 Variant<_Types...> const& __rhs) { |
| 2007 return (__lhs.index() == __rhs.index()) && |
| 2008 ((__lhs.index() == -1) || |
| 2009 __equality_op_table< |
| 2010 Variant<_Types...>>::__equality_compare[__lhs.index()](__lhs, |
| 2011 __rhs)); |
| 2012 } |
| 2013 |
| 2014 template <typename... _Types> |
| 2015 constexpr bool operator!=(Variant<_Types...> const& __lhs, |
| 2016 Variant<_Types...> const& __rhs) { |
| 2017 return !(__lhs == __rhs); |
| 2018 } |
| 2019 |
| 2020 template <typename... _Types> |
| 2021 constexpr bool operator<(Variant<_Types...> const& __lhs, |
| 2022 Variant<_Types...> const& __rhs) { |
| 2023 return (__lhs.index() < __rhs.index()) || |
| 2024 ((__lhs.index() == __rhs.index()) && |
| 2025 ((__lhs.index() != -1) && |
| 2026 __less_than_op_table< |
| 2027 Variant<_Types...>>::__less_than_compare[__lhs.index()](__lhs, |
| 2028 __rhs))); |
| 2029 } |
| 2030 |
| 2031 template <typename... _Types> |
| 2032 constexpr bool operator>(Variant<_Types...> const& __lhs, |
| 2033 Variant<_Types...> const& __rhs) { |
| 2034 return __rhs < __lhs; |
| 2035 } |
| 2036 |
| 2037 template <typename... _Types> |
| 2038 constexpr bool operator>=(Variant<_Types...> const& __lhs, |
| 2039 Variant<_Types...> const& __rhs) { |
| 2040 return !(__lhs < __rhs); |
| 2041 } |
| 2042 |
| 2043 template <typename... _Types> |
| 2044 constexpr bool operator<=(Variant<_Types...> const& __lhs, |
| 2045 Variant<_Types...> const& __rhs) { |
| 2046 return !(__lhs > __rhs); |
| 2047 } |
| 2048 |
| 2049 struct Monostate {}; |
| 2050 |
| 2051 constexpr inline bool operator==(Monostate const&, Monostate const&) { |
| 2052 return true; |
| 2053 } |
| 2054 constexpr inline bool operator!=(Monostate const&, Monostate const&) { |
| 2055 return false; |
| 2056 } |
| 2057 constexpr inline bool operator>=(Monostate const&, Monostate const&) { |
| 2058 return true; |
| 2059 } |
| 2060 constexpr inline bool operator<=(Monostate const&, Monostate const&) { |
| 2061 return true; |
| 2062 } |
| 2063 constexpr inline bool operator>(Monostate const&, Monostate const&) { |
| 2064 return false; |
| 2065 } |
| 2066 constexpr inline bool operator<(Monostate const&, Monostate const&) { |
| 2067 return false; |
| 2068 } |
| 2069 |
| 2070 struct __hash_visitor { |
| 2071 template <typename _Type> |
| 2072 size_t operator()(_Type const& __x) { |
| 2073 return std::hash<_Type>()(__x); |
| 2074 } |
| 2075 }; |
| 2076 |
| 2077 // -- WebKit Additions -- |
| 2078 |
| 2079 template <class V, class... F> |
| 2080 auto switchOn(V&& v, F&&... f) |
| 2081 -> decltype(visit(makeVisitor(std::forward<F>(f)...), std::forward<V>(v))) { |
| 2082 return visit(makeVisitor(std::forward<F>(f)...), std::forward<V>(v)); |
| 2083 } |
| 2084 |
| 2085 } // namespace WTF |
| 2086 |
| 2087 namespace std { |
| 2088 |
| 2089 template <> |
| 2090 struct hash<WTF::Monostate> { |
| 2091 size_t operator()(WTF::Monostate) __NOEXCEPT { return 42; } |
| 2092 }; |
| 2093 |
| 2094 template <typename... _Types> |
| 2095 struct hash<WTF::Variant<_Types...>> { |
| 2096 size_t operator()(WTF::Variant<_Types...> const& v) __NOEXCEPT { |
| 2097 return std::hash<ptrdiff_t>()(v.index()) ^ |
| 2098 WTF::visit(WTF::__hash_visitor(), v); |
| 2099 } |
| 2100 }; |
| 2101 |
| 2102 } // namespace std |
| 2103 |
| 2104 using WTF::Monostate; |
| 2105 using WTF::Variant; |
| 2106 |
| 2107 #if COMPILER(MSVC) |
| 2108 #pragma warning(pop) |
| 2109 #endif |
| 2110 |
| 2111 #endif |
| OLD | NEW |