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#include <__compare/common_comparison_category.h> 216#include <__compare/compare_three_way_result.h> 217#include <__compare/ordering.h> 218#include <__compare/three_way_comparable.h> 219#include <__config> 220#include <__exception/exception.h> 221#include <__functional/hash.h> 222#include <__functional/operations.h> 223#include <__functional/unary_function.h> 224#include <__fwd/variant.h> 225#include <__memory/addressof.h> 226#include <__memory/construct_at.h> 227#include <__tuple/find_index.h> 228#include <__tuple/sfinae_helpers.h> 229#include <__type_traits/add_cv_quals.h> 230#include <__type_traits/add_pointer.h> 231#include <__type_traits/common_type.h> 232#include <__type_traits/conditional.h> 233#include <__type_traits/conjunction.h> 234#include <__type_traits/decay.h> 235#include <__type_traits/dependent_type.h> 236#include <__type_traits/enable_if.h> 237#include <__type_traits/invoke.h> 238#include <__type_traits/is_array.h> 239#include <__type_traits/is_assignable.h> 240#include <__type_traits/is_constructible.h> 241#include <__type_traits/is_convertible.h> 242#include <__type_traits/is_destructible.h> 243#include <__type_traits/is_nothrow_assignable.h> 244#include <__type_traits/is_nothrow_constructible.h> 245#include <__type_traits/is_reference.h> 246#include <__type_traits/is_same.h> 247#include <__type_traits/is_swappable.h> 248#include <__type_traits/is_trivially_assignable.h> 249#include <__type_traits/is_trivially_constructible.h> 250#include <__type_traits/is_trivially_destructible.h> 251#include <__type_traits/is_trivially_relocatable.h> 252#include <__type_traits/is_void.h> 253#include <__type_traits/remove_const.h> 254#include <__type_traits/remove_cvref.h> 255#include <__type_traits/remove_reference.h> 256#include <__type_traits/type_identity.h> 257#include <__type_traits/void_t.h> 258#include <__utility/declval.h> 259#include <__utility/forward.h> 260#include <__utility/forward_like.h> 261#include <__utility/in_place.h> 262#include <__utility/integer_sequence.h> 263#include <__utility/move.h> 264#include <__utility/swap.h> 265#include <__variant/monostate.h> 266#include <__verbose_abort> 267#include <initializer_list> 268#include <limits> 269#include <new> 270#include <version> 271 272// standard-mandated includes 273 274// [variant.syn] 275#include <compare> 276 277#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 278# pragma GCC system_header 279#endif 280 281_LIBCPP_PUSH_MACROS 282#include <__undef_macros> 283 284namespace std { // explicitly not using versioning namespace 285 286class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { 287public: 288 const char* what() const _NOEXCEPT override; 289}; 290 291} // namespace std 292 293_LIBCPP_BEGIN_NAMESPACE_STD 294 295#if _LIBCPP_STD_VER >= 17 296 297// Light N-dimensional array of function pointers. Used in place of std::array to avoid 298// adding a dependency. 299template <class _Tp, size_t _Size> 300struct __farray { 301 static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit"); 302 _Tp __buf_[_Size] = {}; 303 304 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __n) const noexcept { return __buf_[__n]; } 305}; 306 307[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS void 308__throw_bad_variant_access() { 309# if _LIBCPP_HAS_EXCEPTIONS 310 throw bad_variant_access(); 311# else 312 _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode"); 313# endif 314} 315 316// variant_size 317template <class _Tp> 318struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {}; 319 320template <class _Tp> 321struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {}; 322 323template <class _Tp> 324struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp> : variant_size<_Tp> {}; 325 326template <class... _Types> 327struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>> : integral_constant<size_t, sizeof...(_Types)> {}; 328 329// variant_alternative 330template <size_t _Ip, class _Tp> 331struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp> : add_const<variant_alternative_t<_Ip, _Tp>> {}; 332 333template <size_t _Ip, class _Tp> 334struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp> : add_volatile<variant_alternative_t<_Ip, _Tp>> {}; 335 336template <size_t _Ip, class _Tp> 337struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp> : add_cv<variant_alternative_t<_Ip, _Tp>> {}; 338 339template <size_t _Ip, class... _Types> 340struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> { 341 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>"); 342 using type = __type_pack_element<_Ip, _Types...>; 343}; 344 345template <size_t _NumAlternatives> 346_LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() { 347# ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION 348 if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max()) 349 return static_cast<unsigned char>(0); 350 else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max()) 351 return static_cast<unsigned short>(0); 352 else 353# endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION 354 return static_cast<unsigned int>(0); 355} 356 357template <size_t _NumAlts> 358using __variant_index_t = decltype(std::__choose_index_type<_NumAlts>()); 359 360template <class _IndexType> 361constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1); 362 363template <class... _Types> 364_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>& __as_variant(variant<_Types...>& __vs) noexcept { 365 return __vs; 366} 367 368template <class... _Types> 369_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>& __as_variant(const variant<_Types...>& __vs) noexcept { 370 return __vs; 371} 372 373template <class... _Types> 374_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>&& __as_variant(variant<_Types...>&& __vs) noexcept { 375 return std::move(__vs); 376} 377 378template <class... _Types> 379_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>&& __as_variant(const variant<_Types...>&& __vs) noexcept { 380 return std::move(__vs); 381} 382 383namespace __find_detail { 384 385template <class _Tp, class... _Types> 386_LIBCPP_HIDE_FROM_ABI constexpr size_t __find_index() { 387 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...}; 388 size_t __result = __not_found; 389 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) { 390 if (__matches[__i]) { 391 if (__result != __not_found) { 392 return __ambiguous; 393 } 394 __result = __i; 395 } 396 } 397 return __result; 398} 399 400template <size_t _Index> 401struct __find_unambiguous_index_sfinae_impl : integral_constant<size_t, _Index> {}; 402 403template <> 404struct __find_unambiguous_index_sfinae_impl<__not_found> {}; 405 406template <> 407struct __find_unambiguous_index_sfinae_impl<__ambiguous> {}; 408 409template <class _Tp, class... _Types> 410struct __find_unambiguous_index_sfinae : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {}; 411 412} // namespace __find_detail 413 414namespace __variant_detail { 415 416struct __valueless_t {}; 417 418enum class _Trait { _TriviallyAvailable, _Available, _Unavailable }; 419 420template <typename _Tp, template <typename> class _IsTriviallyAvailable, template <typename> class _IsAvailable> 421constexpr _Trait __trait = 422 _IsTriviallyAvailable<_Tp>::value ? _Trait::_TriviallyAvailable 423 : _IsAvailable<_Tp>::value 424 ? _Trait::_Available 425 : _Trait::_Unavailable; 426 427_LIBCPP_HIDE_FROM_ABI constexpr _Trait __common_trait(initializer_list<_Trait> __traits) { 428 _Trait __result = _Trait::_TriviallyAvailable; 429 for (_Trait __t : __traits) { 430 if (static_cast<int>(__t) > static_cast<int>(__result)) { 431 __result = __t; 432 } 433 } 434 return __result; 435} 436 437template <typename... _Types> 438struct __traits { 439 static constexpr _Trait __copy_constructible_trait = 440 __variant_detail::__common_trait({__trait<_Types, is_trivially_copy_constructible, is_copy_constructible>...}); 441 442 static constexpr _Trait __move_constructible_trait = 443 __variant_detail::__common_trait({__trait<_Types, is_trivially_move_constructible, is_move_constructible>...}); 444 445 static constexpr _Trait __copy_assignable_trait = __variant_detail::__common_trait( 446 {__copy_constructible_trait, __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...}); 447 448 static constexpr _Trait __move_assignable_trait = __variant_detail::__common_trait( 449 {__move_constructible_trait, __trait<_Types, is_trivially_move_assignable, is_move_assignable>...}); 450 451 static constexpr _Trait __destructible_trait = 452 __variant_detail::__common_trait({__trait<_Types, is_trivially_destructible, is_destructible>...}); 453}; 454 455namespace __access { 456 457struct __union { 458 template <class _Vp> 459 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) { 460 return std::forward<_Vp>(__v).__head; 461 } 462 463 template <class _Vp, size_t _Ip> 464 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) { 465 return __get_alt(std::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>); 466 } 467}; 468 469struct __base { 470 template <size_t _Ip, class _Vp> 471 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) { 472 return __union::__get_alt(std::forward<_Vp>(__v).__data, in_place_index<_Ip>); 473 } 474}; 475 476struct __variant { 477 template <size_t _Ip, class _Vp> 478 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) { 479 return __base::__get_alt<_Ip>(std::forward<_Vp>(__v).__impl_); 480 } 481}; 482 483} // namespace __access 484 485namespace __visitation { 486 487struct __base { 488 template <class _Visitor, class... _Vs> 489 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) 490 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 491 constexpr auto __fdiagonal = __make_fdiagonal<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>(); 492 return __fdiagonal[__index](std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...); 493 } 494 495 template <class _Visitor, class... _Vs> 496 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) { 497 constexpr auto __fmatrix = __make_fmatrix<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>(); 498 return __at(__fmatrix, __vs.index()...)(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...); 499 } 500 501private: 502 template <class _Tp> 503 _LIBCPP_HIDE_FROM_ABI static constexpr const _Tp& __at(const _Tp& __elem) { 504 return __elem; 505 } 506 507 template <class _Tp, size_t _Np, typename... _Indices> 508 _LIBCPP_HIDE_FROM_ABI static constexpr auto&& 509 __at(const __farray<_Tp, _Np>& __elems, size_t __index, _Indices... __indices) { 510 return __at(__elems[__index], __indices...); 511 } 512 513 template <class _Fp, class... _Fs> 514 static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() { 515 static_assert( 516 __all<is_same_v<_Fp, _Fs>...>::value, "`std::visit` requires the visitor to have a single return type."); 517 } 518 519 template <class... _Fs> 520 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_farray(_Fs&&... __fs) { 521 __std_visit_visitor_return_type_check<__remove_cvref_t<_Fs>...>(); 522 using __result = __farray<common_type_t<__remove_cvref_t<_Fs>...>, sizeof...(_Fs)>; 523 return __result{{std::forward<_Fs>(__fs)...}}; 524 } 525 526 template <size_t... _Is> 527 struct __dispatcher { 528 template <class _Fp, class... _Vs> 529 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) { 530 return std::__invoke(static_cast<_Fp>(__f), __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...); 531 } 532 }; 533 534 template <class _Fp, class... _Vs, size_t... _Is> 535 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_dispatch(index_sequence<_Is...>) { 536 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>; 537 } 538 539 template <size_t _Ip, class _Fp, class... _Vs> 540 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl() { 541 return __make_dispatch<_Fp, _Vs...>(index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{}); 542 } 543 544 template <class _Fp, class... _Vs, size_t... _Is> 545 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) { 546 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...); 547 } 548 549 template <class _Fp, class _Vp, class... _Vs> 550 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal() { 551 constexpr size_t __np = __remove_cvref_t<_Vp>::__size(); 552 static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value); 553 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{}); 554 } 555 556 template <class _Fp, class... _Vs, size_t... _Is> 557 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) { 558 return __make_dispatch<_Fp, _Vs...>(__is); 559 } 560 561 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls> 562 _LIBCPP_HIDE_FROM_ABI static constexpr auto 563 __make_fmatrix_impl(index_sequence<_Is...>, index_sequence<_Js...>, _Ls... __ls) { 564 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(index_sequence<_Is..., _Js>{}, __ls...)...); 565 } 566 567 template <class _Fp, class... _Vs> 568 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix() { 569 return __make_fmatrix_impl<_Fp, _Vs...>( 570 index_sequence<>{}, make_index_sequence<__remove_cvref_t<_Vs>::__size()>{}...); 571 } 572}; 573 574struct __variant { 575 template <class _Visitor, class... _Vs> 576 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) 577 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 578 return __base::__visit_alt_at(__index, std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__impl_...); 579 } 580 581 template <class _Visitor, class... _Vs> 582 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) { 583 return __base::__visit_alt( 584 std::forward<_Visitor>(__visitor), std::__as_variant(std::forward<_Vs>(__vs)).__impl_...); 585 } 586 587 template <class _Visitor, class... _Vs> 588 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) 589 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 590 return __visit_alt_at(__index, __make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...); 591 } 592 593 template <class _Visitor, class... _Vs> 594 _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, _Vs&&... __vs) { 595 return __visit_alt(__make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...); 596 } 597 598# if _LIBCPP_STD_VER >= 20 599 template <class _Rp, class _Visitor, class... _Vs> 600 _LIBCPP_HIDE_FROM_ABI static constexpr _Rp __visit_value(_Visitor&& __visitor, _Vs&&... __vs) { 601 return __visit_alt(__make_value_visitor<_Rp>(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...); 602 } 603# endif 604 605private: 606 template <class _Visitor, class... _Values> 607 static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() { 608 static_assert(is_invocable_v<_Visitor, _Values...>, "`std::visit` requires the visitor to be exhaustive."); 609 } 610 611 template <class _Visitor> 612 struct __value_visitor { 613 template <class... _Alts> 614 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Alts&&... __alts) const { 615 __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>(); 616 return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...); 617 } 618 _Visitor&& __visitor; 619 }; 620 621# if _LIBCPP_STD_VER >= 20 622 template <class _Rp, class _Visitor> 623 struct __value_visitor_return_type { 624 template <class... _Alts> 625 _LIBCPP_HIDE_FROM_ABI constexpr _Rp operator()(_Alts&&... __alts) const { 626 __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>(); 627 if constexpr (is_void_v<_Rp>) { 628 std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...); 629 } else { 630 return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...); 631 } 632 } 633 634 _Visitor&& __visitor; 635 }; 636# endif 637 638 template <class _Visitor> 639 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) { 640 return __value_visitor<_Visitor>{std::forward<_Visitor>(__visitor)}; 641 } 642 643# if _LIBCPP_STD_VER >= 20 644 template <class _Rp, class _Visitor> 645 _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) { 646 return __value_visitor_return_type<_Rp, _Visitor>{std::forward<_Visitor>(__visitor)}; 647 } 648# endif 649}; 650 651} // namespace __visitation 652 653// Adding semi-colons in macro expansions helps clang-format to do a better job. 654// This macro is used to avoid compilation errors due to "stray" semi-colons. 655# define _LIBCPP_EAT_SEMICOLON static_assert(true, "") 656 657template <size_t _Index, class _Tp> 658struct _LIBCPP_TEMPLATE_VIS __alt { 659 using __value_type = _Tp; 660 static constexpr size_t __index = _Index; 661 662 template <class... _Args> 663 _LIBCPP_HIDE_FROM_ABI explicit constexpr __alt(in_place_t, _Args&&... __args) 664 : __value(std::forward<_Args>(__args)...) {} 665 666 __value_type __value; 667}; 668 669template <_Trait _DestructibleTrait, size_t _Index, class... _Types> 670union _LIBCPP_TEMPLATE_VIS __union; 671 672template <_Trait _DestructibleTrait, size_t _Index> 673union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {}; 674 675# define _LIBCPP_VARIANT_UNION(destructible_trait, destructor_definition) \ 676 template <size_t _Index, class _Tp, class... _Types> \ 677 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, _Index, _Tp, _Types...> { \ 678 public: \ 679 _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \ 680 \ 681 template <class... _Args> \ 682 _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \ 683 : __head(in_place, std::forward<_Args>(__args)...) {} \ 684 \ 685 template <size_t _Ip, class... _Args> \ 686 _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \ 687 : __tail(in_place_index<_Ip - 1>, std::forward<_Args>(__args)...) {} \ 688 \ 689 _LIBCPP_HIDE_FROM_ABI __union(const __union&) = default; \ 690 _LIBCPP_HIDE_FROM_ABI __union(__union&&) = default; \ 691 _LIBCPP_HIDE_FROM_ABI __union& operator=(const __union&) = default; \ 692 _LIBCPP_HIDE_FROM_ABI __union& operator=(__union&&) = default; \ 693 destructor_definition; \ 694 \ 695 private: \ 696 char __dummy; \ 697 __alt<_Index, _Tp> __head; \ 698 __union<destructible_trait, _Index + 1, _Types...> __tail; \ 699 \ 700 friend struct __access::__union; \ 701 } 702 703_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, 704 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = default); 705_LIBCPP_VARIANT_UNION( 706 _Trait::_Available, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() {} _LIBCPP_EAT_SEMICOLON); 707_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = delete); 708 709# undef _LIBCPP_VARIANT_UNION 710 711template <_Trait _DestructibleTrait, class... _Types> 712class _LIBCPP_TEMPLATE_VIS __base { 713public: 714 using __index_t = __variant_index_t<sizeof...(_Types)>; 715 716 _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(__valueless_t __tag) noexcept 717 : __data(__tag), __index(__variant_npos<__index_t>) {} 718 719 template <size_t _Ip, class... _Args> 720 _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args) 721 : __data(in_place_index<_Ip>, std::forward<_Args>(__args)...), __index(_Ip) {} 722 723 _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept { return index() == variant_npos; } 724 725 _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { 726 return __index == __variant_npos<__index_t> ? variant_npos : __index; 727 } 728 729protected: 730 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() & { return *this; } 731 732 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() && { return std::move(*this); } 733 734 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const& { return *this; } 735 736 _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const&& { return std::move(*this); } 737 738 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Types); } 739 740 __union<_DestructibleTrait, 0, _Types...> __data; 741 __index_t __index; 742 743 friend struct __access::__base; 744 friend struct __visitation::__base; 745}; 746 747template <class _Traits, _Trait = _Traits::__destructible_trait> 748class _LIBCPP_TEMPLATE_VIS __dtor; 749 750# define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor_definition, destroy) \ 751 template <class... _Types> \ 752 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, destructible_trait> \ 753 : public __base<destructible_trait, _Types...> { \ 754 using __base_type = __base<destructible_trait, _Types...>; \ 755 using __index_t = typename __base_type::__index_t; \ 756 \ 757 public: \ 758 using __base_type::__base_type; \ 759 using __base_type::operator=; \ 760 _LIBCPP_HIDE_FROM_ABI __dtor(const __dtor&) = default; \ 761 _LIBCPP_HIDE_FROM_ABI __dtor(__dtor&&) = default; \ 762 _LIBCPP_HIDE_FROM_ABI __dtor& operator=(const __dtor&) = default; \ 763 _LIBCPP_HIDE_FROM_ABI __dtor& operator=(__dtor&&) = default; \ 764 destructor_definition; \ 765 \ 766 protected: \ 767 destroy; \ 768 } 769 770_LIBCPP_VARIANT_DESTRUCTOR( 771 _Trait::_TriviallyAvailable, 772 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = default, 773 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept { 774 this->__index = __variant_npos<__index_t>; 775 } _LIBCPP_EAT_SEMICOLON); 776 777_LIBCPP_VARIANT_DESTRUCTOR( 778 _Trait::_Available, 779 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() { __destroy(); } _LIBCPP_EAT_SEMICOLON, 780 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept { 781 if (!this->valueless_by_exception()) { 782 __visitation::__base::__visit_alt( 783 [](auto& __alt) noexcept { 784 using __alt_type = __remove_cvref_t<decltype(__alt)>; 785 __alt.~__alt_type(); 786 }, 787 *this); 788 } 789 this->__index = __variant_npos<__index_t>; 790 } _LIBCPP_EAT_SEMICOLON); 791 792_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, 793 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = delete, 794 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept = delete); 795 796# undef _LIBCPP_VARIANT_DESTRUCTOR 797 798template <class _Traits> 799class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> { 800 using __base_type = __dtor<_Traits>; 801 802public: 803 using __base_type::__base_type; 804 using __base_type::operator=; 805 806protected: 807 template <class _Rhs> 808 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) { 809 __lhs.__destroy(); 810 if (!__rhs.valueless_by_exception()) { 811 auto __rhs_index = __rhs.index(); 812 __visitation::__base::__visit_alt_at( 813 __rhs_index, 814 [&__lhs](auto&& __rhs_alt) { 815 std::__construct_at(std::addressof(__lhs.__data), 816 in_place_index<__decay_t<decltype(__rhs_alt)>::__index>, 817 std::forward<decltype(__rhs_alt)>(__rhs_alt).__value); 818 }, 819 std::forward<_Rhs>(__rhs)); 820 __lhs.__index = __rhs_index; 821 } 822 } 823}; 824 825template <class _Traits, _Trait = _Traits::__move_constructible_trait> 826class _LIBCPP_TEMPLATE_VIS __move_constructor; 827 828# define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, move_constructor_definition) \ 829 template <class... _Types> \ 830 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, move_constructible_trait> \ 831 : public __ctor<__traits<_Types...>> { \ 832 using __base_type = __ctor<__traits<_Types...>>; \ 833 \ 834 public: \ 835 using __base_type::__base_type; \ 836 using __base_type::operator=; \ 837 \ 838 _LIBCPP_HIDE_FROM_ABI __move_constructor(const __move_constructor&) = default; \ 839 _LIBCPP_HIDE_FROM_ABI ~__move_constructor() = default; \ 840 _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(const __move_constructor&) = default; \ 841 _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(__move_constructor&&) = default; \ 842 move_constructor_definition; \ 843 } 844 845_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 846 _Trait::_TriviallyAvailable, 847 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) = default); 848 849_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 850 _Trait::_Available, 851 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) noexcept( 852 __all<is_nothrow_move_constructible_v<_Types>...>::value) 853 : __move_constructor(__valueless_t{}) { 854 this->__generic_construct(*this, std::move(__that)); 855 } _LIBCPP_EAT_SEMICOLON); 856 857_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 858 _Trait::_Unavailable, 859 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&&) = delete); 860 861# undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR 862 863template <class _Traits, _Trait = _Traits::__copy_constructible_trait> 864class _LIBCPP_TEMPLATE_VIS __copy_constructor; 865 866# define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, copy_constructor_definition) \ 867 template <class... _Types> \ 868 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, copy_constructible_trait> \ 869 : public __move_constructor<__traits<_Types...>> { \ 870 using __base_type = __move_constructor<__traits<_Types...>>; \ 871 \ 872 public: \ 873 using __base_type::__base_type; \ 874 using __base_type::operator=; \ 875 \ 876 _LIBCPP_HIDE_FROM_ABI __copy_constructor(__copy_constructor&&) = default; \ 877 _LIBCPP_HIDE_FROM_ABI ~__copy_constructor() = default; \ 878 _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(const __copy_constructor&) = default; \ 879 _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(__copy_constructor&&) = default; \ 880 copy_constructor_definition; \ 881 } 882 883_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 884 _Trait::_TriviallyAvailable, 885 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) = default); 886 887_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 888 _Trait::_Available, 889 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) 890 : __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON); 891 892_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 893 _Trait::_Unavailable, 894 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor&) = delete); 895 896# undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR 897 898template <class _Traits> 899class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> { 900 using __base_type = __copy_constructor<_Traits>; 901 902public: 903 using __base_type::__base_type; 904 using __base_type::operator=; 905 906 template <size_t _Ip, class... _Args> 907 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto& __emplace(_Args&&... __args) { 908 this->__destroy(); 909 std::__construct_at(std::addressof(this->__data), in_place_index<_Ip>, std::forward<_Args>(__args)...); 910 this->__index = _Ip; 911 return __access::__base::__get_alt<_Ip>(*this).__value; 912 } 913 914protected: 915 template <size_t _Ip, class _Tp, class _Arg> 916 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) { 917 if (this->index() == _Ip) { 918 __a.__value = std::forward<_Arg>(__arg); 919 } else { 920 struct { 921 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(true_type) const { 922 __this->__emplace<_Ip>(std::forward<_Arg>(__arg)); 923 } 924 _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(false_type) const { 925 __this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg))); 926 } 927 __assignment* __this; 928 _Arg&& __arg; 929 } __impl{this, std::forward<_Arg>(__arg)}; 930 __impl(bool_constant < is_nothrow_constructible_v<_Tp, _Arg> || !is_nothrow_move_constructible_v < _Tp >> {}); 931 } 932 } 933 934 template <class _That> 935 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_assign(_That&& __that) { 936 if (this->valueless_by_exception() && __that.valueless_by_exception()) { 937 // do nothing. 938 } else if (__that.valueless_by_exception()) { 939 this->__destroy(); 940 } else { 941 __visitation::__base::__visit_alt_at( 942 __that.index(), 943 [this](auto& __this_alt, auto&& __that_alt) { 944 this->__assign_alt(__this_alt, std::forward<decltype(__that_alt)>(__that_alt).__value); 945 }, 946 *this, 947 std::forward<_That>(__that)); 948 } 949 } 950}; 951 952template <class _Traits, _Trait = _Traits::__move_assignable_trait> 953class _LIBCPP_TEMPLATE_VIS __move_assignment; 954 955# define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, move_assignment_definition) \ 956 template <class... _Types> \ 957 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, move_assignable_trait> \ 958 : public __assignment<__traits<_Types...>> { \ 959 using __base_type = __assignment<__traits<_Types...>>; \ 960 \ 961 public: \ 962 using __base_type::__base_type; \ 963 using __base_type::operator=; \ 964 \ 965 _LIBCPP_HIDE_FROM_ABI __move_assignment(const __move_assignment&) = default; \ 966 _LIBCPP_HIDE_FROM_ABI __move_assignment(__move_assignment&&) = default; \ 967 _LIBCPP_HIDE_FROM_ABI ~__move_assignment() = default; \ 968 _LIBCPP_HIDE_FROM_ABI __move_assignment& operator=(const __move_assignment&) = default; \ 969 move_assignment_definition; \ 970 } 971 972_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_TriviallyAvailable, 973 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=( 974 __move_assignment&& __that) = default); 975 976_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 977 _Trait::_Available, 978 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& 979 operator=(__move_assignment&& __that) noexcept( 980 __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_move_assignable_v<_Types>)...>::value) { 981 this->__generic_assign(std::move(__that)); 982 return *this; 983 } _LIBCPP_EAT_SEMICOLON); 984 985_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 986 _Trait::_Unavailable, 987 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(__move_assignment&&) = delete); 988 989# undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT 990 991template <class _Traits, _Trait = _Traits::__copy_assignable_trait> 992class _LIBCPP_TEMPLATE_VIS __copy_assignment; 993 994# define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, copy_assignment_definition) \ 995 template <class... _Types> \ 996 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, copy_assignable_trait> \ 997 : public __move_assignment<__traits<_Types...>> { \ 998 using __base_type = __move_assignment<__traits<_Types...>>; \ 999 \ 1000 public: \ 1001 using __base_type::__base_type; \ 1002 using __base_type::operator=; \ 1003 \ 1004 _LIBCPP_HIDE_FROM_ABI __copy_assignment(const __copy_assignment&) = default; \ 1005 _LIBCPP_HIDE_FROM_ABI __copy_assignment(__copy_assignment&&) = default; \ 1006 _LIBCPP_HIDE_FROM_ABI ~__copy_assignment() = default; \ 1007 _LIBCPP_HIDE_FROM_ABI __copy_assignment& operator=(__copy_assignment&&) = default; \ 1008 copy_assignment_definition; \ 1009 } 1010 1011_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_TriviallyAvailable, 1012 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=( 1013 const __copy_assignment& __that) = default); 1014 1015_LIBCPP_VARIANT_COPY_ASSIGNMENT( 1016 _Trait::_Available, 1017 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& 1018 operator=(const __copy_assignment& __that) { 1019 this->__generic_assign(__that); 1020 return *this; 1021 } _LIBCPP_EAT_SEMICOLON); 1022 1023_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable, 1024 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=( 1025 const __copy_assignment&) = delete); 1026 1027# undef _LIBCPP_VARIANT_COPY_ASSIGNMENT 1028 1029template <class... _Types> 1030class _LIBCPP_TEMPLATE_VIS __impl : public __copy_assignment<__traits<_Types...>> { 1031 using __base_type = __copy_assignment<__traits<_Types...>>; 1032 1033public: 1034 using __base_type::__base_type; // get in_place_index_t constructor & friends 1035 _LIBCPP_HIDE_FROM_ABI __impl(__impl const&) = default; 1036 _LIBCPP_HIDE_FROM_ABI __impl(__impl&&) = default; 1037 _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default; 1038 _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&) = default; 1039 1040 template <size_t _Ip, class _Arg> 1041 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign(_Arg&& __arg) { 1042 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), std::forward<_Arg>(__arg)); 1043 } 1044 1045 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__impl& __that) { 1046 if (this->valueless_by_exception() && __that.valueless_by_exception()) { 1047 // do nothing. 1048 } else if (this->index() == __that.index()) { 1049 __visitation::__base::__visit_alt_at( 1050 this->index(), 1051 [](auto& __this_alt, auto& __that_alt) { 1052 using std::swap; 1053 swap(__this_alt.__value, __that_alt.__value); 1054 }, 1055 *this, 1056 __that); 1057 } else { 1058 __impl* __lhs = this; 1059 __impl* __rhs = std::addressof(__that); 1060 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) { 1061 std::swap(__lhs, __rhs); 1062 } 1063 __impl __tmp(std::move(*__rhs)); 1064# if _LIBCPP_HAS_EXCEPTIONS 1065 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) { 1066 this->__generic_construct(*__rhs, std::move(*__lhs)); 1067 } else { 1068 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws 1069 // and `__tmp` is nothrow move constructible then we move `__tmp` back 1070 // into `__rhs` and provide the strong exception safety guarantee. 1071 try { 1072 this->__generic_construct(*__rhs, std::move(*__lhs)); 1073 } catch (...) { 1074 if (__tmp.__move_nothrow()) { 1075 this->__generic_construct(*__rhs, std::move(__tmp)); 1076 } 1077 throw; 1078 } 1079 } 1080# else 1081 // this isn't consolidated with the `if constexpr` branch above due to 1082 // `throw` being ill-formed with exceptions disabled even when discarded. 1083 this->__generic_construct(*__rhs, std::move(*__lhs)); 1084# endif 1085 this->__generic_construct(*__lhs, std::move(__tmp)); 1086 } 1087 } 1088 1089private: 1090 constexpr inline _LIBCPP_HIDE_FROM_ABI bool __move_nothrow() const { 1091 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...}; 1092 return this->valueless_by_exception() || __results[this->index()]; 1093 } 1094}; 1095 1096struct __no_narrowing_check { 1097 template <class _Dest, class _Source> 1098 using _Apply = __type_identity<_Dest>; 1099}; 1100 1101struct __narrowing_check { 1102 template <class _Dest> 1103 static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>; 1104 template <class _Dest, class _Source> 1105 using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({std::declval<_Source>()})); 1106}; 1107 1108template <class _Dest, class _Source> 1109using __check_for_narrowing _LIBCPP_NODEBUG = 1110 typename _If< is_arithmetic<_Dest>::value, __narrowing_check, __no_narrowing_check >::template _Apply<_Dest, 1111 _Source>; 1112 1113template <class _Tp, size_t _Idx> 1114struct __overload { 1115 template <class _Up> 1116 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>; 1117}; 1118 1119template <class... _Bases> 1120struct __all_overloads : _Bases... { 1121 void operator()() const; 1122 using _Bases::operator()...; 1123}; 1124 1125template <class _IdxSeq> 1126struct __make_overloads_imp; 1127 1128template <size_t... _Idx> 1129struct __make_overloads_imp<__tuple_indices<_Idx...> > { 1130 template <class... _Types> 1131 using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>; 1132}; 1133 1134template <class... _Types> 1135using _MakeOverloads _LIBCPP_NODEBUG = 1136 typename __make_overloads_imp< __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>; 1137 1138template <class _Tp, class... _Types> 1139using __best_match_t = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type; 1140 1141} // namespace __variant_detail 1142 1143template <class _Visitor, class... _Vs, typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>> 1144_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr decltype(auto) 1145visit(_Visitor&& __visitor, _Vs&&... __vs); 1146 1147# if _LIBCPP_STD_VER >= 20 1148template <class _Rp, 1149 class _Visitor, 1150 class... _Vs, 1151 typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>> 1152_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp 1153visit(_Visitor&& __visitor, _Vs&&... __vs); 1154# endif 1155 1156template <class... _Types> 1157class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant 1158 : private __sfinae_ctor_base< __all<is_copy_constructible_v<_Types>...>::value, 1159 __all<is_move_constructible_v<_Types>...>::value>, 1160 private __sfinae_assign_base< 1161 __all<(is_copy_constructible_v<_Types> && is_copy_assignable_v<_Types>)...>::value, 1162 __all<(is_move_constructible_v<_Types> && is_move_assignable_v<_Types>)...>::value> { 1163 static_assert(0 < sizeof...(_Types), "variant must consist of at least one alternative."); 1164 1165 static_assert(__all<!is_array_v<_Types>...>::value, "variant can not have an array type as an alternative."); 1166 1167 static_assert(__all<!is_reference_v<_Types>...>::value, "variant can not have a reference type as an alternative."); 1168 1169 static_assert(__all<!is_void_v<_Types>...>::value, "variant can not have a void type as an alternative."); 1170 1171 using __first_type = variant_alternative_t<0, variant>; 1172 1173public: 1174 using __trivially_relocatable = 1175 conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>; 1176 1177 template <bool _Dummy = true, 1178 enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0> 1179 _LIBCPP_HIDE_FROM_ABI constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) 1180 : __impl_(in_place_index<0>) {} 1181 1182 _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default; 1183 _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&) = default; 1184 1185 template < class _Arg, 1186 enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0, 1187 enable_if_t<!__is_inplace_type<__remove_cvref_t<_Arg>>::value, int> = 0, 1188 enable_if_t<!__is_inplace_index<__remove_cvref_t<_Arg>>::value, int> = 0, 1189 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, 1190 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1191 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0> 1192 _LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>) 1193 : __impl_(in_place_index<_Ip>, std::forward<_Arg>(__arg)) {} 1194 1195 template <size_t _Ip, 1196 class... _Args, 1197 class = enable_if_t<(_Ip < sizeof...(_Types)), int>, 1198 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1199 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1200 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_index_t<_Ip>, _Args&&... __args) noexcept( 1201 is_nothrow_constructible_v<_Tp, _Args...>) 1202 : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {} 1203 1204 template < size_t _Ip, 1205 class _Up, 1206 class... _Args, 1207 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1208 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1209 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1210 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant( 1211 in_place_index_t<_Ip>, 1212 initializer_list<_Up> __il, 1213 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) 1214 : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {} 1215 1216 template < class _Tp, 1217 class... _Args, 1218 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1219 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1220 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept( 1221 is_nothrow_constructible_v<_Tp, _Args...>) 1222 : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {} 1223 1224 template < class _Tp, 1225 class _Up, 1226 class... _Args, 1227 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1228 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1229 _LIBCPP_HIDE_FROM_ABI explicit constexpr variant( 1230 in_place_type_t<_Tp>, 1231 initializer_list<_Up> __il, 1232 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>) 1233 : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {} 1234 1235 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~variant() = default; 1236 1237 _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default; 1238 _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&) = default; 1239 1240 template < class _Arg, 1241 enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0, 1242 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, 1243 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1244 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, int> = 0> 1245 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 variant& 1246 operator=(_Arg&& __arg) noexcept(is_nothrow_assignable_v<_Tp&, _Arg> && is_nothrow_constructible_v<_Tp, _Arg>) { 1247 __impl_.template __assign<_Ip>(std::forward<_Arg>(__arg)); 1248 return *this; 1249 } 1250 1251 template < size_t _Ip, 1252 class... _Args, 1253 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1254 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1255 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1256 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) { 1257 return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...); 1258 } 1259 1260 template < size_t _Ip, 1261 class _Up, 1262 class... _Args, 1263 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1264 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1265 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1266 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { 1267 return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...); 1268 } 1269 1270 template < class _Tp, 1271 class... _Args, 1272 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1273 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 1274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) { 1275 return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...); 1276 } 1277 1278 template < class _Tp, 1279 class _Up, 1280 class... _Args, 1281 size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 1282 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0> 1283 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { 1284 return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...); 1285 } 1286 1287 _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept { 1288 return __impl_.valueless_by_exception(); 1289 } 1290 1291 _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { return __impl_.index(); } 1292 1293 template < bool _Dummy = true, 1294 enable_if_t< __all<(__dependent_type<is_move_constructible<_Types>, _Dummy>::value && 1295 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value, 1296 int> = 0> 1297 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(variant& __that) noexcept( 1298 __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_swappable_v<_Types>)...>::value) { 1299 __impl_.__swap(__that.__impl_); 1300 } 1301 1302# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 1303 // Helper class to implement [variant.visit]/10 1304 // Constraints: The call to visit does not use an explicit template-argument-list 1305 // that begins with a type template-argument. 1306 struct __variant_visit_barrier_tag { 1307 _LIBCPP_HIDE_FROM_ABI explicit __variant_visit_barrier_tag() = default; 1308 }; 1309 1310 template <__variant_visit_barrier_tag = __variant_visit_barrier_tag{}, class _Self, class _Visitor> 1311 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor) { 1312 using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>; 1313 return std::visit(std::forward<_Visitor>(__visitor), (_VariantT)__self); 1314 } 1315 1316 template <class _Rp, class _Self, class _Visitor> 1317 _LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(this _Self&& __self, _Visitor&& __visitor) { 1318 using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>; 1319 return std::visit<_Rp>(std::forward<_Visitor>(__visitor), (_VariantT)__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 1641#endif // _LIBCPP_VARIANT 1642