00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef ABSL_TYPES_VARIANT_H_
00043 #define ABSL_TYPES_VARIANT_H_
00044
00045 #include "absl/base/config.h"
00046 #include "absl/utility/utility.h"
00047
00048 #ifdef ABSL_HAVE_STD_VARIANT
00049
00050 #include <variant>
00051
00052 namespace absl {
00053 using std::bad_variant_access;
00054 using std::get;
00055 using std::get_if;
00056 using std::holds_alternative;
00057 using std::monostate;
00058 using std::variant;
00059 using std::variant_alternative;
00060 using std::variant_alternative_t;
00061 using std::variant_npos;
00062 using std::variant_size;
00063 using std::variant_size_v;
00064 using std::visit;
00065 }
00066
00067 #else // ABSL_HAVE_STD_VARIANT
00068
00069 #include <functional>
00070 #include <new>
00071 #include <type_traits>
00072 #include <utility>
00073
00074 #include "absl/base/macros.h"
00075 #include "absl/base/port.h"
00076 #include "absl/meta/type_traits.h"
00077 #include "absl/types/internal/variant.h"
00078
00079 namespace absl {
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 template <typename... Ts>
00120 class variant;
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 template <
00133 typename... Ts,
00134 absl::enable_if_t<
00135 absl::conjunction<std::is_move_constructible<Ts>...,
00136 type_traits_internal::IsSwappable<Ts>...>::value,
00137 int> = 0>
00138 void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
00139 v.swap(w);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 template <class T>
00169 struct variant_size;
00170
00171 template <class... Ts>
00172 struct variant_size<variant<Ts...>>
00173 : std::integral_constant<std::size_t, sizeof...(Ts)> {};
00174
00175
00176 template <class T>
00177 struct variant_size<const T> : variant_size<T>::type {};
00178
00179
00180 template <class T>
00181 struct variant_size<volatile T> : variant_size<T>::type {};
00182
00183
00184 template <class T>
00185 struct variant_size<const volatile T> : variant_size<T>::type {};
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 template <std::size_t I, class T>
00212 struct variant_alternative;
00213
00214 template <std::size_t I, class... Types>
00215 struct variant_alternative<I, variant<Types...>> {
00216 using type =
00217 variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>;
00218 };
00219
00220
00221 template <std::size_t I, class T>
00222 struct variant_alternative<I, const T> {
00223 using type = const typename variant_alternative<I, T>::type;
00224 };
00225
00226
00227 template <std::size_t I, class T>
00228 struct variant_alternative<I, volatile T> {
00229 using type = volatile typename variant_alternative<I, T>::type;
00230 };
00231
00232
00233
00234 template <std::size_t I, class T>
00235 struct variant_alternative<I, const volatile T> {
00236 using type = const volatile typename variant_alternative<I, T>::type;
00237 };
00238
00239
00240
00241
00242
00243
00244
00245
00246 template <std::size_t I, class T>
00247 using variant_alternative_t = typename variant_alternative<I, T>::type;
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 template <class T, class... Types>
00261 constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
00262 static_assert(
00263 variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T,
00264 0>::value != sizeof...(Types),
00265 "The type T must occur exactly once in Types...");
00266 return v.index() ==
00267 variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 template <class T, class... Types>
00297 constexpr T& get(variant<Types...>& v) {
00298 return variant_internal::VariantCoreAccess::CheckedAccess<
00299 variant_internal::IndexOf<T, Types...>::value>(v);
00300 }
00301
00302
00303
00304 template <class T, class... Types>
00305 constexpr T&& get(variant<Types...>&& v) {
00306 return variant_internal::VariantCoreAccess::CheckedAccess<
00307 variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
00308 }
00309
00310
00311 template <class T, class... Types>
00312 constexpr const T& get(const variant<Types...>& v) {
00313 return variant_internal::VariantCoreAccess::CheckedAccess<
00314 variant_internal::IndexOf<T, Types...>::value>(v);
00315 }
00316
00317
00318
00319 template <class T, class... Types>
00320 constexpr const T&& get(const variant<Types...>&& v) {
00321 return variant_internal::VariantCoreAccess::CheckedAccess<
00322 variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
00323 }
00324
00325
00326 template <std::size_t I, class... Types>
00327 constexpr variant_alternative_t<I, variant<Types...>>& get(
00328 variant<Types...>& v) {
00329 return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
00330 }
00331
00332
00333
00334 template <std::size_t I, class... Types>
00335 constexpr variant_alternative_t<I, variant<Types...>>&& get(
00336 variant<Types...>&& v) {
00337 return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
00338 }
00339
00340
00341 template <std::size_t I, class... Types>
00342 constexpr const variant_alternative_t<I, variant<Types...>>& get(
00343 const variant<Types...>& v) {
00344 return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
00345 }
00346
00347
00348
00349 template <std::size_t I, class... Types>
00350 constexpr const variant_alternative_t<I, variant<Types...>>&& get(
00351 const variant<Types...>&& v) {
00352 return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 template <std::size_t I, class... Types>
00368 constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>>
00369 get_if(variant<Types...>* v) noexcept {
00370 return (v != nullptr && v->index() == I)
00371 ? std::addressof(
00372 variant_internal::VariantCoreAccess::Access<I>(*v))
00373 : nullptr;
00374 }
00375
00376
00377
00378 template <std::size_t I, class... Types>
00379 constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
00380 get_if(const variant<Types...>* v) noexcept {
00381 return (v != nullptr && v->index() == I)
00382 ? std::addressof(
00383 variant_internal::VariantCoreAccess::Access<I>(*v))
00384 : nullptr;
00385 }
00386
00387
00388
00389 template <class T, class... Types>
00390 constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept {
00391 return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
00392 }
00393
00394
00395
00396 template <class T, class... Types>
00397 constexpr absl::add_pointer_t<const T> get_if(
00398 const variant<Types...>* v) noexcept {
00399 return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 template <typename Visitor, typename... Variants>
00427 variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
00428 Variants&&... vars) {
00429 return variant_internal::
00430 VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run(
00431 variant_internal::PerformVisitation<Visitor, Variants...>{
00432 std::forward_as_tuple(absl::forward<Variants>(vars)...),
00433 absl::forward<Visitor>(vis)},
00434 vars.index()...);
00435 }
00436
00437
00438
00439
00440
00441 struct monostate {};
00442
00443
00444
00445 constexpr bool operator<(monostate, monostate) noexcept { return false; }
00446 constexpr bool operator>(monostate, monostate) noexcept { return false; }
00447 constexpr bool operator<=(monostate, monostate) noexcept { return true; }
00448 constexpr bool operator>=(monostate, monostate) noexcept { return true; }
00449 constexpr bool operator==(monostate, monostate) noexcept { return true; }
00450 constexpr bool operator!=(monostate, monostate) noexcept { return false; }
00451
00452
00453
00454
00455
00456 template <typename T0, typename... Tn>
00457 class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
00458 static_assert(absl::conjunction<std::is_object<T0>,
00459 std::is_object<Tn>...>::value,
00460 "Attempted to instantiate a variant containing a non-object "
00461 "type.");
00462
00463
00464 static_assert(absl::conjunction<negation<std::is_array<T0> >,
00465 negation<std::is_array<Tn> >...>::value,
00466 "Attempted to instantiate a variant containing an array type.");
00467 static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
00468 std::is_nothrow_destructible<Tn>...>::value,
00469 "Attempted to instantiate a variant containing a non-nothrow "
00470 "destructible type.");
00471
00472 friend struct variant_internal::VariantCoreAccess;
00473
00474 private:
00475 using Base = variant_internal::VariantBase<T0, Tn...>;
00476
00477 public:
00478
00479
00480
00481
00482 constexpr variant() = default;
00483
00484
00485 variant(const variant& other) = default;
00486
00487
00488 variant(variant&& other) = default;
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 template <
00501 class T,
00502 std::size_t I = std::enable_if<
00503 variant_internal::IsNeitherSelfNorInPlace<variant,
00504 absl::decay_t<T>>::value,
00505 variant_internal::IndexOfConstructedType<variant, T>>::type::value,
00506 class Tj = absl::variant_alternative_t<I, variant>,
00507 absl::enable_if_t<std::is_constructible<Tj, T>::value>* =
00508 nullptr>
00509 constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value)
00510 : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}
00511
00512
00513
00514
00515
00516
00517 template <class T, class... Args,
00518 typename std::enable_if<std::is_constructible<
00519 variant_internal::UnambiguousTypeOfT<variant, T>,
00520 Args...>::value>::type* = nullptr>
00521 constexpr explicit variant(in_place_type_t<T>, Args&&... args)
00522 : Base(variant_internal::EmplaceTag<
00523 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
00524 absl::forward<Args>(args)...) {}
00525
00526
00527
00528
00529
00530
00531 template <class T, class U, class... Args,
00532 typename std::enable_if<std::is_constructible<
00533 variant_internal::UnambiguousTypeOfT<variant, T>,
00534 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00535 constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il,
00536 Args&&... args)
00537 : Base(variant_internal::EmplaceTag<
00538 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
00539 il, absl::forward<Args>(args)...) {}
00540
00541
00542
00543 template <std::size_t I, class... Args,
00544 typename std::enable_if<std::is_constructible<
00545 variant_internal::VariantAlternativeSfinaeT<I, variant>,
00546 Args...>::value>::type* = nullptr>
00547 constexpr explicit variant(in_place_index_t<I>, Args&&... args)
00548 : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {}
00549
00550
00551
00552
00553 template <std::size_t I, class U, class... Args,
00554 typename std::enable_if<std::is_constructible<
00555 variant_internal::VariantAlternativeSfinaeT<I, variant>,
00556 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00557 constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il,
00558 Args&&... args)
00559 : Base(variant_internal::EmplaceTag<I>(), il,
00560 absl::forward<Args>(args)...) {}
00561
00562
00563
00564
00565
00566 ~variant() = default;
00567
00568
00569
00570
00571 variant& operator=(const variant& other) = default;
00572
00573
00574 variant& operator=(variant&& other) = default;
00575
00576
00577
00578
00579
00580
00581 template <
00582 class T,
00583 std::size_t I = std::enable_if<
00584 !std::is_same<absl::decay_t<T>, variant>::value,
00585 variant_internal::IndexOfConstructedType<variant, T>>::type::value,
00586 class Tj = absl::variant_alternative_t<I, variant>,
00587 typename std::enable_if<std::is_assignable<Tj&, T>::value &&
00588 std::is_constructible<Tj, T>::value>::type* =
00589 nullptr>
00590 variant& operator=(T&& t) noexcept(
00591 std::is_nothrow_assignable<Tj&, T>::value&&
00592 std::is_nothrow_constructible<Tj, T>::value) {
00593 variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
00594 variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
00595 this, absl::forward<T>(t)),
00596 index());
00597
00598 return *this;
00599 }
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 template <
00612 class T, class... Args,
00613 typename std::enable_if<std::is_constructible<
00614 absl::variant_alternative_t<
00615 variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
00616 Args...>::value>::type* = nullptr>
00617 T& emplace(Args&&... args) {
00618 return variant_internal::VariantCoreAccess::Replace<
00619 variant_internal::UnambiguousIndexOf<variant, T>::value>(
00620 this, absl::forward<Args>(args)...);
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630 template <
00631 class T, class U, class... Args,
00632 typename std::enable_if<std::is_constructible<
00633 absl::variant_alternative_t<
00634 variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
00635 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00636 T& emplace(std::initializer_list<U> il, Args&&... args) {
00637 return variant_internal::VariantCoreAccess::Replace<
00638 variant_internal::UnambiguousIndexOf<variant, T>::value>(
00639 this, il, absl::forward<Args>(args)...);
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 template <std::size_t I, class... Args,
00653 typename std::enable_if<
00654 std::is_constructible<absl::variant_alternative_t<I, variant>,
00655 Args...>::value>::type* = nullptr>
00656 absl::variant_alternative_t<I, variant>& emplace(Args&&... args) {
00657 return variant_internal::VariantCoreAccess::Replace<I>(
00658 this, absl::forward<Args>(args)...);
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 template <std::size_t I, class U, class... Args,
00670 typename std::enable_if<std::is_constructible<
00671 absl::variant_alternative_t<I, variant>,
00672 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00673 absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il,
00674 Args&&... args) {
00675 return variant_internal::VariantCoreAccess::Replace<I>(
00676 this, il, absl::forward<Args>(args)...);
00677 }
00678
00679
00680
00681
00682 constexpr bool valueless_by_exception() const noexcept {
00683 return this->index_ == absl::variant_npos;
00684 }
00685
00686
00687
00688
00689
00690 constexpr std::size_t index() const noexcept { return this->index_; }
00691
00692
00693
00694
00695
00696 void swap(variant& rhs) noexcept(
00697 absl::conjunction<
00698 std::is_nothrow_move_constructible<T0>,
00699 std::is_nothrow_move_constructible<Tn>...,
00700 type_traits_internal::IsNothrowSwappable<T0>,
00701 type_traits_internal::IsNothrowSwappable<Tn>...>::value) {
00702 return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
00703 variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
00704 }
00705 };
00706
00707
00708
00709
00710 template <>
00711 class variant<>;
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 template <typename... Types>
00739 constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
00740 const variant<Types...>& a, const variant<Types...>& b) {
00741 return (a.index() == b.index()) &&
00742 variant_internal::VisitIndices<sizeof...(Types)>::Run(
00743 variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
00744 }
00745
00746
00747 template <typename... Types>
00748 constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
00749 const variant<Types...>& a, const variant<Types...>& b) {
00750 return (a.index() != b.index()) ||
00751 variant_internal::VisitIndices<sizeof...(Types)>::Run(
00752 variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
00753 }
00754
00755
00756 template <typename... Types>
00757 constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
00758 const variant<Types...>& a, const variant<Types...>& b) {
00759 return (a.index() != b.index())
00760 ? (a.index() + 1) < (b.index() + 1)
00761 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00762 variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
00763 }
00764
00765
00766 template <typename... Types>
00767 constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
00768 const variant<Types...>& a, const variant<Types...>& b) {
00769 return (a.index() != b.index())
00770 ? (a.index() + 1) > (b.index() + 1)
00771 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00772 variant_internal::GreaterThanOp<Types...>{&a, &b},
00773 a.index());
00774 }
00775
00776
00777 template <typename... Types>
00778 constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
00779 const variant<Types...>& a, const variant<Types...>& b) {
00780 return (a.index() != b.index())
00781 ? (a.index() + 1) < (b.index() + 1)
00782 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00783 variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
00784 a.index());
00785 }
00786
00787
00788 template <typename... Types>
00789 constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
00790 operator>=(const variant<Types...>& a, const variant<Types...>& b) {
00791 return (a.index() != b.index())
00792 ? (a.index() + 1) > (b.index() + 1)
00793 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00794 variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
00795 a.index());
00796 }
00797
00798 }
00799
00800 namespace std {
00801
00802
00803 template <>
00804 struct hash<absl::monostate> {
00805 std::size_t operator()(absl::monostate) const { return 0; }
00806 };
00807
00808 template <class... T>
00809 struct hash<absl::variant<T...>>
00810 : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
00811 absl::remove_const_t<T>...> {};
00812
00813 }
00814
00815 #endif // ABSL_HAVE_STD_VARIANT
00816
00817 namespace absl {
00818 namespace variant_internal {
00819
00820
00821
00822 template <typename To>
00823 struct ConversionVisitor {
00824 template <typename T>
00825 To operator()(T&& v) const {
00826 return To(std::forward<T>(v));
00827 }
00828 };
00829
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 template <typename To, typename Variant>
00848 To ConvertVariantTo(Variant&& variant) {
00849 return absl::visit(variant_internal::ConversionVisitor<To>{},
00850 std::forward<Variant>(variant));
00851 }
00852
00853 }
00854
00855 #endif // ABSL_TYPES_VARIANT_H_