// 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.
//
// -----------------------------------------------------------------------------
// variant.h
// -----------------------------------------------------------------------------
//
// This header file defines an `absl::variant` type for holding a type-safe
// value of some prescribed set of types (noted as alternative types), and
// associated functions for managing variants.
//
// The `absl::variant` type is a form of type-safe union. An `absl::variant`
// should always hold a value of one of its alternative types (except in the
// "valueless by exception state" -- see below). A default-constructed
// `absl::variant` will hold the value of its first alternative type, provided
// it is default-constructible.
//
// In exceptional cases due to error, an `absl::variant` can hold no
// value (known as a "valueless by exception" state), though this is not the
// norm.
//
// As with `absl::optional`, an `absl::variant` -- when it holds a value --
// allocates a value of that type directly within the `variant` itself; it
// cannot hold a reference, array, or the type `void`; it can, however, hold a
// pointer to externally managed memory.
//
// `absl::variant` is a C++11 compatible version of the C++17 `std::variant`
// abstraction and is designed to be a drop-in replacement for code compliant
// with C++17.

#ifndef ABSL_TYPES_VARIANT_H_
#define ABSL_TYPES_VARIANT_H_

#include "absl/base/config.h"
#include "absl/utility/utility.h"

#ifdef ABSL_USES_STD_VARIANT

#include <variant>  // IWYU pragma: export

namespace absl {
ABSL_NAMESPACE_BEGIN
using std::bad_variant_access;
using std::get;
using std::get_if;
using std::holds_alternative;
using std::monostate;
using std::variant;
using std::variant_alternative;
using std::variant_alternative_t;
using std::variant_npos;
using std::variant_size;
using std::variant_size_v;
using std::visit;
ABSL_NAMESPACE_END
}  // namespace absl

#else  // ABSL_USES_STD_VARIANT

#include <functional>
#include <new>
#include <type_traits>
#include <utility>

#include "absl/base/macros.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
#include "absl/types/internal/variant.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

// -----------------------------------------------------------------------------
// absl::variant
// -----------------------------------------------------------------------------
//
// An `absl::variant` type is a form of type-safe union. An `absl::variant` --
// except in exceptional cases -- always holds a value of one of its alternative
// types.
//
// Example:
//
//   // Construct a variant that holds either an integer or a std::string and
//   // assign it to a std::string.
//   absl::variant<int, std::string> v = std::string("abc");
//
//   // A default-constructed variant will hold a value-initialized value of
//   // the first alternative type.
//   auto a = absl::variant<int, std::string>();   // Holds an int of value '0'.
//
//   // variants are assignable.
//
//   // copy assignment
//   auto v1 = absl::variant<int, std::string>("abc");
//   auto v2 = absl::variant<int, std::string>(10);
//   v2 = v1;  // copy assign
//
//   // move assignment
//   auto v1 = absl::variant<int, std::string>("abc");
//   v1 = absl::variant<int, std::string>(10);
//
//   // assignment through type conversion
//   a = 128;         // variant contains int
//   a = "128";       // variant contains std::string
//
// An `absl::variant` holding a value of one of its alternative types `T` holds
// an allocation of `T` directly within the variant itself. An `absl::variant`
// is not allowed to allocate additional storage, such as dynamic memory, to
// allocate the contained value. The contained value shall be allocated in a
// region of the variant storage suitably aligned for all alternative types.
template <typename... Ts>
class variant;

// swap()
//
// Swaps two `absl::variant` values. This function is equivalent to `v.swap(w)`
// where `v` and `w` are `absl::variant` types.
//
// Note that this function requires all alternative types to be both swappable
// and move-constructible, because any two variants may refer to either the same
// type (in which case, they will be swapped) or to two different types (in
// which case the values will need to be moved).
//
template <
    typename... Ts,
    absl::enable_if_t<
        absl::conjunction<std::is_move_constructible<Ts>...,
                          type_traits_internal::IsSwappable<Ts>...>::value,
        int> = 0>
