19 #ifndef ABSL_TYPES_variant_internal_H_ 20 #define ABSL_TYPES_variant_internal_H_ 28 #include <type_traits> 40 #if !defined(ABSL_HAVE_STD_VARIANT) 44 template <
class... Types>
52 template <std::
size_t I,
class T>
55 namespace variant_internal {
58 template <std::
size_t I,
class T>
64 template <std::size_t I,
class T0,
class... Tn>
69 template <
class T0,
class... Ts>
74 template <std::
size_t I,
class T>
78 template <
class T,
class U>
81 template <
class T,
class U>
86 template <
class T,
class U>
91 template <
class T,
class U>
96 template <
class T,
class U>
101 template <
class T,
class U>
106 template <
class T,
class U>
111 template <
class T,
class U>
113 using type =
volatile const U&;
116 template <
class T,
class U>
118 using type =
volatile const U&&;
121 template <
class T,
class U>
125 template <std::
size_t I>
126 using SizeT = std::integral_constant<std::size_t, I>;
130 template <
class Variant,
class T,
class =
void>
133 template <std::
size_t I,
class Variant>
136 template <std::size_t I,
template <
class...>
class Variantemplate,
class... T>
141 template <std::size_t I,
template <
class...>
class Variantemplate,
class... T>
147 template <std::size_t I,
template <
class...>
class Variantemplate,
class... T>
152 template <std::size_t I,
template <
class...>
class Variantemplate,
class... T>
158 template <std::
size_t I,
class Variant>
163 template <
class T, std::
size_t Size>
165 static_assert(Size != 0,
"");
177 template <
class T, std::
size_t Size>
187 template <
class T, std::size_t Size,
class...
SizeT>
189 std::size_t head_index,
190 SizeT... tail_indices) {
198 template <
class Op,
class... Vs>
203 template <
class Op,
class... Vs>
206 template <
class ReturnType,
class FunctionObject,
class EndIndices,
207 std::size_t... BoundIndices>
210 template <
class ReturnType,
class FunctionObject, std::size_t... Indices>
213 std::is_same<ReturnType, decltype(std::declval<FunctionObject>()(
215 "Not all visitation overloads have the same return type.");
216 return absl::forward<FunctionObject>(
function)(
SizeT<Indices>()...);
219 template <
class ReturnType,
class FunctionObject, std::size_t... BoundIndices>
225 (BoundIndices - 1)...>;
229 template <
class ReturnType,
class FunctionObject,
class EndIndices,
230 class CurrIndices, std::size_t... BoundIndices>
233 template <
class ReturnType,
class FunctionObject, std::size_t... EndIndices,
234 std::size_t... CurrIndices, std::size_t... BoundIndices>
241 sizeof...(CurrIndices)>;
243 static constexpr ResultType
Run() {
246 BoundIndices..., CurrIndices>::Run()...}};
250 template <
class ReturnType,
class FunctionObject, std::size_t HeadEndIndex,
251 std::size_t... TailEndIndices, std::size_t... BoundIndices>
256 ReturnType, FunctionObject, index_sequence<TailEndIndices...>,
257 absl::make_index_sequence<HeadEndIndex>, BoundIndices...> {};
263 #if ABSL_HAVE_BUILTIN(__builtin_unreachable) || \ 264 (defined(__GNUC__) && !defined(__clang__)) 265 __builtin_unreachable();
266 #elif defined(_MSC_VER) 275 return Run(absl::forward<Op>(op));
276 #endif // Checks for __builtin_unreachable 280 template <
class Op, std::
size_t I>
295 template <
bool IsReachable>
297 template <
class Op, std::
size_t I>
303 template <
class Op, std::
size_t I>
312 template <
class Op, std::
size_t I, std::
size_t EndIndex>
315 template <
class ReturnType>
323 template <std::size_t... NumAlternatives>
326 template <std::size_t HeadNumAlternatives, std::size_t... TailNumAlternatives>
328 static constexpr std::size_t
value =
329 (HeadNumAlternatives + 1) *
335 static constexpr std::size_t
value = 1;
339 template <std::
size_t EndIndex>
341 static_assert(EndIndex <= MaxUnrolledVisitCases,
342 "Maximum unrolled switch size exceeded.");
420 template <std::size_t... EndIndices>
422 template <
class Op,
class...
SizeT>
427 (indices + 1)...)(absl::forward<Op>(op));
434 template <std::size_t...>
437 template <std::size_t HeadSize, std::size_t... TailSize>
439 template<
class... SizeType>
440 static constexpr std::size_t
Run(std::size_t head, SizeType... tail) {
447 static constexpr std::size_t
Run() {
return 0; }
452 template <std::size_t I, std::size_t IndexToGet, std::size_t HeadSize,
453 std::size_t... TailSize>
455 static constexpr std::size_t
value =
459 template <std::size_t I, std::size_t HeadSize, std::size_t... TailSize>
461 static constexpr std::size_t
value = (I % HeadSize);
465 template <
class IndexSequence, std::size_t... EndIndices>
468 template <std::size_t... N, std::size_t... EndIndices>
475 template <std::
size_t I>
479 absl::forward<Op>(op),
481 std::size_t{1}>()...);
487 template <
class Op,
class... SizeType>
489 Op&& op, SizeType...
i) {
491 FlattenedOp<Op>{absl::forward<Op>(op)},
493 (
i + std::size_t{1})...));
497 template <std::size_t... EndIndices>
510 template <std::size_t... EndIndices>
513 MaxUnrolledVisitCases),
514 VisitIndicesVariadic<EndIndices...>,
515 VisitIndicesFallback<EndIndices...>> {};
517 template <std::size_t EndIndex>
518 struct VisitIndices<EndIndex>
519 : absl::conditional_t<(EndIndex <= MaxUnrolledVisitCases),
520 VisitIndicesSwitch<EndIndex>,
521 VisitIndicesFallback<EndIndex>> {};
526 #pragma warning(push)
527 #pragma warning(disable : 4172)
534 template <class Self, std::size_t I>
535 inline VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> ) {
536 return reinterpret_cast<VariantAccessResult<I, Self>>(self);
544 void DeducedDestroy(T& self) {
552 struct VariantCoreAccess {
553 template <class VariantType>
554 static typename VariantType::Variant& Derived(VariantType& self) {
555 return static_cast<typename VariantType::Variant&>(self);
558 template <class VariantType>
559 static const typename VariantType::Variant& Derived(
560 const VariantType& self) {
561 return static_cast<const typename VariantType::Variant&>(self);
564 template <class VariantType>
565 static void Destroy(VariantType& self) {
566 Derived(self).destroy();
567 self.index_ = absl::variant_npos;
570 template <class Variant>
571 static void SetIndex(Variant& self, std::size_t i) {
575 template <class Variant>
576 static void InitFrom(Variant& self, Variant&& other) {
577 VisitIndices<absl::variant_size<Variant>::value>::Run(
578 InitFromVisitor<Variant, Variant&&>{&self,
579 std::forward<Variant>(other)},
581 self.index_ = other.index();
585 template <std::size_t I, class Variant>
586 static VariantAccessResult<I, Variant> Access(Variant&& self) {
591 return static_cast<VariantAccessResult<I, Variant>>(
592 variant_internal::AccessUnion(self.state_, SizeT<I>()));
596 template <std::size_t I, class Variant>
597 static VariantAccessResult<I, Variant> CheckedAccess(Variant&& self) {
598 if (ABSL_PREDICT_FALSE(self.index_ != I)) {
599 TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();
602 return Access<I>(absl::forward<Variant>(self));
606 template <class VType>
607 struct MoveAssignVisitor {
608 using DerivedType = typename VType::Variant;
609 template <std::size_t NewIndex>
610 void operator()(SizeT<NewIndex> ) const {
611 if (left->index_ == NewIndex) {
612 Access<NewIndex>(*left) = std::move(Access<NewIndex>(*right));
614 Derived(*left).template emplace<NewIndex>(
615 std::move(Access<NewIndex>(*right)));
619 void operator()(SizeT<absl::variant_npos> ) const {
627 template <class VType>
628 static MoveAssignVisitor<VType> MakeMoveAssignVisitor(VType* left,
630 return {left, other};
634 template <class VType>
635 struct CopyAssignVisitor {
636 using DerivedType = typename VType::Variant;
637 template <std::size_t NewIndex>
638 void operator()(SizeT<NewIndex> ) const {
640 typename absl::variant_alternative<NewIndex, DerivedType>::type;
642 if (left->index_ == NewIndex) {
643 Access<NewIndex>(*left) = Access<NewIndex>(*right);
646 Derived(*left).template emplace<NewIndex>(Access<NewIndex>(*right));
660 template <
class VType>
662 const VType& other) {
663 return {left, &other};
667 template <
class Left,
class QualifiedNew>
674 Access<NewIndex::value>(*left) = absl::forward<QualifiedNew>(other);
677 template <std::
size_t OldIndex>
684 left->template emplace<NewIndex::value>(
685 absl::forward<QualifiedNew>(other));
690 left->template emplace<NewIndex::value>(
691 New(absl::forward<QualifiedNew>(other)));
699 template <
class Left,
class QualifiedNew>
702 return {left, absl::forward<QualifiedNew>(qual)};
707 template <std::size_t NewIndex,
class Self,
class... Args>
709 Self*
self, Args&&... args) {
712 New*
const result = ::new (static_cast<void*>(&self->state_))
713 New(absl::forward<Args>(args)...);
714 self->index_ = NewIndex;
718 template <
class LeftVariant,
class QualifiedRightVariant>
720 template <std::
size_t NewIndex>
724 ::new (static_cast<void*>(&left->state_)) Alternative(
725 Access<NewIndex>(std::forward<QualifiedRightVariant>(right)));
736 template <
class Expected,
class... T>
739 template <
class Expected>
746 template <
class Expected,
class Head,
class... Tail>
752 template <
class Expected,
class... Tail>
762 template <
class Expected,
class... Types>
766 "Attempted to access a variant by specifying a type that " 767 "matches more than one alternative.");
769 "Attempted to access a variant by specifying a type that does " 770 "not match any alternative.");
774 template <
class Expected,
class... Types>
777 template <
class Variant,
class T, std::
size_t CurrIndex>
781 template <
class T, std::
size_t CurrIndex>
785 template <
class Head,
class... Tail,
class T, std::size_t CurrIndex>
790 template <
class Head,
class... Tail, std::size_t CurrIndex>
792 :
SizeT<UnambiguousIndexOfImpl<variant<Tail...>, Head, 0>::value ==
795 : CurrIndex + sizeof...(Tail) + 1> {};
797 template <
class Variant,
class T>
804 template <
class... Alts,
class T>
806 : std::conditional<UnambiguousIndexOfImpl<variant<Alts...>, T, 0>::value !=
808 UnambiguousIndexOfImpl<variant<Alts...>, T, 0>,
809 NoMatch>::type::type {};
811 template <
class T, std::size_t >
814 template <
class Variant,
class T>
818 template <
class H,
class... T>
825 template <
class Variant, std::
size_t I = 0>
828 template <std::
size_t I>
830 static void Run() =
delete;
833 template <
class H,
class... T, std::size_t I>
846 template <
class Self,
class T>
849 template <
class Self>
852 template <
class Self,
class T>
855 template <
class Self, std::
size_t I>
858 template <
class Variant,
class T,
class =
void>
861 template <
class Variant,
class T>
863 Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>>
866 template <
class Variant,
class T>
869 template <
class Variant,
class T>
871 Variant, T, void_t<decltype(ImaginaryFun<Variant>::Run(std::declval<T>()))>>
872 : decltype(ImaginaryFun<Variant>::Run(std::declval<T>())) {};
874 template <std::size_t... Is>
875 struct ContainsVariantNPos
877 absl::integer_sequence<bool, 0 <= Is...>,
878 absl::integer_sequence<bool, Is != absl::variant_npos...>>> {};
880 template <class Op, class... QualifiedVariants>
881 using RawVisitResult =
882 absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>;
890 template <class Op, class... QualifiedVariants>
891 struct VisitResultImpl {
893 absl::result_of_t<Op(VariantAccessResult<0, QualifiedVariants>...)>;
897 template <class Op, class... QualifiedVariants>
898 using VisitResult = typename VisitResultImpl<Op, QualifiedVariants...>::type;
900 template <class Op, class... QualifiedVariants>
901 struct PerformVisitation {
902 using ReturnType = VisitResult<Op, QualifiedVariants...>;
904 template <std::size_t... Is>
905 constexpr ReturnType operator()(SizeT<Is>... indices) const {
906 return Run(typename ContainsVariantNPos<Is...>::type{},
907 absl::index_sequence_for<QualifiedVariants...>(), indices...);
910 template <std::size_t... TupIs, std::size_t... Is>
911 constexpr ReturnType Run(std::false_type ,
912 index_sequence<TupIs...>, SizeT<Is>...) const {
914 std::is_same<ReturnType,
915 absl::result_of_t<Op(VariantAccessResult<
916 Is, QualifiedVariants>...)>>::value,
917 "All visitation overloads must have the same return type.");
918 return absl::base_internal::Invoke(
919 absl::forward<Op>(op),
920 VariantCoreAccess::Access<Is>(
921 absl::forward<QualifiedVariants>(std::get<TupIs>(variant_tup)))...);
924 template <std::size_t... TupIs, std::size_t... Is>
925 [[noreturn]] ReturnType Run(std::true_type ,
926 index_sequence<TupIs...>, SizeT<Is>...) const {
927 absl::variant_internal::ThrowBadVariantAccess();
932 std::tuple<QualifiedVariants&&...> variant_tup;
936 template <class... T>
943 struct NoopConstructorTag {};
945 template <std::size_t I>
946 struct EmplaceTag {};
950 constexpr explicit Union(NoopConstructorTag) noexcept {}
956 #pragma warning(push)
957 #pragma warning(disable : 4624)
960 template <class Head, class... Tail>
961 union Union<Head, Tail...> {
962 using TailUnion = Union<Tail...>;
964 explicit constexpr Union(NoopConstructorTag ) noexcept
965 : tail(NoopConstructorTag()) {}
967 template <class... P>
968 explicit constexpr Union(EmplaceTag<0>, P&&... args)
969 : head(absl::forward<P>(args)...) {}
971 template <std::size_t I, class... P>
972 explicit constexpr Union(EmplaceTag<I>, P&&... args)
973 : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {}
984 template <class... T>
985 union DestructibleUnionImpl;
988 union DestructibleUnionImpl<> {
989 constexpr explicit DestructibleUnionImpl(NoopConstructorTag) noexcept {}
992 template <class Head, class... Tail>
993 union DestructibleUnionImpl<Head, Tail...> {
994 using TailUnion = DestructibleUnionImpl<Tail...>;
996 explicit constexpr DestructibleUnionImpl(NoopConstructorTag ) noexcept
997 : tail(NoopConstructorTag()) {}
999 template <class... P>
1000 explicit constexpr DestructibleUnionImpl(EmplaceTag<0>, P&&... args)
1001 : head(absl::forward<P>(args)...) {}
1003 template <std::size_t I, class... P>
1004 explicit constexpr DestructibleUnionImpl(EmplaceTag<I>, P&&... args)
1005 : tail(EmplaceTag<I - 1>{}, absl::forward<P>(args)...) {}
1007 ~DestructibleUnionImpl() {}
1016 template <class... T>
1017 using DestructibleUnion =
1018 absl::conditional_t<std::is_destructible<Union<T...>>::value, Union<T...>,
1019 DestructibleUnionImpl<T...>>;
1022 template <class H, class... T>
1023 class VariantStateBase {
1025 using Variant = variant<H, T...>;
1027 template <class LazyH = H,
1028 class ConstructibleH = absl::enable_if_t<
1029 std::is_default_constructible<LazyH>::value, LazyH>>
1030 constexpr VariantStateBase() noexcept(
1031 std::is_nothrow_default_constructible<ConstructibleH>::value)
1032 : state_(EmplaceTag<0>()), index_(0) {}
1034 template <std::size_t I, class... P>
1035 explicit constexpr VariantStateBase(EmplaceTag<I> tag, P&&... args)
1036 : state_(tag, absl::forward<P>(args)...), index_(I) {}
1038 explicit constexpr VariantStateBase(NoopConstructorTag)
1039 : state_(NoopConstructorTag()), index_(variant_npos) {}
1043 DestructibleUnion<H, T...> state_;
1047 using absl::internal::identity;
1056 template <typename... Ts>
1059 template <typename T, typename... Ts>
1060 struct OverloadSet<T, Ts...> : OverloadSet<Ts...> {
1061 using Base = OverloadSet<Ts...>;
1062 static identity<T> Overload(const T&);
1063 using Base::Overload;
1067 struct OverloadSet<> {
1069 static void Overload(...);
1073 using LessThanResult = decltype(std::declval<T>() < std::declval<T>());
1076 using GreaterThanResult = decltype(std::declval<T>() > std::declval<T>());
1079 using LessThanOrEqualResult = decltype(std::declval<T>() <= std::declval<T>());
1082 using GreaterThanOrEqualResult =
1083 decltype(std::declval<T>() >= std::declval<T>());
1086 using EqualResult = decltype(std::declval<T>() == std::declval<T>());
1089 using NotEqualResult = decltype(std::declval<T>() != std::declval<T>());
1091 using type_traits_internal::is_detected_convertible;
1093 template <class... T>
1094 using RequireAllHaveEqualT = absl::enable_if_t<
1095 absl::conjunction<is_detected_convertible<bool, EqualResult, T>...>::value,
1098 template <class... T>
1099 using RequireAllHaveNotEqualT =
1100 absl::enable_if_t<absl::conjunction<is_detected_convertible<
1101 bool, NotEqualResult, T>...>::value,
1104 template <class... T>
1105 using RequireAllHaveLessThanT =
1106 absl::enable_if_t<absl::conjunction<is_detected_convertible<
1107 bool, LessThanResult, T>...>::value,
1110 template <class... T>
1111 using RequireAllHaveLessThanOrEqualT =
1112 absl::enable_if_t<absl::conjunction<is_detected_convertible<
1113 bool, LessThanOrEqualResult, T>...>::value,
1116 template <class... T>
1117 using RequireAllHaveGreaterThanOrEqualT =
1118 absl::enable_if_t<absl::conjunction<is_detected_convertible<
1119 bool, GreaterThanOrEqualResult, T>...>::value,
1122 template <class... T>
1123 using RequireAllHaveGreaterThanT =
1124 absl::enable_if_t<absl::conjunction<is_detected_convertible<
1125 bool, GreaterThanResult, T>...>::value,
1131 template <typename T>
1132 struct VariantHelper;
1134 template <typename... Ts>
1135 struct VariantHelper<variant<Ts...>> {
1138 template <typename U>
1139 using BestMatch = decltype(
1140 variant_internal::OverloadSet<Ts...>::Overload(std::declval<U>()));
1146 template <typename U>
1148 std::integral_constant<bool, !std::is_void<BestMatch<U>>::value> {};
1154 template <typename Other>
1155 struct CanConvertFrom;
1157 template <typename... Us>
1158 struct CanConvertFrom<variant<Us...>>
1159 : public absl::conjunction<CanAccept<Us>...> {};
1163 struct TrivialMoveOnly {
1164 TrivialMoveOnly(TrivialMoveOnly&&) = default;
1170 template <typename T>
1171 struct IsTriviallyMoveConstructible:
1172 std::is_move_constructible<Union<T, TrivialMoveOnly>> {};
1190 template <class... T>
1191 class VariantStateBaseDestructorNontrivial;
1193 template <class... T>
1194 class VariantMoveBaseNontrivial;
1196 template <class... T>
1197 class VariantCopyBaseNontrivial;
1199 template <class... T>
1200 class VariantMoveAssignBaseNontrivial;
1202 template <class... T>
1203 class VariantCopyAssignBaseNontrivial;
1206 template <class... T>
1207 using VariantStateBaseDestructor =
1208 absl::conditional_t<std::is_destructible<Union<T...>>::value,
1209 VariantStateBase<T...>,
1210 VariantStateBaseDestructorNontrivial<T...>>;
1219 template <class... T>
1220 using VariantMoveBase = absl::conditional_t<
1222 absl::negation<absl::conjunction<std::is_move_constructible<T>...>>,
1223 absl::conjunction<IsTriviallyMoveConstructible<T>...>>::value,
1224 VariantStateBaseDestructor<T...>, VariantMoveBaseNontrivial<T...>>;
1227 template <class... T>
1228 using VariantCopyBase = absl::conditional_t<
1230 absl::negation<absl::conjunction<std::is_copy_constructible<T>...>>,
1231 std::is_copy_constructible<Union<T...>>>::value,
1232 VariantMoveBase<T...>, VariantCopyBaseNontrivial<T...>>;
1235 template <class... T>
1236 using VariantMoveAssignBase = absl::conditional_t<
1238 absl::conjunction<absl::is_move_assignable<Union<T...>>,
1239 std::is_move_constructible<Union<T...>>,
1240 std::is_destructible<Union<T...>>>,
1241 absl::negation<absl::conjunction<std::is_move_constructible<T>...,
1245 is_move_assignable<T>...>>>::value,
1246 VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>;
1249 template <class... T>
1250 using VariantCopyAssignBase = absl::conditional_t<
1252 absl::conjunction<absl::is_copy_assignable<Union<T...>>,
1253 std::is_copy_constructible<Union<T...>>,
1254 std::is_destructible<Union<T...>>>,
1255 absl::negation<absl::conjunction<std::is_copy_constructible<T>...,
1259 is_copy_assignable<T>...>>>::value,
1260 VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>;
1262 template <class... T>
1263 using VariantBase = VariantCopyAssignBase<T...>;
1265 template <class... T>
1266 class VariantStateBaseDestructorNontrivial : protected VariantStateBase<T...> {
1268 using Base = VariantStateBase<T...>;
1273 VariantStateBaseDestructorNontrivial() = default;
1274 VariantStateBaseDestructorNontrivial(VariantStateBaseDestructorNontrivial&&) =
1276 VariantStateBaseDestructorNontrivial(
1277 const VariantStateBaseDestructorNontrivial&) = default;
1278 VariantStateBaseDestructorNontrivial& operator=(
1279 VariantStateBaseDestructorNontrivial&&) = default;
1280 VariantStateBaseDestructorNontrivial& operator=(
1281 const VariantStateBaseDestructorNontrivial&) = default;
1284 template <std::size_t I>
1285 void operator()(SizeT<I> i) const {
1287 typename absl::variant_alternative<I, variant<T...>>::type;
1288 variant_internal::AccessUnion(self->state_, i).~Alternative();
1291 void operator()(SizeT<absl::variant_npos> ) const {
1295 VariantStateBaseDestructorNontrivial*
self;
1300 ~VariantStateBaseDestructorNontrivial() {
destroy(); }
1307 template <
class... T>
1308 class VariantMoveBaseNontrivial :
protected VariantStateBaseDestructor<T...> {
1310 using Base = VariantStateBaseDestructor<T...>;
1316 template <std::
size_t I>
1320 ::new (static_cast<void*>(&self->state_)) Alternative(
1326 VariantMoveBaseNontrivial*
self;
1327 VariantMoveBaseNontrivial* other;
1330 VariantMoveBaseNontrivial() =
default;
1331 VariantMoveBaseNontrivial(VariantMoveBaseNontrivial&& other) noexcept(
1333 : Base(NoopConstructorTag()) {
1334 VisitIndices<
sizeof...(T)>::Run(Construct{
this, &other}, other.index_);
1335 index_ = other.index_;
1338 VariantMoveBaseNontrivial(VariantMoveBaseNontrivial
const&) =
default;
1340 VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial&&) =
default;
1341 VariantMoveBaseNontrivial& operator=(VariantMoveBaseNontrivial
const&) =
1349 template <
class... T>
1350 class VariantCopyBaseNontrivial :
protected VariantMoveBase<T...> {
1352 using Base = VariantMoveBase<T...>;
1357 VariantCopyBaseNontrivial() =
default;
1358 VariantCopyBaseNontrivial(VariantCopyBaseNontrivial&&) =
default;
1361 template <std::
size_t I>
1365 ::new (static_cast<void*>(&self->state_))
1371 VariantCopyBaseNontrivial*
self;
1372 const VariantCopyBaseNontrivial* other;
1375 VariantCopyBaseNontrivial(VariantCopyBaseNontrivial
const& other)
1376 : Base(NoopConstructorTag()) {
1377 VisitIndices<
sizeof...(T)>::Run(Construct{
this, &other}, other.index_);
1378 index_ = other.index_;
1381 VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial&&) =
default;
1382 VariantCopyBaseNontrivial& operator=(VariantCopyBaseNontrivial
const&) =
1390 template <
class... T>
1391 class VariantMoveAssignBaseNontrivial :
protected VariantCopyBase<T...> {
1395 using Base = VariantCopyBase<T...>;
1400 VariantMoveAssignBaseNontrivial() =
default;
1401 VariantMoveAssignBaseNontrivial(VariantMoveAssignBaseNontrivial&&) =
default;
1402 VariantMoveAssignBaseNontrivial(
const VariantMoveAssignBaseNontrivial&) =
1404 VariantMoveAssignBaseNontrivial& operator=(
1405 VariantMoveAssignBaseNontrivial
const&) =
default;
1407 VariantMoveAssignBaseNontrivial&
1408 operator=(VariantMoveAssignBaseNontrivial&& other) noexcept(
1410 std::is_nothrow_move_assignable<T>...>::
value) {
1421 template <
class... T>
1422 class VariantCopyAssignBaseNontrivial :
protected VariantMoveAssignBase<T...> {
1426 using Base = VariantMoveAssignBase<T...>;
1431 VariantCopyAssignBaseNontrivial() =
default;
1432 VariantCopyAssignBaseNontrivial(VariantCopyAssignBaseNontrivial&&) =
default;
1433 VariantCopyAssignBaseNontrivial(
const VariantCopyAssignBaseNontrivial&) =
1435 VariantCopyAssignBaseNontrivial& operator=(
1436 VariantCopyAssignBaseNontrivial&&) =
default;
1438 VariantCopyAssignBaseNontrivial& operator=(
1439 const VariantCopyAssignBaseNontrivial& other) {
1454 template <
class... Types>
1463 template <std::
size_t I>
1464 constexpr
bool operator()(
SizeT<I> )
const {
1465 return VariantCoreAccess::Access<I>(*v) == VariantCoreAccess::Access<I>(*w);
1469 template <
class... Types>
1470 struct NotEqualsOp {
1478 template <std::
size_t I>
1479 constexpr
bool operator()(
SizeT<I> )
const {
1480 return VariantCoreAccess::Access<I>(*v) != VariantCoreAccess::Access<I>(*w);
1484 template <
class... Types>
1493 template <std::
size_t I>
1494 constexpr
bool operator()(
SizeT<I> )
const {
1495 return VariantCoreAccess::Access<I>(*v) < VariantCoreAccess::Access<I>(*w);
1499 template <
class... Types>
1500 struct GreaterThanOp {
1508 template <std::
size_t I>
1509 constexpr
bool operator()(
SizeT<I> )
const {
1510 return VariantCoreAccess::Access<I>(*v) > VariantCoreAccess::Access<I>(*w);
1514 template <
class... Types>
1515 struct LessThanOrEqualsOp {
1523 template <std::
size_t I>
1524 constexpr
bool operator()(
SizeT<I> )
const {
1525 return VariantCoreAccess::Access<I>(*v) <= VariantCoreAccess::Access<I>(*w);
1529 template <
class... Types>
1530 struct GreaterThanOrEqualsOp {
1538 template <std::
size_t I>
1539 constexpr
bool operator()(
SizeT<I> )
const {
1540 return VariantCoreAccess::Access<I>(*v) >= VariantCoreAccess::Access<I>(*w);
1545 template <
class... Types>
1546 struct SwapSameIndex {
1549 template <std::
size_t I>
1552 VariantCoreAccess::Access<I>(*w));
1559 template <
class... Types>
1564 void generic_swap()
const {
1573 if (!
v->valueless_by_exception()) {
1578 template <std::
size_t Wi>
1580 if (
v->index() == Wi) {
1581 VisitIndices<
sizeof...(Types)>::Run(SwapSameIndex<Types...>{
v, w}, Wi);
1588 template <
typename Variant,
typename = void,
typename... Ts>
1589 struct VariantHashBase {
1590 VariantHashBase() =
delete;
1591 VariantHashBase(
const VariantHashBase&) =
delete;
1592 VariantHashBase(VariantHashBase&&) =
delete;
1593 VariantHashBase& operator=(
const VariantHashBase&) =
delete;
1594 VariantHashBase& operator=(VariantHashBase&&) =
delete;
1597 struct VariantHashVisitor {
1598 template <
typename T>
1599 size_t operator()(
const T& t) {
1600 return std::hash<T>{}(t);
1604 template <
typename Variant,
typename... Ts>
1605 struct VariantHashBase<Variant,
1607 type_traits_internal::IsHashable<Ts>...>::value>,
1609 using argument_type = Variant;
1610 using result_type = size_t;
1611 size_t operator()(
const Variant& var)
const {
1613 if (var.valueless_by_exception()) {
1617 PerformVisitation<VariantHashVisitor, const Variant&>{
1618 std::forward_as_tuple(var), VariantHashVisitor{}},
1622 return result ^ var.index();
1629 #endif // !defined(ABSL_HAVE_STD_VARIANT) 1630 #endif // ABSL_TYPES_variant_internal_H_
static constexpr std::size_t Run()
QualifiedRightVariant && right
static constexpr ResultType Run()
void operator()(SizeT< NewIndex >) const
typename std::result_of< T >::type result_of_t
constexpr T AccessSimpleArray(const T &value)
VariantAccessResult< I, Self > AccessUnion(Self &&self, SizeT< I >)
InvokeT< F, Args... > Invoke(F &&f, Args &&...args)
static VisitIndicesResultT< Op, std::size_t > Run(Op &&op)
UnambiguousTypeOfImpl< T, UnambiguousIndexOf< Variant, T >::value > UnambiguousTypeOfT
static ConversionAssignVisitor< Left, QualifiedNew > MakeConversionAssignVisitor(Left *left, QualifiedNew &&qual)
const typename absl::variant_alternative< I, variant< T... >>::type & type
const typename absl::variant_alternative< I, variant< T... >>::type && type
static constexpr std::size_t Run(std::size_t head, SizeType...tail)
#define ABSL_ASSERT(expr)
static void Destroy(VariantType &self)
typename GiveQualsTo< T, U >::type GiveQualsToT
SizeT< IndexOfImpl< Expected, Tail... >::IndexFromEnd::value+1 > IndexFromEnd
IndexFromEnd MatchedIndexFromEnd
static VisitIndicesResultT< Op, std::size_t > Run(Op &&)
typename VariantAccessResultImpl< I, Variant && >::type VariantAccessResult
ReturnType TypedThrowBadVariantAccess()
static void InitFrom(Variant &self, Variant &&other)
typename AccessedType< T >::type AccessedTypeT
constexpr ReturnType call_with_indices(FunctionObject &&function)
typename VariantAlternativeSfinae< I, T >::type VariantAlternativeSfinaeT
void(*)(utility_internal::InPlaceTypeTag< T >) in_place_type_t
IndexFromEnd MatchedIndexFromEnd
typename std::conditional< B, T, F >::type conditional_t
static VisitIndicesResultT< Op, std::size_t > Run(Op &&op, std::size_t i)
typename VType::Variant DerivedType
void operator()(SizeT< absl::variant_npos >) const
typename std::enable_if< B, T >::type enable_if_t
static CopyAssignVisitor< VType > MakeCopyAssignVisitor(VType *left, const VType &other)
static std::function< void(void *, Slot *)> destroy
static constexpr ResultType Run()
SizeT< variant_npos > NPos
typename absl::variant_alternative< I, variant< T... >>::type && type
static absl::variant_alternative< NewIndex, Self >::type & Replace(Self *self, Args &&...args)
void Swap(T &lhs, T &rhs) noexcept(IsNothrowSwappable< T >::value)
std::integral_constant< std::size_t, I > SizeT
typename VisitIndicesResultImpl< Op, Vs... >::type VisitIndicesResultT
VisitIndicesResultT< Op, decltype(EndIndices)... > operator()(SizeT< I >)&&
void operator()(SizeT< NewIndex::value >) const
SizeT< IndexOfImpl< Expected, Tail... >::IndexFromEnd::value+1 > IndexFromEnd
static VisitIndicesResultT< Op, decltype(EndIndices)... > Run(Op &&op, SizeType...i)
void ThrowBadVariantAccess()
ReturnType(*)(FunctionObject &&) ResultType
void(*)(utility_internal::InPlaceIndexTag< I >) in_place_index_t
std::false_type MultipleMatches
ABSL_INTERNAL_INLINE_CONSTEXPR(std::size_t, MaxUnrolledVisitCases, 33)
void operator()(SizeT< absl::variant_npos >) const
ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos,-1)
std::integral_constant< bool, IndexOfImpl< Expected, Tail... >::MatchedIndexFromEnd::value!=0 > MultipleMatches
void operator()(SizeT< OldIndex >) const
std::shared_ptr< AllocState > state_
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
typename IndexOfMeta< Expected, Types... >::type IndexOf
static MoveAssignVisitor< VType > MakeMoveAssignVisitor(VType *left, VType *other)
typename PickCaseImpl<(I< EndIndex)>::template Apply< Op, I > PickCase
static VisitIndicesResultT< Op, SizeT... > Run(Op &&op, SizeT...indices)
absl::result_of_t< Op(AlwaysZero< Vs >...)> type
typename absl::variant_alternative< I, variant< T... >>::type & type