00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ABSL_TYPES_variant_internal_H_
00020 #define ABSL_TYPES_variant_internal_H_
00021
00022 #include <cassert>
00023 #include <cstddef>
00024 #include <cstdlib>
00025 #include <memory>
00026 #include <stdexcept>
00027 #include <tuple>
00028 #include <type_traits>
00029
00030 #include "absl/base/config.h"
00031 #include "absl/base/internal/identity.h"
00032 #include "absl/base/internal/inline_variable.h"
00033 #include "absl/base/internal/invoke.h"
00034 #include "absl/base/macros.h"
00035 #include "absl/base/optimization.h"
00036 #include "absl/meta/type_traits.h"
00037 #include "absl/types/bad_variant_access.h"
00038 #include "absl/utility/utility.h"
00039
00040 #if !defined(ABSL_HAVE_STD_VARIANT)
00041
00042 namespace absl {
00043
00044 template <class... Types>
00045 class variant;
00046
00047 ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1);
00048
00049 template <class T>
00050 struct variant_size;
00051
00052 template <std::size_t I, class T>
00053 struct variant_alternative;
00054
00055 namespace variant_internal {
00056
00057
00058 template <std::size_t I, class T>
00059 struct VariantAlternativeSfinae {};
00060
00061
00062
00063
00064 template <std::size_t I, class T0, class... Tn>
00065 struct VariantAlternativeSfinae<I, variant<T0, Tn...>>
00066 : VariantAlternativeSfinae<I - 1, variant<Tn...>> {};
00067
00068
00069 template <class T0, class... Ts>
00070 struct VariantAlternativeSfinae<0, variant<T0, Ts...>> {
00071 using type = T0;
00072 };
00073
00074 template <std::size_t I, class T>
00075 using VariantAlternativeSfinaeT = typename VariantAlternativeSfinae<I, T>::type;
00076
00077
00078 template <class T, class U>
00079 struct GiveQualsTo;
00080
00081 template <class T, class U>
00082 struct GiveQualsTo<T&, U> {
00083 using type = U&;
00084 };
00085
00086 template <class T, class U>
00087 struct GiveQualsTo<T&&, U> {
00088 using type = U&&;
00089 };
00090
00091 template <class T, class U>
00092 struct GiveQualsTo<const T&, U> {
00093 using type = const U&;
00094 };
00095
00096 template <class T, class U>
00097 struct GiveQualsTo<const T&&, U> {
00098 using type = const U&&;
00099 };
00100
00101 template <class T, class U>
00102 struct GiveQualsTo<volatile T&, U> {
00103 using type = volatile U&;
00104 };
00105
00106 template <class T, class U>
00107 struct GiveQualsTo<volatile T&&, U> {
00108 using type = volatile U&&;
00109 };
00110
00111 template <class T, class U>
00112 struct GiveQualsTo<volatile const T&, U> {
00113 using type = volatile const U&;
00114 };
00115
00116 template <class T, class U>
00117 struct GiveQualsTo<volatile const T&&, U> {
00118 using type = volatile const U&&;
00119 };
00120
00121 template <class T, class U>
00122 using GiveQualsToT = typename GiveQualsTo<T, U>::type;
00123
00124
00125 template <std::size_t I>
00126 using SizeT = std::integral_constant<std::size_t, I>;
00127
00128 using NPos = SizeT<variant_npos>;
00129
00130 template <class Variant, class T, class = void>
00131 struct IndexOfConstructedType {};
00132
00133 template <std::size_t I, class Variant>
00134 struct VariantAccessResultImpl;
00135
00136 template <std::size_t I, template <class...> class Variantemplate, class... T>
00137 struct VariantAccessResultImpl<I, Variantemplate<T...>&> {
00138 using type = typename absl::variant_alternative<I, variant<T...>>::type&;
00139 };
00140
00141 template <std::size_t I, template <class...> class Variantemplate, class... T>
00142 struct VariantAccessResultImpl<I, const Variantemplate<T...>&> {
00143 using type =
00144 const typename absl::variant_alternative<I, variant<T...>>::type&;
00145 };
00146
00147 template <std::size_t I, template <class...> class Variantemplate, class... T>
00148 struct VariantAccessResultImpl<I, Variantemplate<T...>&&> {
00149 using type = typename absl::variant_alternative<I, variant<T...>>::type&&;
00150 };
00151
00152 template <std::size_t I, template <class...> class Variantemplate, class... T>
00153 struct VariantAccessResultImpl<I, const Variantemplate<T...>&&> {
00154 using type =
00155 const typename absl::variant_alternative<I, variant<T...>>::type&&;
00156 };
00157
00158 template <std::size_t I, class Variant>
00159 using VariantAccessResult =
00160 typename VariantAccessResultImpl<I, Variant&&>::type;
00161
00162
00163 template <class T, std::size_t Size>
00164 struct SimpleArray {
00165 static_assert(Size != 0, "");
00166 T value[Size];
00167 };
00168
00169 template <class T>
00170 struct AccessedType {
00171 using type = T;
00172 };
00173
00174 template <class T>
00175 using AccessedTypeT = typename AccessedType<T>::type;
00176
00177 template <class T, std::size_t Size>
00178 struct AccessedType<SimpleArray<T, Size>> {
00179 using type = AccessedTypeT<T>;
00180 };
00181
00182 template <class T>
00183 constexpr T AccessSimpleArray(const T& value) {
00184 return value;
00185 }
00186
00187 template <class T, std::size_t Size, class... SizeT>
00188 constexpr AccessedTypeT<T> AccessSimpleArray(const SimpleArray<T, Size>& table,
00189 std::size_t head_index,
00190 SizeT... tail_indices) {
00191 return AccessSimpleArray(table.value[head_index], tail_indices...);
00192 }
00193
00194
00195 template <class T>
00196 using AlwaysZero = SizeT<0>;
00197
00198 template <class Op, class... Vs>
00199 struct VisitIndicesResultImpl {
00200 using type = absl::result_of_t<Op(AlwaysZero<Vs>...)>;
00201 };
00202
00203 template <class Op, class... Vs>
00204 using VisitIndicesResultT = typename VisitIndicesResultImpl<Op, Vs...>::type;
00205
00206 template <class ReturnType, class FunctionObject, class EndIndices,
00207 std::size_t... BoundIndices>
00208 struct MakeVisitationMatrix;
00209
00210 template <class ReturnType, class FunctionObject, std::size_t... Indices>
00211 constexpr ReturnType call_with_indices(FunctionObject&& function) {
00212 static_assert(
00213 std::is_same<ReturnType, decltype(std::declval<FunctionObject>()(
00214 SizeT<Indices>()...))>::value,
00215 "Not all visitation overloads have the same return type.");
00216 return absl::forward<FunctionObject>(function)(SizeT<Indices>()...);
00217 }
00218
00219 template <class ReturnType, class FunctionObject, std::size_t... BoundIndices>
00220 struct MakeVisitationMatrix<ReturnType, FunctionObject, index_sequence<>,
00221 BoundIndices...> {
00222 using ResultType = ReturnType (*)(FunctionObject&&);
00223 static constexpr ResultType Run() {
00224 return &call_with_indices<ReturnType, FunctionObject,
00225 (BoundIndices - 1)...>;
00226 }
00227 };
00228
00229 template <class ReturnType, class FunctionObject, class EndIndices,
00230 class CurrIndices, std::size_t... BoundIndices>
00231 struct MakeVisitationMatrixImpl;
00232
00233 template <class ReturnType, class FunctionObject, std::size_t... EndIndices,
00234 std::size_t... CurrIndices, std::size_t... BoundIndices>
00235 struct MakeVisitationMatrixImpl<
00236 ReturnType, FunctionObject, index_sequence<EndIndices...>,
00237 index_sequence<CurrIndices...>, BoundIndices...> {
00238 using ResultType = SimpleArray<
00239 typename MakeVisitationMatrix<ReturnType, FunctionObject,
00240 index_sequence<EndIndices...>>::ResultType,
00241 sizeof...(CurrIndices)>;
00242
00243 static constexpr ResultType Run() {
00244 return {{MakeVisitationMatrix<ReturnType, FunctionObject,
00245 index_sequence<EndIndices...>,
00246 BoundIndices..., CurrIndices>::Run()...}};
00247 }
00248 };
00249
00250 template <class ReturnType, class FunctionObject, std::size_t HeadEndIndex,
00251 std::size_t... TailEndIndices, std::size_t... BoundIndices>
00252 struct MakeVisitationMatrix<ReturnType, FunctionObject,
00253 index_sequence<HeadEndIndex, TailEndIndices...>,
00254 BoundIndices...>
00255 : MakeVisitationMatrixImpl<
00256 ReturnType, FunctionObject, index_sequence<TailEndIndices...>,
00257 absl::make_index_sequence<HeadEndIndex>, BoundIndices...> {};
00258
00259 struct UnreachableSwitchCase {
00260 template <class Op>
00261 [[noreturn]] static VisitIndicesResultT<Op, std::size_t> Run(
00262 Op&& ) {
00263 #if ABSL_HAVE_BUILTIN(__builtin_unreachable) || \
00264 (defined(__GNUC__) && !defined(__clang__))
00265 __builtin_unreachable();
00266 #elif defined(_MSC_VER)
00267 __assume(false);
00268 #else
00269
00270
00271
00272 assert(false);
00273
00274
00275 return Run(absl::forward<Op>(op));
00276 #endif // Checks for __builtin_unreachable
00277 }
00278 };
00279
00280 template <class Op, std::size_t I>
00281 struct ReachableSwitchCase {
00282 static VisitIndicesResultT<Op, std::size_t> Run(Op&& op) {
00283 return absl::base_internal::Invoke(absl::forward<Op>(op), SizeT<I>());
00284 }
00285 };
00286
00287
00288
00289
00290
00291
00292 ABSL_INTERNAL_INLINE_CONSTEXPR(std::size_t, MaxUnrolledVisitCases, 33);
00293
00294
00295 template <bool IsReachable>
00296 struct PickCaseImpl {
00297 template <class Op, std::size_t I>
00298 using Apply = UnreachableSwitchCase;
00299 };
00300
00301 template <>
00302 struct PickCaseImpl<true> {
00303 template <class Op, std::size_t I>
00304 using Apply = ReachableSwitchCase<Op, I>;
00305 };
00306
00307
00308
00309
00310
00311
00312 template <class Op, std::size_t I, std::size_t EndIndex>
00313 using PickCase = typename PickCaseImpl<(I < EndIndex)>::template Apply<Op, I>;
00314
00315 template <class ReturnType>
00316 [[noreturn]] ReturnType TypedThrowBadVariantAccess() {
00317 absl::variant_internal::ThrowBadVariantAccess();
00318 }
00319
00320
00321
00322
00323 template <std::size_t... NumAlternatives>
00324 struct NumCasesOfSwitch;
00325
00326 template <std::size_t HeadNumAlternatives, std::size_t... TailNumAlternatives>
00327 struct NumCasesOfSwitch<HeadNumAlternatives, TailNumAlternatives...> {
00328 static constexpr std::size_t value =
00329 (HeadNumAlternatives + 1) *
00330 NumCasesOfSwitch<TailNumAlternatives...>::value;
00331 };
00332
00333 template <>
00334 struct NumCasesOfSwitch<> {
00335 static constexpr std::size_t value = 1;
00336 };
00337
00338
00339 template <std::size_t EndIndex>
00340 struct VisitIndicesSwitch {
00341 static_assert(EndIndex <= MaxUnrolledVisitCases,
00342 "Maximum unrolled switch size exceeded.");
00343
00344 template <class Op>
00345 static VisitIndicesResultT<Op, std::size_t> Run(Op&& op, std::size_t i) {
00346 switch (i) {
00347 case 0:
00348 return PickCase<Op, 0, EndIndex>::Run(absl::forward<Op>(op));
00349 case 1:
00350 return PickCase<Op, 1, EndIndex>::Run(absl::forward<Op>(op));
00351 case 2:
00352 return PickCase<Op, 2, EndIndex>::Run(absl::forward<Op>(op));
00353 case 3:
00354 return PickCase<Op, 3, EndIndex>::Run(absl::forward<Op>(op));
00355 case 4:
00356 return PickCase<Op, 4, EndIndex>::Run(absl::forward<Op>(op));
00357 case 5:
00358 return PickCase<Op, 5, EndIndex>::Run(absl::forward<Op>(op));
00359 case 6:
00360 return PickCase<Op, 6, EndIndex>::Run(absl::forward<Op>(op));
00361 case 7:
00362 return PickCase<Op, 7, EndIndex>::Run(absl::forward<Op>(op));
00363 case 8:
00364 return PickCase<Op, 8, EndIndex>::Run(absl::forward<Op>(op));
00365 case 9:
00366 return PickCase<Op, 9, EndIndex>::Run(absl::forward<Op>(op));
00367 case 10:
00368 return PickCase<Op, 10, EndIndex>::Run(absl::forward<Op>(op));
00369 case 11:
00370 return PickCase<Op, 11, EndIndex>::Run(absl::forward<Op>(op));
00371 case 12:
00372 return PickCase<Op, 12, EndIndex>::Run(absl::forward<Op>(op));
00373 case 13:
00374 return PickCase<Op, 13, EndIndex>::Run(absl::forward<Op>(op));
00375 case 14:
00376 return PickCase<Op, 14, EndIndex>::Run(absl::forward<Op>(op));
00377 case 15:
00378 return PickCase<Op, 15, EndIndex>::Run(absl::forward<Op>(op));
00379 case 16:
00380 return PickCase<Op, 16, EndIndex>::Run(absl::forward<Op>(op));
00381 case 17:
00382 return PickCase<Op, 17, EndIndex>::Run(absl::forward<Op>(op));
00383 case 18:
00384 return PickCase<Op, 18, EndIndex>::Run(absl::forward<Op>(op));
00385 case 19:
00386 return PickCase<Op, 19, EndIndex>::Run(absl::forward<Op>(op));
00387 case 20:
00388 return PickCase<Op, 20, EndIndex>::Run(absl::forward<Op>(op));
00389 case 21:
00390 return PickCase<Op, 21, EndIndex>::Run(absl::forward<Op>(op));
00391 case 22:
00392 return PickCase<Op, 22, EndIndex>::Run(absl::forward<Op>(op));
00393 case 23:
00394 return PickCase<Op, 23, EndIndex>::Run(absl::forward<Op>(op));
00395 case 24:
00396 return PickCase<Op, 24, EndIndex>::Run(absl::forward<Op>(op));
00397 case 25:
00398 return PickCase<Op, 25, EndIndex>::Run(absl::forward<Op>(op));
00399 case 26:
00400 return PickCase<Op, 26, EndIndex>::Run(absl::forward<Op>(op));
00401 case 27:
00402 return PickCase<Op, 27, EndIndex>::Run(absl::forward<Op>(op));
00403 case 28:
00404 return PickCase<Op, 28, EndIndex>::Run(absl::forward<Op>(op));
00405 case 29:
00406 return PickCase<Op, 29, EndIndex>::Run(absl::forward<Op>(op));
00407 case 30:
00408 return PickCase<Op, 30, EndIndex>::Run(absl::forward<Op>(op));
00409 case 31:
00410 return PickCase<Op, 31, EndIndex>::Run(absl::forward<Op>(op));
00411 case 32:
00412 return PickCase<Op, 32, EndIndex>::Run(absl::forward<Op>(op));
00413 default:
00414 ABSL_ASSERT(i == variant_npos);
00415 return absl::base_internal::Invoke(absl::forward<Op>(op), NPos());
00416 }
00417 }
00418 };
00419
00420 template <std::size_t... EndIndices>
00421 struct VisitIndicesFallback {
00422 template <class Op, class... SizeT>
00423 static VisitIndicesResultT<Op, SizeT...> Run(Op&& op, SizeT... indices) {
00424 return AccessSimpleArray(
00425 MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op,
00426 index_sequence<(EndIndices + 1)...>>::Run(),
00427 (indices + 1)...)(absl::forward<Op>(op));
00428 }
00429 };
00430
00431
00432
00433
00434 template <std::size_t...>
00435 struct FlattenIndices;
00436
00437 template <std::size_t HeadSize, std::size_t... TailSize>
00438 struct FlattenIndices<HeadSize, TailSize...> {
00439 template<class... SizeType>
00440 static constexpr std::size_t Run(std::size_t head, SizeType... tail) {
00441 return head + HeadSize * FlattenIndices<TailSize...>::Run(tail...);
00442 }
00443 };
00444
00445 template <>
00446 struct FlattenIndices<> {
00447 static constexpr std::size_t Run() { return 0; }
00448 };
00449
00450
00451
00452 template <std::size_t I, std::size_t IndexToGet, std::size_t HeadSize,
00453 std::size_t... TailSize>
00454 struct UnflattenIndex {
00455 static constexpr std::size_t value =
00456 UnflattenIndex<I / HeadSize, IndexToGet - 1, TailSize...>::value;
00457 };
00458
00459 template <std::size_t I, std::size_t HeadSize, std::size_t... TailSize>
00460 struct UnflattenIndex<I, 0, HeadSize, TailSize...> {
00461 static constexpr std::size_t value = (I % HeadSize);
00462 };
00463
00464
00465 template <class IndexSequence, std::size_t... EndIndices>
00466 struct VisitIndicesVariadicImpl;
00467
00468 template <std::size_t... N, std::size_t... EndIndices>
00469 struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> {
00470
00471
00472
00473 template <class Op>
00474 struct FlattenedOp {
00475 template <std::size_t I>
00476 VisitIndicesResultT<Op, decltype(EndIndices)...> operator()(
00477 SizeT<I> ) && {
00478 return base_internal::Invoke(
00479 absl::forward<Op>(op),
00480 SizeT<UnflattenIndex<I, N, (EndIndices + 1)...>::value -
00481 std::size_t{1}>()...);
00482 }
00483
00484 Op&& op;
00485 };
00486
00487 template <class Op, class... SizeType>
00488 static VisitIndicesResultT<Op, decltype(EndIndices)...> Run(
00489 Op&& op, SizeType... i) {
00490 return VisitIndicesSwitch<NumCasesOfSwitch<EndIndices...>::value>::Run(
00491 FlattenedOp<Op>{absl::forward<Op>(op)},
00492 FlattenIndices<(EndIndices + std::size_t{1})...>::Run(
00493 (i + std::size_t{1})...));
00494 }
00495 };
00496
00497 template <std::size_t... EndIndices>
00498 struct VisitIndicesVariadic
00499 : VisitIndicesVariadicImpl<absl::make_index_sequence<sizeof...(EndIndices)>,
00500 EndIndices...> {};
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 template <std::size_t... EndIndices>
00511 struct VisitIndices
00512 : absl::conditional_t<(NumCasesOfSwitch<EndIndices...>::value <=
00513 MaxUnrolledVisitCases),
00514 VisitIndicesVariadic<EndIndices...>,
00515 VisitIndicesFallback<EndIndices...>> {};
00516
00517 template <std::size_t EndIndex>
00518 struct VisitIndices<EndIndex>
00519 : absl::conditional_t<(EndIndex <= MaxUnrolledVisitCases),
00520 VisitIndicesSwitch<EndIndex>,
00521 VisitIndicesFallback<EndIndex>> {};
00522
00523
00524
00525 #ifdef _MSC_VER
00526 #pragma warning(push)
00527 #pragma warning(disable : 4172)
00528 #endif
00529
00530
00531
00532
00533
00534 template <class Self, std::size_t I>
00535 inline VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> ) {
00536 return reinterpret_cast<VariantAccessResult<I, Self>>(self);
00537 }
00538
00539 #ifdef _MSC_VER
00540 #pragma warning(pop)
00541 #endif
00542
00543 template <class T>
00544 void DeducedDestroy(T& self) {
00545 self.~T();
00546 }
00547
00548
00549
00550
00551
00552 struct VariantCoreAccess {
00553 template <class VariantType>
00554 static typename VariantType::Variant& Derived(VariantType& self) {
00555 return static_cast<typename VariantType::Variant&>(self);
00556 }
00557
00558 template <class VariantType>
00559 static const typename VariantType::Variant& Derived(
00560 const VariantType& self) {
00561 return static_cast<const typename VariantType::Variant&>(self);
00562 }
00563
00564 template <class VariantType>
00565 static void Destroy(VariantType& self) {
00566 Derived(self).destroy();
00567 self.index_ = absl::variant_npos;
00568 }
00569
00570 template <class Variant>
00571 static void SetIndex(Variant& self, std::size_t i) {
00572 self.index_ = i;
00573 }
00574
00575 template <class Variant>
00576 static void InitFrom(Variant& self, Variant&& other) {
00577 VisitIndices<absl::variant_size<Variant>::value>::Run(
00578 InitFromVisitor<Variant, Variant&&>{&self,
00579 std::forward<Variant>(other)},
00580 other.index());
00581 self.index_ = other.index();
00582 }
00583
00584
00585 template <std::size_t I, class Variant>
00586 static VariantAccessResult<I, Variant> Access(Variant&& self) {
00587
00588
00589
00590
00591 return static_cast<VariantAccessResult<I, Variant>>(
00592 variant_internal::AccessUnion(self.state_, SizeT<I>()));
00593 }
00594
00595
00596 template <std::size_t I, class Variant>
00597 static VariantAccessResult<I, Variant> CheckedAccess(Variant&& self) {
00598 if (ABSL_PREDICT_FALSE(self.index_ != I)) {
00599 TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();
00600 }
00601
00602 return Access<I>(absl::forward<Variant>(self));
00603 }
00604
00605
00606 template <class VType>
00607 struct MoveAssignVisitor {
00608 using DerivedType = typename VType::Variant;
00609 template <std::size_t NewIndex>
00610 void operator()(SizeT<NewIndex> ) const {
00611 if (left->index_ == NewIndex) {
00612 Access<NewIndex>(*left) = std::move(Access<NewIndex>(*right));
00613 } else {
00614 Derived(*left).template emplace<NewIndex>(
00615 std::move(Access<NewIndex>(*right)));
00616 }
00617 }
00618
00619 void operator()(SizeT<absl::variant_npos> ) const {
00620 Destroy(*left);
00621 }
00622
00623 VType* left;
00624 VType* right;
00625 };
00626
00627 template <class VType>
00628 static MoveAssignVisitor<VType> MakeMoveAssignVisitor(VType* left,
00629 VType* other) {
00630 return {left, other};
00631 }
00632
00633
00634 template <class VType>
00635 struct CopyAssignVisitor {
00636 using DerivedType = typename VType::Variant;
00637 template <std::size_t NewIndex>
00638 void operator()(SizeT<NewIndex> ) const {
00639 using New =
00640 typename absl::variant_alternative<NewIndex, DerivedType>::type;
00641
00642 if (left->index_ == NewIndex) {
00643 Access<NewIndex>(*left) = Access<NewIndex>(*right);
00644 } else if (std::is_nothrow_copy_constructible<New>::value ||
00645 !std::is_nothrow_move_constructible<New>::value) {
00646 Derived(*left).template emplace<NewIndex>(Access<NewIndex>(*right));
00647 } else {
00648 Derived(*left) = DerivedType(Derived(*right));
00649 }
00650 }
00651
00652 void operator()(SizeT<absl::variant_npos> ) const {
00653 Destroy(*left);
00654 }
00655
00656 VType* left;
00657 const VType* right;
00658 };
00659
00660 template <class VType>
00661 static CopyAssignVisitor<VType> MakeCopyAssignVisitor(VType* left,
00662 const VType& other) {
00663 return {left, &other};
00664 }
00665
00666
00667 template <class Left, class QualifiedNew>
00668 struct ConversionAssignVisitor {
00669 using NewIndex =
00670 variant_internal::IndexOfConstructedType<Left, QualifiedNew>;
00671
00672 void operator()(SizeT<NewIndex::value>
00673 ) const {
00674 Access<NewIndex::value>(*left) = absl::forward<QualifiedNew>(other);
00675 }
00676
00677 template <std::size_t OldIndex>
00678 void operator()(SizeT<OldIndex>
00679 ) const {
00680 using New =
00681 typename absl::variant_alternative<NewIndex::value, Left>::type;
00682 if (std::is_nothrow_constructible<New, QualifiedNew>::value ||
00683 !std::is_nothrow_move_constructible<New>::value) {
00684 left->template emplace<NewIndex::value>(
00685 absl::forward<QualifiedNew>(other));
00686 } else {
00687
00688
00689
00690 left->template emplace<NewIndex::value>(
00691 New(absl::forward<QualifiedNew>(other)));
00692 }
00693 }
00694
00695 Left* left;
00696 QualifiedNew&& other;
00697 };
00698
00699 template <class Left, class QualifiedNew>
00700 static ConversionAssignVisitor<Left, QualifiedNew>
00701 MakeConversionAssignVisitor(Left* left, QualifiedNew&& qual) {
00702 return {left, absl::forward<QualifiedNew>(qual)};
00703 }
00704
00705
00706
00707 template <std::size_t NewIndex, class Self, class... Args>
00708 static typename absl::variant_alternative<NewIndex, Self>::type& Replace(
00709 Self* self, Args&&... args) {
00710 Destroy(*self);
00711 using New = typename absl::variant_alternative<NewIndex, Self>::type;
00712 New* const result = ::new (static_cast<void*>(&self->state_))
00713 New(absl::forward<Args>(args)...);
00714 self->index_ = NewIndex;
00715 return *result;
00716 }
00717
00718 template <class LeftVariant, class QualifiedRightVariant>
00719 struct InitFromVisitor {
00720 template <std::size_t NewIndex>
00721 void operator()(SizeT<NewIndex> ) const {
00722 using Alternative =
00723 typename variant_alternative<NewIndex, LeftVariant>::type;
00724 ::new (static_cast<void*>(&left->state_)) Alternative(
00725 Access<NewIndex>(std::forward<QualifiedRightVariant>(right)));
00726 }
00727
00728 void operator()(SizeT<absl::variant_npos> ) const {
00729
00730 }
00731 LeftVariant* left;
00732 QualifiedRightVariant&& right;
00733 };
00734 };
00735
00736 template <class Expected, class... T>
00737 struct IndexOfImpl;
00738
00739 template <class Expected>
00740 struct IndexOfImpl<Expected> {
00741 using IndexFromEnd = SizeT<0>;
00742 using MatchedIndexFromEnd = IndexFromEnd;
00743 using MultipleMatches = std::false_type;
00744 };
00745
00746 template <class Expected, class Head, class... Tail>
00747 struct IndexOfImpl<Expected, Head, Tail...> : IndexOfImpl<Expected, Tail...> {
00748 using IndexFromEnd =
00749 SizeT<IndexOfImpl<Expected, Tail...>::IndexFromEnd::value + 1>;
00750 };
00751
00752 template <class Expected, class... Tail>
00753 struct IndexOfImpl<Expected, Expected, Tail...>
00754 : IndexOfImpl<Expected, Tail...> {
00755 using IndexFromEnd =
00756 SizeT<IndexOfImpl<Expected, Tail...>::IndexFromEnd::value + 1>;
00757 using MatchedIndexFromEnd = IndexFromEnd;
00758 using MultipleMatches = std::integral_constant<
00759 bool, IndexOfImpl<Expected, Tail...>::MatchedIndexFromEnd::value != 0>;
00760 };
00761
00762 template <class Expected, class... Types>
00763 struct IndexOfMeta {
00764 using Results = IndexOfImpl<Expected, Types...>;
00765 static_assert(!Results::MultipleMatches::value,
00766 "Attempted to access a variant by specifying a type that "
00767 "matches more than one alternative.");
00768 static_assert(Results::MatchedIndexFromEnd::value != 0,
00769 "Attempted to access a variant by specifying a type that does "
00770 "not match any alternative.");
00771 using type = SizeT<sizeof...(Types) - Results::MatchedIndexFromEnd::value>;
00772 };
00773
00774 template <class Expected, class... Types>
00775 using IndexOf = typename IndexOfMeta<Expected, Types...>::type;
00776
00777 template <class Variant, class T, std::size_t CurrIndex>
00778 struct UnambiguousIndexOfImpl;
00779
00780
00781 template <class T, std::size_t CurrIndex>
00782 struct UnambiguousIndexOfImpl<variant<>, T, CurrIndex> : SizeT<CurrIndex> {};
00783
00784
00785 template <class Head, class... Tail, class T, std::size_t CurrIndex>
00786 struct UnambiguousIndexOfImpl<variant<Head, Tail...>, T, CurrIndex>
00787 : UnambiguousIndexOfImpl<variant<Tail...>, T, CurrIndex + 1>::type {};
00788
00789
00790 template <class Head, class... Tail, std::size_t CurrIndex>
00791 struct UnambiguousIndexOfImpl<variant<Head, Tail...>, Head, CurrIndex>
00792 : SizeT<UnambiguousIndexOfImpl<variant<Tail...>, Head, 0>::value ==
00793 sizeof...(Tail)
00794 ? CurrIndex
00795 : CurrIndex + sizeof...(Tail) + 1> {};
00796
00797 template <class Variant, class T>
00798 struct UnambiguousIndexOf;
00799
00800 struct NoMatch {
00801 struct type {};
00802 };
00803
00804 template <class... Alts, class T>
00805 struct UnambiguousIndexOf<variant<Alts...>, T>
00806 : std::conditional<UnambiguousIndexOfImpl<variant<Alts...>, T, 0>::value !=
00807 sizeof...(Alts),
00808 UnambiguousIndexOfImpl<variant<Alts...>, T, 0>,
00809 NoMatch>::type::type {};
00810
00811 template <class T, std::size_t >
00812 using UnambiguousTypeOfImpl = T;
00813
00814 template <class Variant, class T>
00815 using UnambiguousTypeOfT =
00816 UnambiguousTypeOfImpl<T, UnambiguousIndexOf<Variant, T>::value>;
00817
00818 template <class H, class... T>
00819 class VariantStateBase;
00820
00821
00822
00823
00824
00825 template <class Variant, std::size_t I = 0>
00826 struct ImaginaryFun;
00827
00828 template <std::size_t I>
00829 struct ImaginaryFun<variant<>, I> {
00830 static void Run() = delete;
00831 };
00832
00833 template <class H, class... T, std::size_t I>
00834 struct ImaginaryFun<variant<H, T...>, I> : ImaginaryFun<variant<T...>, I + 1> {
00835 using ImaginaryFun<variant<T...>, I + 1>::Run;
00836
00837
00838
00839
00840 static SizeT<I> Run(const H&);
00841 static SizeT<I> Run(H&&);
00842 };
00843
00844
00845
00846 template <class Self, class T>
00847 struct IsNeitherSelfNorInPlace : std::true_type {};
00848
00849 template <class Self>
00850 struct IsNeitherSelfNorInPlace<Self, Self> : std::false_type {};
00851
00852 template <class Self, class T>
00853 struct IsNeitherSelfNorInPlace<Self, in_place_type_t<T>> : std::false_type {};
00854
00855 template <class Self, std::size_t I>
00856 struct IsNeitherSelfNorInPlace<Self, in_place_index_t<I>> : std::false_type {};
00857
00858 template <class Variant, class T, class = void>
00859 struct ConversionIsPossibleImpl : std::false_type {};
00860
00861 template <class Variant, class T>
00862 struct ConversionIsPossibleImpl<
00863 Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>>
00864 : std::true_type {};
00865
00866 template <class Variant, class T>
00867 struct ConversionIsPossible : ConversionIsPossibleImpl<Variant, T>::type {};
00868
00869 template <class Variant, class T>
00870 struct IndexOfConstructedType<
00871 Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>>
00872 : decltype(ImaginaryFun<Variant>::Run(std::declval<T>())) {};
00873
00874 template <std::size_t... Is>
00875 struct ContainsVariantNPos
00876 : absl::negation<std::is_same<
00877 absl::integer_sequence<bool, 0 <= Is...>,
00878 absl::integer_sequence<bool, Is != absl::variant_npos...>>> {};
00879
00880 template <class Op, class... QualifiedVariants>
00881 using RawVisitResult =
00882 absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>;
00883
00884
00885
00886
00887
00888
00889
00890 template <class Op, class... QualifiedVariants>
00891 struct VisitResultImpl {
00892 using type =
00893 absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>;
00894 };
00895
00896
00897 template <class Op, class... QualifiedVariants>
00898 using VisitResult = typename VisitResultImpl<Op, QualifiedVariants...>::type;
00899
00900 template <class Op, class... QualifiedVariants>
00901 struct PerformVisitation {
00902 using ReturnType = VisitResult<Op, QualifiedVariants...>;
00903
00904 template <std::size_t... Is>
00905 constexpr ReturnType operator()(SizeT<Is>... indices) const {
00906 return Run(typename ContainsVariantNPos<Is...>::type{},
00907 absl::index_sequence_for<QualifiedVariants...>(), indices...);
00908 }
00909
00910 template <std::size_t... TupIs, std::size_t... Is>
00911 constexpr ReturnType Run(std::false_type ,
00912 index_sequence<TupIs...>, SizeT<Is>...) const {
00913 static_assert(
00914 std::is_same<ReturnType,
00915 absl::result_of_t<Op(VariantAccessResult<
00916 Is, QualifiedVariants>...)>>::value,
00917 "All visitation overloads must have the same return type.");
00918 return absl::base_internal::Invoke(
00919 absl::forward<Op>(op),
00920 VariantCoreAccess::Access<Is>(
00921 absl::forward<QualifiedVariants>(std::get<TupIs>(variant_tup)))...);
00922 }
00923
00924 template <std::size_t... TupIs, std::size_t... Is>
00925 [[noreturn]] ReturnType Run(std::true_type ,
00926 index_sequence<TupIs...>, SizeT<Is>...) const {
00927 absl::variant_internal::ThrowBadVariantAccess();
00928 }
00929
00930
00931
00932 std::tuple<QualifiedVariants&&...> variant_tup;
00933 Op&& op;
00934 };
00935
00936 template <class... T>
00937 union Union;
00938
00939
00940
00941
00942
00943 struct NoopConstructorTag {};
00944
00945 template <std::size_t I>
00946 struct EmplaceTag {};
00947
00948 template <>
00949 union Union<> {
00950 constexpr explicit Union(NoopConstructorTag) noexcept {}
00951 };
00952
00953
00954
00955 #ifdef _MSC_VER
00956 #pragma warning(push)
00957 #pragma warning(disable : 4624)
00958 #endif
00959
00960 template <class Head, class... Tail>
00961 union Union<Head, Tail...> {
00962 using TailUnion = Union<Tail...>;
00963
00964 explicit constexpr Union(NoopConstructorTag ) noexcept
00965 : tail(NoopConstructorTag()) {}
00966
00967 template <class... P>
00968 explicit constexpr Union(EmplaceTag<0>, P&&... args)
00969 : head(absl::forward<P>(args)...) {}
00970
00971 template <std::size_t I, class... P>
00972 explicit constexpr Union(EmplaceTag<I>, P&&... args)
00973 : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {}
00974
00975 Head head;
00976 TailUnion tail;
00977 };
00978
00979 #ifdef _MSC_VER
00980 #pragma warning(pop)
00981 #endif
00982
00983
00984 template <class... T>
00985 union DestructibleUnionImpl;
00986
00987 template <>
00988 union DestructibleUnionImpl<> {
00989 constexpr explicit DestructibleUnionImpl(NoopConstructorTag) noexcept {}
00990 };
00991
00992 template <class Head, class... Tail>
00993 union DestructibleUnionImpl<Head, Tail...> {
00994 using TailUnion = DestructibleUnionImpl<Tail...>;
00995
00996 explicit constexpr DestructibleUnionImpl(NoopConstructorTag ) noexcept
00997 : tail(NoopConstructorTag()) {}
00998
00999 template <class... P>
01000 explicit constexpr DestructibleUnionImpl(EmplaceTag<0>, P&&... args)
01001 : head(absl::forward<P>(args)...) {}
01002
01003 template <std::size_t I, class... P>
01004 explicit constexpr DestructibleUnionImpl(EmplaceTag<I>, P&&... args)
01005 : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {}
01006
01007 ~DestructibleUnionImpl() {}
01008
01009 Head head;
01010 TailUnion tail;
01011 };
01012
01013
01014
01015
01016 template <class... T>
01017 using DestructibleUnion =
01018 absl::conditional_t<std::is_destructible<Union<T...>>::value, Union<T...>,
01019 DestructibleUnionImpl<T...>>;
01020
01021
01022 template <class H, class... T>
01023 class VariantStateBase {
01024 protected:
01025 using Variant = variant<H, T...>;
01026
01027 template <class LazyH = H,
01028 class ConstructibleH = absl::enable_if_t<
01029 std::is_default_constructible<LazyH>::value, LazyH>>
01030 constexpr VariantStateBase() noexcept(
01031 std::is_nothrow_default_constructible<ConstructibleH>::value)
01032 : state_(EmplaceTag<0>()), index_(0) {}
01033
01034 template <std::size_t I, class... P>
01035 explicit constexpr VariantStateBase(EmplaceTag<I> tag, P&&... args)
01036 : state_(tag, absl::forward<P>(args)...), index_(I) {}
01037
01038 explicit constexpr VariantStateBase(NoopConstructorTag)
01039 : state_(NoopConstructorTag()), index_(variant_npos) {}
01040
01041 void destroy() {}
01042
01043 DestructibleUnion<H, T...> state_;
01044 std::size_t index_;
01045 };
01046
01047 using absl::internal::identity;
01048
01049
01050
01051
01052
01053
01054
01055
01056 template <typename... Ts>
01057 struct OverloadSet;
01058
01059 template <typename T, typename... Ts>
01060 struct OverloadSet<T, Ts...> : OverloadSet<Ts...> {
01061 using Base = OverloadSet<Ts...>;
01062 static identity<T> Overload(const T&);
01063 using Base::Overload;
01064 };
01065
01066 template <>
01067 struct OverloadSet<> {
01068
01069 static void Overload(...);
01070 };
01071
01072 template <class T>
01073 using LessThanResult = decltype(std::declval<T>() < std::declval<T>());
01074
01075 template <class T>
01076 using GreaterThanResult = decltype(std::declval<T>() > std::declval<T>());
01077
01078 template <class T>
01079 using LessThanOrEqualResult = decltype(std::declval<T>() <= std::declval<T>());
01080
01081 template <class T>
01082 using GreaterThanOrEqualResult =
01083 decltype(std::declval<T>() >= std::declval<T>());
01084
01085 template <class T>
01086 using EqualResult = decltype(std::declval<T>() == std::declval<T>());
01087
01088 template <class T>
01089 using NotEqualResult = decltype(std::declval<T>() != std::declval<T>());
01090
01091 using type_traits_internal::is_detected_convertible;
01092
01093 template <class... T>
01094 using RequireAllHaveEqualT = absl::enable_if_t<
01095 absl::conjunction<is_detected_convertible<bool, EqualResult, T>...>::value,
01096 bool>;
01097
01098 template <class... T>
01099 using RequireAllHaveNotEqualT =
01100 absl::enable_if_t<absl::conjunction<is_detected_convertible<
01101 bool, NotEqualResult, T>...>::value,
01102 bool>;
01103
01104 template <class... T>
01105 using RequireAllHaveLessThanT =
01106 absl::enable_if_t<absl::conjunction<is_detected_convertible<
01107 bool, LessThanResult, T>...>::value,
01108 bool>;
01109
01110 template <class... T>
01111 using RequireAllHaveLessThanOrEqualT =
01112 absl::enable_if_t<absl::conjunction<is_detected_convertible<
01113 bool, LessThanOrEqualResult, T>...>::value,
01114 bool>;
01115
01116 template <class... T>
01117 using RequireAllHaveGreaterThanOrEqualT =
01118 absl::enable_if_t<absl::conjunction<is_detected_convertible<
01119 bool, GreaterThanOrEqualResult, T>...>::value,
01120 bool>;
01121
01122 template <class... T>
01123 using RequireAllHaveGreaterThanT =
01124 absl::enable_if_t<absl::conjunction<is_detected_convertible<
01125 bool, GreaterThanResult, T>...>::value,
01126 bool>;
01127
01128
01129
01130
01131 template <typename T>
01132 struct VariantHelper;
01133
01134 template <typename... Ts>
01135 struct VariantHelper<variant<Ts...>> {
01136
01137
01138 template <typename U>
01139 using BestMatch = decltype(
01140 variant_internal::OverloadSet<Ts...>::Overload(std::declval<U>()));
01141
01142
01143
01144
01145
01146 template <typename U>
01147 struct CanAccept :
01148 std::integral_constant<bool, !std::is_void<BestMatch<U>>::value> {};
01149
01150
01151
01152
01153
01154 template <typename Other>
01155 struct CanConvertFrom;
01156
01157 template <typename... Us>
01158 struct CanConvertFrom<variant<Us...>>
01159 : public absl::conjunction<CanAccept<Us>...> {};
01160 };
01161
01162
01163 struct TrivialMoveOnly {
01164 TrivialMoveOnly(TrivialMoveOnly&&) = default;
01165 };
01166
01167
01168
01169
01170 template <typename T>
01171 struct IsTriviallyMoveConstructible:
01172 std::is_move_constructible<Union<T, TrivialMoveOnly>> {};
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 template <class... T>
01191 class VariantStateBaseDestructorNontrivial;
01192
01193 template <class... T>
01194 class VariantMoveBaseNontrivial;
01195
01196 template <class... T>
01197 class VariantCopyBaseNontrivial;
01198
01199 template <class... T>
01200 class VariantMoveAssignBaseNontrivial;
01201
01202 template <class... T>
01203 class VariantCopyAssignBaseNontrivial;
01204
01205
01206 template <class... T>
01207 using VariantStateBaseDestructor =
01208 absl::conditional_t<std::is_destructible<Union<T...>>::value,
01209 VariantStateBase<T...>,
01210 VariantStateBaseDestructorNontrivial<T...>>;
01211
01212
01213
01214
01215
01216
01217
01218
01219 template <class... T>
01220 using VariantMoveBase = absl::conditional_t<
01221 absl::disjunction<
01222 absl::negation<absl::conjunction<std::is_move_constructible<T>...>>,
01223 absl::conjunction<IsTriviallyMoveConstructible<T>...>>::value,
01224 VariantStateBaseDestructor<T...>, VariantMoveBaseNontrivial<T...>>;
01225
01226
01227 template <class... T>
01228 using VariantCopyBase = absl::conditional_t<
01229 absl::disjunction<
01230 absl::negation<absl::conjunction<std::is_copy_constructible<T>...>>,
01231 std::is_copy_constructible<Union<T...>>>::value,
01232 VariantMoveBase<T...>, VariantCopyBaseNontrivial<T...>>;
01233
01234
01235 template <class... T>
01236 using VariantMoveAssignBase = absl::conditional_t<
01237 absl::disjunction<
01238 absl::conjunction<absl::is_move_assignable<Union<T...>>,
01239 std::is_move_constructible<Union<T...>>,
01240 std::is_destructible<Union<T...>>>,
01241 absl::negation<absl::conjunction<std::is_move_constructible<T>...,
01242
01243
01244
01245 is_move_assignable<T>...>>>::value,
01246 VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>;
01247
01248
01249 template <class... T>
01250 using VariantCopyAssignBase = absl::conditional_t<
01251 absl::disjunction<
01252 absl::conjunction<absl::is_copy_assignable<Union<T...>>,
01253 std::is_copy_constructible<Union<T...>>,
01254 std::is_destructible<Union<T...>>>,
01255 absl::negation<absl::conjunction<std::is_copy_constructible<T>...,
01256
01257
01258
01259 is_copy_assignable<T>...>>>::value,
01260 VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>;
01261
01262 template <class... T>
01263 using VariantBase = VariantCopyAssignBase<T...>;
01264
01265 template <class... T>
01266 class VariantStateBaseDestructorNontrivial : protected VariantStateBase<T...> {
01267 private:
01268 using Base = VariantStateBase<T...>;
01269
01270 protected:
01271 using Base::Base;
01272
01273 VariantStateBaseDestructorNontrivial() = default;
01274 VariantStateBaseDestructorNontrivial(VariantStateBaseDestructorNontrivial&&) =
01275 default;
01276 VariantStateBaseDestructorNontrivial(
01277 const VariantStateBaseDestructorNontrivial&) = default;
01278 VariantStateBaseDestructorNontrivial& operator=(
01279 VariantStateBaseDestructorNontrivial&&) = default;
01280 VariantStateBaseDestructorNontrivial& operator=(
01281 const VariantStateBaseDestructorNontrivial&) = default;
01282
01283 struct Destroyer {
01284 template <std::size_t I>
01285 void operator()(SizeT<I> i) const {
01286 using Alternative =
01287 typename absl::variant_alternative<I, variant<T...>>::type;
01288 variant_internal::AccessUnion(self->state_, i).~Alternative();
01289 }
01290
01291 void operator()(SizeT<absl::variant_npos> ) const {
01292
01293 }
01294
01295 VariantStateBaseDestructorNontrivial* self;
01296 };
01297
01298 void destroy() { VisitIndices<sizeof...(T)>::Run(Destroyer{this}, index_); }
01299
01300 ~VariantStateBaseDestructorNontrivial() { destroy(); }
01301
01302 protected:
01303 using Base::index_;
01304 using Base::state_;
01305 };
01306
01307 template <class... T>
01308 class VariantMoveBaseNontrivial : protected VariantStateBaseDestructor<T...> {
01309 private:
01310 using Base = VariantStateBaseDestructor<T...>;
01311
01312 protected:
01313 using Base::Base;
01314
01315 struct Construct {
01316 template <std::size_t I>
01317 void operator()(SizeT<I> i) const {
01318 using Alternative =
01319 typename absl::variant_alternative<I, variant<T...>>::type;
01320 ::new (static_cast<void*>(&self->state_)) Alternative(
01321 variant_internal::AccessUnion(absl::move(other->state_), i));
01322 }
01323
01324 void operator()(SizeT<absl::variant_npos> ) const {}
01325
01326 VariantMoveBaseNontrivial* self;
01327 VariantMoveBaseNontrivial* other;
01328 };
01329
01330 VariantMoveBaseNontrivial() = default;
01331 VariantMoveBaseNontrivial(VariantMoveBaseNontrivial&& other) noexcept(
01332 absl::conjunction<std::is_nothrow_move_constructible<T>...>::value)
01333 : Base(NoopConstructorTag()) {
01334 VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_);
01335 index_ = other.index_;
01336 }
01337
01338 VariantMoveBaseNontrivial(VariantMoveBaseNontrivial const&) = default;
01339
01340 VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial&&) = default;
01341 VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial const&) =
01342 default;
01343
01344 protected:
01345 using Base::index_;
01346 using Base::state_;
01347 };
01348
01349 template <class... T>
01350 class VariantCopyBaseNontrivial : protected VariantMoveBase<T...> {
01351 private:
01352 using Base = VariantMoveBase<T...>;
01353
01354 protected:
01355 using Base::Base;
01356
01357 VariantCopyBaseNontrivial() = default;
01358 VariantCopyBaseNontrivial(VariantCopyBaseNontrivial&&) = default;
01359
01360 struct Construct {
01361 template <std::size_t I>
01362 void operator()(SizeT<I> i) const {
01363 using Alternative =
01364 typename absl::variant_alternative<I, variant<T...>>::type;
01365 ::new (static_cast<void*>(&self->state_))
01366 Alternative(variant_internal::AccessUnion(other->state_, i));
01367 }
01368
01369 void operator()(SizeT<absl::variant_npos> ) const {}
01370
01371 VariantCopyBaseNontrivial* self;
01372 const VariantCopyBaseNontrivial* other;
01373 };
01374
01375 VariantCopyBaseNontrivial(VariantCopyBaseNontrivial const& other)
01376 : Base(NoopConstructorTag()) {
01377 VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_);
01378 index_ = other.index_;
01379 }
01380
01381 VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial&&) = default;
01382 VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial const&) =
01383 default;
01384
01385 protected:
01386 using Base::index_;
01387 using Base::state_;
01388 };
01389
01390 template <class... T>
01391 class VariantMoveAssignBaseNontrivial : protected VariantCopyBase<T...> {
01392 friend struct VariantCoreAccess;
01393
01394 private:
01395 using Base = VariantCopyBase<T...>;
01396
01397 protected:
01398 using Base::Base;
01399
01400 VariantMoveAssignBaseNontrivial() = default;
01401 VariantMoveAssignBaseNontrivial(VariantMoveAssignBaseNontrivial&&) = default;
01402 VariantMoveAssignBaseNontrivial(const VariantMoveAssignBaseNontrivial&) =
01403 default;
01404 VariantMoveAssignBaseNontrivial& operator=(
01405 VariantMoveAssignBaseNontrivial const&) = default;
01406
01407 VariantMoveAssignBaseNontrivial&
01408 operator=(VariantMoveAssignBaseNontrivial&& other) noexcept(
01409 absl::conjunction<std::is_nothrow_move_constructible<T>...,
01410 std::is_nothrow_move_assignable<T>...>::value) {
01411 VisitIndices<sizeof...(T)>::Run(
01412 VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_);
01413 return *this;
01414 }
01415
01416 protected:
01417 using Base::index_;
01418 using Base::state_;
01419 };
01420
01421 template <class... T>
01422 class VariantCopyAssignBaseNontrivial : protected VariantMoveAssignBase<T...> {
01423 friend struct VariantCoreAccess;
01424
01425 private:
01426 using Base = VariantMoveAssignBase<T...>;
01427
01428 protected:
01429 using Base::Base;
01430
01431 VariantCopyAssignBaseNontrivial() = default;
01432 VariantCopyAssignBaseNontrivial(VariantCopyAssignBaseNontrivial&&) = default;
01433 VariantCopyAssignBaseNontrivial(const VariantCopyAssignBaseNontrivial&) =
01434 default;
01435 VariantCopyAssignBaseNontrivial& operator=(
01436 VariantCopyAssignBaseNontrivial&&) = default;
01437
01438 VariantCopyAssignBaseNontrivial& operator=(
01439 const VariantCopyAssignBaseNontrivial& other) {
01440 VisitIndices<sizeof...(T)>::Run(
01441 VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_);
01442 return *this;
01443 }
01444
01445 protected:
01446 using Base::index_;
01447 using Base::state_;
01448 };
01449
01451
01453
01454 template <class... Types>
01455 struct EqualsOp {
01456 const variant<Types...>* v;
01457 const variant<Types...>* w;
01458
01459 constexpr bool operator()(SizeT<absl::variant_npos> ) const {
01460 return true;
01461 }
01462
01463 template <std::size_t I>
01464 constexpr bool operator()(SizeT<I> ) const {
01465 return VariantCoreAccess::Access<I>(*v) == VariantCoreAccess::Access<I>(*w);
01466 }
01467 };
01468
01469 template <class... Types>
01470 struct NotEqualsOp {
01471 const variant<Types...>* v;
01472 const variant<Types...>* w;
01473
01474 constexpr bool operator()(SizeT<absl::variant_npos> ) const {
01475 return false;
01476 }
01477
01478 template <std::size_t I>
01479 constexpr bool operator()(SizeT<I> ) const {
01480 return VariantCoreAccess::Access<I>(*v) != VariantCoreAccess::Access<I>(*w);
01481 }
01482 };
01483
01484 template <class... Types>
01485 struct LessThanOp {
01486 const variant<Types...>* v;
01487 const variant<Types...>* w;
01488
01489 constexpr bool operator()(SizeT<absl::variant_npos> ) const {
01490 return false;
01491 }
01492
01493 template <std::size_t I>
01494 constexpr bool operator()(SizeT<I> ) const {
01495 return VariantCoreAccess::Access<I>(*v) < VariantCoreAccess::Access<I>(*w);
01496 }
01497 };
01498
01499 template <class... Types>
01500 struct GreaterThanOp {
01501 const variant<Types...>* v;
01502 const variant<Types...>* w;
01503
01504 constexpr bool operator()(SizeT<absl::variant_npos> ) const {
01505 return false;
01506 }
01507
01508 template <std::size_t I>
01509 constexpr bool operator()(SizeT<I> ) const {
01510 return VariantCoreAccess::Access<I>(*v) > VariantCoreAccess::Access<I>(*w);
01511 }
01512 };
01513
01514 template <class... Types>
01515 struct LessThanOrEqualsOp {
01516 const variant<Types...>* v;
01517 const variant<Types...>* w;
01518
01519 constexpr bool operator()(SizeT<absl::variant_npos> ) const {
01520 return true;
01521 }
01522
01523 template <std::size_t I>
01524 constexpr bool operator()(SizeT<I> ) const {
01525 return VariantCoreAccess::Access<I>(*v) <= VariantCoreAccess::Access<I>(*w);
01526 }
01527 };
01528
01529 template <class... Types>
01530 struct GreaterThanOrEqualsOp {
01531 const variant<Types...>* v;
01532 const variant<Types...>* w;
01533
01534 constexpr bool operator()(SizeT<absl::variant_npos> ) const {
01535 return true;
01536 }
01537
01538 template <std::size_t I>
01539 constexpr bool operator()(SizeT<I> ) const {
01540 return VariantCoreAccess::Access<I>(*v) >= VariantCoreAccess::Access<I>(*w);
01541 }
01542 };
01543
01544
01545 template <class... Types>
01546 struct SwapSameIndex {
01547 variant<Types...>* v;
01548 variant<Types...>* w;
01549 template <std::size_t I>
01550 void operator()(SizeT<I>) const {
01551 type_traits_internal::Swap(VariantCoreAccess::Access<I>(*v),
01552 VariantCoreAccess::Access<I>(*w));
01553 }
01554
01555 void operator()(SizeT<variant_npos>) const {}
01556 };
01557
01558
01559 template <class... Types>
01560 struct Swap {
01561 variant<Types...>* v;
01562 variant<Types...>* w;
01563
01564 void generic_swap() const {
01565 variant<Types...> tmp(std::move(*w));
01566 VariantCoreAccess::Destroy(*w);
01567 VariantCoreAccess::InitFrom(*w, std::move(*v));
01568 VariantCoreAccess::Destroy(*v);
01569 VariantCoreAccess::InitFrom(*v, std::move(tmp));
01570 }
01571
01572 void operator()(SizeT<absl::variant_npos> ) const {
01573 if (!v->valueless_by_exception()) {
01574 generic_swap();
01575 }
01576 }
01577
01578 template <std::size_t Wi>
01579 void operator()(SizeT<Wi> ) {
01580 if (v->index() == Wi) {
01581 VisitIndices<sizeof...(Types)>::Run(SwapSameIndex<Types...>{v, w}, Wi);
01582 } else {
01583 generic_swap();
01584 }
01585 }
01586 };
01587
01588 template <typename Variant, typename = void, typename... Ts>
01589 struct VariantHashBase {
01590 VariantHashBase() = delete;
01591 VariantHashBase(const VariantHashBase&) = delete;
01592 VariantHashBase(VariantHashBase&&) = delete;
01593 VariantHashBase& operator=(const VariantHashBase&) = delete;
01594 VariantHashBase& operator=(VariantHashBase&&) = delete;
01595 };
01596
01597 struct VariantHashVisitor {
01598 template <typename T>
01599 size_t operator()(const T& t) {
01600 return std::hash<T>{}(t);
01601 }
01602 };
01603
01604 template <typename Variant, typename... Ts>
01605 struct VariantHashBase<Variant,
01606 absl::enable_if_t<absl::conjunction<
01607 type_traits_internal::IsHashable<Ts>...>::value>,
01608 Ts...> {
01609 using argument_type = Variant;
01610 using result_type = size_t;
01611 size_t operator()(const Variant& var) const {
01612 type_traits_internal::AssertHashEnabled<Ts...>();
01613 if (var.valueless_by_exception()) {
01614 return 239799884;
01615 }
01616 size_t result = VisitIndices<variant_size<Variant>::value>::Run(
01617 PerformVisitation<VariantHashVisitor, const Variant&>{
01618 std::forward_as_tuple(var), VariantHashVisitor{}},
01619 var.index());
01620
01621
01622 return result ^ var.index();
01623 }
01624 };
01625
01626 }
01627 }
01628
01629 #endif // !defined(ABSL_HAVE_STD_VARIANT)
01630 #endif // ABSL_TYPES_variant_internal_H_