void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
  v.swap(w);
}

// variant_size
//
// Returns the number of alternative types available for a given `absl::variant`
// type as a compile-time constant expression. As this is a class template, it
// is not generally useful for accessing the number of alternative types of
// any given `absl::variant` instance.
//
// Example:
//
//   auto a = absl::variant<int, std::string>;
//   constexpr int num_types =
//       absl::variant_size<absl::variant<int, std::string>>();
//
//   // You can also use the member constant `value`.
//   constexpr int num_types =
//       absl::variant_size<absl::variant<int, std::string>>::value;
//
//   // `absl::variant_size` is more valuable for use in generic code:
//   template <typename Variant>
//   constexpr bool IsVariantMultivalue() {
//       return absl::variant_size<Variant>() > 1;
//   }
//
// Note that the set of cv-qualified specializations of `variant_size` are
// provided to ensure that those specializations compile (especially when passed
// within template logic).
template <class T>
struct variant_size;

template <class... Ts>
struct variant_size<variant<Ts...>>
    : std::integral_constant<std::size_t, sizeof...(Ts)> {};

// Specialization of `variant_size` for const qualified variants.
template <class T>
struct variant_size<const T> : variant_size<T>::type {};

// Specialization of `variant_size` for volatile qualified variants.
template <class T>
struct variant_size<volatile T> : variant_size<T>::type {};

// Specialization of `variant_size` for const volatile qualified variants.
template <class T>
struct variant_size<const volatile T> : variant_size<T>::type {};

// variant_alternative
//
// Returns the alternative type for a given `absl::variant` at the passed
// index value as a compile-time constant expression. As this is a class
// template resulting in a type, it is not useful for access of the run-time
// value of any given `absl::variant` variable.
//
// Example:
//
//   // The type of the 0th alternative is "int".
//   using alternative_type_0
//     = absl::variant_alternative<0, absl::variant<int, std::string>>::type;
//
//   static_assert(std::is_same<alternative_type_0, int>::value, "");
//
//   // `absl::variant_alternative` is more valuable for use in generic code:
//   template <typename Variant>
//   constexpr bool IsFirstElementTrivial() {
//       return std::is_trivial_v<variant_alternative<0, Variant>::type>;
//   }
//
// Note that the set of cv-qualified specializations of `variant_alternative`
// are provided to ensure that those specializations compile (especially when
// passed within template logic).
template <std::size_t I, class T>
struct variant_alternative;

template <std::size_t I, class... Types>
struct variant_alternative<I, variant<Types...>> {
  using type =
      variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>;
};

// Specialization of `variant_alternative` for const qualified variants.
template <std::size_t I, class T>
struct variant_alternative<I, const T> {
  using type = const typename variant_alternative<I, T>::type;
};

// Specialization of `variant_alternative` for volatile qualified variants.
template <std::size_t I, class T>
struct variant_alternative<I, volatile T> {
  using type = volatile typename variant_alternative<I, T>::type;
};

// Specialization of `variant_alternative` for const volatile qualified
// variants.
template <std::size_t I, class T>
struct variant_alternative<I, const volatile T> {
  using type = const volatile typename variant_alternative<I, T>::type;
};

// Template type alias for variant_alternative<I, T>::type.
//
// Example:
//
//   using alternative_type_0
//     = absl::variant_alternative_t<0, absl::variant<int, std::string>>;
//   static_assert(std::is_same<alternative_type_0, int>::value, "");
template <std::size_t I, class T>
using variant_alternative_t = typename variant_alternative<I, T>::type;

// holds_alternative()
//
// Checks whether the given variant currently holds a given alternative type,
// returning `true` if so.
//
// Example:
//
//   absl::variant<int, std::string> foo = 42;
//   if (absl::holds_alternative<int>(foo)) {
//       std::cout << "The variant holds an integer";
//   }
template <class T, class... Types>
constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
  static_assert(
      variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T,
                                               0>::value != sizeof...(Types),
      "The type T must occur exactly once in Types...");
  return v.index() ==
         variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value;
}

