codekingpro/portable-devtools
114k
1// -*- C++ -*-2//===------------------------------ variant -------------------------------===//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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCUDACXX_VARIANT11#define _LIBCUDACXX_VARIANT12 13/*14 variant synopsis15 16namespace std {17 18 // 20.7.2, class template variant19 template <class... Types>20 class variant {21 public:22 23 // 20.7.2.1, constructors24 constexpr variant() noexcept(see below);25 variant(const variant&); // constexpr in C++2026 variant(variant&&) noexcept(see below); // constexpr in C++2027 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, destructor45 ~variant();46 47 // 20.7.2.3, assignment48 variant& operator=(const variant&); // constexpr in C++2049 variant& operator=(variant&&) noexcept(see below); // constexpr in C++2050 51 template <class T> variant& operator=(T&&) noexcept(see below);52 53 // 20.7.2.4, modifiers54 template <class T, class... Args>55 T& emplace(Args&&...);56 57 template <class T, class U, class... Args>58 T& emplace(initializer_list<U>, Args&&...);59 60 template <size_t I, class... Args>61 variant_alternative_t<I, variant>& emplace(Args&&...);62 63 template <size_t I, class U, class... Args>64 variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...);65 66 // 20.7.2.5, value status67 constexpr bool valueless_by_exception() const noexcept;68 constexpr size_t index() const noexcept;69 70 // 20.7.2.6, swap71 void swap(variant&) noexcept(see below);72 };73 74 // 20.7.3, variant helper classes75 template <class T> struct variant_size; // undefined76 77 template <class T>78 inline constexpr size_t variant_size_v = variant_size<T>::value;79 80 template <class T> struct variant_size<const T>;81 template <class T> struct variant_size<volatile T>;82 template <class T> struct variant_size<const volatile T>;83 84 template <class... Types>85 struct variant_size<variant<Types...>>;86 87 template <size_t I, class T> struct variant_alternative; // undefined88 89 template <size_t I, class T>90 using variant_alternative_t = typename variant_alternative<I, T>::type;91 92 template <size_t I, class T> struct variant_alternative<I, const T>;93 template <size_t I, class T> struct variant_alternative<I, volatile T>;94 template <size_t I, class T> struct variant_alternative<I, const volatile T>;95 96 template <size_t I, class... Types>97 struct variant_alternative<I, variant<Types...>>;98 99 inline constexpr size_t variant_npos = -1;100 101 // 20.7.4, value access102 template <class T, class... Types>103 constexpr bool holds_alternative(const variant<Types...>&) noexcept;104 105 template <size_t I, class... Types>106 constexpr variant_alternative_t<I, variant<Types...>>&107 get(variant<Types...>&);108 109 template <size_t I, class... Types>110 constexpr variant_alternative_t<I, variant<Types...>>&&111 get(variant<Types...>&&);112 113 template <size_t I, class... Types>114 constexpr variant_alternative_t<I, variant<Types...>> const&115 get(const variant<Types...>&);116 117 template <size_t I, class... Types>118 constexpr variant_alternative_t<I, variant<Types...>> const&&119 get(const variant<Types...>&&);120 121 template <class T, class... Types>122 constexpr T& get(variant<Types...>&);123 124 template <class T, class... Types>125 constexpr T&& get(variant<Types...>&&);126 127 template <class T, class... Types>128 constexpr const T& get(const variant<Types...>&);129 130 template <class T, class... Types>131 constexpr const T&& get(const variant<Types...>&&);132 133 template <size_t I, class... Types>134 constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>135 get_if(variant<Types...>*) noexcept;136 137 template <size_t I, class... Types>138 constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>139 get_if(const variant<Types...>*) noexcept;140 141 template <class T, class... Types>142 constexpr add_pointer_t<T>143 get_if(variant<Types...>*) noexcept;144 145 template <class T, class... Types>146 constexpr add_pointer_t<const T>147 get_if(const variant<Types...>*) noexcept;148 149 // 20.7.5, relational operators150 template <class... Types>151 constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);152 153 template <class... Types>154 constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);155 156 template <class... Types>157 constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);158 159 template <class... Types>160 constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);161 162 template <class... Types>163 constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);164 165 template <class... Types>166 constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);167 168 // 20.7.6, visitation169 template <class Visitor, class... Variants>170 constexpr see below visit(Visitor&&, Variants&&...);171 172 // 20.7.7, class monostate173 struct monostate;174 175 // 20.7.8, monostate relational operators176 constexpr bool operator<(monostate, monostate) noexcept;177 constexpr bool operator>(monostate, monostate) noexcept;178 constexpr bool operator<=(monostate, monostate) noexcept;179 constexpr bool operator>=(monostate, monostate) noexcept;180 constexpr bool operator==(monostate, monostate) noexcept;181 constexpr bool operator!=(monostate, monostate) noexcept;182 183 // 20.7.9, specialized algorithms184 template <class... Types>185 void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);186 187 // 20.7.10, class bad_variant_access188 class bad_variant_access;189 190 // 20.7.11, hash support191 template <class T> struct hash;192 template <class... Types> struct hash<variant<Types...>>;193 template <> struct hash<monostate>;194 195} // namespace std196 197*/198 199#include <__config>200#include <array>201#include <exception>202#include <functional>203#include <initializer_list>204#include <new>205#include <tuple>206#include <type_traits>207#include <utility>208#include <limits>209#include <version>210 211#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)212# pragma GCC system_header213#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)214# pragma clang system_header215#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)216# pragma system_header217#endif // no system header218 219_LIBCUDACXX_PUSH_MACROS220#include <__undef_macros>221 222namespace std { // explicitly not using versioning namespace223 224class _LIBCUDACXX_EXCEPTION_ABI _LIBCUDACXX_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {225public:226 virtual const char* what() const noexcept;227};228 229_LIBCUDACXX_END_NAMESPACE_STD_NOVERSION230 231#endif // __cuda_std__232 233#if _LIBCUDACXX_STD_VER >= 14 && !defined(_LIBCUDACXX_COMPILER_MSVC_2017)234 235_LIBCUDACXX_BEGIN_NAMESPACE_STD236 237#if _LIBCUDACXX_STD_VER > 14238 239_LIBCUDACXX_NORETURN240inline _LIBCUDACXX_INLINE_VISIBILITY241_LIBCUDACXX_AVAILABILITY_THROW_BAD_VARIANT_ACCESS242void __throw_bad_variant_access() {243#ifndef _LIBCUDACXX_NO_EXCEPTIONS244 throw bad_variant_access();245#else246 _CUDA_VSTD::abort();247#endif248}249 250template <class... _Types>251class _LIBCUDACXX_TEMPLATE_VIS variant;252 253template <class _Tp>254struct _LIBCUDACXX_TEMPLATE_VIS variant_size;255 256template <class _Tp>257_LIBCUDACXX_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value;258 259template <class _Tp>260struct _LIBCUDACXX_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};261 262template <class _Tp>263struct _LIBCUDACXX_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};264 265template <class _Tp>266struct _LIBCUDACXX_TEMPLATE_VIS variant_size<const volatile _Tp>267 : variant_size<_Tp> {};268 269template <class... _Types>270struct _LIBCUDACXX_TEMPLATE_VIS variant_size<variant<_Types...>>271 : integral_constant<size_t, sizeof...(_Types)> {};272 273template <size_t _Ip, class _Tp>274struct _LIBCUDACXX_TEMPLATE_VIS variant_alternative;275 276template <size_t _Ip, class _Tp>277using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;278 279template <size_t _Ip, class _Tp>280struct _LIBCUDACXX_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>281 : add_const<variant_alternative_t<_Ip, _Tp>> {};282 283template <size_t _Ip, class _Tp>284struct _LIBCUDACXX_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>285 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};286 287template <size_t _Ip, class _Tp>288struct _LIBCUDACXX_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>289 : add_cv<variant_alternative_t<_Ip, _Tp>> {};290 291template <size_t _Ip, class... _Types>292struct _LIBCUDACXX_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {293 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");294 using type = __type_pack_element<_Ip, _Types...>;295};296 297_LIBCUDACXX_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1);298 299constexpr int __choose_index_type(unsigned int __num_elem) {300 if (__num_elem < std::numeric_limits<unsigned char>::max())301 return 0;302 if (__num_elem < std::numeric_limits<unsigned short>::max())303 return 1;304 return 2;305}306 307template <size_t _NumAlts>308using __variant_index_t =309#ifndef _LIBCUDACXX_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION310 unsigned int;311#else312 std::tuple_element_t<313 __choose_index_type(_NumAlts),314 std::tuple<unsigned char, unsigned short, unsigned int>315 >;316#endif317 318template <class _IndexType>319constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);320 321namespace __find_detail {322 323template <class _Tp, class... _Types>324inline _LIBCUDACXX_INLINE_VISIBILITY325constexpr size_t __find_index() {326 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};327 size_t __result = __not_found;328 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {329 if (__matches[__i]) {330 if (__result != __not_found) {331 return __ambiguous;332 }333 __result = __i;334 }335 }336 return __result;337}338 339template <size_t _Index>340struct __find_unambiguous_index_sfinae_impl341 : integral_constant<size_t, _Index> {};342 343template <>344struct __find_unambiguous_index_sfinae_impl<__not_found> {};345 346template <>347struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};348 349template <class _Tp, class... _Types>350struct __find_unambiguous_index_sfinae351 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};352 353} // namespace __find_detail354 355namespace __variant_detail {356 357struct __valueless_t {};358 359enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };360 361template <typename _Tp,362 template <typename> class _IsTriviallyAvailable,363 template <typename> class _IsAvailable>364constexpr _Trait __trait =365 _IsTriviallyAvailable<_Tp>::value366 ? _Trait::_TriviallyAvailable367 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;368 369inline _LIBCUDACXX_INLINE_VISIBILITY370constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {371 _Trait __result = _Trait::_TriviallyAvailable;372 for (_Trait __t : __traits) {373 if (static_cast<int>(__t) > static_cast<int>(__result)) {374 __result = __t;375 }376 }377 return __result;378}379 380template <typename... _Types>381struct __traits {382 static constexpr _Trait __copy_constructible_trait =383 __common_trait({__trait<_Types,384 is_trivially_copy_constructible,385 is_copy_constructible>...});386 387 static constexpr _Trait __move_constructible_trait =388 __common_trait({__trait<_Types,389 is_trivially_move_constructible,390 is_move_constructible>...});391 392 static constexpr _Trait __copy_assignable_trait = __common_trait(393 {__copy_constructible_trait,394 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});395 396 static constexpr _Trait __move_assignable_trait = __common_trait(397 {__move_constructible_trait,398 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});399 400 static constexpr _Trait __destructible_trait = __common_trait(401 {__trait<_Types, is_trivially_destructible, is_destructible>...});402};403 404namespace __access {405 406struct __union {407 template <class _Vp>408 inline _LIBCUDACXX_INLINE_VISIBILITY409 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {410 return _CUDA_VSTD::forward<_Vp>(__v).__head;411 }412 413 template <class _Vp, size_t _Ip>414 inline _LIBCUDACXX_INLINE_VISIBILITY415 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {416 return __get_alt(_CUDA_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);417 }418};419 420struct __base {421 template <size_t _Ip, class _Vp>422 inline _LIBCUDACXX_INLINE_VISIBILITY423 static constexpr auto&& __get_alt(_Vp&& __v) {424 return __union::__get_alt(_CUDA_VSTD::forward<_Vp>(__v).__data,425 in_place_index<_Ip>);426 }427};428 429struct __variant {430 template <size_t _Ip, class _Vp>431 inline _LIBCUDACXX_INLINE_VISIBILITY432 static constexpr auto&& __get_alt(_Vp&& __v) {433 return __base::__get_alt<_Ip>(_CUDA_VSTD::forward<_Vp>(__v).__impl);434 }435};436 437} // namespace __access438 439namespace __visitation {440 441struct __base {442 template <class _Visitor, class... _Vs>443 inline _LIBCUDACXX_INLINE_VISIBILITY444 static constexpr decltype(auto)445 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {446 constexpr auto __fdiagonal =447 __make_fdiagonal<_Visitor&&,448 decltype(_CUDA_VSTD::forward<_Vs>(__vs).__as_base())...>();449 return __fdiagonal[__index](_CUDA_VSTD::forward<_Visitor>(__visitor),450 _CUDA_VSTD::forward<_Vs>(__vs).__as_base()...);451 }452 453 template <class _Visitor, class... _Vs>454 inline _LIBCUDACXX_INLINE_VISIBILITY455 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,456 _Vs&&... __vs) {457 constexpr auto __fmatrix =458 __make_fmatrix<_Visitor&&,459 decltype(_CUDA_VSTD::forward<_Vs>(__vs).__as_base())...>();460 return __at(__fmatrix, __vs.index()...)(461 _CUDA_VSTD::forward<_Visitor>(__visitor),462 _CUDA_VSTD::forward<_Vs>(__vs).__as_base()...);463 }464 465private:466 template <class _Tp>467 inline _LIBCUDACXX_INLINE_VISIBILITY468 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }469 470 template <class _Tp, size_t _Np, typename... _Indices>471 inline _LIBCUDACXX_INLINE_VISIBILITY472 static constexpr auto&& __at(const array<_Tp, _Np>& __elems,473 size_t __index, _Indices... __indices) {474 return __at(__elems[__index], __indices...);475 }476 477 template <class _Fp, class... _Fs>478 static constexpr void __std_visit_visitor_return_type_check() {479 static_assert(480 __all<is_same_v<_Fp, _Fs>...>::value,481 "`std::visit` requires the visitor to have a single return type.");482 }483 484 template <class... _Fs>485 inline _LIBCUDACXX_INLINE_VISIBILITY486 static constexpr auto __make_farray(_Fs&&... __fs) {487 __std_visit_visitor_return_type_check<__remove_cvref_t<_Fs>...>();488 using __result = array<common_type_t<__remove_cvref_t<_Fs>...>, sizeof...(_Fs)>;489 return __result{{_CUDA_VSTD::forward<_Fs>(__fs)...}};490 }491 492 template <std::size_t... _Is>493 struct __dispatcher {494 template <class _Fp, class... _Vs>495 inline _LIBCUDACXX_INLINE_VISIBILITY496 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {497 return __invoke(498 static_cast<_Fp>(__f),499 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);500 }501 };502 503 template <class _Fp, class... _Vs, size_t... _Is>504 inline _LIBCUDACXX_INLINE_VISIBILITY505 static constexpr auto __make_dispatch(index_sequence<_Is...>) {506 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;507 }508 509 template <size_t _Ip, class _Fp, class... _Vs>510 inline _LIBCUDACXX_INLINE_VISIBILITY511 static constexpr auto __make_fdiagonal_impl() {512 return __make_dispatch<_Fp, _Vs...>(513 index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});514 }515 516 template <class _Fp, class... _Vs, size_t... _Is>517 inline _LIBCUDACXX_INLINE_VISIBILITY518 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {519 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);520 }521 522 template <class _Fp, class _Vp, class... _Vs>523 inline _LIBCUDACXX_INLINE_VISIBILITY524 static constexpr auto __make_fdiagonal() {525 constexpr size_t _Np = __remove_cvref_t<_Vp>::__size();526 static_assert(__all<(_Np == __remove_cvref_t<_Vs>::__size())...>::value);527 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});528 }529 530 template <class _Fp, class... _Vs, size_t... _Is>531 inline _LIBCUDACXX_INLINE_VISIBILITY532 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {533 return __make_dispatch<_Fp, _Vs...>(__is);534 }535 536 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>537 inline _LIBCUDACXX_INLINE_VISIBILITY538 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,539 index_sequence<_Js...>,540 _Ls... __ls) {541 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(542 index_sequence<_Is..., _Js>{}, __ls...)...);543 }544 545 template <class _Fp, class... _Vs>546 inline _LIBCUDACXX_INLINE_VISIBILITY547 static constexpr auto __make_fmatrix() {548 return __make_fmatrix_impl<_Fp, _Vs...>(549 index_sequence<>{}, make_index_sequence<__remove_cvref_t<_Vs>::__size()>{}...);550 }551};552 553struct __variant {554 template <class _Visitor, class... _Vs>555 inline _LIBCUDACXX_INLINE_VISIBILITY556 static constexpr decltype(auto)557 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {558 return __base::__visit_alt_at(__index,559 _CUDA_VSTD::forward<_Visitor>(__visitor),560 _CUDA_VSTD::forward<_Vs>(__vs).__impl...);561 }562 563 template <class _Visitor, class... _Vs>564 inline _LIBCUDACXX_INLINE_VISIBILITY565 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,566 _Vs&&... __vs) {567 return __base::__visit_alt(_CUDA_VSTD::forward<_Visitor>(__visitor),568 _CUDA_VSTD::forward<_Vs>(__vs).__impl...);569 }570 571 template <class _Visitor, class... _Vs>572 inline _LIBCUDACXX_INLINE_VISIBILITY573 static constexpr decltype(auto)574 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {575 return __visit_alt_at(576 __index,577 __make_value_visitor(_CUDA_VSTD::forward<_Visitor>(__visitor)),578 _CUDA_VSTD::forward<_Vs>(__vs)...);579 }580 581 template <class _Visitor, class... _Vs>582 inline _LIBCUDACXX_INLINE_VISIBILITY583 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,584 _Vs&&... __vs) {585 return __visit_alt(586 __make_value_visitor(_CUDA_VSTD::forward<_Visitor>(__visitor)),587 _CUDA_VSTD::forward<_Vs>(__vs)...);588 }589 590private:591 template <class _Visitor, class... _Values>592 static constexpr void __std_visit_exhaustive_visitor_check() {593 static_assert(is_invocable_v<_Visitor, _Values...>,594 "`std::visit` requires the visitor to be exhaustive.");595 }596 597 template <class _Visitor>598 struct __value_visitor {599 template <class... _Alts>600 inline _LIBCUDACXX_INLINE_VISIBILITY601 constexpr decltype(auto) operator()(_Alts&&... __alts) const {602 __std_visit_exhaustive_visitor_check<603 _Visitor,604 decltype((_CUDA_VSTD::forward<_Alts>(__alts).__value))...>();605 return __invoke(_CUDA_VSTD::forward<_Visitor>(__visitor),606 _CUDA_VSTD::forward<_Alts>(__alts).__value...);607 }608 _Visitor&& __visitor;609 };610 611 template <class _Visitor>612 inline _LIBCUDACXX_INLINE_VISIBILITY613 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {614 return __value_visitor<_Visitor>{_CUDA_VSTD::forward<_Visitor>(__visitor)};615 }616};617 618} // namespace __visitation619 620template <size_t _Index, class _Tp>621struct _LIBCUDACXX_TEMPLATE_VIS __alt {622 using __value_type = _Tp;623 624 template <class... _Args>625 inline _LIBCUDACXX_INLINE_VISIBILITY626 explicit constexpr __alt(in_place_t, _Args&&... __args)627 : __value(_CUDA_VSTD::forward<_Args>(__args)...) {}628 629 __value_type __value;630};631 632template <_Trait _DestructibleTrait, size_t _Index, class... _Types>633union _LIBCUDACXX_TEMPLATE_VIS __union;634 635template <_Trait _DestructibleTrait, size_t _Index>636union _LIBCUDACXX_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};637 638#define _LIBCUDACXX_VARIANT_UNION(destructible_trait, destructor) \639 template <size_t _Index, class _Tp, class... _Types> \640 union _LIBCUDACXX_TEMPLATE_VIS __union<destructible_trait, \641 _Index, \642 _Tp, \643 _Types...> { \644 public: \645 inline _LIBCUDACXX_INLINE_VISIBILITY \646 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \647 \648 template <class... _Args> \649 inline _LIBCUDACXX_INLINE_VISIBILITY \650 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \651 : __head(in_place, _CUDA_VSTD::forward<_Args>(__args)...) {} \652 \653 template <size_t _Ip, class... _Args> \654 inline _LIBCUDACXX_INLINE_VISIBILITY \655 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \656 : __tail(in_place_index<_Ip - 1>, _CUDA_VSTD::forward<_Args>(__args)...) {} \657 \658 __union(const __union&) = default; \659 __union(__union&&) = default; \660 \661 destructor \662 \663 __union& operator=(const __union&) = default; \664 __union& operator=(__union&&) = default; \665 \666 private: \667 char __dummy; \668 __alt<_Index, _Tp> __head; \669 __union<destructible_trait, _Index + 1, _Types...> __tail; \670 \671 friend struct __access::__union; \672 }673 674_LIBCUDACXX_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);675_LIBCUDACXX_VARIANT_UNION(_Trait::_Available, ~__union() {});676_LIBCUDACXX_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);677 678#undef _LIBCUDACXX_VARIANT_UNION679 680template <_Trait _DestructibleTrait, class... _Types>681class _LIBCUDACXX_TEMPLATE_VIS __base {682public:683 using __index_t = __variant_index_t<sizeof...(_Types)>;684 685 inline _LIBCUDACXX_INLINE_VISIBILITY686 explicit constexpr __base(__valueless_t tag) noexcept687 : __data(tag), __index(__variant_npos<__index_t>) {}688 689 template <size_t _Ip, class... _Args>690 inline _LIBCUDACXX_INLINE_VISIBILITY691 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)692 :693 __data(in_place_index<_Ip>, _CUDA_VSTD::forward<_Args>(__args)...),694 __index(_Ip) {}695 696 inline _LIBCUDACXX_INLINE_VISIBILITY697 constexpr bool valueless_by_exception() const noexcept {698 return index() == variant_npos;699 }700 701 inline _LIBCUDACXX_INLINE_VISIBILITY702 constexpr size_t index() const noexcept {703 return __index == __variant_npos<__index_t> ? variant_npos : __index;704 }705 706protected:707 inline _LIBCUDACXX_INLINE_VISIBILITY708 constexpr auto&& __as_base() & { return *this; }709 710 inline _LIBCUDACXX_INLINE_VISIBILITY711 constexpr auto&& __as_base() && { return _CUDA_VSTD::move(*this); }712 713 inline _LIBCUDACXX_INLINE_VISIBILITY714 constexpr auto&& __as_base() const & { return *this; }715 716 inline _LIBCUDACXX_INLINE_VISIBILITY717 constexpr auto&& __as_base() const && { return _CUDA_VSTD::move(*this); }718 719 inline _LIBCUDACXX_INLINE_VISIBILITY720 static constexpr size_t __size() { return sizeof...(_Types); }721 722 __union<_DestructibleTrait, 0, _Types...> __data;723 __index_t __index;724 725 friend struct __access::__base;726 friend struct __visitation::__base;727};728 729template <class _Traits, _Trait = _Traits::__destructible_trait>730class _LIBCUDACXX_TEMPLATE_VIS __destructor;731 732#define _LIBCUDACXX_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \733 template <class... _Types> \734 class _LIBCUDACXX_TEMPLATE_VIS __destructor<__traits<_Types...>, \735 destructible_trait> \736 : public __base<destructible_trait, _Types...> { \737 using __base_type = __base<destructible_trait, _Types...>; \738 using __index_t = typename __base_type::__index_t; \739 \740 public: \741 using __base_type::__base_type; \742 using __base_type::operator=; \743 \744 __destructor(const __destructor&) = default; \745 __destructor(__destructor&&) = default; \746 destructor \747 __destructor& operator=(const __destructor&) = default; \748 __destructor& operator=(__destructor&&) = default; \749 \750 protected: \751 inline _LIBCUDACXX_INLINE_VISIBILITY \752 destroy \753 }754 755_LIBCUDACXX_VARIANT_DESTRUCTOR(756 _Trait::_TriviallyAvailable,757 ~__destructor() = default;,758 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });759 760_LIBCUDACXX_VARIANT_DESTRUCTOR(761 _Trait::_Available,762 ~__destructor() { __destroy(); },763 void __destroy() noexcept {764 if (!this->valueless_by_exception()) {765 __visitation::__base::__visit_alt(766 [](auto& __alt) noexcept {767 using __alt_type = __remove_cvref_t<decltype(__alt)>;768 __alt.~__alt_type();769 },770 *this);771 }772 this->__index = __variant_npos<__index_t>;773 });774 775_LIBCUDACXX_VARIANT_DESTRUCTOR(776 _Trait::_Unavailable,777 ~__destructor() = delete;,778 void __destroy() noexcept = delete;);779 780#undef _LIBCUDACXX_VARIANT_DESTRUCTOR781 782template <class _Traits>783class _LIBCUDACXX_TEMPLATE_VIS __constructor : public __destructor<_Traits> {784 using __base_type = __destructor<_Traits>;785 786public:787 using __base_type::__base_type;788 using __base_type::operator=;789 790protected:791 template <size_t _Ip, class _Tp, class... _Args>792 inline _LIBCUDACXX_INLINE_VISIBILITY793 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {794 ::new ((void*)_CUDA_VSTD::addressof(__a))795 __alt<_Ip, _Tp>(in_place, _CUDA_VSTD::forward<_Args>(__args)...);796 return __a.__value;797 }798 799 template <class _Rhs>800 inline _LIBCUDACXX_INLINE_VISIBILITY801 static void __generic_construct(__constructor& __lhs, _Rhs&& __rhs) {802 __lhs.__destroy();803 if (!__rhs.valueless_by_exception()) {804 __visitation::__base::__visit_alt_at(805 __rhs.index(),806 [](auto& __lhs_alt, auto&& __rhs_alt) {807 __construct_alt(808 __lhs_alt,809 _CUDA_VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);810 },811 __lhs, _CUDA_VSTD::forward<_Rhs>(__rhs));812 __lhs.__index = __rhs.index();813 }814 }815};816 817template <class _Traits, _Trait = _Traits::__move_constructible_trait>818class _LIBCUDACXX_TEMPLATE_VIS __move_constructor;819 820#define _LIBCUDACXX_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \821 move_constructor) \822 template <class... _Types> \823 class _LIBCUDACXX_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \824 move_constructible_trait> \825 : public __constructor<__traits<_Types...>> { \826 using __base_type = __constructor<__traits<_Types...>>; \827 \828 public: \829 using __base_type::__base_type; \830 using __base_type::operator=; \831 \832 __move_constructor(const __move_constructor&) = default; \833 move_constructor \834 ~__move_constructor() = default; \835 __move_constructor& operator=(const __move_constructor&) = default; \836 __move_constructor& operator=(__move_constructor&&) = default; \837 }838 839_LIBCUDACXX_VARIANT_MOVE_CONSTRUCTOR(840 _Trait::_TriviallyAvailable,841 __move_constructor(__move_constructor&& __that) = default;);842 843_LIBCUDACXX_VARIANT_MOVE_CONSTRUCTOR(844 _Trait::_Available,845 __move_constructor(__move_constructor&& __that) noexcept(846 __all<is_nothrow_move_constructible_v<_Types>...>::value)847 : __move_constructor(__valueless_t{}) {848 this->__generic_construct(*this, _CUDA_VSTD::move(__that));849 });850 851_LIBCUDACXX_VARIANT_MOVE_CONSTRUCTOR(852 _Trait::_Unavailable,853 __move_constructor(__move_constructor&&) = delete;);854 855#undef _LIBCUDACXX_VARIANT_MOVE_CONSTRUCTOR856 857template <class _Traits, _Trait = _Traits::__copy_constructible_trait>858class _LIBCUDACXX_TEMPLATE_VIS __copy_constructor;859 860#define _LIBCUDACXX_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \861 copy_constructor) \862 template <class... _Types> \863 class _LIBCUDACXX_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \864 copy_constructible_trait> \865 : public __move_constructor<__traits<_Types...>> { \866 using __base_type = __move_constructor<__traits<_Types...>>; \867 \868 public: \869 using __base_type::__base_type; \870 using __base_type::operator=; \871 \872 copy_constructor \873 __copy_constructor(__copy_constructor&&) = default; \874 ~__copy_constructor() = default; \875 __copy_constructor& operator=(const __copy_constructor&) = default; \876 __copy_constructor& operator=(__copy_constructor&&) = default; \877 }878 879_LIBCUDACXX_VARIANT_COPY_CONSTRUCTOR(880 _Trait::_TriviallyAvailable,881 __copy_constructor(const __copy_constructor& __that) = default;);882 883_LIBCUDACXX_VARIANT_COPY_CONSTRUCTOR(884 _Trait::_Available,885 __copy_constructor(const __copy_constructor& __that)886 : __copy_constructor(__valueless_t{}) {887 this->__generic_construct(*this, __that);888 });889 890_LIBCUDACXX_VARIANT_COPY_CONSTRUCTOR(891 _Trait::_Unavailable,892 __copy_constructor(const __copy_constructor&) = delete;);893 894#undef _LIBCUDACXX_VARIANT_COPY_CONSTRUCTOR895 896template <class _Traits>897class _LIBCUDACXX_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {898 using __base_type = __copy_constructor<_Traits>;899 900public:901 using __base_type::__base_type;902 using __base_type::operator=;903 904 template <size_t _Ip, class... _Args>905 inline _LIBCUDACXX_INLINE_VISIBILITY906 auto& __emplace(_Args&&... __args) {907 this->__destroy();908 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),909 _CUDA_VSTD::forward<_Args>(__args)...);910 this->__index = _Ip;911 return __res;912 }913 914protected:915 template <size_t _Ip, class _Tp, class _Arg>916 inline _LIBCUDACXX_INLINE_VISIBILITY917 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {918 if (this->index() == _Ip) {919 __a.__value = _CUDA_VSTD::forward<_Arg>(__arg);920 } else {921 struct {922 void operator()(true_type) const {923 __this->__emplace<_Ip>(_CUDA_VSTD::forward<_Arg>(__arg));924 }925 void operator()(false_type) const {926 __this->__emplace<_Ip>(_Tp(_CUDA_VSTD::forward<_Arg>(__arg)));927 }928 __assignment* __this;929 _Arg&& __arg;930 } __impl{this, _CUDA_VSTD::forward<_Arg>(__arg)};931 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||932 !is_nothrow_move_constructible_v<_Tp>>{});933 }934 }935 936 template <class _That>937 inline _LIBCUDACXX_INLINE_VISIBILITY938 void __generic_assign(_That&& __that) {939 if (this->valueless_by_exception() && __that.valueless_by_exception()) {940 // do nothing.941 } else if (__that.valueless_by_exception()) {942 this->__destroy();943 } else {944 __visitation::__base::__visit_alt_at(945 __that.index(),946 [this](auto& __this_alt, auto&& __that_alt) {947 this->__assign_alt(948 __this_alt,949 _CUDA_VSTD::forward<decltype(__that_alt)>(__that_alt).__value);950 },951 *this, _CUDA_VSTD::forward<_That>(__that));952 }953 }954};955 956template <class _Traits, _Trait = _Traits::__move_assignable_trait>957class _LIBCUDACXX_TEMPLATE_VIS __move_assignment;958 959#define _LIBCUDACXX_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \960 move_assignment) \961 template <class... _Types> \962 class _LIBCUDACXX_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \963 move_assignable_trait> \964 : public __assignment<__traits<_Types...>> { \965 using __base_type = __assignment<__traits<_Types...>>; \966 \967 public: \968 using __base_type::__base_type; \969 using __base_type::operator=; \970 \971 __move_assignment(const __move_assignment&) = default; \972 __move_assignment(__move_assignment&&) = default; \973 ~__move_assignment() = default; \974 __move_assignment& operator=(const __move_assignment&) = default; \975 move_assignment \976 }977 978_LIBCUDACXX_VARIANT_MOVE_ASSIGNMENT(979 _Trait::_TriviallyAvailable,980 __move_assignment& operator=(__move_assignment&& __that) = default;);981 982_LIBCUDACXX_VARIANT_MOVE_ASSIGNMENT(983 _Trait::_Available,984 __move_assignment& operator=(__move_assignment&& __that) noexcept(985 __all<(is_nothrow_move_constructible_v<_Types> &&986 is_nothrow_move_assignable_v<_Types>)...>::value) {987 this->__generic_assign(_CUDA_VSTD::move(__that));988 return *this;989 });990 991_LIBCUDACXX_VARIANT_MOVE_ASSIGNMENT(992 _Trait::_Unavailable,993 __move_assignment& operator=(__move_assignment&&) = delete;);994 995#undef _LIBCUDACXX_VARIANT_MOVE_ASSIGNMENT996 997template <class _Traits, _Trait = _Traits::__copy_assignable_trait>998class _LIBCUDACXX_TEMPLATE_VIS __copy_assignment;999 1000#define _LIBCUDACXX_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \1001 copy_assignment) \1002 template <class... _Types> \1003 class _LIBCUDACXX_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \1004 copy_assignable_trait> \1005 : public __move_assignment<__traits<_Types...>> { \1006 using __base_type = __move_assignment<__traits<_Types...>>; \1007 \1008 public: \1009 using __base_type::__base_type; \1010 using __base_type::operator=; \1011 \1012 __copy_assignment(const __copy_assignment&) = default; \1013 __copy_assignment(__copy_assignment&&) = default; \1014 ~__copy_assignment() = default; \1015 copy_assignment \1016 __copy_assignment& operator=(__copy_assignment&&) = default; \1017 }1018 1019_LIBCUDACXX_VARIANT_COPY_ASSIGNMENT(1020 _Trait::_TriviallyAvailable,1021 __copy_assignment& operator=(const __copy_assignment& __that) = default;);1022 1023_LIBCUDACXX_VARIANT_COPY_ASSIGNMENT(1024 _Trait::_Available,1025 __copy_assignment& operator=(const __copy_assignment& __that) {1026 this->__generic_assign(__that);1027 return *this;1028 });1029 1030_LIBCUDACXX_VARIANT_COPY_ASSIGNMENT(1031 _Trait::_Unavailable,1032 __copy_assignment& operator=(const __copy_assignment&) = delete;);1033 1034#undef _LIBCUDACXX_VARIANT_COPY_ASSIGNMENT1035 1036template <class... _Types>1037class _LIBCUDACXX_TEMPLATE_VIS __impl1038 : public __copy_assignment<__traits<_Types...>> {1039 using __base_type = __copy_assignment<__traits<_Types...>>;1040 1041public:1042 using __base_type::__base_type;1043 using __base_type::operator=;1044 1045 template <size_t _Ip, class _Arg>1046 inline _LIBCUDACXX_INLINE_VISIBILITY1047 void __assign(_Arg&& __arg) {1048 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),1049 _CUDA_VSTD::forward<_Arg>(__arg));1050 }1051 1052 inline _LIBCUDACXX_INLINE_VISIBILITY1053 void __swap(__impl& __that) {1054 if (this->valueless_by_exception() && __that.valueless_by_exception()) {1055 // do nothing.1056 } else if (this->index() == __that.index()) {1057 __visitation::__base::__visit_alt_at(1058 this->index(),1059 [](auto& __this_alt, auto& __that_alt) {1060 using _CUDA_VSTD::swap;1061 swap(__this_alt.__value, __that_alt.__value);1062 },1063 *this,1064 __that);1065 } else {1066 __impl* __lhs = this;1067 __impl* __rhs = _CUDA_VSTD::addressof(__that);1068 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {1069 _CUDA_VSTD::swap(__lhs, __rhs);1070 }1071 __impl __tmp(_CUDA_VSTD::move(*__rhs));1072#ifndef _LIBCUDACXX_NO_EXCEPTIONS1073 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws1074 // and `__tmp` is nothrow move constructible then we move `__tmp` back1075 // into `__rhs` and provide the strong exception safety guarantee.1076 try {1077 this->__generic_construct(*__rhs, _CUDA_VSTD::move(*__lhs));1078 } catch (...) {1079 if (__tmp.__move_nothrow()) {1080 this->__generic_construct(*__rhs, _CUDA_VSTD::move(__tmp));1081 }1082 throw;1083 }1084#else1085 this->__generic_construct(*__rhs, _CUDA_VSTD::move(*__lhs));1086#endif1087 this->__generic_construct(*__lhs, _CUDA_VSTD::move(__tmp));1088 }1089 }1090 1091private:1092 inline _LIBCUDACXX_INLINE_VISIBILITY1093 bool __move_nothrow() const {1094 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};1095 return this->valueless_by_exception() || __results[this->index()];1096 }1097};1098 1099struct __no_narrowing_check {1100 template <class _Dest, class _Source>1101 using _Apply = __type_identity<_Dest>;1102};1103 1104struct __narrowing_check {1105 template <class _Dest>1106 static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>;1107 template <class _Dest, class _Source>1108 using _Apply _LIBCUDACXX_NODEBUG_TYPE = decltype(__test_impl<_Dest>({std::declval<_Source>()}));1109};1110 1111template <class _Dest, class _Source>1112using __check_for_narrowing _LIBCUDACXX_NODEBUG_TYPE =1113 typename _If<1114#ifdef _LIBCUDACXX_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT1115 false &&1116#endif1117 is_arithmetic<_Dest>::value,1118 __narrowing_check,1119 __no_narrowing_check1120 >::template _Apply<_Dest, _Source>;1121 1122template <class _Tp, size_t _Idx>1123struct __overload {1124 template <class _Up>1125 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;1126};1127 1128template <class _Tp, size_t>1129struct __overload_bool {1130 template <class _Up, class _Ap = __remove_cvref_t<_Up>>1131 auto operator()(bool, _Up&&) const1132 -> enable_if_t<is_same_v<_Ap, bool>, __type_identity<_Tp>>;1133};1134 1135template <size_t _Idx>1136struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};1137template <size_t _Idx>1138struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};1139template <size_t _Idx>1140struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};1141template <size_t _Idx>1142struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};1143 1144template <class ..._Bases>1145struct __all_overloads : _Bases... {1146 void operator()() const;1147 using _Bases::operator()...;1148};1149 1150template <class IdxSeq>1151struct __make_overloads_imp;1152 1153template <size_t ..._Idx>1154struct __make_overloads_imp<__tuple_indices<_Idx...> > {1155 template <class ..._Types>1156 using _Apply _LIBCUDACXX_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>;1157};1158 1159template <class ..._Types>1160using _MakeOverloads _LIBCUDACXX_NODEBUG_TYPE = typename __make_overloads_imp<1161 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;1162 1163template <class _Tp, class... _Types>1164using __best_match_t =1165 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;1166 1167} // __variant_detail1168 1169template <class... _Types>1170class _LIBCUDACXX_TEMPLATE_VIS variant1171 : private __sfinae_ctor_base<1172 __all<is_copy_constructible_v<_Types>...>::value,1173 __all<is_move_constructible_v<_Types>...>::value>,1174 private __sfinae_assign_base<1175 __all<(is_copy_constructible_v<_Types> &&1176 is_copy_assignable_v<_Types>)...>::value,1177 __all<(is_move_constructible_v<_Types> &&1178 is_move_assignable_v<_Types>)...>::value> {1179 static_assert(0 < sizeof...(_Types),1180 "variant must consist of at least one alternative.");1181 1182 static_assert(__all<!is_array_v<_Types>...>::value,1183 "variant can not have an array type as an alternative.");1184 1185 static_assert(__all<!is_reference_v<_Types>...>::value,1186 "variant can not have a reference type as an alternative.");1187 1188 static_assert(__all<!is_void_v<_Types>...>::value,1189 "variant can not have a void type as an alternative.");1190 1191 using __first_type = variant_alternative_t<0, variant>;1192 1193public:1194 template <bool _Dummy = true,1195 enable_if_t<__dependent_type<is_default_constructible<__first_type>,1196 _Dummy>::value,1197 int> = 0>1198 inline _LIBCUDACXX_INLINE_VISIBILITY1199 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)1200 : __impl(in_place_index<0>) {}