| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646 | // Copyright 2018 The Abseil Authors.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// Implementation details of absl/types/variant.h, pulled into a// separate file to avoid cluttering the top of the API header with// implementation details.#ifndef ABSL_TYPES_variant_internal_H_#define ABSL_TYPES_variant_internal_H_#include <cassert>#include <cstddef>#include <cstdlib>#include <memory>#include <stdexcept>#include <tuple>#include <type_traits>#include "absl/base/config.h"#include "absl/base/internal/identity.h"#include "absl/base/internal/inline_variable.h"#include "absl/base/internal/invoke.h"#include "absl/base/macros.h"#include "absl/base/optimization.h"#include "absl/meta/type_traits.h"#include "absl/types/bad_variant_access.h"#include "absl/utility/utility.h"#if !defined(ABSL_USES_STD_VARIANT)namespace absl {ABSL_NAMESPACE_BEGINtemplate <class... Types>class variant;ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1);template <class T>struct variant_size;template <std::size_t I, class T>struct variant_alternative;namespace variant_internal {// NOTE: See specializations below for details.template <std::size_t I, class T>struct VariantAlternativeSfinae {};// Requires: I < variant_size_v<T>.//// Value: The Ith type of Types...template <std::size_t I, class T0, class... Tn>struct VariantAlternativeSfinae<I, variant<T0, Tn...>>    : VariantAlternativeSfinae<I - 1, variant<Tn...>> {};// Value: T0template <class T0, class... Ts>struct VariantAlternativeSfinae<0, variant<T0, Ts...>> {  using type = T0;};template <std::size_t I, class T>using VariantAlternativeSfinaeT = typename VariantAlternativeSfinae<I, T>::type;// NOTE: Requires T to be a reference type.template <class T, class U>struct GiveQualsTo;template <class T, class U>struct GiveQualsTo<T&, U> {  using type = U&;};template <class T, class U>struct GiveQualsTo<T&&, U> {  using type = U&&;};template <class T, class U>struct GiveQualsTo<const T&, U> {  using type = const U&;};template <class T, class U>struct GiveQualsTo<const T&&, U> {  using type = const U&&;};template <class T, class U>struct GiveQualsTo<volatile T&, U> {  using type = volatile U&;};template <class T, class U>struct GiveQualsTo<volatile T&&, U> {  using type = volatile U&&;};template <class T, class U>struct GiveQualsTo<volatile const T&, U> {  using type = volatile const U&;};template <class T, class U>struct GiveQualsTo<volatile const T&&, U> {  using type = volatile const U&&;};template <class T, class U>using GiveQualsToT = typename GiveQualsTo<T, U>::type;// Convenience alias, since size_t integral_constant is used a lot in this file.template <std::size_t I>using SizeT = std::integral_constant<std::size_t, I>;using NPos = SizeT<variant_npos>;template <class Variant, class T, class = void>struct IndexOfConstructedType {};template <std::size_t I, class Variant>struct VariantAccessResultImpl;template <std::size_t I, template <class...> class Variantemplate, class... T>struct VariantAccessResultImpl<I, Variantemplate<T...>&> {  using type = typename absl::variant_alternative<I, variant<T...>>::type&;};template <std::size_t I, template <class...> class Variantemplate, class... T>struct VariantAccessResultImpl<I, const Variantemplate<T...>&> {  using type =      const typename absl::variant_alternative<I, variant<T...>>::type&;};template <std::size_t I, template <class...> class Variantemplate, class... T>struct VariantAccessResultImpl<I, Variantemplate<T...>&&> {  using type = typename absl::variant_alternative<I, variant<T...>>::type&&;};template <std::size_t I, template <class...> class Variantemplate, class... T>struct VariantAccessResultImpl<I, const Variantemplate<T...>&&> {  using type =      const typename absl::variant_alternative<I, variant<T...>>::type&&;};template <std::size_t I, class Variant>using VariantAccessResult =    typename VariantAccessResultImpl<I, Variant&&>::type;// NOTE: This is used instead of std::array to reduce instantiation overhead.template <class T, std::size_t Size>struct SimpleArray {  static_assert(Size != 0, "");  T value[Size];};template <class T>struct AccessedType {  using type = T;};template <class T>using AccessedTypeT = typename AccessedType<T>::type;template <class T, std::size_t Size>struct AccessedType<SimpleArray<T, Size>> {  using type = AccessedTypeT<T>;};template <class T>constexpr T AccessSimpleArray(const T& value) {  return value;}template <class T, std::size_t Size, class... SizeT>constexpr AccessedTypeT<T> AccessSimpleArray(const SimpleArray<T, Size>& table,                                             std::size_t head_index,                                             SizeT... tail_indices) {  return AccessSimpleArray(table.value[head_index], tail_indices...);}// Note: Intentionally is an alias.template <class T>using AlwaysZero = SizeT<0>;template <class Op, class... Vs>struct VisitIndicesResultImpl {  using type = absl::result_of_t<Op(AlwaysZero<Vs>...)>;};template <class Op, class... Vs>using VisitIndicesResultT = typename VisitIndicesResultImpl<Op, Vs...>::type;template <class ReturnType, class FunctionObject, class EndIndices,          class BoundIndices>struct MakeVisitationMatrix;template <class ReturnType, class FunctionObject, std::size_t... Indices>constexpr ReturnType call_with_indices(FunctionObject&& function) {  static_assert(      std::is_same<ReturnType, decltype(std::declval<FunctionObject>()(                                   SizeT<Indices>()...))>::value,      "Not all visitation overloads have the same return type.");  return absl::forward<FunctionObject>(function)(SizeT<Indices>()...);}template <class ReturnType, class FunctionObject, std::size_t... BoundIndices>struct MakeVisitationMatrix<ReturnType, FunctionObject, index_sequence<>,                            index_sequence<BoundIndices...>> {  using ResultType = ReturnType (*)(FunctionObject&&);  static constexpr ResultType Run() {    return &call_with_indices<ReturnType, FunctionObject,                              (BoundIndices - 1)...>;  }};template <typename Is, std::size_t J>struct AppendToIndexSequence;template <typename Is, std::size_t J>using AppendToIndexSequenceT = typename AppendToIndexSequence<Is, J>::type;template <std::size_t... Is, std::size_t J>struct AppendToIndexSequence<index_sequence<Is...>, J> {  using type = index_sequence<Is..., J>;};template <class ReturnType, class FunctionObject, class EndIndices,          class CurrIndices, class BoundIndices>struct MakeVisitationMatrixImpl;template <class ReturnType, class FunctionObject, class EndIndices,          std::size_t... CurrIndices, class BoundIndices>struct MakeVisitationMatrixImpl<ReturnType, FunctionObject, EndIndices,                                index_sequence<CurrIndices...>, BoundIndices> {  using ResultType = SimpleArray<      typename MakeVisitationMatrix<ReturnType, FunctionObject, EndIndices,                                    index_sequence<>>::ResultType,      sizeof...(CurrIndices)>;  static constexpr ResultType Run() {    return {{MakeVisitationMatrix<        ReturnType, FunctionObject, EndIndices,        AppendToIndexSequenceT<BoundIndices, CurrIndices>>::Run()...}};  }};template <class ReturnType, class FunctionObject, std::size_t HeadEndIndex,          std::size_t... TailEndIndices, std::size_t... BoundIndices>struct MakeVisitationMatrix<ReturnType, FunctionObject,                            index_sequence<HeadEndIndex, TailEndIndices...>,                            index_sequence<BoundIndices...>>    : MakeVisitationMatrixImpl<ReturnType, FunctionObject,                               index_sequence<TailEndIndices...>,                               absl::make_index_sequence<HeadEndIndex>,                               index_sequence<BoundIndices...>> {};struct UnreachableSwitchCase {  template <class Op>  [[noreturn]] static VisitIndicesResultT<Op, std::size_t> Run(      Op&& /*ignored*/) {#if ABSL_HAVE_BUILTIN(__builtin_unreachable) || \    (defined(__GNUC__) && !defined(__clang__))    __builtin_unreachable();#elif defined(_MSC_VER)    __assume(false);#else    // Try to use assert of false being identified as an unreachable intrinsic.    // NOTE: We use assert directly to increase chances of exploiting an assume    //       intrinsic.    assert(false);  // NOLINT    // Hack to silence potential no return warning -- cause an infinite loop.    return Run(absl::forward<Op>(op));#endif  // Checks for __builtin_unreachable  }};template <class Op, std::size_t I>struct ReachableSwitchCase {  static VisitIndicesResultT<Op, std::size_t> Run(Op&& op) {    return absl::base_internal::Invoke(absl::forward<Op>(op), SizeT<I>());  }};// The number 33 is just a guess at a reasonable maximum to our switch. It is// not based on any analysis. The reason it is a power of 2 plus 1 instead of a// power of 2 is because the number was picked to correspond to a power of 2// amount of "normal" alternatives, plus one for the possibility of the user// providing "monostate" in addition to the more natural alternatives.ABSL_INTERNAL_INLINE_CONSTEXPR(std::size_t, MaxUnrolledVisitCases, 33);// Note: The default-definition is for unreachable cases.template <bool IsReachable>struct PickCaseImpl {  template <class Op, std::size_t I>  using Apply = UnreachableSwitchCase;};template <>struct PickCaseImpl</*IsReachable =*/true> {  template <class Op, std::size_t I>  using Apply = ReachableSwitchCase<Op, I>;};// Note: This form of dance with template aliases is to make sure that we//       instantiate a number of templates proportional to the number of variant//       alternatives rather than a number of templates proportional to our//       maximum unrolled amount of visitation cases (aliases are effectively//       "free" whereas other template instantiations are costly).template <class Op, std::size_t I, std::size_t EndIndex>using PickCase = typename PickCaseImpl<(I < EndIndex)>::template Apply<Op, I>;template <class ReturnType>[[noreturn]] ReturnType TypedThrowBadVariantAccess() {  absl::variant_internal::ThrowBadVariantAccess();}// Given N variant sizes, determine the number of cases there would need to be// in a single switch-statement that would cover every possibility in the// corresponding N-ary visit operation.template <std::size_t... NumAlternatives>struct NumCasesOfSwitch;template <std::size_t HeadNumAlternatives, std::size_t... TailNumAlternatives>struct NumCasesOfSwitch<HeadNumAlternatives, TailNumAlternatives...> {  static constexpr std::size_t value =      (HeadNumAlternatives + 1) *      NumCasesOfSwitch<TailNumAlternatives...>::value;};template <>struct NumCasesOfSwitch<> {  static constexpr std::size_t value = 1;};// A switch statement optimizes better than the table of function pointers.template <std::size_t EndIndex>struct VisitIndicesSwitch {  static_assert(EndIndex <= MaxUnrolledVisitCases,                "Maximum unrolled switch size exceeded.");  template <class Op>  static VisitIndicesResultT<Op, std::size_t> Run(Op&& op, std::size_t i) {    switch (i) {      case 0:        return PickCase<Op, 0, EndIndex>::Run(absl::forward<Op>(op));      case 1:        return PickCase<Op, 1, EndIndex>::Run(absl::forward<Op>(op));      case 2:        return PickCase<Op, 2, EndIndex>::Run(absl::forward<Op>(op));      case 3:        return PickCase<Op, 3, EndIndex>::Run(absl::forward<Op>(op));      case 4:        return PickCase<Op, 4, EndIndex>::Run(absl::forward<Op>(op));      case 5:        return PickCase<Op, 5, EndIndex>::Run(absl::forward<Op>(op));      case 6:        return PickCase<Op, 6, EndIndex>::Run(absl::forward<Op>(op));      case 7:        return PickCase<Op, 7, EndIndex>::Run(absl::forward<Op>(op));      case 8:        return PickCase<Op, 8, EndIndex>::Run(absl::forward<Op>(op));      case 9:        return PickCase<Op, 9, EndIndex>::Run(absl::forward<Op>(op));      case 10:        return PickCase<Op, 10, EndIndex>::Run(absl::forward<Op>(op));      case 11:        return PickCase<Op, 11, EndIndex>::Run(absl::forward<Op>(op));      case 12:        return PickCase<Op, 12, EndIndex>::Run(absl::forward<Op>(op));      case 13:        return PickCase<Op, 13, EndIndex>::Run(absl::forward<Op>(op));      case 14:        return PickCase<Op, 14, EndIndex>::Run(absl::forward<Op>(op));      case 15:        return PickCase<Op, 15, EndIndex>::Run(absl::forward<Op>(op));      case 16:        return PickCase<Op, 16, EndIndex>::Run(absl::forward<Op>(op));      case 17:        return PickCase<Op, 17, EndIndex>::Run(absl::forward<Op>(op));      case 18:        return PickCase<Op, 18, EndIndex>::Run(absl::forward<Op>(op));      case 19:        return PickCase<Op, 19, EndIndex>::Run(absl::forward<Op>(op));      case 20:        return PickCase<Op, 20, EndIndex>::Run(absl::forward<Op>(op));      case 21:        return PickCase<Op, 21, EndIndex>::Run(absl::forward<Op>(op));      case 22:        return PickCase<Op, 22, EndIndex>::Run(absl::forward<Op>(op));      case 23:        return PickCase<Op, 23, EndIndex>::Run(absl::forward<Op>(op));      case 24:        return PickCase<Op, 24, EndIndex>::Run(absl::forward<Op>(op));      case 25:        return PickCase<Op, 25, EndIndex>::Run(absl::forward<Op>(op));      case 26:        return PickCase<Op, 26, EndIndex>::Run(absl::forward<Op>(op));      case 27:        return PickCase<Op, 27, EndIndex>::Run(absl::forward<Op>(op));      case 28:        return PickCase<Op, 28, EndIndex>::Run(absl::forward<Op>(op));      case 29:        return PickCase<Op, 29, EndIndex>::Run(absl::forward<Op>(op));      case 30:        return PickCase<Op, 30, EndIndex>::Run(absl::forward<Op>(op));      case 31:        return PickCase<Op, 31, EndIndex>::Run(absl::forward<Op>(op));      case 32:        return PickCase<Op, 32, EndIndex>::Run(absl::forward<Op>(op));      default:        ABSL_ASSERT(i == variant_npos);        return absl::base_internal::Invoke(absl::forward<Op>(op), NPos());    }  }};template <std::size_t... EndIndices>struct VisitIndicesFallback {  template <class Op, class... SizeT>  static VisitIndicesResultT<Op, SizeT...> Run(Op&& op, SizeT... indices) {    return AccessSimpleArray(        MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op,                             index_sequence<(EndIndices + 1)...>,                             index_sequence<>>::Run(),        (indices + 1)...)(absl::forward<Op>(op));  }};// Take an N-dimensional series of indices and convert them into a single index// without loss of information. The purpose of this is to be able to convert an// N-ary visit operation into a single switch statement.template <std::size_t...>struct FlattenIndices;template <std::size_t HeadSize, std::size_t... TailSize>struct FlattenIndices<HeadSize, TailSize...> {  template<class... SizeType>  static constexpr std::size_t Run(std::size_t head, SizeType... tail) {    return head + HeadSize * FlattenIndices<TailSize...>::Run(tail...);  }};template <>struct FlattenIndices<> {  static constexpr std::size_t Run() { return 0; }};// Take a single "flattened" index (flattened by FlattenIndices) and determine// the value of the index of one of the logically represented dimensions.template <std::size_t I, std::size_t IndexToGet, std::size_t HeadSize,          std::size_t... TailSize>struct UnflattenIndex {  static constexpr std::size_t value =      UnflattenIndex<I / HeadSize, IndexToGet - 1, TailSize...>::value;};template <std::size_t I, std::size_t HeadSize, std::size_t... TailSize>struct UnflattenIndex<I, 0, HeadSize, TailSize...> {  static constexpr std::size_t value = (I % HeadSize);};// The backend for converting an N-ary visit operation into a unary visit.template <class IndexSequence, std::size_t... EndIndices>struct VisitIndicesVariadicImpl;template <std::size_t... N, std::size_t... EndIndices>struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> {  // A type that can take an N-ary function object and converts it to a unary  // function object that takes a single, flattened index, and "unflattens" it  // into its individual dimensions when forwarding to the wrapped object.  template <class Op>  struct FlattenedOp {    template <std::size_t I>    VisitIndicesResultT<Op, decltype(EndIndices)...> operator()(        SizeT<I> /*index*/) && {      return base_internal::Invoke(          absl::forward<Op>(op),          SizeT<UnflattenIndex<I, N, (EndIndices + 1)...>::value -                std::size_t{1}>()...);    }    Op&& op;  };  template <class Op, class... SizeType>  static VisitIndicesResultT<Op, decltype(EndIndices)...> Run(      Op&& op, SizeType... i) {    return VisitIndicesSwitch<NumCasesOfSwitch<EndIndices...>::value>::Run(        FlattenedOp<Op>{absl::forward<Op>(op)},        FlattenIndices<(EndIndices + std::size_t{1})...>::Run(            (i + std::size_t{1})...));  }};template <std::size_t... EndIndices>struct VisitIndicesVariadic    : VisitIndicesVariadicImpl<absl::make_index_sequence<sizeof...(EndIndices)>,                               EndIndices...> {};// This implementation will flatten N-ary visit operations into a single switch// statement when the number of cases would be less than our maximum specified// switch-statement size.// TODO(calabrese)//   Based on benchmarks, determine whether the function table approach actually//   does optimize better than a chain of switch statements and possibly update//   the implementation accordingly. Also consider increasing the maximum switch//   size.template <std::size_t... EndIndices>struct VisitIndices    : absl::conditional_t<(NumCasesOfSwitch<EndIndices...>::value <=                           MaxUnrolledVisitCases),                          VisitIndicesVariadic<EndIndices...>,                          VisitIndicesFallback<EndIndices...>> {};template <std::size_t EndIndex>struct VisitIndices<EndIndex>    : absl::conditional_t<(EndIndex <= MaxUnrolledVisitCases),                          VisitIndicesSwitch<EndIndex>,                          VisitIndicesFallback<EndIndex>> {};// Suppress bogus warning on MSVC: MSVC complains that the `reinterpret_cast`// below is returning the address of a temporary or local object.#ifdef _MSC_VER#pragma warning(push)#pragma warning(disable : 4172)#endif  // _MSC_VER// TODO(calabrese) std::launder// TODO(calabrese) constexpr// NOTE: DO NOT REMOVE the `inline` keyword as it is necessary to work around a// MSVC bug. See https://github.com/abseil/abseil-cpp/issues/129 for details.template <class Self, std::size_t I>inline VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> /*i*/) {  return reinterpret_cast<VariantAccessResult<I, Self>>(self);}#ifdef _MSC_VER#pragma warning(pop)#endif  // _MSC_VERtemplate <class T>void DeducedDestroy(T& self) {  // NOLINT  self.~T();}// NOTE: This type exists as a single entity for variant and its bases to// befriend. It contains helper functionality that manipulates the state of the// variant, such as the implementation of things like assignment and emplace// operations.struct VariantCoreAccess {  template <class VariantType>  static typename VariantType::Variant& Derived(VariantType& self) {  // NOLINT    return static_cast<typename VariantType::Variant&>(self);  }  template <class VariantType>  static const typename VariantType::Variant& Derived(      const VariantType& self) {  // NOLINT    return static_cast<const typename VariantType::Variant&>(self);  }  template <class VariantType>  static void Destroy(VariantType& self) {  // NOLINT    Derived(self).destroy();    self.index_ = absl::variant_npos;  }  template <class Variant>  static void SetIndex(Variant& self, std::size_t i) {  // NOLINT    self.index_ = i;  }  template <class Variant>  static void InitFrom(Variant& self, Variant&& other) {  // NOLINT    VisitIndices<absl::variant_size<Variant>::value>::Run(        InitFromVisitor<Variant, Variant&&>{&self,                                            std::forward<Variant>(other)},        other.index());    self.index_ = other.index();  }  // Access a variant alternative, assuming the index is correct.  template <std::size_t I, class Variant>  static VariantAccessResult<I, Variant> Access(Variant&& self) {    // This cast instead of invocation of AccessUnion with an rvalue is a    // workaround for msvc. Without this there is a runtime failure when dealing    // with rvalues.    // TODO(calabrese) Reduce test case and find a simpler workaround.    return static_cast<VariantAccessResult<I, Variant>>(        variant_internal::AccessUnion(self.state_, SizeT<I>()));  }  // Access a variant alternative, throwing if the index is incorrect.  template <std::size_t I, class Variant>  static VariantAccessResult<I, Variant> CheckedAccess(Variant&& self) {    if (ABSL_PREDICT_FALSE(self.index_ != I)) {      TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();    }    return Access<I>(absl::forward<Variant>(self));  }  // The implementation of the move-assignment operation for a variant.  template <class VType>  struct MoveAssignVisitor {    using DerivedType = typename VType::Variant;    template <std::size_t NewIndex>    void operator()(SizeT<NewIndex> /*new_i*/) const {      if (left->index_ == NewIndex) {        Access<NewIndex>(*left) = std::move(Access<NewIndex>(*right));      } else {        Derived(*left).template emplace<NewIndex>(            std::move(Access<NewIndex>(*right)));      }    }    void operator()(SizeT<absl::variant_npos> /*new_i*/) const {      Destroy(*left);    }    VType* left;    VType* right;  };  template <class VType>  static MoveAssignVisitor<VType> MakeMoveAssignVisitor(VType* left,                                                        VType* other) {    return {left, other};  }  // The implementation of the assignment operation for a variant.  template <class VType>  struct CopyAssignVisitor {    using DerivedType = typename VType::Variant;    template <std::size_t NewIndex>    void operator()(SizeT<NewIndex> /*new_i*/) const {      using New =          typename absl::variant_alternative<NewIndex, DerivedType>::type;      if (left->index_ == NewIndex) {        Access<NewIndex>(*left) = Access<NewIndex>(*right);      } else if (std::is_nothrow_copy_constructible<New>::value ||                 !std::is_nothrow_move_constructible<New>::value) {        Derived(*left).template emplace<NewIndex>(Access<NewIndex>(*right));      } else {        Derived(*left) = DerivedType(Derived(*right));      }    }    void operator()(SizeT<absl::variant_npos> /*new_i*/) const {      Destroy(*left);    }    VType* left;    const VType* right;  };  template <class VType>  static CopyAssignVisitor<VType> MakeCopyAssignVisitor(VType* left,                                                        const VType& other) {    return {left, &other};  }  // The implementation of conversion-assignment operations for variant.  template <class Left, class QualifiedNew>  struct ConversionAssignVisitor {    using NewIndex =        variant_internal::IndexOfConstructedType<Left, QualifiedNew>;    void operator()(SizeT<NewIndex::value> /*old_i*/                    ) const {      Access<NewIndex::value>(*left) = absl::forward<QualifiedNew>(other);    }    template <std::size_t OldIndex>    void operator()(SizeT<OldIndex> /*old_i*/                    ) const {      using New =          typename absl::variant_alternative<NewIndex::value, Left>::type;      if (std::is_nothrow_constructible<New, QualifiedNew>::value ||          !std::is_nothrow_move_constructible<New>::value) {        left->template emplace<NewIndex::value>(            absl::forward<QualifiedNew>(other));      } else {        // the standard says "equivalent to        // operator=(variant(std::forward<T>(t)))", but we use `emplace` here        // because the variant's move assignment operator could be deleted.        left->template emplace<NewIndex::value>(            New(absl::forward<QualifiedNew>(other)));      }    }    Left* left;    QualifiedNew&& other;  };  template <class Left, class QualifiedNew>  static ConversionAssignVisitor<Left, QualifiedNew>  MakeConversionAssignVisitor(Left* left, QualifiedNew&& qual) {    return {left, absl::forward<QualifiedNew>(qual)};  }  // Backend for operations for `emplace()` which destructs `*self` then  // construct a new alternative with `Args...`.  template <std::size_t NewIndex, class Self, class... Args>  static typename absl::variant_alternative<NewIndex, Self>::type& Replace(      Self* self, Args&&... args) {    Destroy(*self);    using New = typename absl::variant_alternative<NewIndex, Self>::type;    New* const result = ::new (static_cast<void*>(&self->state_))        New(absl::forward<Args>(args)...);    self->index_ = NewIndex;    return *result;  }  template <class LeftVariant, class QualifiedRightVariant>  struct InitFromVisitor {    template <std::size_t NewIndex>    void operator()(SizeT<NewIndex> /*new_i*/) const {      using Alternative =          typename variant_alternative<NewIndex, LeftVariant>::type;      ::new (static_cast<void*>(&left->state_)) Alternative(          Access<NewIndex>(std::forward<QualifiedRightVariant>(right)));    }    void operator()(SizeT<absl::variant_npos> /*new_i*/) const {      // This space intentionally left blank.    }    LeftVariant* left;    QualifiedRightVariant&& right;  };};template <class Expected, class... T>struct IndexOfImpl;template <class Expected>struct IndexOfImpl<Expected> {  using IndexFromEnd = SizeT<0>;  using MatchedIndexFromEnd = IndexFromEnd;  using MultipleMatches = std::false_type;};template <class Expected, class Head, class... Tail>struct IndexOfImpl<Expected, Head, Tail...> : IndexOfImpl<Expected, Tail...> {  using IndexFromEnd =      SizeT<IndexOfImpl<Expected, Tail...>::IndexFromEnd::value + 1>;};template <class Expected, class... Tail>struct IndexOfImpl<Expected, Expected, Tail...>    : IndexOfImpl<Expected, Tail...> {  using IndexFromEnd =      SizeT<IndexOfImpl<Expected, Tail...>::IndexFromEnd::value + 1>;  using MatchedIndexFromEnd = IndexFromEnd;  using MultipleMatches = std::integral_constant<      bool, IndexOfImpl<Expected, Tail...>::MatchedIndexFromEnd::value != 0>;};template <class Expected, class... Types>struct IndexOfMeta {  using Results = IndexOfImpl<Expected, Types...>;  static_assert(!Results::MultipleMatches::value,                "Attempted to access a variant by specifying a type that "                "matches more than one alternative.");  static_assert(Results::MatchedIndexFromEnd::value != 0,                "Attempted to access a variant by specifying a type that does "                "not match any alternative.");  using type = SizeT<sizeof...(Types) - Results::MatchedIndexFromEnd::value>;};template <class Expected, class... Types>using IndexOf = typename IndexOfMeta<Expected, Types...>::type;template <class Variant, class T, std::size_t CurrIndex>struct UnambiguousIndexOfImpl;// Terminating case encountered once we've checked all of the alternativestemplate <class T, std::size_t CurrIndex>struct UnambiguousIndexOfImpl<variant<>, T, CurrIndex> : SizeT<CurrIndex> {};// Case where T is not Headtemplate <class Head, class... Tail, class T, std::size_t CurrIndex>struct UnambiguousIndexOfImpl<variant<Head, Tail...>, T, CurrIndex>    : UnambiguousIndexOfImpl<variant<Tail...>, T, CurrIndex + 1>::type {};// Case where T is Headtemplate <class Head, class... Tail, std::size_t CurrIndex>struct UnambiguousIndexOfImpl<variant<Head, Tail...>, Head, CurrIndex>    : SizeT<UnambiguousIndexOfImpl<variant<Tail...>, Head, 0>::value ==                    sizeof...(Tail)                ? CurrIndex                : CurrIndex + sizeof...(Tail) + 1> {};template <class Variant, class T>struct UnambiguousIndexOf;struct NoMatch {  struct type {};};template <class... Alts, class T>struct UnambiguousIndexOf<variant<Alts...>, T>    : std::conditional<UnambiguousIndexOfImpl<variant<Alts...>, T, 0>::value !=                           sizeof...(Alts),                       UnambiguousIndexOfImpl<variant<Alts...>, T, 0>,                       NoMatch>::type::type {};template <class T, std::size_t /*Dummy*/>using UnambiguousTypeOfImpl = T;template <class Variant, class T>using UnambiguousTypeOfT =    UnambiguousTypeOfImpl<T, UnambiguousIndexOf<Variant, T>::value>;template <class H, class... T>class VariantStateBase;// This is an implementation of the "imaginary function" that is described in// [variant.ctor]// It is used in order to determine which alternative to construct during// initialization from some type T.template <class Variant, std::size_t I = 0>struct ImaginaryFun;template <std::size_t I>struct ImaginaryFun<variant<>, I> {  static void Run() = delete;};template <class H, class... T, std::size_t I>struct ImaginaryFun<variant<H, T...>, I> : ImaginaryFun<variant<T...>, I + 1> {  using ImaginaryFun<variant<T...>, I + 1>::Run;  // NOTE: const& and && are used instead of by-value due to lack of guaranteed  // move elision of C++17. This may have other minor differences, but tests  // pass.  static SizeT<I> Run(const H&, SizeT<I>);  static SizeT<I> Run(H&&, SizeT<I>);};// The following metafunctions are used in constructor and assignment// constraints.template <class Self, class T>struct IsNeitherSelfNorInPlace : std::true_type {};template <class Self>struct IsNeitherSelfNorInPlace<Self, Self> : std::false_type {};template <class Self, class T>struct IsNeitherSelfNorInPlace<Self, in_place_type_t<T>> : std::false_type {};template <class Self, std::size_t I>struct IsNeitherSelfNorInPlace<Self, in_place_index_t<I>> : std::false_type {};template <class Variant, class T, class = void>struct ConversionIsPossibleImpl : std::false_type {};template <class Variant, class T>struct ConversionIsPossibleImpl<    Variant, T,    void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {}))>>    : std::true_type {};template <class Variant, class T>struct ConversionIsPossible : ConversionIsPossibleImpl<Variant, T>::type {};template <class Variant, class T>struct IndexOfConstructedType<    Variant, T,    void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {}))>>    : decltype(ImaginaryFun<Variant>::Run(std::declval<T>(), {})) {};template <std::size_t... Is>struct ContainsVariantNPos    : absl::negation<std::is_same<  // NOLINT          absl::integer_sequence<bool, 0 <= Is...>,          absl::integer_sequence<bool, Is != absl::variant_npos...>>> {};template <class Op, class... QualifiedVariants>using RawVisitResult =    absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>;// NOTE: The spec requires that all return-paths yield the same type and is not// SFINAE-friendly, so we can deduce the return type by examining the first// result. If it's not callable, then we get an error, but are compliant and// fast to compile.// TODO(calabrese) Possibly rewrite in a way that yields better compile errors// at the cost of longer compile-times.template <class Op, class... QualifiedVariants>struct VisitResultImpl {  using type =      absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>;};// Done in two steps intentionally so that we don't cause substitution to fail.template <class Op, class... QualifiedVariants>using VisitResult = typename VisitResultImpl<Op, QualifiedVariants...>::type;template <class Op, class... QualifiedVariants>struct PerformVisitation {  using ReturnType = VisitResult<Op, QualifiedVariants...>;  template <std::size_t... Is>  constexpr ReturnType operator()(SizeT<Is>... indices) const {    return Run(typename ContainsVariantNPos<Is...>::type{},               absl::index_sequence_for<QualifiedVariants...>(), indices...);  }  template <std::size_t... TupIs, std::size_t... Is>  constexpr ReturnType Run(std::false_type /*has_valueless*/,                           index_sequence<TupIs...>, SizeT<Is>...) const {    static_assert(        std::is_same<ReturnType,                     absl::result_of_t<Op(VariantAccessResult<                                          Is, QualifiedVariants>...)>>::value,        "All visitation overloads must have the same return type.");    return absl::base_internal::Invoke(        absl::forward<Op>(op),        VariantCoreAccess::Access<Is>(            absl::forward<QualifiedVariants>(std::get<TupIs>(variant_tup)))...);  }  template <std::size_t... TupIs, std::size_t... Is>  [[noreturn]] ReturnType Run(std::true_type /*has_valueless*/,                              index_sequence<TupIs...>, SizeT<Is>...) const {    absl::variant_internal::ThrowBadVariantAccess();  }  // TODO(calabrese) Avoid using a tuple, which causes lots of instantiations  // Attempts using lambda variadic captures fail on current GCC.  std::tuple<QualifiedVariants&&...> variant_tup;  Op&& op;};template <class... T>union Union;// We want to allow for variant<> to be trivial. For that, we need the default// constructor to be trivial, which means we can't define it ourselves.// Instead, we use a non-default constructor that takes NoopConstructorTag// that doesn't affect the triviality of the types.struct NoopConstructorTag {};template <std::size_t I>struct EmplaceTag {};template <>union Union<> {  constexpr explicit Union(NoopConstructorTag) noexcept {}};// Suppress bogus warning on MSVC: MSVC complains that Union<T...> has a defined// deleted destructor from the `std::is_destructible` check below.#ifdef _MSC_VER#pragma warning(push)#pragma warning(disable : 4624)#endif  // _MSC_VERtemplate <class Head, class... Tail>union Union<Head, Tail...> {  using TailUnion = Union<Tail...>;  explicit constexpr Union(NoopConstructorTag /*tag*/) noexcept      : tail(NoopConstructorTag()) {}  template <class... P>  explicit constexpr Union(EmplaceTag<0>, P&&... args)      : head(absl::forward<P>(args)...) {}  template <std::size_t I, class... P>  explicit constexpr Union(EmplaceTag<I>, P&&... args)      : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {}  Head head;  TailUnion tail;};#ifdef _MSC_VER#pragma warning(pop)#endif  // _MSC_VER// TODO(calabrese) Just contain a Union in this union (certain configs fail).template <class... T>union DestructibleUnionImpl;template <>union DestructibleUnionImpl<> {  constexpr explicit DestructibleUnionImpl(NoopConstructorTag) noexcept {}};template <class Head, class... Tail>union DestructibleUnionImpl<Head, Tail...> {  using TailUnion = DestructibleUnionImpl<Tail...>;  explicit constexpr DestructibleUnionImpl(NoopConstructorTag /*tag*/) noexcept      : tail(NoopConstructorTag()) {}  template <class... P>  explicit constexpr DestructibleUnionImpl(EmplaceTag<0>, P&&... args)      : head(absl::forward<P>(args)...) {}  template <std::size_t I, class... P>  explicit constexpr DestructibleUnionImpl(EmplaceTag<I>, P&&... args)      : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {}  ~DestructibleUnionImpl() {}  Head head;  TailUnion tail;};// This union type is destructible even if one or more T are not trivially// destructible. In the case that all T are trivially destructible, then so is// this resultant type.template <class... T>using DestructibleUnion =    absl::conditional_t<std::is_destructible<Union<T...>>::value, Union<T...>,                        DestructibleUnionImpl<T...>>;// Deepest base, containing the actual union and the discriminatortemplate <class H, class... T>class VariantStateBase { protected:  using Variant = variant<H, T...>;  template <class LazyH = H,            class ConstructibleH = absl::enable_if_t<                std::is_default_constructible<LazyH>::value, LazyH>>  constexpr VariantStateBase() noexcept(      std::is_nothrow_default_constructible<ConstructibleH>::value)      : state_(EmplaceTag<0>()), index_(0) {}  template <std::size_t I, class... P>  explicit constexpr VariantStateBase(EmplaceTag<I> tag, P&&... args)      : state_(tag, absl::forward<P>(args)...), index_(I) {}  explicit constexpr VariantStateBase(NoopConstructorTag)      : state_(NoopConstructorTag()), index_(variant_npos) {}  void destroy() {}  // Does nothing (shadowed in child if non-trivial)  DestructibleUnion<H, T...> state_;  std::size_t index_;};using absl::internal::identity;// OverloadSet::Overload() is a unary function which is overloaded to// take any of the element types of the variant, by reference-to-const.// The return type of the overload on T is identity<T>, so that you// can statically determine which overload was called.//// Overload() is not defined, so it can only be called in unevaluated// contexts.template <typename... Ts>struct OverloadSet;template <typename T, typename... Ts>struct OverloadSet<T, Ts...> : OverloadSet<Ts...> {  using Base = OverloadSet<Ts...>;  static identity<T> Overload(const T&);  using Base::Overload;};template <>struct OverloadSet<> {  // For any case not handled above.  static void Overload(...);};template <class T>using LessThanResult = decltype(std::declval<T>() < std::declval<T>());template <class T>using GreaterThanResult = decltype(std::declval<T>() > std::declval<T>());template <class T>using LessThanOrEqualResult = decltype(std::declval<T>() <= std::declval<T>());template <class T>using GreaterThanOrEqualResult =    decltype(std::declval<T>() >= std::declval<T>());template <class T>using EqualResult = decltype(std::declval<T>() == std::declval<T>());template <class T>using NotEqualResult = decltype(std::declval<T>() != std::declval<T>());using type_traits_internal::is_detected_convertible;template <class... T>using RequireAllHaveEqualT = absl::enable_if_t<    absl::conjunction<is_detected_convertible<bool, EqualResult, T>...>::value,    bool>;template <class... T>using RequireAllHaveNotEqualT =    absl::enable_if_t<absl::conjunction<is_detected_convertible<                          bool, NotEqualResult, T>...>::value,                      bool>;template <class... T>using RequireAllHaveLessThanT =    absl::enable_if_t<absl::conjunction<is_detected_convertible<                          bool, LessThanResult, T>...>::value,                      bool>;template <class... T>using RequireAllHaveLessThanOrEqualT =    absl::enable_if_t<absl::conjunction<is_detected_convertible<                          bool, LessThanOrEqualResult, T>...>::value,                      bool>;template <class... T>using RequireAllHaveGreaterThanOrEqualT =    absl::enable_if_t<absl::conjunction<is_detected_convertible<                          bool, GreaterThanOrEqualResult, T>...>::value,                      bool>;template <class... T>using RequireAllHaveGreaterThanT =    absl::enable_if_t<absl::conjunction<is_detected_convertible<                          bool, GreaterThanResult, T>...>::value,                      bool>;// Helper template containing implementations details of variant that can't go// in the private section. For convenience, this takes the variant type as a// single template parameter.template <typename T>struct VariantHelper;template <typename... Ts>struct VariantHelper<variant<Ts...>> {  // Type metafunction which returns the element type selected if  // OverloadSet::Overload() is well-formed when called with argument type U.  template <typename U>  using BestMatch = decltype(      variant_internal::OverloadSet<Ts...>::Overload(std::declval<U>()));  // Type metafunction which returns true if OverloadSet::Overload() is  // well-formed when called with argument type U.  // CanAccept can't be just an alias because there is a MSVC bug on parameter  // pack expansion involving decltype.  template <typename U>  struct CanAccept :      std::integral_constant<bool, !std::is_void<BestMatch<U>>::value> {};  // Type metafunction which returns true if Other is an instantiation of  // variant, and variants's converting constructor from Other will be  // well-formed. We will use this to remove constructors that would be  // ill-formed from the overload set.  template <typename Other>  struct CanConvertFrom;  template <typename... Us>  struct CanConvertFrom<variant<Us...>>      : public absl::conjunction<CanAccept<Us>...> {};};// A type with nontrivial copy ctor and trivial move ctor.struct TrivialMoveOnly {  TrivialMoveOnly(TrivialMoveOnly&&) = default;};// Trait class to detect whether a type is trivially move constructible.// A union's defaulted copy/move constructor is deleted if any variant member's// copy/move constructor is nontrivial.template <typename T>struct IsTriviallyMoveConstructible:  std::is_move_constructible<Union<T, TrivialMoveOnly>> {};// To guarantee triviality of all special-member functions that can be trivial,// we use a chain of conditional bases for each one.// The order of inheritance of bases from child to base are logically://// variant// VariantCopyAssignBase// VariantMoveAssignBase// VariantCopyBase// VariantMoveBase// VariantStateBaseDestructor// VariantStateBase//// Note that there is a separate branch at each base that is dependent on// whether or not that corresponding special-member-function can be trivial in// the resultant variant type.template <class... T>class VariantStateBaseDestructorNontrivial;template <class... T>class VariantMoveBaseNontrivial;template <class... T>class VariantCopyBaseNontrivial;template <class... T>class VariantMoveAssignBaseNontrivial;template <class... T>class VariantCopyAssignBaseNontrivial;// Base that is dependent on whether or not the destructor can be trivial.template <class... T>using VariantStateBaseDestructor =    absl::conditional_t<std::is_destructible<Union<T...>>::value,                        VariantStateBase<T...>,                        VariantStateBaseDestructorNontrivial<T...>>;// Base that is dependent on whether or not the move-constructor can be// implicitly generated by the compiler (trivial or deleted).// Previously we were using `std::is_move_constructible<Union<T...>>` to check// whether all Ts have trivial move constructor, but it ran into a GCC bug:// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84866// So we have to use a different approach (i.e. `HasTrivialMoveConstructor`) to// work around the bug.template <class... T>using VariantMoveBase = absl::conditional_t<    absl::disjunction<        absl::negation<absl::conjunction<std::is_move_constructible<T>...>>,        absl::conjunction<IsTriviallyMoveConstructible<T>...>>::value,    VariantStateBaseDestructor<T...>, VariantMoveBaseNontrivial<T...>>;// Base that is dependent on whether or not the copy-constructor can be trivial.template <class... T>using VariantCopyBase = absl::conditional_t<    absl::disjunction<        absl::negation<absl::conjunction<std::is_copy_constructible<T>...>>,        std::is_copy_constructible<Union<T...>>>::value,    VariantMoveBase<T...>, VariantCopyBaseNontrivial<T...>>;// Base that is dependent on whether or not the move-assign can be trivial.template <class... T>using VariantMoveAssignBase = absl::conditional_t<    absl::disjunction<        absl::conjunction<absl::is_move_assignable<Union<T...>>,                          std::is_move_constructible<Union<T...>>,                          std::is_destructible<Union<T...>>>,        absl::negation<absl::conjunction<std::is_move_constructible<T>...,                                         // Note: We're not qualifying this with                                         // absl:: because it doesn't compile                                         // under MSVC.                                         is_move_assignable<T>...>>>::value,    VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>;// Base that is dependent on whether or not the copy-assign can be trivial.template <class... T>using VariantCopyAssignBase = absl::conditional_t<    absl::disjunction<        absl::conjunction<absl::is_copy_assignable<Union<T...>>,                          std::is_copy_constructible<Union<T...>>,                          std::is_destructible<Union<T...>>>,        absl::negation<absl::conjunction<std::is_copy_constructible<T>...,                                         // Note: We're not qualifying this with                                         // absl:: because it doesn't compile                                         // under MSVC.                                         is_copy_assignable<T>...>>>::value,    VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>;template <class... T>using VariantBase = VariantCopyAssignBase<T...>;template <class... T>class VariantStateBaseDestructorNontrivial : protected VariantStateBase<T...> { private:  using Base = VariantStateBase<T...>; protected:  using Base::Base;  VariantStateBaseDestructorNontrivial() = default;  VariantStateBaseDestructorNontrivial(VariantStateBaseDestructorNontrivial&&) =      default;  VariantStateBaseDestructorNontrivial(      const VariantStateBaseDestructorNontrivial&) = default;  VariantStateBaseDestructorNontrivial& operator=(      VariantStateBaseDestructorNontrivial&&) = default;  VariantStateBaseDestructorNontrivial& operator=(      const VariantStateBaseDestructorNontrivial&) = default;  struct Destroyer {    template <std::size_t I>    void operator()(SizeT<I> i) const {      using Alternative =          typename absl::variant_alternative<I, variant<T...>>::type;      variant_internal::AccessUnion(self->state_, i).~Alternative();    }    void operator()(SizeT<absl::variant_npos> /*i*/) const {      // This space intentionally left blank    }    VariantStateBaseDestructorNontrivial* self;  };  void destroy() { VisitIndices<sizeof...(T)>::Run(Destroyer{this}, index_); }  ~VariantStateBaseDestructorNontrivial() { destroy(); } protected:  using Base::index_;  using Base::state_;};template <class... T>class VariantMoveBaseNontrivial : protected VariantStateBaseDestructor<T...> { private:  using Base = VariantStateBaseDestructor<T...>; protected:  using Base::Base;  struct Construct {    template <std::size_t I>    void operator()(SizeT<I> i) const {      using Alternative =          typename absl::variant_alternative<I, variant<T...>>::type;      ::new (static_cast<void*>(&self->state_)) Alternative(          variant_internal::AccessUnion(absl::move(other->state_), i));    }    void operator()(SizeT<absl::variant_npos> /*i*/) const {}    VariantMoveBaseNontrivial* self;    VariantMoveBaseNontrivial* other;  };  VariantMoveBaseNontrivial() = default;  VariantMoveBaseNontrivial(VariantMoveBaseNontrivial&& other) noexcept(      absl::conjunction<std::is_nothrow_move_constructible<T>...>::value)      : Base(NoopConstructorTag()) {    VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_);    index_ = other.index_;  }  VariantMoveBaseNontrivial(VariantMoveBaseNontrivial const&) = default;  VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial&&) = default;  VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial const&) =      default; protected:  using Base::index_;  using Base::state_;};template <class... T>class VariantCopyBaseNontrivial : protected VariantMoveBase<T...> { private:  using Base = VariantMoveBase<T...>; protected:  using Base::Base;  VariantCopyBaseNontrivial() = default;  VariantCopyBaseNontrivial(VariantCopyBaseNontrivial&&) = default;  struct Construct {    template <std::size_t I>    void operator()(SizeT<I> i) const {      using Alternative =          typename absl::variant_alternative<I, variant<T...>>::type;      ::new (static_cast<void*>(&self->state_))          Alternative(variant_internal::AccessUnion(other->state_, i));    }    void operator()(SizeT<absl::variant_npos> /*i*/) const {}    VariantCopyBaseNontrivial* self;    const VariantCopyBaseNontrivial* other;  };  VariantCopyBaseNontrivial(VariantCopyBaseNontrivial const& other)      : Base(NoopConstructorTag()) {    VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_);    index_ = other.index_;  }  VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial&&) = default;  VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial const&) =      default; protected:  using Base::index_;  using Base::state_;};template <class... T>class VariantMoveAssignBaseNontrivial : protected VariantCopyBase<T...> {  friend struct VariantCoreAccess; private:  using Base = VariantCopyBase<T...>; protected:  using Base::Base;  VariantMoveAssignBaseNontrivial() = default;  VariantMoveAssignBaseNontrivial(VariantMoveAssignBaseNontrivial&&) = default;  VariantMoveAssignBaseNontrivial(const VariantMoveAssignBaseNontrivial&) =      default;  VariantMoveAssignBaseNontrivial& operator=(      VariantMoveAssignBaseNontrivial const&) = default;    VariantMoveAssignBaseNontrivial&    operator=(VariantMoveAssignBaseNontrivial&& other) noexcept(        absl::conjunction<std::is_nothrow_move_constructible<T>...,                          std::is_nothrow_move_assignable<T>...>::value) {      VisitIndices<sizeof...(T)>::Run(          VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_);      return *this;    } protected:  using Base::index_;  using Base::state_;};template <class... T>class VariantCopyAssignBaseNontrivial : protected VariantMoveAssignBase<T...> {  friend struct VariantCoreAccess; private:  using Base = VariantMoveAssignBase<T...>; protected:  using Base::Base;  VariantCopyAssignBaseNontrivial() = default;  VariantCopyAssignBaseNontrivial(VariantCopyAssignBaseNontrivial&&) = default;  VariantCopyAssignBaseNontrivial(const VariantCopyAssignBaseNontrivial&) =      default;  VariantCopyAssignBaseNontrivial& operator=(      VariantCopyAssignBaseNontrivial&&) = default;    VariantCopyAssignBaseNontrivial& operator=(        const VariantCopyAssignBaseNontrivial& other) {      VisitIndices<sizeof...(T)>::Run(          VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_);      return *this;    } protected:  using Base::index_;  using Base::state_;};////////////////////////////////////////// Visitors for Comparison Operations //////////////////////////////////////////template <class... Types>struct EqualsOp {  const variant<Types...>* v;  const variant<Types...>* w;  constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const {    return true;  }  template <std::size_t I>  constexpr bool operator()(SizeT<I> /*v_i*/) const {    return VariantCoreAccess::Access<I>(*v) == VariantCoreAccess::Access<I>(*w);  }};template <class... Types>struct NotEqualsOp {  const variant<Types...>* v;  const variant<Types...>* w;  constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const {    return false;  }  template <std::size_t I>  constexpr bool operator()(SizeT<I> /*v_i*/) const {    return VariantCoreAccess::Access<I>(*v) != VariantCoreAccess::Access<I>(*w);  }};template <class... Types>struct LessThanOp {  const variant<Types...>* v;  const variant<Types...>* w;  constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const {    return false;  }  template <std::size_t I>  constexpr bool operator()(SizeT<I> /*v_i*/) const {    return VariantCoreAccess::Access<I>(*v) < VariantCoreAccess::Access<I>(*w);  }};template <class... Types>struct GreaterThanOp {  const variant<Types...>* v;  const variant<Types...>* w;  constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const {    return false;  }  template <std::size_t I>  constexpr bool operator()(SizeT<I> /*v_i*/) const {    return VariantCoreAccess::Access<I>(*v) > VariantCoreAccess::Access<I>(*w);  }};template <class... Types>struct LessThanOrEqualsOp {  const variant<Types...>* v;  const variant<Types...>* w;  constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const {    return true;  }  template <std::size_t I>  constexpr bool operator()(SizeT<I> /*v_i*/) const {    return VariantCoreAccess::Access<I>(*v) <= VariantCoreAccess::Access<I>(*w);  }};template <class... Types>struct GreaterThanOrEqualsOp {  const variant<Types...>* v;  const variant<Types...>* w;  constexpr bool operator()(SizeT<absl::variant_npos> /*v_i*/) const {    return true;  }  template <std::size_t I>  constexpr bool operator()(SizeT<I> /*v_i*/) const {    return VariantCoreAccess::Access<I>(*v) >= VariantCoreAccess::Access<I>(*w);  }};// Precondition: v.index() == w.index();template <class... Types>struct SwapSameIndex {  variant<Types...>* v;  variant<Types...>* w;  template <std::size_t I>  void operator()(SizeT<I>) const {    type_traits_internal::Swap(VariantCoreAccess::Access<I>(*v),                               VariantCoreAccess::Access<I>(*w));  }  void operator()(SizeT<variant_npos>) const {}};// TODO(calabrese) do this from a different namespace for proper adl usagetemplate <class... Types>struct Swap {  variant<Types...>* v;  variant<Types...>* w;  void generic_swap() const {    variant<Types...> tmp(std::move(*w));    VariantCoreAccess::Destroy(*w);    VariantCoreAccess::InitFrom(*w, std::move(*v));    VariantCoreAccess::Destroy(*v);    VariantCoreAccess::InitFrom(*v, std::move(tmp));  }  void operator()(SizeT<absl::variant_npos> /*w_i*/) const {    if (!v->valueless_by_exception()) {      generic_swap();    }  }  template <std::size_t Wi>  void operator()(SizeT<Wi> /*w_i*/) {    if (v->index() == Wi) {      VisitIndices<sizeof...(Types)>::Run(SwapSameIndex<Types...>{v, w}, Wi);    } else {      generic_swap();    }  }};template <typename Variant, typename = void, typename... Ts>struct VariantHashBase {  VariantHashBase() = delete;  VariantHashBase(const VariantHashBase&) = delete;  VariantHashBase(VariantHashBase&&) = delete;  VariantHashBase& operator=(const VariantHashBase&) = delete;  VariantHashBase& operator=(VariantHashBase&&) = delete;};struct VariantHashVisitor {  template <typename T>  size_t operator()(const T& t) {    return std::hash<T>{}(t);  }};template <typename Variant, typename... Ts>struct VariantHashBase<Variant,                       absl::enable_if_t<absl::conjunction<                           type_traits_internal::IsHashable<Ts>...>::value>,                       Ts...> {  using argument_type = Variant;  using result_type = size_t;  size_t operator()(const Variant& var) const {    type_traits_internal::AssertHashEnabled<Ts...>();    if (var.valueless_by_exception()) {      return 239799884;    }    size_t result = VisitIndices<variant_size<Variant>::value>::Run(        PerformVisitation<VariantHashVisitor, const Variant&>{            std::forward_as_tuple(var), VariantHashVisitor{}},        var.index());    // Combine the index and the hash result in order to distinguish    // std::variant<int, int> holding the same value as different alternative.    return result ^ var.index();  }};}  // namespace variant_internalABSL_NAMESPACE_END}  // namespace absl#endif  // !defined(ABSL_USES_STD_VARIANT)#endif  // ABSL_TYPES_variant_internal_H_
 |