// get()
//
// Returns a reference to the value currently within a given variant, using
// either a unique alternative type amongst the variant's set of alternative
// types, or the variant's index value. Attempting to get a variant's value
// using a type that is not unique within the variant's set of alternative types
// is a compile-time error. If the index of the alternative being specified is
// different from the index of the alternative that is currently stored, throws
// `absl::bad_variant_access`.
//
// Example:
//
//   auto a = absl::variant<int, std::string>;
//
//   // Get the value by type (if unique).
//   int i = absl::get<int>(a);
//
//   auto b = absl::variant<int, int>;
//
//   // Getting the value by a type that is not unique is ill-formed.
//   int j = absl::get<int>(b);     // Compile Error!
//
//   // Getting value by index not ambiguous and allowed.
//   int k = absl::get<1>(b);

// Overload for getting a variant's lvalue by type.
template <class T, class... Types>
constexpr T& get(variant<Types...>& v) {  // NOLINT
  return variant_internal::VariantCoreAccess::CheckedAccess<
      variant_internal::IndexOf<T, Types...>::value>(v);
}

// Overload for getting a variant's rvalue by type.
// Note: `absl::move()` is required to allow use of constexpr in C++11.
template <class T, class... Types>
constexpr T&& get(variant<Types...>&& v) {
  return variant_internal::VariantCoreAccess::CheckedAccess<
      variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
}

// Overload for getting a variant's const lvalue by type.
template <class T, class... Types>
constexpr const T& get(const variant<Types...>& v) {
  return variant_internal::VariantCoreAccess::CheckedAccess<
      variant_internal::IndexOf<T, Types...>::value>(v);
}

// Overload for getting a variant's const rvalue by type.
// Note: `absl::move()` is required to allow use of constexpr in C++11.
template <class T, class... Types>
constexpr const T&& get(const variant<Types...>&& v) {
  return variant_internal::VariantCoreAccess::CheckedAccess<
      variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
}

// Overload for getting a variant's lvalue by index.
template <std::size_t I, class... Types>
constexpr variant_alternative_t<I, variant<Types...>>& get(
    variant<Types...>& v) {  // NOLINT
  return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
}

// Overload for getting a variant's rvalue by index.
// Note: `absl::move()` is required to allow use of constexpr in C++11.
template <std::size_t I, class... Types>
constexpr variant_alternative_t<I, variant<Types...>>&& get(
    variant<Types...>&& v) {
  return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
}

// Overload for getting a variant's const lvalue by index.
template <std::size_t I, class... Types>
constexpr const variant_alternative_t<I, variant<Types...>>& get(
    const variant<Types...>& v) {
  return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
}

// Overload for getting a variant's const rvalue by index.
// Note: `absl::move()` is required to allow use of constexpr in C++11.
template <std::size_t I, class... Types>
constexpr const variant_alternative_t<I, variant<Types...>>&& get(
    const variant<Types...>&& v) {
  return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
}

// get_if()
//
// Returns a pointer to the value currently stored within a given variant, if
// present, using either a unique alternative type amongst the variant's set of
// alternative types, or the variant's index value. If such a value does not
// exist, returns `nullptr`.
//
// As with `get`, attempting to get a variant's value using a type that is not
// unique within the variant's set of alternative types is a compile-time error.

// Overload for getting a pointer to the value stored in the given variant by
// index.
template <std::size_t I, class... Types>
constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>>
get_if(variant<Types...>* v) noexcept {
  return (v != nullptr && v->index() == I)
             ? std::addressof(
                   variant_internal::VariantCoreAccess::Access<I>(*v))
             : nullptr;
}

// Overload for getting a pointer to the const value stored in the given
// variant by index.
template <std::size_t I, class... Types>
constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
get_if(const variant<Types...>* v) noexcept {
  return (v != nullptr && v->index() == I)
             ? std::addressof(
                   variant_internal::VariantCoreAccess::Access<I>(*v))
             : nullptr;
}

