1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_VARIANT 11#define _LIBCPP_VARIANT 12 13/* 14 variant synopsis 15 16namespace std { 17 18 // 20.7.2, class template variant 19 template <class... Types> 20 class variant { 21 public: 22 23 // 20.7.2.1, constructors 24 constexpr variant() noexcept(see below); 25 constexpr variant(const variant&); 26 constexpr variant(variant&&) noexcept(see below); 27 28 template <class T> constexpr variant(T&&) noexcept(see below); 29 30 template <class T, class... Args> 31 constexpr explicit variant(in_place_type_t<T>, Args&&...); 32 33 template <class T, class U, class... Args> 34 constexpr explicit variant( 35 in_place_type_t<T>, initializer_list<U>, Args&&...); 36 37 template <size_t I, class... Args> 38 constexpr explicit variant(in_place_index_t<I>, Args&&...); 39 40 template <size_t I, class U, class... Args> 41 constexpr explicit variant( 42 in_place_index_t<I>, initializer_list<U>, Args&&...); 43 44 // 20.7.2.2, destructor 45 constexpr ~variant(); // constexpr since c++20 46 47 // 20.7.2.3, assignment 48 constexpr variant& operator=(const variant&); 49 constexpr variant& operator=(variant&&) noexcept(see below); 50 51 template <class T> 52 constexpr variant& operator=(T&&) noexcept(see below); // constexpr since c++20 53 54 // 20.7.2.4, modifiers 55 template <class T, class... Args> 56 constexpr T& emplace(Args&&...); // constexpr since c++20 57 58 template <class T, class U, class... Args> 59 constexpr T& emplace(initializer_list<U>, Args&&...); // constexpr since c++20 60 61 template <size_t I, class... Args> 62 constexpr variant_alternative_t<I, variant>& emplace(Args&&...); // constexpr since c++20 63 64 template <size_t I, class U, class... Args> 65 constexpr variant_alternative_t<I, variant>& 66 emplace(initializer_list<U>, Args&&...); // constexpr since c++20 67 68 // 20.7.2.5, value status 69 constexpr bool valueless_by_exception() const noexcept; 70 constexpr size_t index() const noexcept; 71 72 // 20.7.2.6, swap 73 void swap(variant&) noexcept(see below); 74 75 // [variant.visit], visitation 76 template<class Self, class Visitor> 77 constexpr decltype(auto) visit(this Self&&, Visitor&&); // Since C++26 78 template<class R, class Self, class Visitor> 79 constexpr R visit(this Self&&, Visitor&&); // Since C++26 80 }; 81 82 // 20.7.3, variant helper classes 83 template <class T> struct variant_size; // undefined 84 85 template <class T> 86 inline constexpr size_t variant_size_v = variant_size<T>::value; 87 88 template <class T> struct variant_size<const T>; 89 template <class T> struct variant_size<volatile T>; 90 template <class T> struct variant_size<const volatile T>; 91 92 template <class... Types> 93 struct variant_size<variant<Types...>>; 94 95 template <size_t I, class T> struct variant_alternative; // undefined 96 97 template <size_t I, class T> 98 using variant_alternative_t = typename variant_alternative<I, T>::type; 99 100 template <size_t I, class T> struct variant_alternative<I, const T>; 101 template <size_t I, class T> struct variant_alternative<I, volatile T>; 102 template <size_t I, class T> struct variant_alternative<I, const volatile T>; 103 104 template <size_t I, class... Types> 105 struct variant_alternative<I, variant<Types...>>; 106 107 inline constexpr size_t variant_npos = -1; 108 109 // 20.7.4, value access 110 template <class T, class... Types> 111 constexpr bool holds_alternative(const variant<Types...>&) noexcept; 112 113 template <size_t I, class... Types> 114 constexpr variant_alternative_t<I, variant<Types...>>& 115 get(variant<Types...>&); 116 117 template <size_t I, class... Types> 118 constexpr variant_alternative_t<I, variant<Types...>>&& 119 get(variant<Types...>&&); 120 121 template <size_t I, class... Types> 122 constexpr variant_alternative_t<I, variant<Types...>> const& 123 get(const variant<Types...>&); 124 125 template <size_t I, class... Types> 126 constexpr variant_alternative_t<I, variant<Types...>> const&& 127 get(const variant<Types...>&&); 128 129 template <class T, class... Types> 130 constexpr T& get(variant<Types...>&); 131 132 template <class T, class... Types> 133 constexpr T&& get(variant<Types...>&&); 134 135 template <class T, class... Types> 136 constexpr const T& get(const variant<Types...>&); 137 138 template <class T, class... Types> 139 constexpr const T&& get(const variant<Types...>&&); 140 141 template <size_t I, class... Types> 142 constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> 143 get_if(variant<Types...>*) noexcept; 144 145 template <size_t I, class... Types> 146 constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> 147 get_if(const variant<Types...>*) noexcept; 148 149 template <class T, class... Types> 150 constexpr add_pointer_t<T> 151 get_if(variant<Types...>*) noexcept; 152 153 template <class T, class... Types> 154 constexpr add_pointer_t<const T> 155 get_if(const variant<Types...>*) noexcept; 156 157 // 20.7.5, relational operators 158 template <class... Types> 159 constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); 160 161 template <class... Types> 162 constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); 163 164 template <class... Types> 165 constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); 166 167 template <class... Types> 168 constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); 169 170 template <class... Types> 171 constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); 172 173 template <class... Types> 174 constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); 175 176 template <class... Types> requires (three_way_comparable<Types> && ...) 177 constexpr common_comparison_category_t<compare_three_way_result_t<Types>...> 178 operator<=>(const variant<Types...>&, const variant<Types...>&); // since C++20 179 180 // 20.7.6, visitation 181 template <class Visitor, class... Variants> 182 constexpr see below visit(Visitor&&, Variants&&...); 183 184 template <class R, class Visitor, class... Variants> 185 constexpr R visit(Visitor&&, Variants&&...); // since C++20 186 187 // 20.7.7, class monostate 188 struct monostate; 189 190 // 20.7.8, monostate relational operators 191 constexpr bool operator==(monostate, monostate) noexcept; 192 constexpr bool operator!=(monostate, monostate) noexcept; // until C++20 193 constexpr bool operator<(monostate, monostate) noexcept; // until C++20 194 constexpr bool operator>(monostate, monostate) noexcept; // until C++20 195 constexpr bool operator<=(monostate, monostate) noexcept; // until C++20 196 constexpr bool operator>=(monostate, monostate) noexcept; // until C++20 197 constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // since C++20 198 199 // 20.7.9, specialized algorithms 200 template <class... Types> 201 void swap(variant<Types...>&, variant<Types...>&) noexcept(see below); 202 203 // 20.7.10, class bad_variant_access 204 class bad_variant_access; 205 206 // 20.7.11, hash support 207 template <class T> struct hash; 208 template <class... Types> struct hash<variant<Types...>>; 209 template <> struct hash<monostate>; 210 211} // namespace std 212 213*/ 214 215#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 216# include <__cxx03/variant> 217#else 218# include <__compare/common_comparison_category.h> 219# include <__compare/compare_three_way_result.h> 220# include <__compare/ordering.h> 221# include <__compare/three_way_comparable.h> 222# include <__config> 223# include <__exception/exception.h> 224# include <__functional/hash.h> 225# include <__functional/operations.h> 226# include <__functional/unary_function.h> 227# include <__fwd/variant.h> 228# include <__memory/addressof.h> 229# include <__memory/construct_at.h> 230# include <__tuple/find_index.h> 231# include <__tuple/sfinae_helpers.h> 232# include <__type_traits/add_cv_quals.h> 233# include <__type_traits/add_pointer.h> 234# include <__type_traits/common_type.h> 235# include <__type_traits/conditional.h> 236# include <__type_traits/conjunction.h> 237# include <__type_traits/decay.h> 238# include <__type_traits/dependent_type.h> 239# include <__type_traits/enable_if.h> 240# include <__type_traits/invoke.h> 241# include <__type_traits/is_array.h> 242# include <__type_traits/is_assignable.h> 243# include <__type_traits/is_constructible.h> 244# include <__type_traits/is_convertible.h> 245# include <__type_traits/is_destructible.h> 246# include <__type_traits/is_nothrow_assignable.h> 247# include <__type_traits/is_nothrow_constructible.h> 248# include <__type_traits/is_reference.h> 249# include <__type_traits/is_same.h> 250# include <__type_traits/is_swappable.h> 251# include <__type_traits/is_trivially_assignable.h> 252# include <__type_traits/is_trivially_constructible.h> 253# include <__type_traits/is_trivially_destructible.h> 254# include <__type_traits/is_trivially_relocatable.h> 255# include <__type_traits/is_void.h> 256# include <__type_traits/remove_const.h> 257# include <__type_traits/remove_cvref.h> 258# include <__type_traits/remove_reference.h> 259# include <__type_traits/type_identity.h> 260# include <__type_traits/void_t.h> 261# include <__utility/declval.h> 262# include <__utility/forward.h> 263# include <__utility/forward_like.h> 264# include <__utility/in_place.h> 265# include <__utility/integer_sequence.h> 266# include <__utility/move.h> 267# include <__utility/swap.h> 268# include <__variant/monostate.h> 269# include <__verbose_abort> 270# include <initializer_list> 271# include <limits> 272# include <version> 273 274// standard-mandated includes 275 276// [variant.syn] 277# include <compare> 278 279# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 280# pragma GCC system_header 281# endif 282 283_LIBCPP_PUSH_MACROS 284# include <__undef_macros> 285 286namespace std { // explicitly not using versioning namespace 287 288class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { 289public: 290 const char* what() const _NOEXCEPT override; 291}; 292 293} // namespace std 294 295_LIBCPP_BEGIN_NAMESPACE_STD 296 297# if _LIBCPP_STD_VER >= 17 298 299// Light N-dimensional array of function pointers. Used in place of std::array to avoid 300// adding a dependency. 301template <class _Tp, size_t _Size> 302struct __farray { 303 static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit"); 304 _Tp __buf_[_Size] = {}; 305 306 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __n) const noexcept { return __buf_[__n]; } 307}; 308 309[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS void 310__throw_bad_variant_access() { 311# if _LIBCPP_HAS_EXCEPTIONS 312 throw bad_variant_access(); 313# else 314 _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode"); 315# endif 316} 317 318// variant_size 319template <class _Tp> 320struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {}; 321 322template <class _Tp> 323struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {}; 324 325template <class _Tp> 326struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp> : variant_size<_Tp> {}; 327 328template <class... _Types> 329struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>> : integral_constant<size_t, sizeof...(_Types)> {}; 330 331// variant_alternative 332template <size_t _Ip, class _Tp> 333struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp> : add_const<variant_alternative_t<_Ip, _Tp>> {}; 334 335template <size_t _Ip, class _Tp> 336struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp> : add_volatile<variant_alternative_t<_Ip, _Tp>> {}; 337 338template <size_t _Ip, class _Tp> 339struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp> : add_cv<variant_alternative_t<_Ip, _Tp>> {}; 340 341template <size_t _Ip, class... _Types> 342struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> { 343 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>"); 344 using type = __type_pack_element<_Ip, _Types...>; 345}; 346 347template <size_t _NumAlternatives> 348_LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() { 349# ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION 350 if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max()) 351 return static_cast<unsigned char>(0); 352 else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max()) 353 return static_cast<unsigned short>(0); 354 else 355# endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION 356 return static_cast<unsigned int>(0); 357} 358 359template <size_t _NumAlts> 360using __variant_index_t _LIBCPP_NODEBUG = decltype(std::__choose_index_type<_NumAlts>()); 361 362template <class _IndexType> 363constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1); 364 365template <class... _Types> 366_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>& __as_variant(variant<_Types...>& __vs) noexcept { 367 return __vs; 368} 369 370template <class... _Types> 371_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>& __as_variant(const variant<_Types...>& __vs) noexcept { 372 return __vs; 373} 374 375template <class... _Types> 376_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>&& __as_variant(variant<_Types...>&& __vs) noexcept { 377 return std::move(__vs); 378} 379 380template <class... _Types> 381_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>&& __as_variant(const variant<_Types...>&& __vs) noexcept { 382 return std::move(__vs); 383} 384 385namespace __find_detail { 386 387template <class _Tp, class... _Types> 388_LIBCPP_HIDE_FROM_ABI constexpr size_t __find_index() { 389 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...}; 390 size_t __result = __not_found; 391 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) { 392 if (__matches[__i]) { 393 if (__result != __not_found) { 394 return __ambiguous; 395 } 396 __result = __i; 397 } 398 } 399 return __result; 400} 401 402template <size_t _Index> 403struct __find_unambiguous_index_sfinae_impl : integral_constant<size_t, _Index> {}; 404 405template <> 406struct __find_unambiguous_index_sfinae_impl<__not_found> {}; 407 408template <> 409struct __find_unambiguous_index_sfinae_impl<__ambiguous> {}; 410 411template <class _Tp, class... _Types> 412struct __find_unambiguous_index_sfinae : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {}; 413 414} // namespace __find_detail 415 416namespace __variant_detail { 417 418struct __valueless_t {}; 419 420enum class _Trait { _TriviallyAvailable, _Available, _Unavailable }; 421 422template <typename _Tp, template <typename> class _IsTriviallyAvailable, template <typename> class _IsAvailable> 423constexpr _Trait __trait = 424 _IsTriviallyAvailable<_Tp>::value ? _Trait::_TriviallyAvailable 425 : _IsAvailable<_Tp>::value 426 ? _Trait::_Available 427 : _Trait::_Unavailable; 428 429_LIBCPP_HIDE_FROM_ABI constexpr _Trait __common_trait(initializer_list<_Trait> __traits) { 430 _Trait __result = _Trait::_TriviallyAvailable; 431 for (_Trait __t : __traits) { 432 if (static_cast<int>(__t) > static_cast<int>(__result)) { 433 __result = __t; 434 } 435 } 436 return __result; 437} 438 439template <typename... _Types> 440struct __traits { 441 static constexpr _Trait __copy_constructible_trait = 442 __variant_detail::__common_trait({__trait<_Types, is_trivially_copy_constructible, is_copy_constructible>...}); 443 444 static constexpr _Trait __move_constructible_trait = 445 __variant_detail::__common_trait({__trait<_Types, is_trivially_move_constructible, is_move_constructible>...}); 446 447 static constexpr _Trait __copy_assignable_trait = __variant_detail::__common_trait( 448 {__copy_constructible_trait, __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...}); 449 450 static constexpr _Trait __move_assignable_trait = __variant_detail::__common_trait( 451 {__move_constructible_trait, __trait<_Types, is_trivially_move_assignable, is_move_assignable>...}); 452 453 static constexpr _Trait __destructible_trait = 454 __variant_detail::__common_trait({__trait<_Types, is_trivially_destructible, is_destructible>...}); 455}; 456 457namespace __access { 458 459struct __union { 460 template <class _Vp> 461 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) { 462 return std::forward<_Vp>(__v).__head; 463 } 464 465 template <class _Vp, size_t _Ip> 466 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) { 467 return __get_alt(std::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>); 468 } 469}; 470 471struct __base { 472 template <size_t _Ip, class _Vp> 473 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) { 474 return __union::__get_alt(std::forward<_Vp>(__v).__data, in_place_index<_Ip>); 475 } 476}; 477 478struct __variant { 479 template <size_t _Ip, class _Vp> 480 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) { 481 return __base::__get_alt<_Ip>(std::forward<_Vp>(__v).__impl_); 482 } 483}; 484 485} // namespace __access 486 487namespace __visitation { 488 489struct __base { 490 template <class _Visitor, class... _Vs> 491 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) 492 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 493 constexpr auto __fdiagonal = __make_fdiagonal<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>(); 494 return __fdiagonal[__index](std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...); 495 } 496 497 template <class _Visitor, class... _Vs> 498 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) { 499 constexpr auto __fmatrix = __make_fmatrix<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>(); 500 return __at(__fmatrix, __vs.index()...)(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...); 501 } 502 503private: 504 template <class _Tp> 505 _LIBCPP_HIDE_FROM_ABI static constexpr const _Tp& __at(const _Tp& __elem) { 506 return __elem; 507 } 508 509 template <class _Tp, size_t _Np, typename... _Indices> 510 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& 511 __at(const __farray<_Tp, _Np>& __elems, size_t __index, _Indices... __indices) { 512 return __at(__elems[__index], __indices...); 513 } 514 515 template <class _Fp, class... _Fs> 516 static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() { 517 static_assert( 518 __all<is_same_v<_Fp, _Fs>...>::value, "`std::visit` requires the visitor to have a single return type."); 519 } 520 521 template <class... _Fs> 522 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_farray(_Fs&&... __fs) { 523 __std_visit_visitor_return_type_check<__remove_cvref_t<_Fs>...>(); 524 using __result = __farray<common_type_t<__remove_cvref_t<_Fs>...>, sizeof...(_Fs)>; 525 return __result{{std::forward<_Fs>(__fs)...}}; 526 } 527 528 template <size_t... _Is> 529 struct __dispatcher { 530 template <class _Fp, class... _Vs> 531 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) { 532 return std::__invoke(static_cast<_Fp>(__f), __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...); 533 } 534 }; 535 536 template <class _Fp, class... _Vs, size_t... _Is> 537 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_dispatch(index_sequence<_Is...>) { 538 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>; 539 } 540 541 template <size_t _Ip, class _Fp, class... _Vs> 542 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl() { 543 return __make_dispatch<_Fp, _Vs...>(index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{}); 544 } 545 546 template <class _Fp, class... _Vs, size_t... _Is> 547 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) { 548 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...); 549 } 550 551 template <class _Fp, class _Vp, class... _Vs> 552 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal() { 553 constexpr size_t __np = __remove_cvref_t<_Vp>::__size(); 554 static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value); 555 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{}); 556 } 557 558 template <class _Fp, class... _Vs, size_t... _Is> 559 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) { 560 return __make_dispatch<_Fp, _Vs...>(__is); 561 } 562 563 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls> 564 _LIBCPP_HIDE_FROM_ABI static constexpr auto 565 __make_fmatrix_impl(index_sequence<_Is...>, index_sequence<_Js...>, _Ls... __ls) { 566 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(index_sequence<_Is..., _Js>{}, __ls...)...); 567 } 568 569 template <class _Fp, class... _Vs> 570 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix() { 571 return __make_fmatrix_impl<_Fp, _Vs...>( 572 index_sequence<>{}, make_index_sequence<__remove_cvref_t<_Vs>::__size()>{}...); 573 } 574}; 575 576struct __variant { 577 template <class _Visitor, class... _Vs> 578 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) 579 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 580 return __base::__visit_alt_at(__index, std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__impl_...); 581 } 582 583 template <class _Visitor, class... _Vs> 584 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) { 585 return __base::__visit_alt( 586 std::forward<_Visitor>(__visitor), std::__as_variant(std::forward<_Vs>(__vs)).__impl_...); 587 } 588 589 template <class _Visitor, class... _Vs> 590 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) 591 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 592 return __visit_alt_at(__index, __make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...); 593 } 594 595 template <class _Visitor, class... _Vs> 596 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, _Vs&&... __vs) { 597 return __visit_alt(__make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...); 598 } 599 600# if _LIBCPP_STD_VER >= 20 601 template <class _Rp, class _Visitor, class... _Vs> 602 _LIBCPP_HIDE_FROM_ABI static constexpr _Rp __visit_value(_Visitor&& __visitor, _Vs&&... __vs) { 603 return __visit_alt(__make_value_visitor<_Rp>(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...); 604 } 605# endif 606 607private: 608 template <class _Visitor, class... _Values> 609 static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() { 610 static_assert(is_invocable_v<_Visitor, _Values...>, "`std::visit` requires the visitor to be exhaustive."); 611 } 612 613 template <class _Visitor> 614 struct __value_visitor { 615 template <class... _Alts> 616 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Alts&&... __alts) const { 617 __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>(); 618 return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...); 619 } 620 _Visitor&& __visitor; 621 }; 622 623# if _LIBCPP_STD_VER >= 20 624 template <class _Rp, class _Visitor> 625 struct __value_visitor_return_type { 626 template <class... _Alts> 627 _LIBCPP_HIDE_FROM_ABI constexpr _Rp operator()(_Alts&&... __alts) const { 628 __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>(); 629 if constexpr (is_void_v<_Rp>) { 630 std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...); 631 } else { 632 return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...); 633 } 634 } 635 636 _Visitor&& __visitor; 637 }; 638# endif 639 640 template <class _Visitor> 641 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) { 642 return __value_visitor<_Visitor>{std::forward<_Visitor>(__visitor)}; 643 } 644 645# if _LIBCPP_STD_VER >= 20 646 template <class _Rp, class _Visitor> 647 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) { 648 return __value_visitor_return_type<_Rp, _Visitor>{std::forward<_Visitor>(__visitor)}; 649 } 650# endif 651}; 652 653} // namespace __visitation 654 655// Adding semi-colons in macro expansions helps clang-format to do a better job. 656// This macro is used to avoid compilation errors due to "stray" semi-colons. 657# define _LIBCPP_EAT_SEMICOLON static_assert(true, "") 658 659template <size_t _Index, class _Tp> 660struct _LIBCPP_TEMPLATE_VIS __alt { 661 using __value_type _LIBCPP_NODEBUG = _Tp; 662 static constexpr size_t __index = _Index; 663 664 template <class... _Args> 665 _LIBCPP_HIDE_FROM_ABI explicit constexpr __alt(in_place_t, _Args&&... __args) 666 : __value(std::forward<_Args>(__args)...) {} 667 668 __value_type __value; 669}; 670 671template <_Trait _DestructibleTrait, size_t _Index, class... _Types> 672union _LIBCPP_TEMPLATE_VIS __union; 673 674template <_Trait _DestructibleTrait, size_t _Index> 675union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {}; 676 677# define _LIBCPP_VARIANT_UNION(destructible_trait, destructor_definition) \ 678 template <size_t _Index, class _Tp, class... _Types> \ 679 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, _Index, _Tp, _Types...> { \ 680 public: \ 681 _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \ 682 \ 683 template <class... _Args> \ 684 _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \ 685 : __head(in_place, std::forward<_Args>(__args)...) {} \ 686 \ 687 template <size_t _Ip, class... _Args> \ 688 _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \ 689 : __tail(in_place_index<_Ip - 1>, std::forward<_Args>(__args)...) {} \ 690 \ 691 _LIBCPP_HIDE_FROM_ABI __union(const __union&) = default; \ 692 _LIBCPP_HIDE_FROM_ABI __union(__union&&) = default; \ 693 _LIBCPP_HIDE_FROM_ABI __union& operator=(const __union&) = default; \ 694 _LIBCPP_HIDE_FROM_ABI __union& operator=(__union&&) = default; \ 695 destructor_definition; \ 696 \ 697 private: \ 698 char __dummy; \ 699 __alt<_Index, _Tp> __head; \ 700 __union<destructible_trait, _Index + 1, _Types...> __tail; \ 701 \ 702 friend struct __access::__union; \ 703 } 704 705_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, 706 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = default); 707_LIBCPP_VARIANT_UNION( 708 _Trait::_Available, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() {} _LIBCPP_EAT_SEMICOLON); 709_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = delete); 710 711# undef _LIBCPP_VARIANT_UNION 712 713template <_Trait _DestructibleTrait, class... _Types> 714class _LIBCPP_TEMPLATE_VIS __base { 715public: 716 using __index_t _LIBCPP_NODEBUG = __variant_index_t<sizeof...(_Types)>; 717 718 _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(__valueless_t __tag) noexcept 719 : __data(__tag), __index(__variant_npos<__index_t>) {} 720 721 template <size_t _Ip, class... _Args> 722 _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args) 723 : __data(in_place_index<_Ip>, std::forward<_Args>(__args)...), __index(_Ip) {} 724 725 _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept { return index() == variant_npos; } 726 727 _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { 728 return __index == __variant_npos<__index_t> ? variant_npos : __index; 729 } 730 731protected: 732 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() & { return *this; } 733 734 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() && { return std::move(*this); } 735 736 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const& { return *this; } 737 738 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const&& { return std::move(*this); } 739 740 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Types); } 741 742 __union<_DestructibleTrait, 0, _Types...> __data; 743 __index_t __index; 744 745 friend struct __access::__base; 746 friend struct __visitation::__base; 747}; 748 749template <class _Traits, _Trait = _Traits::__destructible_trait> 750class _LIBCPP_TEMPLATE_VIS __dtor; 751 752# define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor_definition, destroy) \ 753 template <class... _Types> \ 754 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, destructible_trait> \ 755 : public __base<destructible_trait, _Types...> { \ 756 using __base_type _LIBCPP_NODEBUG = __base<destructible_trait, _Types...>; \ 757 using __index_t _LIBCPP_NODEBUG = typename __base_type::__index_t; \ 758 \ 759 public: \ 760 using __base_type::__base_type; \ 761 using __base_type::operator=; \ 762 _LIBCPP_HIDE_FROM_ABI __dtor(const __dtor&) = default; \ 763 _LIBCPP_HIDE_FROM_ABI __dtor(__dtor&&) = default; \ 764 _LIBCPP_HIDE_FROM_ABI __dtor& operator=(const __dtor&) = default; \ 765 _LIBCPP_HIDE_FROM_ABI __dtor& operator=(__dtor&&) = default; \ 766 destructor_definition; \ 767 \ 768 protected: \ 769 destroy; \ 770 } 771 772_LIBCPP_VARIANT_DESTRUCTOR( 773 _Trait::_TriviallyAvailable, 774 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = default, 775 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept { 776 this->__index = __variant_npos<__index_t>; 777 } _LIBCPP_EAT_SEMICOLON); 778 779_LIBCPP_VARIANT_DESTRUCTOR( 780 _Trait::_Available, 781 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() { __destroy(); } _LIBCPP_EAT_SEMICOLON, 782 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept { 783 if (!this->valueless_by_exception()) { 784 __visitation::__base::__visit_alt( 785 [](auto& __alt) noexcept { 786 using __alt_type = __remove_cvref_t<decltype(__alt)>; 787 __alt.~__alt_type(); 788 }, 789 *this); 790 } 791 this->__index = __variant_npos<__index_t>; 792 } _LIBCPP_EAT_SEMICOLON); 793 794_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, 795 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = delete, 796 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept = delete); 797 798# undef _LIBCPP_VARIANT_DESTRUCTOR 799 800template <class _Traits> 801class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> { 802 using __base_type _LIBCPP_NODEBUG = __dtor<_Traits>; 803 804public: 805 using __base_type::__base_type; 806 using __base_type::operator=; 807 808protected: 809 template <class _Rhs> 810 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) { 811 __lhs.__destroy(); 812 if (!__rhs.valueless_by_exception()) { 813 auto __rhs_index = __rhs.index(); 814 __visitation::__base::__visit_alt_at( 815 __rhs_index, 816 [&__lhs](auto&& __rhs_alt) { 817 std::__construct_at(std::addressof(__lhs.__data), 818 in_place_index<__decay_t<decltype(__rhs_alt)>::__index>, 819 std::forward<decltype(__rhs_alt)>(__rhs_alt).__value); 820 }, 821 std::forward<_Rhs>(__rhs)); 822 __lhs.__index = __rhs_index; 823 } 824 } 825}; 826 827template <class _Traits, _Trait = _Traits::__move_constructible_trait> 828class _LIBCPP_TEMPLATE_VIS __move_constructor; 829 830# define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, move_constructor_definition) \ 831 template <class... _Types> \ 832 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, move_constructible_trait> \ 833 : public __ctor<__traits<_Types...>> { \ 834 using __base_type _LIBCPP_NODEBUG = __ctor<__traits<_Types...>>; \ 835 \ 836 public: \ 837 using __base_type::__base_type; \ 838 using __base_type::operator=; \ 839 \ 840 _LIBCPP_HIDE_FROM_ABI __move_constructor(const __move_constructor&) = default; \ 841 _LIBCPP_HIDE_FROM_ABI ~__move_constructor() = default; \ 842 _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(const __move_constructor&) = default; \ 843 _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(__move_constructor&&) = default; \ 844 move_constructor_definition; \ 845 } 846 847_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 848 _Trait::_TriviallyAvailable, 849 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) = default); 850 851_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 852 _Trait::_Available, 853 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) noexcept( 854 __all<is_nothrow_move_constructible_v<_Types>...>::value) 855 : __move_constructor(__valueless_t{}) { 856 this->__generic_construct(*this, std::move(__that)); 857 } _LIBCPP_EAT_SEMICOLON); 858 859_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 860 _Trait::_Unavailable, 861 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&&) = delete); 862 863# undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR 864 865template <class _Traits, _Trait = _Traits::__copy_constructible_trait> 866class _LIBCPP_TEMPLATE_VIS __copy_constructor; 867 868# define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, copy_constructor_definition) \ 869 template <class... _Types> \ 870 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, copy_constructible_trait> \ 871 : public __move_constructor<__traits<_Types...>> { \ 872 using __base_type _LIBCPP_NODEBUG = __move_constructor<__traits<_Types...>>; \ 873 \ 874 public: \ 875 using __base_type::__base_type; \ 876 using __base_type::operator=; \ 877 \ 878 _LIBCPP_HIDE_FROM_ABI __copy_constructor(__copy_constructor&&) = default; \ 879 _LIBCPP_HIDE_FROM_ABI ~__copy_constructor() = default; \ 880 _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(const __copy_constructor&) = default; \ 881 _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(__copy_constructor&&) = default; \ 882 copy_constructor_definition; \ 883 } 884 885_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 886 _Trait::_TriviallyAvailable, 887 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) = default); 888 889_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 890 _Trait::_Available, 891 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) 892 : __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON); 893 894_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 895 _Trait::_Unavailable, 896 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor&) = delete); 897 898# undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR 899 900template <class _Traits> 901class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> { 902 using __base_type _LIBCPP_NODEBUG = __copy_constructor<_Traits>; 903 904public: 905 using __base_type::__base_type; 906 using __base_type::operator=; 907 908 template <size_t _Ip, class... _Args> 909 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto& __emplace(_Args&&... __args) { 910 this->__destroy(); 911 std::__construct_at(std::addressof(this->__data), in_place_index<_Ip>, std::forward<_Args>(__args)...); 912 this->__index = _Ip; 913 return __access::__base::__get_alt<_Ip>(*this).__value; 914 } 915 916protected: 917 template <size_t _Ip, class _Tp, class _Arg> 918 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) { 919 if (this->index() == _Ip) { 920 __a.__value = std::forward<_Arg>(__arg); 921 } else { 922 struct { 923 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(true_type) const { 924 __this->__emplace<_Ip>(std::forward<_Arg>(__arg)); 925 } 926 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(false_type) const { 927 __this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg))); 928 } 929 __assignment* __this; 930 _Arg&& __arg; 931 } __impl{this, std::forward<_Arg>(__arg)}; 932 __impl(bool_constant < is_nothrow_constructible_v<_Tp, _Arg> || !is_nothrow_move_constructible_v < _Tp >> {}); 933 } 934 } 935 936 template <class _That> 937 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_assign(_That&& __that) { 938 if (this->valueless_by_exception() && __that.valueless_by_exception()) { 939 // do nothing. 940 } else if (__that.valueless_by_exception()) { 941 this->__destroy(); 942 } else { 943 __visitation::__base::__visit_alt_at( 944 __that.index(), 945 [this](auto& __this_alt, auto&& __that_alt) { 946 this->__assign_alt(__this_alt, std::forward<decltype(__that_alt)>(__that_alt).__value); 947 }, 948 *this, 949 std::forward<_That>(__that)); 950 } 951 } 952}; 953 954template <class _Traits, _Trait = _Traits::__move_assignable_trait> 955class _LIBCPP_TEMPLATE_VIS __move_assignment; 956 957# define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, move_assignment_definition) \ 958 template <class... _Types> \ 959 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, move_assignable_trait> \ 960 : public __assignment<__traits<_Types...>> { \ 961 using __base_type _LIBCPP_NODEBUG = __assignment<__traits<_Types...>>; \ 962 \ 963 public: \ 964 using __base_type::__base_type; \ 965 using __base_type::operator=; \ 966 \ 967 _LIBCPP_HIDE_FROM_ABI __move_assignment(const __move_assignment&) = default; \ 968 _LIBCPP_HIDE_FROM_ABI __move_assignment(__move_assignment&&) = default; \ 969 _LIBCPP_HIDE_FROM_ABI ~__move_assignment() = default; \ 970 _LIBCPP_HIDE_FROM_ABI __move_assignment& operator=(const __move_assignment&) = default; \ 971 move_assignment_definition; \ 972 } 973 974_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_TriviallyAvailable, 975 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=( 976 __move_assignment&& __that) = default); 977 978_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 979 _Trait::_Available, 980 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& 981 operator=(__move_assignment&& __that) noexcept( 982 __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_move_assignable_v<_Types>)...>::value) { 983 this->__generic_assign(std::move(__that)); 984 return *this; 985 } _LIBCPP_EAT_SEMICOLON); 986 987_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 988 _Trait::_Unavailable, 989 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(__move_assignment&&) = delete); 990 991# undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT 992 993template <class _Traits, _Trait = _Traits::__copy_assignable_trait> 994class _LIBCPP_TEMPLATE_VIS __copy_assignment; 995 996# define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, copy_assignment_definition) \ 997 template <class... _Types> \ 998 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, copy_assignable_trait> \ 999 : public __move_assignment<__traits<_Types...>> { \ 1000 using __base_type _LIBCPP_NODEBUG = __move_assignment<__traits<_Types...>>; \ 1001 \ 1002 public: \ 1003 using __base_type::__base_type; \ 1004 using __base_type::operator=; \ 1005 \ 1006 _LIBCPP_HIDE_FROM_ABI __copy_assignment(const __copy_assignment&) = default; \ 1007 _LIBCPP_HIDE_FROM_ABI __copy_assignment(__copy_assignment&&) = default; \ 1008 _LIBCPP_HIDE_FROM_ABI ~__copy_assignment() = default; \ 1009 _LIBCPP_HIDE_FROM_ABI __copy_assignment& operator=(__copy_assignment&&) = default; \ 1010 copy_assignment_definition; \ 1011 } 1012 1013_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_TriviallyAvailable, 1014 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=( 1015 const __copy_assignment& __that) = default); 1016 1017_LIBCPP_VARIANT_COPY_ASSIGNMENT( 1018 _Trait::_Available, 1019 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& 1020 operator=(const __copy_assignment& __that) { 1021 this->__generic_assign(__that); 1022 return *this; 1023 } _LIBCPP_EAT_SEMICOLON); 1024 1025_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable, 1026 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=( 1027 const __copy_assignment&) = delete); 1028 1029# undef _LIBCPP_VARIANT_COPY_ASSIGNMENT 1030 1031template <class... _Types> 1032class _LIBCPP_TEMPLATE_VIS __impl : public __copy_assignment<__traits<_Types...>> { 1033 using __base_type _LIBCPP_NODEBUG = __copy_assignment<__traits<_Types...>>; 1034 1035public: 1036 using __base_type::__base_type; // get in_place_index_t constructor & friends 1037 _LIBCPP_HIDE_FROM_ABI __impl(__impl const&) = default; 1038 _LIBCPP_HIDE_FROM_ABI __impl(__impl&&) = default; 1039 _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default; 1040 _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&) = default; 1041 1042 template <size_t _Ip, class _Arg> 1043 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign(_Arg&& __arg) { 1044 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), std::forward<_Arg>(__arg)); 1045 } 1046 1047 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__impl& __that) { 1048 if (this->valueless_by_exception() && __that.valueless_by_exception()) { 1049 // do nothing. 1050 } else if (this->index() == __that.index()) { 1051 __visitation::__base::__visit_alt_at( 1052 this->index(), 1053 [](auto& __this_alt, auto& __that_alt) { 1054 using std::swap; 1055 swap(__this_alt.__value, __that_alt.__value); 1056 }, 1057 *this, 1058 __that); 1059 } else { 1060 __impl* __lhs = this; 1061 __impl* __rhs = std::addressof(__that); 1062 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) { 1063 std::swap(__lhs, __rhs); 1064 } 1065 __impl __tmp(std::move(*__rhs)); 1066# if _LIBCPP_HAS_EXCEPTIONS 1067 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) { 1068 this->__generic_construct(*__rhs, std::move(*__lhs)); 1069 } else { 1070 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws 1071 // and `__tmp` is nothrow move constructible then we move `__tmp` back 1072 // into `__rhs` and provide the strong exception safety guarantee. 1073 try { 1074 this->__generic_construct(*__rhs, std::move(*__lhs)); 1075 } catch (...) { 1076 if (__tmp.__move_nothrow()) { 1077 this->__generic_construct(*__rhs, std::move(__tmp)); 1078 } 1079 throw; 1080 } 1081 } 1082# else 1083 // this isn't consolidated with the `if constexpr` branch above due to 1084 // `throw` being ill-formed with exceptions disabled even when discarded. 1085 this->__generic_construct(*__rhs, std::move(*__lhs)); 1086# endif 1087 this->__generic_construct(*__lhs, std::move(__tmp)); 1088 } 1089 } 1090 1091private: 1092 constexpr inline _LIBCPP_HIDE_FROM_ABI bool __move_nothrow() const { 1093 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...}; 1094 return this->valueless_by_exception() || __results[this->index()]; 1095 } 1096}; 1097 1098struct __no_narrowing_check { 1099 template <class _Dest, class _Source> 1100 using _Apply _LIBCPP_NODEBUG = __type_identity<_Dest>; 1101}; 1102 1103struct __narrowing_check { 1104 template <class _Dest> 1105 static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>; 1106 template <class _Dest, class _Source> 1107 using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({std::declval<_Source>()})); 1108}; 1109 1110template <class _Dest, class _Source> 1111using __check_for_narrowing _LIBCPP_NODEBUG = 1112 typename _If< is_arithmetic<_Dest>::value, __narrowing_check, __no_narrowing_check >::template _Apply<_Dest, 1113 _Source>; 1114 1115template <class _Tp, size_t _Idx> 1116struct __overload { 1117 template <class _Up> 1118 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>; 1119}; 1120 1121template <class... _Bases> 1122struct __all_overloads : _Bases... { 1123 void operator()() const; 1124 using _Bases::operator()...; 1125}; 1126 1127template <class _IdxSeq> 1128struct __make_overloads_imp; 1129 1130template <size_t... _Idx> 1131struct __make_overloads_imp<__tuple_indices<_Idx...> > { 1132 template <class... _Types> 1133 using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>; 1134}; 1135 1136template <class... _Types> 1137using _MakeOverloads _LIBCPP_NODEBUG = 1138 typename __make_overloads_imp< __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>; 1139 1140template <class _Tp, class... _Types> 1141using __best_match_t _LIBCPP_NODEBUG = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type; 1142 1143} // namespace __variant_detail 1144 1145template <class _Visitor, class... _Vs, typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>> 1146_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr decltype(auto) 1147visit(_Visitor&& __visitor, _Vs&&... __vs); 1148 1149# if _LIBCPP_STD_VER >= 20 1150template <class _Rp, 1151 class _Visitor, 1152 class... _Vs, 1153 typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>> 1154_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp 1155visit(_Visitor&& __visitor, _Vs&&... __vs); 1156# endif 1157 1158template <class... _Types> 1159class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant 1160 : private __sfinae_ctor_base< __all<is_copy_constructible_v<_Types>...>::value, 1161 __all<is_move_constructible_v<_Types>...>::value>, 1162 private __sfinae_assign_base< 1163 __all<(is_copy_constructible_v<_Types> && is_copy_assignable_v<_Types>)...>::value, 1164 __all<(is_move_constructible_v<_Types> && is_move_assignable_v<_Types>)...>::value> { 1165 static_assert(0 < sizeof...(_Types), "variant must consist of at least one alternative."); 1166 1167 static_assert(__all<!is_array_v<_Types>...>::value, "variant can not have an array type as an alternative."); 1168 1169 static_assert(__all<!is_reference_v<_Types>...>::value, "variant can not have a reference type as an alternative."); 1170 1171 static_assert(__all<!is_void_v<_Types>...>::value, "variant can not have a void type as an alternative."); 1172 1173 using __first_type _LIBCPP_NODEBUG = variant_alternative_t<0, variant>; 1174 1175public: 1176 using __trivially_relocatable _LIBCPP_NODEBUG = 1177 conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>; 1178 1179 template <bool _Dummy = true, 1180 enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0> 1181 _LIBCPP_HIDE_FROM_ABI constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) 1182 : __impl_(in_place_index<0>) {} 1183 1184 _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default; 1185 _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&) = default; 1186 1187 template < class _Arg, 1188 enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0, 1189 enable_if_t<!__is_inplace_type<__remove_cvref_t<_Arg>>::value, int> = 0, 1190 enable_if_t<!__is_inplace_index<__remove_cvref_t<_Arg>>::value, int> = 0, 1191 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, 1192 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1193 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0> 1194 _LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>) 1195 : __impl_(in_place_index<_Ip>, std::forward<_Arg>(__arg)) {} 1196 1197 template <size_t _Ip, 1198 class... _Args, 1199 class = enable_if_t<(_Ip < sizeof...(_Types)), int>, 1200 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1201 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1202 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_index_t<_Ip>, _Args&&... __args) noexcept( 1203 is_nothrow_constructible_v<_Tp, _Args...>) 1204 : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {} 1205 1206 template < size_t _Ip, 1207 class _Up, 1208 class... _Args, 1209 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1210 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1211 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1212 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant( 1213 in_place_index_t<_Ip>, 1214 initializer_list<_Up> __il, 1215 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) 1216 : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {} 1217 1218 template < class _Tp, 1219 class... _Args, 1220 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1221 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1222 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept( 1223 is_nothrow_constructible_v<_Tp, _Args...>) 1224 : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {} 1225 1226 template < class _Tp, 1227 class _Up, 1228 class... _Args, 1229 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1230 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1231 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant( 1232 in_place_type_t<_Tp>, 1233 initializer_list<_Up> __il, 1234 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>) 1235 : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {} 1236 1237 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~variant() = default; 1238 1239 _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default; 1240 _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&) = default; 1241 1242 template < class _Arg, 1243 enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0, 1244 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, 1245 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1246 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, int> = 0> 1247 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 variant& 1248 operator=(_Arg&& __arg) noexcept(is_nothrow_assignable_v<_Tp&, _Arg> && is_nothrow_constructible_v<_Tp, _Arg>) { 1249 __impl_.template __assign<_Ip>(std::forward<_Arg>(__arg)); 1250 return *this; 1251 } 1252 1253 template < size_t _Ip, 1254 class... _Args, 1255 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1256 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1257 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1258 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) { 1259 return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...); 1260 } 1261 1262 template < size_t _Ip, 1263 class _Up, 1264 class... _Args, 1265 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1266 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1267 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1268 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { 1269 return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...); 1270 } 1271 1272 template < class _Tp, 1273 class... _Args, 1274 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1275 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) { 1277 return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...); 1278 } 1279 1280 template < class _Tp, 1281 class _Up, 1282 class... _Args, 1283 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1284 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1285 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { 1286 return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...); 1287 } 1288 1289 _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept { 1290 return __impl_.valueless_by_exception(); 1291 } 1292 1293 _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { return __impl_.index(); } 1294 1295 template < bool _Dummy = true, 1296 enable_if_t< __all<(__dependent_type<is_move_constructible<_Types>, _Dummy>::value && 1297 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value, 1298 int> = 0> 1299 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(variant& __that) noexcept( 1300 __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_swappable_v<_Types>)...>::value) { 1301 __impl_.__swap(__that.__impl_); 1302 } 1303 1304# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 1305 // Helper class to implement [variant.visit]/10 1306 // Constraints: The call to visit does not use an explicit template-argument-list 1307 // that begins with a type template-argument. 1308 struct __variant_visit_barrier_tag { 1309 _LIBCPP_HIDE_FROM_ABI explicit __variant_visit_barrier_tag() = default; 1310 }; 1311 1312 template <__variant_visit_barrier_tag = __variant_visit_barrier_tag{}, class _Self, class _Visitor> 1313 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor) { 1314 return std::visit(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self)); 1315 } 1316 1317 template <class _Rp, class _Self, class _Visitor> 1318 _LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(this _Self&& __self, _Visitor&& __visitor) { 1319 return std::visit<_Rp>(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self)); 1320 } 1321# endif 1322 1323private: 1324 __variant_detail::__impl<_Types...> __impl_; 1325 1326 friend struct __variant_detail::__access::__variant; 1327 friend struct __variant_detail::__visitation::__variant; 1328}; 1329 1330template <size_t _Ip, class... _Types> 1331_LIBCPP_HIDE_FROM_ABI constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept { 1332 return __v.index() == _Ip; 1333} 1334 1335template <class _Tp, class... _Types> 1336_LIBCPP_HIDE_FROM_ABI constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { 1337 return std::__holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1338} 1339 1340template <size_t _Ip, class _Vp> 1341_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr auto&& __generic_get(_Vp&& __v) { 1342 using __variant_detail::__access::__variant; 1343 if (!std::__holds_alternative<_Ip>(__v)) { 1344 __throw_bad_variant_access(); 1345 } 1346 return __variant::__get_alt<_Ip>(std::forward<_Vp>(__v)).__value; 1347} 1348 1349template <size_t _Ip, class... _Types> 1350_LIBCPP_HIDE_FROM_ABI 1351_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr variant_alternative_t<_Ip, variant<_Types...>>& 1352get(variant<_Types...>& __v) { 1353 static_assert(_Ip < sizeof...(_Types)); 1354 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 1355 return std::__generic_get<_Ip>(__v); 1356} 1357 1358template <size_t _Ip, class... _Types> 1359_LIBCPP_HIDE_FROM_ABI 1360_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr variant_alternative_t<_Ip, variant<_Types...>>&& 1361get(variant<_Types...>&& __v) { 1362 static_assert(_Ip < sizeof...(_Types)); 1363 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 1364 return std::__generic_get<_Ip>(std::move(__v)); 1365} 1366 1367template <size_t _Ip, class... _Types> 1368_LIBCPP_HIDE_FROM_ABI 1369_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const variant_alternative_t<_Ip, variant<_Types...>>& 1370get(const variant<_Types...>& __v) { 1371 static_assert(_Ip < sizeof...(_Types)); 1372 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 1373 return std::__generic_get<_Ip>(__v); 1374} 1375 1376template <size_t _Ip, class... _Types> 1377_LIBCPP_HIDE_FROM_ABI 1378_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& 1379get(const variant<_Types...>&& __v) { 1380 static_assert(_Ip < sizeof...(_Types)); 1381 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 1382 return std::__generic_get<_Ip>(std::move(__v)); 1383} 1384 1385template <class _Tp, class... _Types> 1386_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Tp& get(variant<_Types...>& __v) { 1387 static_assert(!is_void_v<_Tp>); 1388 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1389} 1390 1391template <class _Tp, class... _Types> 1392_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Tp&& get(variant<_Types...>&& __v) { 1393 static_assert(!is_void_v<_Tp>); 1394 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v)); 1395} 1396 1397template <class _Tp, class... _Types> 1398_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const _Tp& 1399get(const variant<_Types...>& __v) { 1400 static_assert(!is_void_v<_Tp>); 1401 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1402} 1403 1404template <class _Tp, class... _Types> 1405_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const _Tp&& 1406get(const variant<_Types...>&& __v) { 1407 static_assert(!is_void_v<_Tp>); 1408 return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v)); 1409} 1410 1411template <size_t _Ip, class _Vp> 1412_LIBCPP_HIDE_FROM_ABI constexpr auto* __generic_get_if(_Vp* __v) noexcept { 1413 using __variant_detail::__access::__variant; 1414 return __v && std::__holds_alternative<_Ip>(*__v) ? std::addressof(__variant::__get_alt<_Ip>(*__v).__value) : nullptr; 1415} 1416 1417template <size_t _Ip, class... _Types> 1418_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>> 1419get_if(variant<_Types...>* __v) noexcept { 1420 static_assert(_Ip < sizeof...(_Types)); 1421 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 1422 return std::__generic_get_if<_Ip>(__v); 1423} 1424 1425template <size_t _Ip, class... _Types> 1426_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>> 1427get_if(const variant<_Types...>* __v) noexcept { 1428 static_assert(_Ip < sizeof...(_Types)); 1429 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 1430 return std::__generic_get_if<_Ip>(__v); 1431} 1432 1433template <class _Tp, class... _Types> 1434_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __v) noexcept { 1435 static_assert(!is_void_v<_Tp>); 1436 return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1437} 1438 1439template <class _Tp, class... _Types> 1440_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const _Tp> get_if(const variant<_Types...>* __v) noexcept { 1441 static_assert(!is_void_v<_Tp>); 1442 return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1443} 1444 1445template <class _Operator> 1446struct __convert_to_bool { 1447 template <class _T1, class _T2> 1448 _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_T1&& __t1, _T2&& __t2) const { 1449 static_assert(is_convertible<decltype(_Operator{}(std::forward<_T1>(__t1), std::forward<_T2>(__t2))), bool>::value, 1450 "the relational operator does not return a type which is implicitly convertible to bool"); 1451 return _Operator{}(std::forward<_T1>(__t1), std::forward<_T2>(__t2)); 1452 } 1453}; 1454 1455template <class... _Types> 1456_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1457 using __variant_detail::__visitation::__variant; 1458 if (__lhs.index() != __rhs.index()) 1459 return false; 1460 if (__lhs.valueless_by_exception()) 1461 return true; 1462 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs); 1463} 1464 1465# if _LIBCPP_STD_VER >= 20 1466 1467template <class... _Types> 1468 requires(three_way_comparable<_Types> && ...) 1469_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...> 1470operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1471 using __variant_detail::__visitation::__variant; 1472 using __result_t = common_comparison_category_t<compare_three_way_result_t<_Types>...>; 1473 if (__lhs.valueless_by_exception() && __rhs.valueless_by_exception()) 1474 return strong_ordering::equal; 1475 if (__lhs.valueless_by_exception()) 1476 return strong_ordering::less; 1477 if (__rhs.valueless_by_exception()) 1478 return strong_ordering::greater; 1479 if (auto __c = __lhs.index() <=> __rhs.index(); __c != 0) 1480 return __c; 1481 auto __three_way = []<class _Type>(const _Type& __v, const _Type& __w) -> __result_t { return __v <=> __w; }; 1482 return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs); 1483} 1484 1485# endif // _LIBCPP_STD_VER >= 20 1486 1487template <class... _Types> 1488_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1489 using __variant_detail::__visitation::__variant; 1490 if (__lhs.index() != __rhs.index()) 1491 return true; 1492 if (__lhs.valueless_by_exception()) 1493 return false; 1494 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs); 1495} 1496 1497template <class... _Types> 1498_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1499 using __variant_detail::__visitation::__variant; 1500 if (__rhs.valueless_by_exception()) 1501 return false; 1502 if (__lhs.valueless_by_exception()) 1503 return true; 1504 if (__lhs.index() < __rhs.index()) 1505 return true; 1506 if (__lhs.index() > __rhs.index()) 1507 return false; 1508 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs); 1509} 1510 1511template <class... _Types> 1512_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1513 using __variant_detail::__visitation::__variant; 1514 if (__lhs.valueless_by_exception()) 1515 return false; 1516 if (__rhs.valueless_by_exception()) 1517 return true; 1518 if (__lhs.index() > __rhs.index()) 1519 return true; 1520 if (__lhs.index() < __rhs.index()) 1521 return false; 1522 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs); 1523} 1524 1525template <class... _Types> 1526_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1527 using __variant_detail::__visitation::__variant; 1528 if (__lhs.valueless_by_exception()) 1529 return true; 1530 if (__rhs.valueless_by_exception()) 1531 return false; 1532 if (__lhs.index() < __rhs.index()) 1533 return true; 1534 if (__lhs.index() > __rhs.index()) 1535 return false; 1536 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs); 1537} 1538 1539template <class... _Types> 1540_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { 1541 using __variant_detail::__visitation::__variant; 1542 if (__rhs.valueless_by_exception()) 1543 return true; 1544 if (__lhs.valueless_by_exception()) 1545 return false; 1546 if (__lhs.index() > __rhs.index()) 1547 return true; 1548 if (__lhs.index() < __rhs.index()) 1549 return false; 1550 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs); 1551} 1552 1553template <class... _Vs> 1554_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void __throw_if_valueless(_Vs&&... __vs) { 1555 const bool __valueless = (... || std::__as_variant(__vs).valueless_by_exception()); 1556 if (__valueless) { 1557 __throw_bad_variant_access(); 1558 } 1559} 1560 1561template < class _Visitor, class... _Vs, typename> 1562_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr decltype(auto) 1563visit(_Visitor&& __visitor, _Vs&&... __vs) { 1564 using __variant_detail::__visitation::__variant; 1565 std::__throw_if_valueless(std::forward<_Vs>(__vs)...); 1566 return __variant::__visit_value(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...); 1567} 1568 1569# if _LIBCPP_STD_VER >= 20 1570template < class _Rp, class _Visitor, class... _Vs, typename> 1571_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp 1572visit(_Visitor&& __visitor, _Vs&&... __vs) { 1573 using __variant_detail::__visitation::__variant; 1574 std::__throw_if_valueless(std::forward<_Vs>(__vs)...); 1575 return __variant::__visit_value<_Rp>(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...); 1576} 1577# endif 1578 1579template <class... _Types> 1580_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto 1581swap(variant<_Types...>& __lhs, 1582 variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) -> decltype(__lhs.swap(__rhs)) { 1583 return __lhs.swap(__rhs); 1584} 1585 1586template <class... _Types> 1587struct _LIBCPP_TEMPLATE_VIS hash< __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> { 1588 using argument_type = variant<_Types...>; 1589 using result_type = size_t; 1590 1591 _LIBCPP_HIDE_FROM_ABI result_type operator()(const argument_type& __v) const { 1592 using __variant_detail::__visitation::__variant; 1593 size_t __res = 1594 __v.valueless_by_exception() 1595 ? 299792458 // Random value chosen by the universe upon creation 1596 : __variant::__visit_alt( 1597 [](const auto& __alt) { 1598 using __alt_type = __remove_cvref_t<decltype(__alt)>; 1599 using __value_type = remove_const_t< typename __alt_type::__value_type>; 1600 return hash<__value_type>{}(__alt.__value); 1601 }, 1602 __v); 1603 return std::__hash_combine(__res, hash<size_t>{}(__v.index())); 1604 } 1605}; 1606 1607// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong 1608// type whereas std::get will throw or returning nullptr. This makes it faster than 1609// std::get. 1610template <size_t _Ip, class _Vp> 1611_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(_Vp&& __v) noexcept { 1612 using __variant_detail::__access::__variant; 1613 return __variant::__get_alt<_Ip>(std::forward<_Vp>(__v)).__value; 1614} 1615 1616template <class _Tp, class... _Types> 1617_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept { 1618 return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1619} 1620 1621template <class _Tp, class... _Types> 1622_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept { 1623 return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 1624} 1625 1626# endif // _LIBCPP_STD_VER >= 17 1627 1628_LIBCPP_END_NAMESPACE_STD 1629 1630_LIBCPP_POP_MACROS 1631 1632# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1633# include <cstddef> 1634# include <exception> 1635# include <tuple> 1636# include <type_traits> 1637# include <typeinfo> 1638# include <utility> 1639# endif 1640#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 1641 1642#endif // _LIBCPP_VARIANT 1643