42 #ifndef ABSL_TYPES_VARIANT_H_ 43 #define ABSL_TYPES_VARIANT_H_ 48 #ifdef ABSL_HAVE_STD_VARIANT 53 using std::bad_variant_access;
59 using std::variant_alternative;
61 using std::variant_npos;
62 using std::variant_size;
63 using std::variant_size_v;
67 #else // ABSL_HAVE_STD_VARIANT 71 #include <type_traits> 119 template <
typename... Ts>
136 type_traits_internal::IsSwappable<Ts>...>
::value,
171 template <
class... Ts>
173 : std::integral_constant<std::size_t, sizeof...(Ts)> {};
211 template <std::
size_t I,
class T>
214 template <std::size_t I,
class... Types>
221 template <std::
size_t I,
class T>
227 template <std::
size_t I,
class T>
234 template <std::
size_t I,
class T>
246 template <std::
size_t I,
class T>
260 template <
class T,
class... Types>
264 0>::
value !=
sizeof...(Types),
265 "The type T must occur exactly once in Types...");
296 template <
class T,
class... Types>
304 template <
class T,
class... Types>
311 template <
class T,
class... Types>
312 constexpr
const T&
get(
const variant<Types...>&
v) {
319 template <
class T,
class... Types>
320 constexpr
const T&&
get(
const variant<Types...>&&
v) {
326 template <std::size_t I,
class... Types>
329 return variant_internal::VariantCoreAccess::CheckedAccess<I>(
v);
334 template <std::size_t I,
class... Types>
337 return variant_internal::VariantCoreAccess::CheckedAccess<I>(
absl::move(
v));
341 template <std::size_t I,
class... Types>
344 return variant_internal::VariantCoreAccess::CheckedAccess<I>(
v);
349 template <std::size_t I,
class... Types>
352 return variant_internal::VariantCoreAccess::CheckedAccess<I>(
absl::move(
v));
367 template <std::size_t I,
class... Types>
370 return (
v !=
nullptr &&
v->index() == I)
372 variant_internal::VariantCoreAccess::Access<I>(*
v))
378 template <std::size_t I,
class... Types>
381 return (
v !=
nullptr &&
v->index() == I)
383 variant_internal::VariantCoreAccess::Access<I>(*
v))
389 template <
class T,
class... Types>
396 template <
class T,
class... Types>
426 template <
typename Visitor,
typename... Variants>
427 variant_internal::VisitResult<Visitor, Variants...>
visit(Visitor&& vis,
428 Variants&&... vars) {
431 variant_internal::PerformVisitation<Visitor, Variants...>{
432 std::forward_as_tuple(absl::forward<Variants>(vars)...),
433 absl::forward<Visitor>(vis)},
456 template <
typename T0,
typename... Tn>
457 class variant<T0, Tn...> :
private variant_internal::VariantBase<T0, Tn...> {
459 std::is_object<Tn>...>::
value,
460 "Attempted to instantiate a variant containing a non-object " 466 "Attempted to instantiate a variant containing an array type.");
468 std::is_nothrow_destructible<Tn>...>::
value,
469 "Attempted to instantiate a variant containing a non-nothrow " 470 "destructible type.");
475 using Base = variant_internal::VariantBase<T0, Tn...>;
502 std::size_t I = std::enable_if<
517 template <
class T,
class... Args,
518 typename std::enable_if<std::is_constructible<
520 Args...>::value>::type* =
nullptr>
522 :
Base(variant_internal::EmplaceTag<
523 variant_internal::UnambiguousIndexOf<variant, T>::
value>(),
531 template <
class T,
class U,
class... Args,
532 typename std::enable_if<std::is_constructible<
533 variant_internal::UnambiguousTypeOfT<variant, T>,
534 std::initializer_list<U>&, Args...>::value>::type* =
nullptr>
537 :
Base(variant_internal::EmplaceTag<
538 variant_internal::UnambiguousIndexOf<variant, T>::
value>(),
543 template <std::size_t I,
class... Args,
544 typename std::enable_if<std::is_constructible<
546 Args...>::value>::type* =
nullptr>
548 :
Base(variant_internal::EmplaceTag<I>(),
absl::
forward<Args>(args)...) {}
553 template <std::size_t I,
class U,
class... Args,
554 typename std::enable_if<std::is_constructible<
555 variant_internal::VariantAlternativeSfinaeT<I, variant>,
556 std::initializer_list<U>&, Args...>::value>::type* =
nullptr>
559 :
Base(variant_internal::EmplaceTag<I>(), il,
566 ~variant() =
default;
571 variant& operator=(
const variant& other) =
default;
574 variant& operator=(variant&& other) =
default;
583 std::size_t I = std::enable_if<
584 !std::is_same<absl::decay_t<T>, variant>
::value,
591 std::is_nothrow_assignable<Tj&, T>::
value&&
592 std::is_nothrow_constructible<Tj, T>::
value) {
595 this, absl::forward<T>(t)),
612 class T,
class... Args,
613 typename std::enable_if<std::is_constructible<
616 Args...>::value>::type* =
nullptr>
619 variant_internal::UnambiguousIndexOf<variant, T>::value>(
620 this, absl::forward<Args>(args)...);
631 class T,
class U,
class... Args,
632 typename std::enable_if<std::is_constructible<
634 variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
635 std::initializer_list<U>&, Args...>::value>::type* =
nullptr>
636 T&
emplace(std::initializer_list<U> il, Args&&... args) {
638 variant_internal::UnambiguousIndexOf<variant, T>::value>(
639 this, il, absl::forward<Args>(args)...);
652 template <std::size_t I,
class... Args,
653 typename std::enable_if<
654 std::is_constructible<absl::variant_alternative_t<I, variant>,
655 Args...>::value>::type* =
nullptr>
657 return variant_internal::VariantCoreAccess::Replace<I>(
658 this, absl::forward<Args>(args)...);
669 template <std::size_t I,
class U,
class... Args,
670 typename std::enable_if<std::is_constructible<
672 std::initializer_list<U>&, Args...>::value>::type* =
nullptr>
673 absl::variant_alternative_t<I, variant>&
emplace(std::initializer_list<U> il,
675 return variant_internal::VariantCoreAccess::Replace<I>(
676 this, il, absl::forward<Args>(args)...);
683 return this->index_ == absl::variant_npos;
690 constexpr std::size_t
index() const noexcept {
return this->index_; }
696 void swap(variant& rhs) noexcept(
698 std::is_nothrow_move_constructible<T0>,
699 std::is_nothrow_move_constructible<Tn>...,
700 type_traits_internal::IsNothrowSwappable<T0>,
701 type_traits_internal::IsNothrowSwappable<Tn>...>::
value) {
703 variant_internal::Swap<T0, Tn...>{
this, &rhs}, rhs.index());
738 template <
typename... Types>
739 constexpr variant_internal::RequireAllHaveEqualT<Types...>
operator==(
741 return (a.index() == b.index()) &&
743 variant_internal::EqualsOp<Types...>{&
a, &b}, a.index());
747 template <
typename... Types>
748 constexpr variant_internal::RequireAllHaveNotEqualT<Types...>
operator!=(
750 return (a.index() != b.index()) ||
752 variant_internal::NotEqualsOp<Types...>{&
a, &b}, a.index());
756 template <
typename... Types>
757 constexpr variant_internal::RequireAllHaveLessThanT<Types...>
operator<(
759 return (a.index() != b.index())
760 ? (a.index() + 1) < (b.index() + 1)
762 variant_internal::LessThanOp<Types...>{&
a, &b}, a.index());
766 template <
typename... Types>
767 constexpr variant_internal::RequireAllHaveGreaterThanT<Types...>
operator>(
769 return (a.index() != b.index())
770 ? (a.index() + 1) > (b.index() + 1)
772 variant_internal::GreaterThanOp<Types...>{&
a, &b},
777 template <
typename... Types>
778 constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...>
operator<=(
780 return (a.index() != b.index())
781 ? (a.index() + 1) < (b.index() + 1)
783 variant_internal::LessThanOrEqualsOp<Types...>{&
a, &b},
788 template <
typename... Types>
789 constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
791 return (a.index() != b.index())
792 ? (a.index() + 1) > (b.index() + 1)
794 variant_internal::GreaterThanOrEqualsOp<Types...>{&
a, &b},
808 template <
class... T>
810 : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
811 absl::remove_const_t<T>...> {};
815 #endif // ABSL_HAVE_STD_VARIANT 818 namespace variant_internal {
822 template <
typename To>
824 template <
typename T>
826 return To(std::forward<T>(
v));
847 template <
typename To,
typename Variant>
850 std::forward<Variant>(
variant));
855 #endif // ABSL_TYPES_VARIANT_H_
typename variant_alternative< I, T >::type variant_alternative_t
constexpr absl::add_pointer_t< variant_alternative_t< I, variant< Types... > > > get_if(variant< Types... > *v) noexcept
constexpr bool valueless_by_exception() const noexcept
const typename variant_alternative< I, T >::type type
constexpr T && forward(absl::remove_reference_t< T > &t) noexcept
bool operator<(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
constexpr std::size_t index() const noexcept
constexpr variant(T &&t) noexcept(std::is_nothrow_constructible< Tj, T >::value)
variant_internal::VariantBase< T0, Tn... > Base
static VariantAccessResult< I, Variant > CheckedAccess(Variant &&self)
UnambiguousTypeOfImpl< T, UnambiguousIndexOf< Variant, T >::value > UnambiguousTypeOfT
static ConversionAssignVisitor< Left, QualifiedNew > MakeConversionAssignVisitor(Left *left, QualifiedNew &&qual)
variant_internal::VariantAlternativeSfinaeT< I, variant< Types... >> type
typename std::add_pointer< T >::type add_pointer_t
typename std::decay< T >::type decay_t
std::size_t operator()(absl::monostate) const
To ConvertVariantTo(Variant &&variant)
constexpr absl::add_pointer_t< const T > get_if(const variant< Types... > *v) noexcept
typename VariantAlternativeSfinae< I, T >::type VariantAlternativeSfinaeT
constexpr variant(in_place_type_t< T >, Args &&...args)
void(*)(utility_internal::InPlaceTypeTag< T >) in_place_type_t
bool operator>(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
typename std::enable_if< B, T >::type enable_if_t
T & emplace(std::initializer_list< U > il, Args &&...args)
constexpr variant(in_place_type_t< T >, std::initializer_list< U > il, Args &&...args)
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
static absl::variant_alternative< NewIndex, Self >::type & Replace(Self *self, Args &&...args)
bool operator>=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
variant & operator=(T &&t) noexcept(std::is_nothrow_assignable< Tj &, T >::value &&std::is_nothrow_constructible< Tj, T >::value)
hash_default_hash< typename T::first_type > hash
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
volatile typename variant_alternative< I, T >::type type
void swap(variant &rhs) noexcept(absl::conjunction< std::is_nothrow_move_constructible< T0 >, std::is_nothrow_move_constructible< Tn >..., type_traits_internal::IsNothrowSwappable< T0 >, type_traits_internal::IsNothrowSwappable< Tn >... >::value)
T & emplace(Args &&...args)
const volatile typename variant_alternative< I, T >::type type
void(*)(utility_internal::InPlaceIndexTag< I >) in_place_index_t
constexpr variant(in_place_index_t< I >, Args &&...args)
variant_internal::VisitResult< Visitor, Variants... > visit(Visitor &&vis, Variants &&...vars)
absl::variant_alternative_t< I, variant > & emplace(std::initializer_list< U > il, Args &&...args)
absl::string_view get(const Cont &c)
absl::variant_alternative_t< I, variant > & emplace(Args &&...args)
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
constexpr variant(in_place_index_t< I >, std::initializer_list< U > il, Args &&...args)
To operator()(T &&v) const
typename IndexOfMeta< Expected, Types... >::type IndexOf
constexpr bool holds_alternative(const variant< Types... > &v) noexcept
bool operator<=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)