// Overload for getting a pointer to the value stored in the given variant by
// type.
template <class T, class... Types>
constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept {
  return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
}

// Overload for getting a pointer to the const value stored in the given variant
// by type.
template <class T, class... Types>
constexpr absl::add_pointer_t<const T> get_if(
    const variant<Types...>* v) noexcept {
  return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
}

// visit()
//
// Calls a provided functor on a given set of variants. `absl::visit()` is
// commonly used to conditionally inspect the state of a given variant (or set
// of variants).
//
// The functor must return the same type when called with any of the variants'
// alternatives.
//
// Example:
//
//   // Define a visitor functor
//   struct GetVariant {
//       template<typename T>
//       void operator()(const T& i) const {
//         std::cout << "The variant's value is: " << i;
//       }
//   };
//
//   // Declare our variant, and call `absl::visit()` on it.
//   // Note that `GetVariant()` returns void in either case.
//   absl::variant<int, std::string> foo = std::string("foo");
//   GetVariant visitor;
//   absl::visit(visitor, foo);  // Prints `The variant's value is: foo'
template <typename Visitor, typename... Variants>
variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
                                                          Variants&&... vars) {
  return variant_internal::
      VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run(
          variant_internal::PerformVisitation<Visitor, Variants...>{
              std::forward_as_tuple(absl::forward<Variants>(vars)...),
              absl::forward<Visitor>(vis)},
          vars.index()...);
}

// monostate
//
// The monostate class serves as a first alternative type for a variant for
// which the first variant type is otherwise not default-constructible.
struct monostate {};

// `absl::monostate` Relational Operators

constexpr bool operator<(monostate, monostate) noexcept { return false; }
constexpr bool operator>(monostate, monostate) noexcept { return false; }
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
constexpr bool operator>=(monostate, monostate) noexcept { return true; }
constexpr bool operator==(monostate, monostate) noexcept { return true; }
constexpr bool operator!=(monostate, monostate) noexcept { return false; }


