Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:03:44

0001 // Copyright 2018 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 // -----------------------------------------------------------------------------
0016 // variant.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // This header file defines an `absl::variant` type for holding a type-safe
0020 // value of some prescribed set of types (noted as alternative types), and
0021 // associated functions for managing variants.
0022 //
0023 // The `absl::variant` type is a form of type-safe union. An `absl::variant`
0024 // should always hold a value of one of its alternative types (except in the
0025 // "valueless by exception state" -- see below). A default-constructed
0026 // `absl::variant` will hold the value of its first alternative type, provided
0027 // it is default-constructible.
0028 //
0029 // In exceptional cases due to error, an `absl::variant` can hold no
0030 // value (known as a "valueless by exception" state), though this is not the
0031 // norm.
0032 //
0033 // As with `absl::optional`, an `absl::variant` -- when it holds a value --
0034 // allocates a value of that type directly within the `variant` itself; it
0035 // cannot hold a reference, array, or the type `void`; it can, however, hold a
0036 // pointer to externally managed memory.
0037 //
0038 // `absl::variant` is a C++11 compatible version of the C++17 `std::variant`
0039 // abstraction and is designed to be a drop-in replacement for code compliant
0040 // with C++17.
0041 
0042 #ifndef ABSL_TYPES_VARIANT_H_
0043 #define ABSL_TYPES_VARIANT_H_
0044 
0045 #include "absl/base/config.h"
0046 #include "absl/utility/utility.h"
0047 
0048 #ifdef ABSL_USES_STD_VARIANT
0049 
0050 #include <variant>  // IWYU pragma: export
0051 
0052 namespace absl {
0053 ABSL_NAMESPACE_BEGIN
0054 using std::bad_variant_access;
0055 using std::get;
0056 using std::get_if;
0057 using std::holds_alternative;
0058 using std::monostate;
0059 using std::variant;
0060 using std::variant_alternative;
0061 using std::variant_alternative_t;
0062 using std::variant_npos;
0063 using std::variant_size;
0064 using std::variant_size_v;
0065 using std::visit;
0066 ABSL_NAMESPACE_END
0067 }  // namespace absl
0068 
0069 #else  // ABSL_USES_STD_VARIANT
0070 
0071 #include <functional>
0072 #include <new>
0073 #include <type_traits>
0074 #include <utility>
0075 
0076 #include "absl/base/macros.h"
0077 #include "absl/base/port.h"
0078 #include "absl/meta/type_traits.h"
0079 #include "absl/types/internal/variant.h"
0080 
0081 namespace absl {
0082 ABSL_NAMESPACE_BEGIN
0083 
0084 // -----------------------------------------------------------------------------
0085 // absl::variant
0086 // -----------------------------------------------------------------------------
0087 //
0088 // An `absl::variant` type is a form of type-safe union. An `absl::variant` --
0089 // except in exceptional cases -- always holds a value of one of its alternative
0090 // types.
0091 //
0092 // Example:
0093 //
0094 //   // Construct a variant that holds either an integer or a std::string and
0095 //   // assign it to a std::string.
0096 //   absl::variant<int, std::string> v = std::string("abc");
0097 //
0098 //   // A default-constructed variant will hold a value-initialized value of
0099 //   // the first alternative type.
0100 //   auto a = absl::variant<int, std::string>();   // Holds an int of value '0'.
0101 //
0102 //   // variants are assignable.
0103 //
0104 //   // copy assignment
0105 //   auto v1 = absl::variant<int, std::string>("abc");
0106 //   auto v2 = absl::variant<int, std::string>(10);
0107 //   v2 = v1;  // copy assign
0108 //
0109 //   // move assignment
0110 //   auto v1 = absl::variant<int, std::string>("abc");
0111 //   v1 = absl::variant<int, std::string>(10);
0112 //
0113 //   // assignment through type conversion
0114 //   a = 128;         // variant contains int
0115 //   a = "128";       // variant contains std::string
0116 //
0117 // An `absl::variant` holding a value of one of its alternative types `T` holds
0118 // an allocation of `T` directly within the variant itself. An `absl::variant`
0119 // is not allowed to allocate additional storage, such as dynamic memory, to
0120 // allocate the contained value. The contained value shall be allocated in a
0121 // region of the variant storage suitably aligned for all alternative types.
0122 template <typename... Ts>
0123 class variant;
0124 
0125 // swap()
0126 //
0127 // Swaps two `absl::variant` values. This function is equivalent to `v.swap(w)`
0128 // where `v` and `w` are `absl::variant` types.
0129 //
0130 // Note that this function requires all alternative types to be both swappable
0131 // and move-constructible, because any two variants may refer to either the same
0132 // type (in which case, they will be swapped) or to two different types (in
0133 // which case the values will need to be moved).
0134 //
0135 template <
0136     typename... Ts,
0137     absl::enable_if_t<
0138         absl::conjunction<std::is_move_constructible<Ts>...,
0139                           type_traits_internal::IsSwappable<Ts>...>::value,
0140         int> = 0>
0141 void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
0142   v.swap(w);
0143 }
0144 
0145 // variant_size
0146 //
0147 // Returns the number of alternative types available for a given `absl::variant`
0148 // type as a compile-time constant expression. As this is a class template, it
0149 // is not generally useful for accessing the number of alternative types of
0150 // any given `absl::variant` instance.
0151 //
0152 // Example:
0153 //
0154 //   auto a = absl::variant<int, std::string>;
0155 //   constexpr int num_types =
0156 //       absl::variant_size<absl::variant<int, std::string>>();
0157 //
0158 //   // You can also use the member constant `value`.
0159 //   constexpr int num_types =
0160 //       absl::variant_size<absl::variant<int, std::string>>::value;
0161 //
0162 //   // `absl::variant_size` is more valuable for use in generic code:
0163 //   template <typename Variant>
0164 //   constexpr bool IsVariantMultivalue() {
0165 //       return absl::variant_size<Variant>() > 1;
0166 //   }
0167 //
0168 // Note that the set of cv-qualified specializations of `variant_size` are
0169 // provided to ensure that those specializations compile (especially when passed
0170 // within template logic).
0171 template <class T>
0172 struct variant_size;
0173 
0174 template <class... Ts>
0175 struct variant_size<variant<Ts...>>
0176     : std::integral_constant<std::size_t, sizeof...(Ts)> {};
0177 
0178 // Specialization of `variant_size` for const qualified variants.
0179 template <class T>
0180 struct variant_size<const T> : variant_size<T>::type {};
0181 
0182 // Specialization of `variant_size` for volatile qualified variants.
0183 template <class T>
0184 struct variant_size<volatile T> : variant_size<T>::type {};
0185 
0186 // Specialization of `variant_size` for const volatile qualified variants.
0187 template <class T>
0188 struct variant_size<const volatile T> : variant_size<T>::type {};
0189 
0190 // variant_alternative
0191 //
0192 // Returns the alternative type for a given `absl::variant` at the passed
0193 // index value as a compile-time constant expression. As this is a class
0194 // template resulting in a type, it is not useful for access of the run-time
0195 // value of any given `absl::variant` variable.
0196 //
0197 // Example:
0198 //
0199 //   // The type of the 0th alternative is "int".
0200 //   using alternative_type_0
0201 //     = absl::variant_alternative<0, absl::variant<int, std::string>>::type;
0202 //
0203 //   static_assert(std::is_same<alternative_type_0, int>::value, "");
0204 //
0205 //   // `absl::variant_alternative` is more valuable for use in generic code:
0206 //   template <typename Variant>
0207 //   constexpr bool IsFirstElementTrivial() {
0208 //       return std::is_trivial_v<variant_alternative<0, Variant>::type>;
0209 //   }
0210 //
0211 // Note that the set of cv-qualified specializations of `variant_alternative`
0212 // are provided to ensure that those specializations compile (especially when
0213 // passed within template logic).
0214 template <std::size_t I, class T>
0215 struct variant_alternative;
0216 
0217 template <std::size_t I, class... Types>
0218 struct variant_alternative<I, variant<Types...>> {
0219   using type =
0220       variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>;
0221 };
0222 
0223 // Specialization of `variant_alternative` for const qualified variants.
0224 template <std::size_t I, class T>
0225 struct variant_alternative<I, const T> {
0226   using type = const typename variant_alternative<I, T>::type;
0227 };
0228 
0229 // Specialization of `variant_alternative` for volatile qualified variants.
0230 template <std::size_t I, class T>
0231 struct variant_alternative<I, volatile T> {
0232   using type = volatile typename variant_alternative<I, T>::type;
0233 };
0234 
0235 // Specialization of `variant_alternative` for const volatile qualified
0236 // variants.
0237 template <std::size_t I, class T>
0238 struct variant_alternative<I, const volatile T> {
0239   using type = const volatile typename variant_alternative<I, T>::type;
0240 };
0241 
0242 // Template type alias for variant_alternative<I, T>::type.
0243 //
0244 // Example:
0245 //
0246 //   using alternative_type_0
0247 //     = absl::variant_alternative_t<0, absl::variant<int, std::string>>;
0248 //   static_assert(std::is_same<alternative_type_0, int>::value, "");
0249 template <std::size_t I, class T>
0250 using variant_alternative_t = typename variant_alternative<I, T>::type;
0251 
0252 // holds_alternative()
0253 //
0254 // Checks whether the given variant currently holds a given alternative type,
0255 // returning `true` if so.
0256 //
0257 // Example:
0258 //
0259 //   absl::variant<int, std::string> foo = 42;
0260 //   if (absl::holds_alternative<int>(foo)) {
0261 //       std::cout << "The variant holds an integer";
0262 //   }
0263 template <class T, class... Types>
0264 constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
0265   static_assert(
0266       variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T,
0267                                                0>::value != sizeof...(Types),
0268       "The type T must occur exactly once in Types...");
0269   return v.index() ==
0270          variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value;
0271 }
0272 
0273 // get()
0274 //
0275 // Returns a reference to the value currently within a given variant, using
0276 // either a unique alternative type amongst the variant's set of alternative
0277 // types, or the variant's index value. Attempting to get a variant's value
0278 // using a type that is not unique within the variant's set of alternative types
0279 // is a compile-time error. If the index of the alternative being specified is
0280 // different from the index of the alternative that is currently stored, throws
0281 // `absl::bad_variant_access`.
0282 //
0283 // Example:
0284 //
0285 //   auto a = absl::variant<int, std::string>;
0286 //
0287 //   // Get the value by type (if unique).
0288 //   int i = absl::get<int>(a);
0289 //
0290 //   auto b = absl::variant<int, int>;
0291 //
0292 //   // Getting the value by a type that is not unique is ill-formed.
0293 //   int j = absl::get<int>(b);     // Compile Error!
0294 //
0295 //   // Getting value by index not ambiguous and allowed.
0296 //   int k = absl::get<1>(b);
0297 
0298 // Overload for getting a variant's lvalue by type.
0299 template <class T, class... Types>
0300 constexpr T& get(variant<Types...>& v) {  // NOLINT
0301   return variant_internal::VariantCoreAccess::CheckedAccess<
0302       variant_internal::IndexOf<T, Types...>::value>(v);
0303 }
0304 
0305 // Overload for getting a variant's rvalue by type.
0306 // Note: `absl::move()` is required to allow use of constexpr in C++11.
0307 template <class T, class... Types>
0308 constexpr T&& get(variant<Types...>&& v) {
0309   return variant_internal::VariantCoreAccess::CheckedAccess<
0310       variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
0311 }
0312 
0313 // Overload for getting a variant's const lvalue by type.
0314 template <class T, class... Types>
0315 constexpr const T& get(const variant<Types...>& v) {
0316   return variant_internal::VariantCoreAccess::CheckedAccess<
0317       variant_internal::IndexOf<T, Types...>::value>(v);
0318 }
0319 
0320 // Overload for getting a variant's const rvalue by type.
0321 // Note: `absl::move()` is required to allow use of constexpr in C++11.
0322 template <class T, class... Types>
0323 constexpr const T&& get(const variant<Types...>&& v) {
0324   return variant_internal::VariantCoreAccess::CheckedAccess<
0325       variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
0326 }
0327 
0328 // Overload for getting a variant's lvalue by index.
0329 template <std::size_t I, class... Types>
0330 constexpr variant_alternative_t<I, variant<Types...>>& get(
0331     variant<Types...>& v) {  // NOLINT
0332   return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
0333 }
0334 
0335 // Overload for getting a variant's rvalue by index.
0336 // Note: `absl::move()` is required to allow use of constexpr in C++11.
0337 template <std::size_t I, class... Types>
0338 constexpr variant_alternative_t<I, variant<Types...>>&& get(
0339     variant<Types...>&& v) {
0340   return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
0341 }
0342 
0343 // Overload for getting a variant's const lvalue by index.
0344 template <std::size_t I, class... Types>
0345 constexpr const variant_alternative_t<I, variant<Types...>>& get(
0346     const variant<Types...>& v) {
0347   return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
0348 }
0349 
0350 // Overload for getting a variant's const rvalue by index.
0351 // Note: `absl::move()` is required to allow use of constexpr in C++11.
0352 template <std::size_t I, class... Types>
0353 constexpr const variant_alternative_t<I, variant<Types...>>&& get(
0354     const variant<Types...>&& v) {
0355   return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
0356 }
0357 
0358 // get_if()
0359 //
0360 // Returns a pointer to the value currently stored within a given variant, if
0361 // present, using either a unique alternative type amongst the variant's set of
0362 // alternative types, or the variant's index value. If such a value does not
0363 // exist, returns `nullptr`.
0364 //
0365 // As with `get`, attempting to get a variant's value using a type that is not
0366 // unique within the variant's set of alternative types is a compile-time error.
0367 
0368 // Overload for getting a pointer to the value stored in the given variant by
0369 // index.
0370 template <std::size_t I, class... Types>
0371 constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>>
0372 get_if(variant<Types...>* v) noexcept {
0373   return (v != nullptr && v->index() == I)
0374              ? std::addressof(
0375                    variant_internal::VariantCoreAccess::Access<I>(*v))
0376              : nullptr;
0377 }
0378 
0379 // Overload for getting a pointer to the const value stored in the given
0380 // variant by index.
0381 template <std::size_t I, class... Types>
0382 constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
0383 get_if(const variant<Types...>* v) noexcept {
0384   return (v != nullptr && v->index() == I)
0385              ? std::addressof(
0386                    variant_internal::VariantCoreAccess::Access<I>(*v))
0387              : nullptr;
0388 }
0389 
0390 // Overload for getting a pointer to the value stored in the given variant by
0391 // type.
0392 template <class T, class... Types>
0393 constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept {
0394   return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
0395 }
0396 
0397 // Overload for getting a pointer to the const value stored in the given variant
0398 // by type.
0399 template <class T, class... Types>
0400 constexpr absl::add_pointer_t<const T> get_if(
0401     const variant<Types...>* v) noexcept {
0402   return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
0403 }
0404 
0405 // visit()
0406 //
0407 // Calls a provided functor on a given set of variants. `absl::visit()` is
0408 // commonly used to conditionally inspect the state of a given variant (or set
0409 // of variants).
0410 //
0411 // The functor must return the same type when called with any of the variants'
0412 // alternatives.
0413 //
0414 // Example:
0415 //
0416 //   // Define a visitor functor
0417 //   struct GetVariant {
0418 //       template<typename T>
0419 //       void operator()(const T& i) const {
0420 //         std::cout << "The variant's value is: " << i;
0421 //       }
0422 //   };
0423 //
0424 //   // Declare our variant, and call `absl::visit()` on it.
0425 //   // Note that `GetVariant()` returns void in either case.
0426 //   absl::variant<int, std::string> foo = std::string("foo");
0427 //   GetVariant visitor;
0428 //   absl::visit(visitor, foo);  // Prints `The variant's value is: foo'
0429 template <typename Visitor, typename... Variants>
0430 variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
0431                                                           Variants&&... vars) {
0432   return variant_internal::
0433       VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run(
0434           variant_internal::PerformVisitation<Visitor, Variants...>{
0435               std::forward_as_tuple(absl::forward<Variants>(vars)...),
0436               absl::forward<Visitor>(vis)},
0437           vars.index()...);
0438 }
0439 
0440 // monostate
0441 //
0442 // The monostate class serves as a first alternative type for a variant for
0443 // which the first variant type is otherwise not default-constructible.
0444 struct monostate {};
0445 
0446 // `absl::monostate` Relational Operators
0447 
0448 constexpr bool operator<(monostate, monostate) noexcept { return false; }
0449 constexpr bool operator>(monostate, monostate) noexcept { return false; }
0450 constexpr bool operator<=(monostate, monostate) noexcept { return true; }
0451 constexpr bool operator>=(monostate, monostate) noexcept { return true; }
0452 constexpr bool operator==(monostate, monostate) noexcept { return true; }
0453 constexpr bool operator!=(monostate, monostate) noexcept { return false; }
0454 
0455 
0456 //------------------------------------------------------------------------------
0457 // `absl::variant` Template Definition
0458 //------------------------------------------------------------------------------
0459 template <typename T0, typename... Tn>
0460 class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
0461   static_assert(absl::conjunction<std::is_object<T0>,
0462                                   std::is_object<Tn>...>::value,
0463                 "Attempted to instantiate a variant containing a non-object "
0464                 "type.");
0465   // Intentionally not qualifying `negation` with `absl::` to work around a bug
0466   // in MSVC 2015 with inline namespace and variadic template.
0467   static_assert(absl::conjunction<negation<std::is_array<T0> >,
0468                                   negation<std::is_array<Tn> >...>::value,
0469                 "Attempted to instantiate a variant containing an array type.");
0470   static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
0471                                   std::is_nothrow_destructible<Tn>...>::value,
0472                 "Attempted to instantiate a variant containing a non-nothrow "
0473                 "destructible type.");
0474 
0475   friend struct variant_internal::VariantCoreAccess;
0476 
0477  private:
0478   using Base = variant_internal::VariantBase<T0, Tn...>;
0479 
0480  public:
0481   // Constructors
0482 
0483   // Constructs a variant holding a default-initialized value of the first
0484   // alternative type.
0485   constexpr variant() /*noexcept(see 111above)*/ = default;
0486 
0487   // Copy constructor, standard semantics
0488   variant(const variant& other) = default;
0489 
0490   // Move constructor, standard semantics
0491   variant(variant&& other) /*noexcept(see above)*/ = default;
0492 
0493   // Constructs a variant of an alternative type specified by overload
0494   // resolution of the provided forwarding arguments through
0495   // direct-initialization.
0496   //
0497   // Note: If the selected constructor is a constexpr constructor, this
0498   // constructor shall be a constexpr constructor.
0499   //
0500   // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
0501   // has been voted passed the design phase in the C++ standard meeting in Mar
0502   // 2018. It will be implemented and integrated into `absl::variant`.
0503   template <
0504       class T,
0505       std::size_t I = std::enable_if<
0506           variant_internal::IsNeitherSelfNorInPlace<variant,
0507                                                     absl::decay_t<T>>::value,
0508           variant_internal::IndexOfConstructedType<variant, T>>::type::value,
0509       class Tj = absl::variant_alternative_t<I, variant>,
0510       absl::enable_if_t<std::is_constructible<Tj, T>::value>* =
0511           nullptr>
0512   constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value)
0513       : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}
0514 
0515   // Constructs a variant of an alternative type from the arguments through
0516   // direct-initialization.
0517   //
0518   // Note: If the selected constructor is a constexpr constructor, this
0519   // constructor shall be a constexpr constructor.
0520   template <class T, class... Args,
0521             typename std::enable_if<std::is_constructible<
0522                 variant_internal::UnambiguousTypeOfT<variant, T>,
0523                 Args...>::value>::type* = nullptr>
0524   constexpr explicit variant(in_place_type_t<T>, Args&&... args)
0525       : Base(variant_internal::EmplaceTag<
0526                  variant_internal::UnambiguousIndexOf<variant, T>::value>(),
0527              absl::forward<Args>(args)...) {}
0528 
0529   // Constructs a variant of an alternative type from an initializer list
0530   // and other arguments through direct-initialization.
0531   //
0532   // Note: If the selected constructor is a constexpr constructor, this
0533   // constructor shall be a constexpr constructor.
0534   template <class T, class U, class... Args,
0535             typename std::enable_if<std::is_constructible<
0536                 variant_internal::UnambiguousTypeOfT<variant, T>,
0537                 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
0538   constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il,
0539                              Args&&... args)
0540       : Base(variant_internal::EmplaceTag<
0541                  variant_internal::UnambiguousIndexOf<variant, T>::value>(),
0542              il, absl::forward<Args>(args)...) {}
0543 
0544   // Constructs a variant of an alternative type from a provided index,
0545   // through value-initialization using the provided forwarded arguments.
0546   template <std::size_t I, class... Args,
0547             typename std::enable_if<std::is_constructible<
0548                 variant_internal::VariantAlternativeSfinaeT<I, variant>,
0549                 Args...>::value>::type* = nullptr>
0550   constexpr explicit variant(in_place_index_t<I>, Args&&... args)
0551       : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {}
0552 
0553   // Constructs a variant of an alternative type from a provided index,
0554   // through value-initialization of an initializer list and the provided
0555   // forwarded arguments.
0556   template <std::size_t I, class U, class... Args,
0557             typename std::enable_if<std::is_constructible<
0558                 variant_internal::VariantAlternativeSfinaeT<I, variant>,
0559                 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
0560   constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il,
0561                              Args&&... args)
0562       : Base(variant_internal::EmplaceTag<I>(), il,
0563              absl::forward<Args>(args)...) {}
0564 
0565   // Destructors
0566 
0567   // Destroys the variant's currently contained value, provided that
0568   // `absl::valueless_by_exception()` is false.
0569   ~variant() = default;
0570 
0571   // Assignment Operators
0572 
0573   // Copy assignment operator
0574   variant& operator=(const variant& other) = default;
0575 
0576   // Move assignment operator
0577   variant& operator=(variant&& other) /*noexcept(see above)*/ = default;
0578 
0579   // Converting assignment operator
0580   //
0581   // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
0582   // has been voted passed the design phase in the C++ standard meeting in Mar
0583   // 2018. It will be implemented and integrated into `absl::variant`.
0584   template <
0585       class T,
0586       std::size_t I = std::enable_if<
0587           !std::is_same<absl::decay_t<T>, variant>::value,
0588           variant_internal::IndexOfConstructedType<variant, T>>::type::value,
0589       class Tj = absl::variant_alternative_t<I, variant>,
0590       typename std::enable_if<std::is_assignable<Tj&, T>::value &&
0591                               std::is_constructible<Tj, T>::value>::type* =
0592           nullptr>
0593   variant& operator=(T&& t) noexcept(
0594       std::is_nothrow_assignable<Tj&, T>::value&&
0595           std::is_nothrow_constructible<Tj, T>::value) {
0596     variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
0597         variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
0598             this, absl::forward<T>(t)),
0599         index());
0600 
0601     return *this;
0602   }
0603 
0604 
0605   // emplace() Functions
0606 
0607   // Constructs a value of the given alternative type T within the variant. The
0608   // existing value of the variant is destroyed first (provided that
0609   // `absl::valueless_by_exception()` is false). Requires that T is unambiguous
0610   // in the variant.
0611   //
0612   // Example:
0613   //
0614   //   absl::variant<std::vector<int>, int, std::string> v;
0615   //   v.emplace<int>(99);
0616   //   v.emplace<std::string>("abc");
0617   template <
0618       class T, class... Args,
0619       typename std::enable_if<std::is_constructible<
0620           absl::variant_alternative_t<
0621               variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
0622           Args...>::value>::type* = nullptr>
0623   T& emplace(Args&&... args) {
0624     return variant_internal::VariantCoreAccess::Replace<
0625         variant_internal::UnambiguousIndexOf<variant, T>::value>(
0626         this, absl::forward<Args>(args)...);
0627   }
0628 
0629   // Constructs a value of the given alternative type T within the variant using
0630   // an initializer list. The existing value of the variant is destroyed first
0631   // (provided that `absl::valueless_by_exception()` is false). Requires that T
0632   // is unambiguous in the variant.
0633   //
0634   // Example:
0635   //
0636   //   absl::variant<std::vector<int>, int, std::string> v;
0637   //   v.emplace<std::vector<int>>({0, 1, 2});
0638   template <
0639       class T, class U, class... Args,
0640       typename std::enable_if<std::is_constructible<
0641           absl::variant_alternative_t<
0642               variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
0643           std::initializer_list<U>&, Args...>::value>::type* = nullptr>
0644   T& emplace(std::initializer_list<U> il, Args&&... args) {
0645     return variant_internal::VariantCoreAccess::Replace<
0646         variant_internal::UnambiguousIndexOf<variant, T>::value>(
0647         this, il, absl::forward<Args>(args)...);
0648   }
0649 
0650   // Destroys the current value of the variant (provided that
0651   // `absl::valueless_by_exception()` is false) and constructs a new value at
0652   // the given index.
0653   //
0654   // Example:
0655   //
0656   //   absl::variant<std::vector<int>, int, int> v;
0657   //   v.emplace<1>(99);
0658   //   v.emplace<2>(98);
0659   //   v.emplace<int>(99);  // Won't compile. 'int' isn't a unique type.
0660   template <std::size_t I, class... Args,
0661             typename std::enable_if<
0662                 std::is_constructible<absl::variant_alternative_t<I, variant>,
0663                                       Args...>::value>::type* = nullptr>
0664   absl::variant_alternative_t<I, variant>& emplace(Args&&... args) {
0665     return variant_internal::VariantCoreAccess::Replace<I>(
0666         this, absl::forward<Args>(args)...);
0667   }
0668 
0669   // Destroys the current value of the variant (provided that
0670   // `absl::valueless_by_exception()` is false) and constructs a new value at
0671   // the given index using an initializer list and the provided arguments.
0672   //
0673   // Example:
0674   //
0675   //   absl::variant<std::vector<int>, int, int> v;
0676   //   v.emplace<0>({0, 1, 2});
0677   template <std::size_t I, class U, class... Args,
0678             typename std::enable_if<std::is_constructible<
0679                 absl::variant_alternative_t<I, variant>,
0680                 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
0681   absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il,
0682                                                    Args&&... args) {
0683     return variant_internal::VariantCoreAccess::Replace<I>(
0684         this, il, absl::forward<Args>(args)...);
0685   }
0686 
0687   // variant::valueless_by_exception()
0688   //
0689   // Returns false if and only if the variant currently holds a valid value.
0690   constexpr bool valueless_by_exception() const noexcept {
0691     return this->index_ == absl::variant_npos;
0692   }
0693 
0694   // variant::index()
0695   //
0696   // Returns the index value of the variant's currently selected alternative
0697   // type.
0698   constexpr std::size_t index() const noexcept { return this->index_; }
0699 
0700   // variant::swap()
0701   //
0702   // Swaps the values of two variant objects.
0703   //
0704   void swap(variant& rhs) noexcept(
0705       absl::conjunction<
0706           std::is_nothrow_move_constructible<T0>,
0707           std::is_nothrow_move_constructible<Tn>...,
0708           type_traits_internal::IsNothrowSwappable<T0>,
0709           type_traits_internal::IsNothrowSwappable<Tn>...>::value) {
0710     return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
0711         variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
0712   }
0713 };
0714 
0715 // We need a valid declaration of variant<> for SFINAE and overload resolution
0716 // to work properly above, but we don't need a full declaration since this type
0717 // will never be constructed. This declaration, though incomplete, suffices.
0718 template <>
0719 class variant<>;
0720 
0721 //------------------------------------------------------------------------------
0722 // Relational Operators
0723 //------------------------------------------------------------------------------
0724 //
0725 // If neither operand is in the `variant::valueless_by_exception` state:
0726 //
0727 //   * If the index of both variants is the same, the relational operator
0728 //     returns the result of the corresponding relational operator for the
0729 //     corresponding alternative type.
0730 //   * If the index of both variants is not the same, the relational operator
0731 //     returns the result of that operation applied to the value of the left
0732 //     operand's index and the value of the right operand's index.
0733 //   * If at least one operand is in the valueless_by_exception state:
0734 //     - A variant in the valueless_by_exception state is only considered equal
0735 //       to another variant in the valueless_by_exception state.
0736 //     - If exactly one operand is in the valueless_by_exception state, the
0737 //       variant in the valueless_by_exception state is less than the variant
0738 //       that is not in the valueless_by_exception state.
0739 //
0740 // Note: The value 1 is added to each index in the relational comparisons such
0741 // that the index corresponding to the valueless_by_exception state wraps around
0742 // to 0 (the lowest value for the index type), and the remaining indices stay in
0743 // the same relative order.
0744 
0745 // Equal-to operator
0746 template <typename... Types>
0747 constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
0748     const variant<Types...>& a, const variant<Types...>& b) {
0749   return (a.index() == b.index()) &&
0750          variant_internal::VisitIndices<sizeof...(Types)>::Run(
0751              variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
0752 }
0753 
0754 // Not equal operator
0755 template <typename... Types>
0756 constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
0757     const variant<Types...>& a, const variant<Types...>& b) {
0758   return (a.index() != b.index()) ||
0759          variant_internal::VisitIndices<sizeof...(Types)>::Run(
0760              variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
0761 }
0762 
0763 // Less-than operator
0764 template <typename... Types>
0765 constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
0766     const variant<Types...>& a, const variant<Types...>& b) {
0767   return (a.index() != b.index())
0768              ? (a.index() + 1) < (b.index() + 1)
0769              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
0770                    variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
0771 }
0772 
0773 // Greater-than operator
0774 template <typename... Types>
0775 constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
0776     const variant<Types...>& a, const variant<Types...>& b) {
0777   return (a.index() != b.index())
0778              ? (a.index() + 1) > (b.index() + 1)
0779              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
0780                    variant_internal::GreaterThanOp<Types...>{&a, &b},
0781                    a.index());
0782 }
0783 
0784 // Less-than or equal-to operator
0785 template <typename... Types>
0786 constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
0787     const variant<Types...>& a, const variant<Types...>& b) {
0788   return (a.index() != b.index())
0789              ? (a.index() + 1) < (b.index() + 1)
0790              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
0791                    variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
0792                    a.index());
0793 }
0794 
0795 // Greater-than or equal-to operator
0796 template <typename... Types>
0797 constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
0798 operator>=(const variant<Types...>& a, const variant<Types...>& b) {
0799   return (a.index() != b.index())
0800              ? (a.index() + 1) > (b.index() + 1)
0801              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
0802                    variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
0803                    a.index());
0804 }
0805 
0806 ABSL_NAMESPACE_END
0807 }  // namespace absl
0808 
0809 namespace std {
0810 
0811 // hash()
0812 template <>  // NOLINT
0813 struct hash<absl::monostate> {
0814   std::size_t operator()(absl::monostate) const { return 0; }
0815 };
0816 
0817 template <class... T>  // NOLINT
0818 struct hash<absl::variant<T...>>
0819     : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
0820                                               absl::remove_const_t<T>...> {};
0821 
0822 }  // namespace std
0823 
0824 #endif  // ABSL_USES_STD_VARIANT
0825 
0826 namespace absl {
0827 ABSL_NAMESPACE_BEGIN
0828 namespace variant_internal {
0829 
0830 // Helper visitor for converting a variant<Ts...>` into another type (mostly
0831 // variant) that can be constructed from any type.
0832 template <typename To>
0833 struct ConversionVisitor {
0834   template <typename T>
0835   To operator()(T&& v) const {
0836     return To(std::forward<T>(v));
0837   }
0838 };
0839 
0840 }  // namespace variant_internal
0841 
0842 // ConvertVariantTo()
0843 //
0844 // Helper functions to convert an `absl::variant` to a variant of another set of
0845 // types, provided that the alternative type of the new variant type can be
0846 // converted from any type in the source variant.
0847 //
0848 // Example:
0849 //
0850 //   absl::variant<name1, name2, float> InternalReq(const Req&);
0851 //
0852 //   // name1 and name2 are convertible to name
0853 //   absl::variant<name, float> ExternalReq(const Req& req) {
0854 //     return absl::ConvertVariantTo<absl::variant<name, float>>(
0855 //              InternalReq(req));
0856 //   }
0857 template <typename To, typename Variant>
0858 To ConvertVariantTo(Variant&& variant) {
0859   return absl::visit(variant_internal::ConversionVisitor<To>{},
0860                      std::forward<Variant>(variant));
0861 }
0862 
0863 ABSL_NAMESPACE_END
0864 }  // namespace absl
0865 
0866 #endif  // ABSL_TYPES_VARIANT_H_