variant.h
Go to the documentation of this file.
00001 // Copyright 2018 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 //
00015 // -----------------------------------------------------------------------------
00016 // variant.h
00017 // -----------------------------------------------------------------------------
00018 //
00019 // This header file defines an `absl::variant` type for holding a type-safe
00020 // value of some prescribed set of types (noted as alternative types), and
00021 // associated functions for managing variants.
00022 //
00023 // The `absl::variant` type is a form of type-safe union. An `absl::variant`
00024 // should always hold a value of one of its alternative types (except in the
00025 // "valueless by exception state" -- see below). A default-constructed
00026 // `absl::variant` will hold the value of its first alternative type, provided
00027 // it is default-constructable.
00028 //
00029 // In exceptional cases due to error, an `absl::variant` can hold no
00030 // value (known as a "valueless by exception" state), though this is not the
00031 // norm.
00032 //
00033 // As with `absl::optional`, an `absl::variant` -- when it holds a value --
00034 // allocates a value of that type directly within the `variant` itself; it
00035 // cannot hold a reference, array, or the type `void`; it can, however, hold a
00036 // pointer to externally managed memory.
00037 //
00038 // `absl::variant` is a C++11 compatible version of the C++17 `std::variant`
00039 // abstraction and is designed to be a drop-in replacement for code compliant
00040 // with C++17.
00041 
00042 #ifndef ABSL_TYPES_VARIANT_H_
00043 #define ABSL_TYPES_VARIANT_H_
00044 
00045 #include "absl/base/config.h"
00046 #include "absl/utility/utility.h"
00047 
00048 #ifdef ABSL_HAVE_STD_VARIANT
00049 
00050 #include <variant>  // IWYU pragma: export
00051 
00052 namespace absl {
00053 using std::bad_variant_access;
00054 using std::get;
00055 using std::get_if;
00056 using std::holds_alternative;
00057 using std::monostate;
00058 using std::variant;
00059 using std::variant_alternative;
00060 using std::variant_alternative_t;
00061 using std::variant_npos;
00062 using std::variant_size;
00063 using std::variant_size_v;
00064 using std::visit;
00065 }  // namespace absl
00066 
00067 #else  // ABSL_HAVE_STD_VARIANT
00068 
00069 #include <functional>
00070 #include <new>
00071 #include <type_traits>
00072 #include <utility>
00073 
00074 #include "absl/base/macros.h"
00075 #include "absl/base/port.h"
00076 #include "absl/meta/type_traits.h"
00077 #include "absl/types/internal/variant.h"
00078 
00079 namespace absl {
00080 
00081 // -----------------------------------------------------------------------------
00082 // absl::variant
00083 // -----------------------------------------------------------------------------
00084 //
00085 // An `absl::variant` type is a form of type-safe union. An `absl::variant` --
00086 // except in exceptional cases -- always holds a value of one of its alternative
00087 // types.
00088 //
00089 // Example:
00090 //
00091 //   // Construct a variant that holds either an integer or a std::string and
00092 //   // assign it to a std::string.
00093 //   absl::variant<int, std::string> v = std::string("abc");
00094 //
00095 //   // A default-contructed variant will hold a value-initialized value of
00096 //   // the first alternative type.
00097 //   auto a = absl::variant<int, std::string>();   // Holds an int of value '0'.
00098 //
00099 //   // variants are assignable.
00100 //
00101 //   // copy assignment
00102 //   auto v1 = absl::variant<int, std::string>("abc");
00103 //   auto v2 = absl::variant<int, std::string>(10);
00104 //   v2 = v1;  // copy assign
00105 //
00106 //   // move assignment
00107 //   auto v1 = absl::variant<int, std::string>("abc");
00108 //   v1 = absl::variant<int, std::string>(10);
00109 //
00110 //   // assignment through type conversion
00111 //   a = 128;         // variant contains int
00112 //   a = "128";       // variant contains std::string
00113 //
00114 // An `absl::variant` holding a value of one of its alternative types `T` holds
00115 // an allocation of `T` directly within the variant itself. An `absl::variant`
00116 // is not allowed to allocate additional storage, such as dynamic memory, to
00117 // allocate the contained value. The contained value shall be allocated in a
00118 // region of the variant storage suitably aligned for all alternative types.
00119 template <typename... Ts>
00120 class variant;
00121 
00122 // swap()
00123 //
00124 // Swaps two `absl::variant` values. This function is equivalent to `v.swap(w)`
00125 // where `v` and `w` are `absl::variant` types.
00126 //
00127 // Note that this function requires all alternative types to be both swappable
00128 // and move-constructible, because any two variants may refer to either the same
00129 // type (in which case, they will be swapped) or to two different types (in
00130 // which case the values will need to be moved).
00131 //
00132 template <
00133     typename... Ts,
00134     absl::enable_if_t<
00135         absl::conjunction<std::is_move_constructible<Ts>...,
00136                           type_traits_internal::IsSwappable<Ts>...>::value,
00137         int> = 0>
00138 void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
00139   v.swap(w);
00140 }
00141 
00142 // variant_size
00143 //
00144 // Returns the number of alternative types available for a given `absl::variant`
00145 // type as a compile-time constant expression. As this is a class template, it
00146 // is not generally useful for accessing the number of alternative types of
00147 // any given `absl::variant` instance.
00148 //
00149 // Example:
00150 //
00151 //   auto a = absl::variant<int, std::string>;
00152 //   constexpr int num_types =
00153 //       absl::variant_size<absl::variant<int, std::string>>();
00154 //
00155 //   // You can also use the member constant `value`.
00156 //   constexpr int num_types =
00157 //       absl::variant_size<absl::variant<int, std::string>>::value;
00158 //
00159 //   // `absl::variant_size` is more valuable for use in generic code:
00160 //   template <typename Variant>
00161 //   constexpr bool IsVariantMultivalue() {
00162 //       return absl::variant_size<Variant>() > 1;
00163 //   }
00164 //
00165 // Note that the set of cv-qualified specializations of `variant_size` are
00166 // provided to ensure that those specializations compile (especially when passed
00167 // within template logic).
00168 template <class T>
00169 struct variant_size;
00170 
00171 template <class... Ts>
00172 struct variant_size<variant<Ts...>>
00173     : std::integral_constant<std::size_t, sizeof...(Ts)> {};
00174 
00175 // Specialization of `variant_size` for const qualified variants.
00176 template <class T>
00177 struct variant_size<const T> : variant_size<T>::type {};
00178 
00179 // Specialization of `variant_size` for volatile qualified variants.
00180 template <class T>
00181 struct variant_size<volatile T> : variant_size<T>::type {};
00182 
00183 // Specialization of `variant_size` for const volatile qualified variants.
00184 template <class T>
00185 struct variant_size<const volatile T> : variant_size<T>::type {};
00186 
00187 // variant_alternative
00188 //
00189 // Returns the alternative type for a given `absl::variant` at the passed
00190 // index value as a compile-time constant expression. As this is a class
00191 // template resulting in a type, it is not useful for access of the run-time
00192 // value of any given `absl::variant` variable.
00193 //
00194 // Example:
00195 //
00196 //   // The type of the 0th alternative is "int".
00197 //   using alternative_type_0
00198 //     = absl::variant_alternative<0, absl::variant<int, std::string>>::type;
00199 //
00200 //   static_assert(std::is_same<alternative_type_0, int>::value, "");
00201 //
00202 //   // `absl::variant_alternative` is more valuable for use in generic code:
00203 //   template <typename Variant>
00204 //   constexpr bool IsFirstElementTrivial() {
00205 //       return std::is_trivial_v<variant_alternative<0, Variant>::type>;
00206 //   }
00207 //
00208 // Note that the set of cv-qualified specializations of `variant_alternative`
00209 // are provided to ensure that those specializations compile (especially when
00210 // passed within template logic).
00211 template <std::size_t I, class T>
00212 struct variant_alternative;
00213 
00214 template <std::size_t I, class... Types>
00215 struct variant_alternative<I, variant<Types...>> {
00216   using type =
00217       variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>;
00218 };
00219 
00220 // Specialization of `variant_alternative` for const qualified variants.
00221 template <std::size_t I, class T>
00222 struct variant_alternative<I, const T> {
00223   using type = const typename variant_alternative<I, T>::type;
00224 };
00225 
00226 // Specialization of `variant_alternative` for volatile qualified variants.
00227 template <std::size_t I, class T>
00228 struct variant_alternative<I, volatile T> {
00229   using type = volatile typename variant_alternative<I, T>::type;
00230 };
00231 
00232 // Specialization of `variant_alternative` for const volatile qualified
00233 // variants.
00234 template <std::size_t I, class T>
00235 struct variant_alternative<I, const volatile T> {
00236   using type = const volatile typename variant_alternative<I, T>::type;
00237 };
00238 
00239 // Template type alias for variant_alternative<I, T>::type.
00240 //
00241 // Example:
00242 //
00243 //   using alternative_type_0
00244 //     = absl::variant_alternative_t<0, absl::variant<int, std::string>>;
00245 //   static_assert(std::is_same<alternative_type_0, int>::value, "");
00246 template <std::size_t I, class T>
00247 using variant_alternative_t = typename variant_alternative<I, T>::type;
00248 
00249 // holds_alternative()
00250 //
00251 // Checks whether the given variant currently holds a given alternative type,
00252 // returning `true` if so.
00253 //
00254 // Example:
00255 //
00256 //   absl::variant<int, std::string> foo = 42;
00257 //   if (absl::holds_alternative<int>(foo)) {
00258 //       std::cout << "The variant holds an integer";
00259 //   }
00260 template <class T, class... Types>
00261 constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
00262   static_assert(
00263       variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T,
00264                                                0>::value != sizeof...(Types),
00265       "The type T must occur exactly once in Types...");
00266   return v.index() ==
00267          variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value;
00268 }
00269 
00270 // get()
00271 //
00272 // Returns a reference to the value currently within a given variant, using
00273 // either a unique alternative type amongst the variant's set of alternative
00274 // types, or the variant's index value. Attempting to get a variant's value
00275 // using a type that is not unique within the variant's set of alternative types
00276 // is a compile-time error. If the index of the alternative being specified is
00277 // different from the index of the alternative that is currently stored, throws
00278 // `absl::bad_variant_access`.
00279 //
00280 // Example:
00281 //
00282 //   auto a = absl::variant<int, std::string>;
00283 //
00284 //   // Get the value by type (if unique).
00285 //   int i = absl::get<int>(a);
00286 //
00287 //   auto b = absl::variant<int, int>;
00288 //
00289 //   // Getting the value by a type that is not unique is ill-formed.
00290 //   int j = absl::get<int>(b);     // Compile Error!
00291 //
00292 //   // Getting value by index not ambiguous and allowed.
00293 //   int k = absl::get<1>(b);
00294 
00295 // Overload for getting a variant's lvalue by type.
00296 template <class T, class... Types>
00297 constexpr T& get(variant<Types...>& v) {  // NOLINT
00298   return variant_internal::VariantCoreAccess::CheckedAccess<
00299       variant_internal::IndexOf<T, Types...>::value>(v);
00300 }
00301 
00302 // Overload for getting a variant's rvalue by type.
00303 // Note: `absl::move()` is required to allow use of constexpr in C++11.
00304 template <class T, class... Types>
00305 constexpr T&& get(variant<Types...>&& v) {
00306   return variant_internal::VariantCoreAccess::CheckedAccess<
00307       variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
00308 }
00309 
00310 // Overload for getting a variant's const lvalue by type.
00311 template <class T, class... Types>
00312 constexpr const T& get(const variant<Types...>& v) {
00313   return variant_internal::VariantCoreAccess::CheckedAccess<
00314       variant_internal::IndexOf<T, Types...>::value>(v);
00315 }
00316 
00317 // Overload for getting a variant's const rvalue by type.
00318 // Note: `absl::move()` is required to allow use of constexpr in C++11.
00319 template <class T, class... Types>
00320 constexpr const T&& get(const variant<Types...>&& v) {
00321   return variant_internal::VariantCoreAccess::CheckedAccess<
00322       variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
00323 }
00324 
00325 // Overload for getting a variant's lvalue by index.
00326 template <std::size_t I, class... Types>
00327 constexpr variant_alternative_t<I, variant<Types...>>& get(
00328     variant<Types...>& v) {  // NOLINT
00329   return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
00330 }
00331 
00332 // Overload for getting a variant's rvalue by index.
00333 // Note: `absl::move()` is required to allow use of constexpr in C++11.
00334 template <std::size_t I, class... Types>
00335 constexpr variant_alternative_t<I, variant<Types...>>&& get(
00336     variant<Types...>&& v) {
00337   return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
00338 }
00339 
00340 // Overload for getting a variant's const lvalue by index.
00341 template <std::size_t I, class... Types>
00342 constexpr const variant_alternative_t<I, variant<Types...>>& get(
00343     const variant<Types...>& v) {
00344   return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
00345 }
00346 
00347 // Overload for getting a variant's const rvalue by index.
00348 // Note: `absl::move()` is required to allow use of constexpr in C++11.
00349 template <std::size_t I, class... Types>
00350 constexpr const variant_alternative_t<I, variant<Types...>>&& get(
00351     const variant<Types...>&& v) {
00352   return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
00353 }
00354 
00355 // get_if()
00356 //
00357 // Returns a pointer to the value currently stored within a given variant, if
00358 // present, using either a unique alternative type amongst the variant's set of
00359 // alternative types, or the variant's index value. If such a value does not
00360 // exist, returns `nullptr`.
00361 //
00362 // As with `get`, attempting to get a variant's value using a type that is not
00363 // unique within the variant's set of alternative types is a compile-time error.
00364 
00365 // Overload for getting a pointer to the value stored in the given variant by
00366 // index.
00367 template <std::size_t I, class... Types>
00368 constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>>
00369 get_if(variant<Types...>* v) noexcept {
00370   return (v != nullptr && v->index() == I)
00371              ? std::addressof(
00372                    variant_internal::VariantCoreAccess::Access<I>(*v))
00373              : nullptr;
00374 }
00375 
00376 // Overload for getting a pointer to the const value stored in the given
00377 // variant by index.
00378 template <std::size_t I, class... Types>
00379 constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
00380 get_if(const variant<Types...>* v) noexcept {
00381   return (v != nullptr && v->index() == I)
00382              ? std::addressof(
00383                    variant_internal::VariantCoreAccess::Access<I>(*v))
00384              : nullptr;
00385 }
00386 
00387 // Overload for getting a pointer to the value stored in the given variant by
00388 // type.
00389 template <class T, class... Types>
00390 constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept {
00391   return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
00392 }
00393 
00394 // Overload for getting a pointer to the const value stored in the given variant
00395 // by type.
00396 template <class T, class... Types>
00397 constexpr absl::add_pointer_t<const T> get_if(
00398     const variant<Types...>* v) noexcept {
00399   return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
00400 }
00401 
00402 // visit()
00403 //
00404 // Calls a provided functor on a given set of variants. `absl::visit()` is
00405 // commonly used to conditionally inspect the state of a given variant (or set
00406 // of variants).
00407 //
00408 // The functor must return the same type when called with any of the variants'
00409 // alternatives.
00410 //
00411 // Example:
00412 //
00413 //   // Define a visitor functor
00414 //   struct GetVariant {
00415 //       template<typename T>
00416 //       void operator()(const T& i) const {
00417 //         std::cout << "The variant's value is: " << i;
00418 //       }
00419 //   };
00420 //
00421 //   // Declare our variant, and call `absl::visit()` on it.
00422 //   // Note that `GetVariant()` returns void in either case.
00423 //   absl::variant<int, std::string> foo = std::string("foo");
00424 //   GetVariant visitor;
00425 //   absl::visit(visitor, foo);  // Prints `The variant's value is: foo'
00426 template <typename Visitor, typename... Variants>
00427 variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
00428                                                           Variants&&... vars) {
00429   return variant_internal::
00430       VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run(
00431           variant_internal::PerformVisitation<Visitor, Variants...>{
00432               std::forward_as_tuple(absl::forward<Variants>(vars)...),
00433               absl::forward<Visitor>(vis)},
00434           vars.index()...);
00435 }
00436 
00437 // monostate
00438 //
00439 // The monostate class serves as a first alternative type for a variant for
00440 // which the first variant type is otherwise not default-constructible.
00441 struct monostate {};
00442 
00443 // `absl::monostate` Relational Operators
00444 
00445 constexpr bool operator<(monostate, monostate) noexcept { return false; }
00446 constexpr bool operator>(monostate, monostate) noexcept { return false; }
00447 constexpr bool operator<=(monostate, monostate) noexcept { return true; }
00448 constexpr bool operator>=(monostate, monostate) noexcept { return true; }
00449 constexpr bool operator==(monostate, monostate) noexcept { return true; }
00450 constexpr bool operator!=(monostate, monostate) noexcept { return false; }
00451 
00452 
00453 //------------------------------------------------------------------------------
00454 // `absl::variant` Template Definition
00455 //------------------------------------------------------------------------------
00456 template <typename T0, typename... Tn>
00457 class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
00458   static_assert(absl::conjunction<std::is_object<T0>,
00459                                   std::is_object<Tn>...>::value,
00460                 "Attempted to instantiate a variant containing a non-object "
00461                 "type.");
00462   // Intentionally not qualifying `negation` with `absl::` to work around a bug
00463   // in MSVC 2015 with inline namespace and variadic template.
00464   static_assert(absl::conjunction<negation<std::is_array<T0> >,
00465                                   negation<std::is_array<Tn> >...>::value,
00466                 "Attempted to instantiate a variant containing an array type.");
00467   static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
00468                                   std::is_nothrow_destructible<Tn>...>::value,
00469                 "Attempted to instantiate a variant containing a non-nothrow "
00470                 "destructible type.");
00471 
00472   friend struct variant_internal::VariantCoreAccess;
00473 
00474  private:
00475   using Base = variant_internal::VariantBase<T0, Tn...>;
00476 
00477  public:
00478   // Constructors
00479 
00480   // Constructs a variant holding a default-initialized value of the first
00481   // alternative type.
00482   constexpr variant() /*noexcept(see 111above)*/ = default;
00483 
00484   // Copy constructor, standard semantics
00485   variant(const variant& other) = default;
00486 
00487   // Move constructor, standard semantics
00488   variant(variant&& other) /*noexcept(see above)*/ = default;
00489 
00490   // Constructs a variant of an alternative type specified by overload
00491   // resolution of the provided forwarding arguments through
00492   // direct-initialization.
00493   //
00494   // Note: If the selected constructor is a constexpr constructor, this
00495   // constructor shall be a constexpr constructor.
00496   //
00497   // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
00498   // has been voted passed the design phase in the C++ standard meeting in Mar
00499   // 2018. It will be implemented and integrated into `absl::variant`.
00500   template <
00501       class T,
00502       std::size_t I = std::enable_if<
00503           variant_internal::IsNeitherSelfNorInPlace<variant,
00504                                                     absl::decay_t<T>>::value,
00505           variant_internal::IndexOfConstructedType<variant, T>>::type::value,
00506       class Tj = absl::variant_alternative_t<I, variant>,
00507       absl::enable_if_t<std::is_constructible<Tj, T>::value>* =
00508           nullptr>
00509   constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value)
00510       : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}
00511 
00512   // Constructs a variant of an alternative type from the arguments through
00513   // direct-initialization.
00514   //
00515   // Note: If the selected constructor is a constexpr constructor, this
00516   // constructor shall be a constexpr constructor.
00517   template <class T, class... Args,
00518             typename std::enable_if<std::is_constructible<
00519                 variant_internal::UnambiguousTypeOfT<variant, T>,
00520                 Args...>::value>::type* = nullptr>
00521   constexpr explicit variant(in_place_type_t<T>, Args&&... args)
00522       : Base(variant_internal::EmplaceTag<
00523                  variant_internal::UnambiguousIndexOf<variant, T>::value>(),
00524              absl::forward<Args>(args)...) {}
00525 
00526   // Constructs a variant of an alternative type from an initializer list
00527   // and other arguments through direct-initialization.
00528   //
00529   // Note: If the selected constructor is a constexpr constructor, this
00530   // constructor shall be a constexpr constructor.
00531   template <class T, class U, class... Args,
00532             typename std::enable_if<std::is_constructible<
00533                 variant_internal::UnambiguousTypeOfT<variant, T>,
00534                 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00535   constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il,
00536                              Args&&... args)
00537       : Base(variant_internal::EmplaceTag<
00538                  variant_internal::UnambiguousIndexOf<variant, T>::value>(),
00539              il, absl::forward<Args>(args)...) {}
00540 
00541   // Constructs a variant of an alternative type from a provided index,
00542   // through value-initialization using the provided forwarded arguments.
00543   template <std::size_t I, class... Args,
00544             typename std::enable_if<std::is_constructible<
00545                 variant_internal::VariantAlternativeSfinaeT<I, variant>,
00546                 Args...>::value>::type* = nullptr>
00547   constexpr explicit variant(in_place_index_t<I>, Args&&... args)
00548       : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {}
00549 
00550   // Constructs a variant of an alternative type from a provided index,
00551   // through value-initialization of an initializer list and the provided
00552   // forwarded arguments.
00553   template <std::size_t I, class U, class... Args,
00554             typename std::enable_if<std::is_constructible<
00555                 variant_internal::VariantAlternativeSfinaeT<I, variant>,
00556                 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00557   constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il,
00558                              Args&&... args)
00559       : Base(variant_internal::EmplaceTag<I>(), il,
00560              absl::forward<Args>(args)...) {}
00561 
00562   // Destructors
00563 
00564   // Destroys the variant's currently contained value, provided that
00565   // `absl::valueless_by_exception()` is false.
00566   ~variant() = default;
00567 
00568   // Assignment Operators
00569 
00570   // Copy assignment operator
00571   variant& operator=(const variant& other) = default;
00572 
00573   // Move assignment operator
00574   variant& operator=(variant&& other) /*noexcept(see above)*/ = default;
00575 
00576   // Converting assignment operator
00577   //
00578   // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
00579   // has been voted passed the design phase in the C++ standard meeting in Mar
00580   // 2018. It will be implemented and integrated into `absl::variant`.
00581   template <
00582       class T,
00583       std::size_t I = std::enable_if<
00584           !std::is_same<absl::decay_t<T>, variant>::value,
00585           variant_internal::IndexOfConstructedType<variant, T>>::type::value,
00586       class Tj = absl::variant_alternative_t<I, variant>,
00587       typename std::enable_if<std::is_assignable<Tj&, T>::value &&
00588                               std::is_constructible<Tj, T>::value>::type* =
00589           nullptr>
00590   variant& operator=(T&& t) noexcept(
00591       std::is_nothrow_assignable<Tj&, T>::value&&
00592           std::is_nothrow_constructible<Tj, T>::value) {
00593     variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
00594         variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
00595             this, absl::forward<T>(t)),
00596         index());
00597 
00598     return *this;
00599   }
00600 
00601 
00602   // emplace() Functions
00603 
00604   // Constructs a value of the given alternative type T within the variant.
00605   //
00606   // Example:
00607   //
00608   //   absl::variant<std::vector<int>, int, std::string> v;
00609   //   v.emplace<int>(99);
00610   //   v.emplace<std::string>("abc");
00611   template <
00612       class T, class... Args,
00613       typename std::enable_if<std::is_constructible<
00614           absl::variant_alternative_t<
00615               variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
00616           Args...>::value>::type* = nullptr>
00617   T& emplace(Args&&... args) {
00618     return variant_internal::VariantCoreAccess::Replace<
00619         variant_internal::UnambiguousIndexOf<variant, T>::value>(
00620         this, absl::forward<Args>(args)...);
00621   }
00622 
00623   // Constructs a value of the given alternative type T within the variant using
00624   // an initializer list.
00625   //
00626   // Example:
00627   //
00628   //   absl::variant<std::vector<int>, int, std::string> v;
00629   //   v.emplace<std::vector<int>>({0, 1, 2});
00630   template <
00631       class T, class U, class... Args,
00632       typename std::enable_if<std::is_constructible<
00633           absl::variant_alternative_t<
00634               variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
00635           std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00636   T& emplace(std::initializer_list<U> il, Args&&... args) {
00637     return variant_internal::VariantCoreAccess::Replace<
00638         variant_internal::UnambiguousIndexOf<variant, T>::value>(
00639         this, il, absl::forward<Args>(args)...);
00640   }
00641 
00642   // Destroys the current value of the variant (provided that
00643   // `absl::valueless_by_exception()` is false, and constructs a new value at
00644   // the given index.
00645   //
00646   // Example:
00647   //
00648   //   absl::variant<std::vector<int>, int, int> v;
00649   //   v.emplace<1>(99);
00650   //   v.emplace<2>(98);
00651   //   v.emplace<int>(99);  // Won't compile. 'int' isn't a unique type.
00652   template <std::size_t I, class... Args,
00653             typename std::enable_if<
00654                 std::is_constructible<absl::variant_alternative_t<I, variant>,
00655                                       Args...>::value>::type* = nullptr>
00656   absl::variant_alternative_t<I, variant>& emplace(Args&&... args) {
00657     return variant_internal::VariantCoreAccess::Replace<I>(
00658         this, absl::forward<Args>(args)...);
00659   }
00660 
00661   // Destroys the current value of the variant (provided that
00662   // `absl::valueless_by_exception()` is false, and constructs a new value at
00663   // the given index using an initializer list and the provided arguments.
00664   //
00665   // Example:
00666   //
00667   //   absl::variant<std::vector<int>, int, int> v;
00668   //   v.emplace<0>({0, 1, 2});
00669   template <std::size_t I, class U, class... Args,
00670             typename std::enable_if<std::is_constructible<
00671                 absl::variant_alternative_t<I, variant>,
00672                 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
00673   absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il,
00674                                                    Args&&... args) {
00675     return variant_internal::VariantCoreAccess::Replace<I>(
00676         this, il, absl::forward<Args>(args)...);
00677   }
00678 
00679   // variant::valueless_by_exception()
00680   //
00681   // Returns false if and only if the variant currently holds a valid value.
00682   constexpr bool valueless_by_exception() const noexcept {
00683     return this->index_ == absl::variant_npos;
00684   }
00685 
00686   // variant::index()
00687   //
00688   // Returns the index value of the variant's currently selected alternative
00689   // type.
00690   constexpr std::size_t index() const noexcept { return this->index_; }
00691 
00692   // variant::swap()
00693   //
00694   // Swaps the values of two variant objects.
00695   //
00696   void swap(variant& rhs) noexcept(
00697       absl::conjunction<
00698           std::is_nothrow_move_constructible<T0>,
00699           std::is_nothrow_move_constructible<Tn>...,
00700           type_traits_internal::IsNothrowSwappable<T0>,
00701           type_traits_internal::IsNothrowSwappable<Tn>...>::value) {
00702     return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
00703         variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
00704   }
00705 };
00706 
00707 // We need a valid declaration of variant<> for SFINAE and overload resolution
00708 // to work properly above, but we don't need a full declaration since this type
00709 // will never be constructed. This declaration, though incomplete, suffices.
00710 template <>
00711 class variant<>;
00712 
00713 //------------------------------------------------------------------------------
00714 // Relational Operators
00715 //------------------------------------------------------------------------------
00716 //
00717 // If neither operand is in the `variant::valueless_by_exception` state:
00718 //
00719 //   * If the index of both variants is the same, the relational operator
00720 //     returns the result of the corresponding relational operator for the
00721 //     corresponding alternative type.
00722 //   * If the index of both variants is not the same, the relational operator
00723 //     returns the result of that operation applied to the value of the left
00724 //     operand's index and the value of the right operand's index.
00725 //   * If at least one operand is in the valueless_by_exception state:
00726 //     - A variant in the valueless_by_exception state is only considered equal
00727 //       to another variant in the valueless_by_exception state.
00728 //     - If exactly one operand is in the valueless_by_exception state, the
00729 //       variant in the valueless_by_exception state is less than the variant
00730 //       that is not in the valueless_by_exception state.
00731 //
00732 // Note: The value 1 is added to each index in the relational comparisons such
00733 // that the index corresponding to the valueless_by_exception state wraps around
00734 // to 0 (the lowest value for the index type), and the remaining indices stay in
00735 // the same relative order.
00736 
00737 // Equal-to operator
00738 template <typename... Types>
00739 constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
00740     const variant<Types...>& a, const variant<Types...>& b) {
00741   return (a.index() == b.index()) &&
00742          variant_internal::VisitIndices<sizeof...(Types)>::Run(
00743              variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
00744 }
00745 
00746 // Not equal operator
00747 template <typename... Types>
00748 constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
00749     const variant<Types...>& a, const variant<Types...>& b) {
00750   return (a.index() != b.index()) ||
00751          variant_internal::VisitIndices<sizeof...(Types)>::Run(
00752              variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
00753 }
00754 
00755 // Less-than operator
00756 template <typename... Types>
00757 constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
00758     const variant<Types...>& a, const variant<Types...>& b) {
00759   return (a.index() != b.index())
00760              ? (a.index() + 1) < (b.index() + 1)
00761              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00762                    variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
00763 }
00764 
00765 // Greater-than operator
00766 template <typename... Types>
00767 constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
00768     const variant<Types...>& a, const variant<Types...>& b) {
00769   return (a.index() != b.index())
00770              ? (a.index() + 1) > (b.index() + 1)
00771              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00772                    variant_internal::GreaterThanOp<Types...>{&a, &b},
00773                    a.index());
00774 }
00775 
00776 // Less-than or equal-to operator
00777 template <typename... Types>
00778 constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
00779     const variant<Types...>& a, const variant<Types...>& b) {
00780   return (a.index() != b.index())
00781              ? (a.index() + 1) < (b.index() + 1)
00782              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00783                    variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
00784                    a.index());
00785 }
00786 
00787 // Greater-than or equal-to operator
00788 template <typename... Types>
00789 constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
00790 operator>=(const variant<Types...>& a, const variant<Types...>& b) {
00791   return (a.index() != b.index())
00792              ? (a.index() + 1) > (b.index() + 1)
00793              : variant_internal::VisitIndices<sizeof...(Types)>::Run(
00794                    variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
00795                    a.index());
00796 }
00797 
00798 }  // namespace absl
00799 
00800 namespace std {
00801 
00802 // hash()
00803 template <>  // NOLINT
00804 struct hash<absl::monostate> {
00805   std::size_t operator()(absl::monostate) const { return 0; }
00806 };
00807 
00808 template <class... T>  // NOLINT
00809 struct hash<absl::variant<T...>>
00810     : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
00811                                               absl::remove_const_t<T>...> {};
00812 
00813 }  // namespace std
00814 
00815 #endif  // ABSL_HAVE_STD_VARIANT
00816 
00817 namespace absl {
00818 namespace variant_internal {
00819 
00820 // Helper visitor for converting a variant<Ts...>` into another type (mostly
00821 // variant) that can be constructed from any type.
00822 template <typename To>
00823 struct ConversionVisitor {
00824   template <typename T>
00825   To operator()(T&& v) const {
00826     return To(std::forward<T>(v));
00827   }
00828 };
00829 
00830 }  // namespace variant_internal
00831 
00832 // ConvertVariantTo()
00833 //
00834 // Helper functions to convert an `absl::variant` to a variant of another set of
00835 // types, provided that the alternative type of the new variant type can be
00836 // converted from any type in the source variant.
00837 //
00838 // Example:
00839 //
00840 //   absl::variant<name1, name2, float> InternalReq(const Req&);
00841 //
00842 //   // name1 and name2 are convertible to name
00843 //   absl::variant<name, float> ExternalReq(const Req& req) {
00844 //     return absl::ConvertVariantTo<absl::variant<name, float>>(
00845 //              InternalReq(req));
00846 //   }
00847 template <typename To, typename Variant>
00848 To ConvertVariantTo(Variant&& variant) {
00849   return absl::visit(variant_internal::ConversionVisitor<To>{},
00850                      std::forward<Variant>(variant));
00851 }
00852 
00853 }  // namespace absl
00854 
00855 #endif  // ABSL_TYPES_VARIANT_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:16