//------------------------------------------------------------------------------
// `absl::variant` Template Definition
//------------------------------------------------------------------------------
template <typename T0, typename... Tn>
class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
  static_assert(absl::conjunction<std::is_object<T0>,
                                  std::is_object<Tn>...>::value,
                "Attempted to instantiate a variant containing a non-object "
                "type.");
  // Intentionally not qualifying `negation` with `absl::` to work around a bug
  // in MSVC 2015 with inline namespace and variadic template.
  static_assert(absl::conjunction<negation<std::is_array<T0> >,
                                  negation<std::is_array<Tn> >...>::value,
                "Attempted to instantiate a variant containing an array type.");
  static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
                                  std::is_nothrow_destructible<Tn>...>::value,
                "Attempted to instantiate a variant containing a non-nothrow "
                "destructible type.");

  friend struct variant_internal::VariantCoreAccess;

 private:
  using Base = variant_internal::VariantBase<T0, Tn...>;

 public:
  // Constructors

  // Constructs a variant holding a default-initialized value of the first
  // alternative type.
  constexpr variant() /*noexcept(see 111above)*/ = default;

  // Copy constructor, standard semantics
  variant(const variant& other) = default;

  // Move constructor, standard semantics
  variant(variant&& other) /*noexcept(see above)*/ = default;

  // Constructs a variant of an alternative type specified by overload
  // resolution of the provided forwarding arguments through
  // direct-initialization.
  //
  // Note: If the selected constructor is a constexpr constructor, this
  // constructor shall be a constexpr constructor.
  //
  // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
  // has been voted passed the design phase in the C++ standard meeting in Mar
  // 2018. It will be implemented and integrated into `absl::variant`.
  template <
      class T,
      std::size_t I = std::enable_if<
          variant_internal::IsNeitherSelfNorInPlace<variant,
                                                    absl::decay_t<T>>::value,
          variant_internal::IndexOfConstructedType<variant, T>>::type::value,
      class Tj = absl::variant_alternative_t<I, variant>,
      absl::enable_if_t<std::is_constructible<Tj, T>::value>* =
          nullptr>
  constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value)
      : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}

  // Constructs a variant of an alternative type from the arguments through
  // direct-initialization.
  //
  // Note: If the selected constructor is a constexpr constructor, this
  // constructor shall be a constexpr constructor.
  template <class T, class... Args,
            typename std::enable_if<std::is_constructible<
                variant_internal::UnambiguousTypeOfT<variant, T>,
                Args...>::value>::type* = nullptr>
  constexpr explicit variant(in_place_type_t<T>, Args&&... args)
      : Base(variant_internal::EmplaceTag<
                 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
             absl::forward<Args>(args)...) {}

  // Constructs a variant of an alternative type from an initializer list
  // and other arguments through direct-initialization.
  //
  // Note: If the selected constructor is a constexpr constructor, this
  // constructor shall be a constexpr constructor.
  template <class T, class U, class... Args,
            typename std::enable_if<std::is_constructible<
                variant_internal::UnambiguousTypeOfT<variant, T>,
                std::initializer_list<U>&, Args...>::value>::type* = nullptr>
  constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il,
                             Args&&... args)
      : Base(variant_internal::EmplaceTag<
                 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
             il, absl::forward<Args>(args)...) {}

  // Constructs a variant of an alternative type from a provided index,
  // through value-initialization using the provided forwarded arguments.
  template <std::size_t I, class... Args,
            typename std::enable_if<std::is_constructible<
                variant_internal::VariantAlternativeSfinaeT<I, variant>,
                Args...>::value>::type* = nullptr>
  constexpr explicit variant(in_place_index_t<I>, Args&&... args)
      : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {}

  // Constructs a variant of an alternative type from a provided index,
  // through value-initialization of an initializer list and the provided
  // forwarded arguments.
  template <std::size_t I, class U, class... Args,
            typename std::enable_if<std::is_constructible<
                variant_internal::VariantAlternativeSfinaeT<I, variant>,
                std::initializer_list<U>&, Args...>::value>::type* = nullptr>
  constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il,
                             Args&&... args)
      : Base(variant_internal::EmplaceTag<I>(), il,
             absl::forward<Args>(args)...) {}

  // Destructors

  // Destroys the variant's currently contained value, provided that
  // `absl::valueless_by_exception()` is false.
  ~variant() = default;

  // Assignment Operators

  // Copy assignment operator
  variant& operator=(const variant& other) = default;

  // Move assignment operator
  variant& operator=(variant&& other) /*noexcept(see above)*/ = default;

  // Converting assignment operator
  //
  // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
  // has been voted passed the design phase in the C++ standard meeting in Mar
  // 2018. It will be implemented and integrated into `absl::variant`.
  template <
      class T,
      std::size_t I = std::enable_if<
          !std::is_same<absl::decay_t<T>, variant>::value,
          variant_internal::IndexOfConstructedType<variant, T>>::type::value,
      class Tj = absl::variant_alternative_t<I, variant>,
      typename std::enable_if<std::is_assignable<Tj&, T>::value &&
                              std::is_constructible<Tj, T>::value>::type* =
          nullptr>
  variant& operator=(T&& t) noexcept(
      std::is_nothrow_assignable<Tj&, T>::value&&
          std::is_nothrow_constructible<Tj, T>::value) {
    variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
        variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
            this, absl::forward<T>(t)),
        index());

    return *this;
  }


  // emplace() Functions

  // Constructs a value of the given alternative type T within the variant. The
  // existing value of the variant is destroyed first (provided that
  // `absl::valueless_by_exception()` is false). Requires that T is unambiguous
  // in the variant.
  //
  // Example:
  //
  //   absl::variant<std::vector<int>, int, std::string> v;
  //   v.emplace<int>(99);
  //   v.emplace<std::string>("abc");
  template <
      class T, class... Args,
      typename std::enable_if<std::is_constructible<
          absl::variant_alternative_t<
              variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
          Args...>::value>::type* = nullptr>
  T& emplace(Args&&... args) {
    return variant_internal::VariantCoreAccess::Replace<
        variant_internal::UnambiguousIndexOf<variant, T>::value>(
        this, absl::forward<Args>(args)...);
  }

  // Constructs a value of the given alternative type T within the variant using
  // an initializer list. The existing value of the variant is destroyed first
  // (provided that `absl::valueless_by_exception()` is false). Requires that T
  // is unambiguous in the variant.
  //
  // Example:
  //
  //   absl::variant<std::vector<int>, int, std::string> v;
  //   v.emplace<std::vector<int>>({0, 1, 2});
  template <
      class T, class U, class... Args,
      typename std::enable_if<std::is_constructible<
          absl::variant_alternative_t<
              variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
          std::initializer_list<U>&, Args...>::value>::type* = nullptr>
  T& emplace(std::initializer_list<U> il, Args&&... args) {
    return variant_internal::VariantCoreAccess::Replace<
        variant_internal::UnambiguousIndexOf<variant, T>::value>(
        this, il, absl::forward<Args>(args)...);
  }

  // Destroys the current value of the variant (provided that
  // `absl::valueless_by_exception()` is false) and constructs a new value at
  // the given index.
  //
  // Example:
  //
  //   absl::variant<std::vector<int>, int, int> v;
  //   v.emplace<1>(99);
  //   v.emplace<2>(98);
  //   v.emplace<int>(99);  // Won't compile. 'int' isn't a unique type.
  template <std::size_t I, class... Args,
            typename std::enable_if<
                std::is_constructible<absl::variant_alternative_t<I, variant>,
                                      Args...>::value>::type* = nullptr>
  absl::variant_alternative_t<I, variant>& emplace(Args&&... args) {
    return variant_internal::VariantCoreAccess::Replace<I>(
        this, absl::forward<Args>(args)...);
  }

  // Destroys the current value of the variant (provided that
  // `absl::valueless_by_exception()` is false) and constructs a new value at
  // the given index using an initializer list and the provided arguments.
  //
  // Example:
  //
  //   absl::variant<std::vector<int>, int, int> v;
  //   v.emplace<0>({0, 1, 2});
  template <std::size_t I, class U, class... Args,
            typename std::enable_if<std::is_constructible<
                absl::variant_alternative_t<I, variant>,
                std::initializer_list<U>&, Args...>::value>::type* = nullptr>
  absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il,
                                                   Args&&... args) {
    return variant_internal::VariantCoreAccess::Replace<I>(
        this, il, absl::forward<Args>(args)...);
  }

  // variant::valueless_by_exception()
  //
  // Returns false if and only if the variant currently holds a valid value.
  constexpr bool valueless_by_exception() const noexcept {
    return this->index_ == absl::variant_npos;
  }

  // variant::index()
  //
  // Returns the index value of the variant's currently selected alternative
  // type.
  constexpr std::size_t index() const noexcept { return this->index_; }

  // variant::swap()
  //
  // Swaps the values of two variant objects.
  //
  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) {
    return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
        variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
  }
};

// We need a valid declaration of variant<> for SFINAE and overload resolution
// to work properly above, but we don't need a full declaration since this type
// will never be constructed. This declaration, though incomplete, suffices.
template <>
class variant<>;

//------------------------------------------------------------------------------
// Relational Operators
//------------------------------------------------------------------------------
//
// If neither operand is in the `variant::valueless_by_exception` state:
//
//   * If the index of both variants is the same, the relational operator
//     returns the result of the corresponding relational operator for the
//     corresponding alternative type.
//   * If the index of both variants is not the same, the relational operator
//     returns the result of that operation applied to the value of the left
//     operand's index and the value of the right operand's index.
//   * If at least one operand is in the valueless_by_exception state:
//     - A variant in the valueless_by_exception state is only considered equal
//       to another variant in the valueless_by_exception state.
//     - If exactly one operand is in the valueless_by_exception state, the
//       variant in the valueless_by_exception state is less than the variant
//       that is not in the valueless_by_exception state.
//
// Note: The value 1 is added to each index in the relational comparisons such
// that the index corresponding to the valueless_by_exception state wraps around
// to 0 (the lowest value for the index type), and the remaining indices stay in
// the same relative order.

// Equal-to operator
template <typename... Types>
constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
    const variant<Types...>& a, const variant<Types...>& b) {
  return (a.index() == b.index()) &&
         variant_internal::VisitIndices<sizeof...(Types)>::Run(
             variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
}

// Not equal operator
template <typename... Types>
constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
    const variant<Types...>& a, const variant<Types...>& b) {
  return (a.index() != b.index()) ||
         variant_internal::VisitIndices<sizeof...(Types)>::Run(
             variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
}

// Less-than operator
template <typename... Types>
constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
    const variant<Types...>& a, const variant<Types...>& b) {
  return (a.index() != b.index())
             ? (a.index() + 1) < (b.index() + 1)
             : variant_internal::VisitIndices<sizeof...(Types)>::Run(
                   variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
}

// Greater-than operator
template <typename... Types>
constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
    const variant<Types...>& a, const variant<Types...>& b) {
  return (a.index() != b.index())
             ? (a.index() + 1) > (b.index() + 1)
             : variant_internal::VisitIndices<sizeof...(Types)>::Run(
                   variant_internal::GreaterThanOp<Types...>{&a, &b},
                   a.index());
}

// Less-than or equal-to operator
template <typename... Types>
constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
    const variant<Types...>& a, const variant<Types...>& b) {
  return (a.index() != b.index())
             ? (a.index() + 1) < (b.index() + 1)
             : variant_internal::VisitIndices<sizeof...(Types)>::Run(
                   variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
                   a.index());
}

// Greater-than or equal-to operator
template <typename... Types>
constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
operator>=(const variant<Types...>& a, const variant<Types...>& b) {
  return (a.index() != b.index())
             ? (a.index() + 1) > (b.index() + 1)
             : variant_internal::VisitIndices<sizeof...(Types)>::Run(
                   variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
                   a.index());
}

ABSL_NAMESPACE_END
}  // namespace absl

namespace std {

// hash()
template <>  // NOLINT
struct hash<absl::monostate> {
  std::size_t operator()(absl::monostate) const { return 0; }
};

template <class... T>  // NOLINT
struct hash<absl::variant<T...>>
    : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
                                              absl::remove_const_t<T>...> {};

}  // namespace std

#endif  // ABSL_USES_STD_VARIANT

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace variant_internal {

// Helper visitor for converting a variant<Ts...>` into another type (mostly
// variant) that can be constructed from any type.
template <typename To>
struct ConversionVisitor {
  template <typename T>
  To operator()(T&& v) const {
    return To(std::forward<T>(v));
  }
};

}  // namespace variant_internal

// ConvertVariantTo()
//
// Helper functions to convert an `absl::variant` to a variant of another set of
// types, provided that the alternative type of the new variant type can be
// converted from any type in the source variant.
//
// Example:
//
//   absl::variant<name1, name2, float> InternalReq(const Req&);
//
//   // name1 and name2 are convertible to name
//   absl::variant<name, float> ExternalReq(const Req& req) {
//     return absl::ConvertVariantTo<absl::variant<name, float>>(
//              InternalReq(req));
//   }
template <typename To, typename Variant>
To ConvertVariantTo(Variant&& variant) {
  return absl::visit(variant_internal::ConversionVisitor<To>{},
                     std::forward<Variant>(variant));
}

ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_TYPES_VARIANT_H_
