1// Copyright 2018 The Abseil Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// -----------------------------------------------------------------------------
16// variant.h
17// -----------------------------------------------------------------------------
18//
19// This header file defines an `absl::variant` type for holding a type-safe
20// value of some prescribed set of types (noted as alternative types), and
21// associated functions for managing variants.
22//
23// The `absl::variant` type is a form of type-safe union. An `absl::variant`
24// should always hold a value of one of its alternative types (except in the
25// "valueless by exception state" -- see below). A default-constructed
26// `absl::variant` will hold the value of its first alternative type, provided
27// it is default-constructable.
28//
29// In exceptional cases due to error, an `absl::variant` can hold no
30// value (known as a "valueless by exception" state), though this is not the
31// norm.
32//
33// As with `absl::optional`, an `absl::variant` -- when it holds a value --
34// allocates a value of that type directly within the `variant` itself; it
35// cannot hold a reference, array, or the type `void`; it can, however, hold a
36// pointer to externally managed memory.
37//
38// `absl::variant` is a C++11 compatible version of the C++17 `std::variant`
39// abstraction and is designed to be a drop-in replacement for code compliant
40// with C++17.
41
42#ifndef ABSL_TYPES_VARIANT_H_
43#define ABSL_TYPES_VARIANT_H_
44
45#include "absl/base/config.h"
46#include "absl/utility/utility.h"
47
48#ifdef ABSL_HAVE_STD_VARIANT
49
50#include <variant> // IWYU pragma: export
51
52namespace absl {
53using std::bad_variant_access;
54using std::get;
55using std::get_if;
56using std::holds_alternative;
57using std::monostate;
58using std::variant;
59using std::variant_alternative;
60using std::variant_alternative_t;
61using std::variant_npos;
62using std::variant_size;
63using std::variant_size_v;
64using std::visit;
65} // namespace absl
66
67#else // ABSL_HAVE_STD_VARIANT
68
69#include <functional>
70#include <new>
71#include <type_traits>
72#include <utility>
73
74#include "absl/base/macros.h"
75#include "absl/base/port.h"
76#include "absl/meta/type_traits.h"
77#include "absl/types/internal/variant.h"
78
79namespace absl {
80
81// -----------------------------------------------------------------------------
82// absl::variant
83// -----------------------------------------------------------------------------
84//
85// An `absl::variant` type is a form of type-safe union. An `absl::variant` --
86// except in exceptional cases -- always holds a value of one of its alternative
87// types.
88//
89// Example:
90//
91// // Construct a variant that holds either an integer or a std::string and
92// // assign it to a std::string.
93// absl::variant<int, std::string> v = std::string("abc");
94//
95// // A default-contructed variant will hold a value-initialized value of
96// // the first alternative type.
97// auto a = absl::variant<int, std::string>(); // Holds an int of value '0'.
98//
99// // variants are assignable.
100//
101// // copy assignment
102// auto v1 = absl::variant<int, std::string>("abc");
103// auto v2 = absl::variant<int, std::string>(10);
104// v2 = v1; // copy assign
105//
106// // move assignment
107// auto v1 = absl::variant<int, std::string>("abc");
108// v1 = absl::variant<int, std::string>(10);
109//
110// // assignment through type conversion
111// a = 128; // variant contains int
112// a = "128"; // variant contains std::string
113//
114// An `absl::variant` holding a value of one of its alternative types `T` holds
115// an allocation of `T` directly within the variant itself. An `absl::variant`
116// is not allowed to allocate additional storage, such as dynamic memory, to
117// allocate the contained value. The contained value shall be allocated in a
118// region of the variant storage suitably aligned for all alternative types.
119template <typename... Ts>
120class variant;
121
122// swap()
123//
124// Swaps two `absl::variant` values. This function is equivalent to `v.swap(w)`
125// where `v` and `w` are `absl::variant` types.
126//
127// Note that this function requires all alternative types to be both swappable
128// and move-constructible, because any two variants may refer to either the same
129// type (in which case, they will be swapped) or to two different types (in
130// which case the values will need to be moved).
131//
132template <
133 typename... Ts,
134 absl::enable_if_t<
135 absl::conjunction<std::is_move_constructible<Ts>...,
136 type_traits_internal::IsSwappable<Ts>...>::value,
137 int> = 0>
138void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
139 v.swap(w);
140}
141
142// variant_size
143//
144// Returns the number of alternative types available for a given `absl::variant`
145// type as a compile-time constant expression. As this is a class template, it
146// is not generally useful for accessing the number of alternative types of
147// any given `absl::variant` instance.
148//
149// Example:
150//
151// auto a = absl::variant<int, std::string>;
152// constexpr int num_types =
153// absl::variant_size<absl::variant<int, std::string>>();
154//
155// // You can also use the member constant `value`.
156// constexpr int num_types =
157// absl::variant_size<absl::variant<int, std::string>>::value;
158//
159// // `absl::variant_size` is more valuable for use in generic code:
160// template <typename Variant>
161// constexpr bool IsVariantMultivalue() {
162// return absl::variant_size<Variant>() > 1;
163// }
164//
165// Note that the set of cv-qualified specializations of `variant_size` are
166// provided to ensure that those specializations compile (especially when passed
167// within template logic).
168template <class T>
169struct variant_size;
170
171template <class... Ts>
172struct variant_size<variant<Ts...>>
173 : std::integral_constant<std::size_t, sizeof...(Ts)> {};
174
175// Specialization of `variant_size` for const qualified variants.
176template <class T>
177struct variant_size<const T> : variant_size<T>::type {};
178
179// Specialization of `variant_size` for volatile qualified variants.
180template <class T>
181struct variant_size<volatile T> : variant_size<T>::type {};
182
183// Specialization of `variant_size` for const volatile qualified variants.
184template <class T>
185struct variant_size<const volatile T> : variant_size<T>::type {};
186
187// variant_alternative
188//
189// Returns the alternative type for a given `absl::variant` at the passed
190// index value as a compile-time constant expression. As this is a class
191// template resulting in a type, it is not useful for access of the run-time
192// value of any given `absl::variant` variable.
193//
194// Example:
195//
196// // The type of the 0th alternative is "int".
197// using alternative_type_0
198// = absl::variant_alternative<0, absl::variant<int, std::string>>::type;
199//
200// static_assert(std::is_same<alternative_type_0, int>::value, "");
201//
202// // `absl::variant_alternative` is more valuable for use in generic code:
203// template <typename Variant>
204// constexpr bool IsFirstElementTrivial() {
205// return std::is_trivial_v<variant_alternative<0, Variant>::type>;
206// }
207//
208// Note that the set of cv-qualified specializations of `variant_alternative`
209// are provided to ensure that those specializations compile (especially when
210// passed within template logic).
211template <std::size_t I, class T>
212struct variant_alternative;
213
214template <std::size_t I, class... Types>
215struct variant_alternative<I, variant<Types...>> {
216 using type =
217 variant_internal::VariantAlternativeSfinaeT<I, variant<Types...>>;
218};
219
220// Specialization of `variant_alternative` for const qualified variants.
221template <std::size_t I, class T>
222struct variant_alternative<I, const T> {
223 using type = const typename variant_alternative<I, T>::type;
224};
225
226// Specialization of `variant_alternative` for volatile qualified variants.
227template <std::size_t I, class T>
228struct variant_alternative<I, volatile T> {
229 using type = volatile typename variant_alternative<I, T>::type;
230};
231
232// Specialization of `variant_alternative` for const volatile qualified
233// variants.
234template <std::size_t I, class T>
235struct variant_alternative<I, const volatile T> {
236 using type = const volatile typename variant_alternative<I, T>::type;
237};
238
239// Template type alias for variant_alternative<I, T>::type.
240//
241// Example:
242//
243// using alternative_type_0
244// = absl::variant_alternative_t<0, absl::variant<int, std::string>>;
245// static_assert(std::is_same<alternative_type_0, int>::value, "");
246template <std::size_t I, class T>
247using variant_alternative_t = typename variant_alternative<I, T>::type;
248
249// holds_alternative()
250//
251// Checks whether the given variant currently holds a given alternative type,
252// returning `true` if so.
253//
254// Example:
255//
256// absl::variant<int, std::string> foo = 42;
257// if (absl::holds_alternative<int>(foo)) {
258// std::cout << "The variant holds an integer";
259// }
260template <class T, class... Types>
261constexpr bool holds_alternative(const variant<Types...>& v) noexcept {
262 static_assert(
263 variant_internal::UnambiguousIndexOfImpl<variant<Types...>, T,
264 0>::value != sizeof...(Types),
265 "The type T must occur exactly once in Types...");
266 return v.index() ==
267 variant_internal::UnambiguousIndexOf<variant<Types...>, T>::value;
268}
269
270// get()
271//
272// Returns a reference to the value currently within a given variant, using
273// either a unique alternative type amongst the variant's set of alternative
274// types, or the variant's index value. Attempting to get a variant's value
275// using a type that is not unique within the variant's set of alternative types
276// is a compile-time error. If the index of the alternative being specified is
277// different from the index of the alternative that is currently stored, throws
278// `absl::bad_variant_access`.
279//
280// Example:
281//
282// auto a = absl::variant<int, std::string>;
283//
284// // Get the value by type (if unique).
285// int i = absl::get<int>(a);
286//
287// auto b = absl::variant<int, int>;
288//
289// // Getting the value by a type that is not unique is ill-formed.
290// int j = absl::get<int>(b); // Compile Error!
291//
292// // Getting value by index not ambiguous and allowed.
293// int k = absl::get<1>(b);
294
295// Overload for getting a variant's lvalue by type.
296template <class T, class... Types>
297constexpr T& get(variant<Types...>& v) { // NOLINT
298 return variant_internal::VariantCoreAccess::CheckedAccess<
299 variant_internal::IndexOf<T, Types...>::value>(v);
300}
301
302// Overload for getting a variant's rvalue by type.
303// Note: `absl::move()` is required to allow use of constexpr in C++11.
304template <class T, class... Types>
305constexpr T&& get(variant<Types...>&& v) {
306 return variant_internal::VariantCoreAccess::CheckedAccess<
307 variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
308}
309
310// Overload for getting a variant's const lvalue by type.
311template <class T, class... Types>
312constexpr const T& get(const variant<Types...>& v) {
313 return variant_internal::VariantCoreAccess::CheckedAccess<
314 variant_internal::IndexOf<T, Types...>::value>(v);
315}
316
317// Overload for getting a variant's const rvalue by type.
318// Note: `absl::move()` is required to allow use of constexpr in C++11.
319template <class T, class... Types>
320constexpr const T&& get(const variant<Types...>&& v) {
321 return variant_internal::VariantCoreAccess::CheckedAccess<
322 variant_internal::IndexOf<T, Types...>::value>(absl::move(v));
323}
324
325// Overload for getting a variant's lvalue by index.
326template <std::size_t I, class... Types>
327constexpr variant_alternative_t<I, variant<Types...>>& get(
328 variant<Types...>& v) { // NOLINT
329 return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
330}
331
332// Overload for getting a variant's rvalue by index.
333// Note: `absl::move()` is required to allow use of constexpr in C++11.
334template <std::size_t I, class... Types>
335constexpr variant_alternative_t<I, variant<Types...>>&& get(
336 variant<Types...>&& v) {
337 return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
338}
339
340// Overload for getting a variant's const lvalue by index.
341template <std::size_t I, class... Types>
342constexpr const variant_alternative_t<I, variant<Types...>>& get(
343 const variant<Types...>& v) {
344 return variant_internal::VariantCoreAccess::CheckedAccess<I>(v);
345}
346
347// Overload for getting a variant's const rvalue by index.
348// Note: `absl::move()` is required to allow use of constexpr in C++11.
349template <std::size_t I, class... Types>
350constexpr const variant_alternative_t<I, variant<Types...>>&& get(
351 const variant<Types...>&& v) {
352 return variant_internal::VariantCoreAccess::CheckedAccess<I>(absl::move(v));
353}
354
355// get_if()
356//
357// Returns a pointer to the value currently stored within a given variant, if
358// present, using either a unique alternative type amongst the variant's set of
359// alternative types, or the variant's index value. If such a value does not
360// exist, returns `nullptr`.
361//
362// As with `get`, attempting to get a variant's value using a type that is not
363// unique within the variant's set of alternative types is a compile-time error.
364
365// Overload for getting a pointer to the value stored in the given variant by
366// index.
367template <std::size_t I, class... Types>
368constexpr absl::add_pointer_t<variant_alternative_t<I, variant<Types...>>>
369get_if(variant<Types...>* v) noexcept {
370 return (v != nullptr && v->index() == I)
371 ? std::addressof(
372 variant_internal::VariantCoreAccess::Access<I>(*v))
373 : nullptr;
374}
375
376// Overload for getting a pointer to the const value stored in the given
377// variant by index.
378template <std::size_t I, class... Types>
379constexpr absl::add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
380get_if(const variant<Types...>* v) noexcept {
381 return (v != nullptr && v->index() == I)
382 ? std::addressof(
383 variant_internal::VariantCoreAccess::Access<I>(*v))
384 : nullptr;
385}
386
387// Overload for getting a pointer to the value stored in the given variant by
388// type.
389template <class T, class... Types>
390constexpr absl::add_pointer_t<T> get_if(variant<Types...>* v) noexcept {
391 return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
392}
393
394// Overload for getting a pointer to the const value stored in the given variant
395// by type.
396template <class T, class... Types>
397constexpr absl::add_pointer_t<const T> get_if(
398 const variant<Types...>* v) noexcept {
399 return absl::get_if<variant_internal::IndexOf<T, Types...>::value>(v);
400}
401
402// visit()
403//
404// Calls a provided functor on a given set of variants. `absl::visit()` is
405// commonly used to conditionally inspect the state of a given variant (or set
406// of variants).
407//
408// The functor must return the same type when called with any of the variants'
409// alternatives.
410//
411// Example:
412//
413// // Define a visitor functor
414// struct GetVariant {
415// template<typename T>
416// void operator()(const T& i) const {
417// std::cout << "The variant's value is: " << i;
418// }
419// };
420//
421// // Declare our variant, and call `absl::visit()` on it.
422// // Note that `GetVariant()` returns void in either case.
423// absl::variant<int, std::string> foo = std::string("foo");
424// GetVariant visitor;
425// absl::visit(visitor, foo); // Prints `The variant's value is: foo'
426template <typename Visitor, typename... Variants>
427variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis,
428 Variants&&... vars) {
429 return variant_internal::
430 VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run(
431 variant_internal::PerformVisitation<Visitor, Variants...>{
432 std::forward_as_tuple(absl::forward<Variants>(vars)...),
433 absl::forward<Visitor>(vis)},
434 vars.index()...);
435}
436
437// monostate
438//
439// The monostate class serves as a first alternative type for a variant for
440// which the first variant type is otherwise not default-constructible.
441struct monostate {};
442
443// `absl::monostate` Relational Operators
444
445constexpr bool operator<(monostate, monostate) noexcept { return false; }
446constexpr bool operator>(monostate, monostate) noexcept { return false; }
447constexpr bool operator<=(monostate, monostate) noexcept { return true; }
448constexpr bool operator>=(monostate, monostate) noexcept { return true; }
449constexpr bool operator==(monostate, monostate) noexcept { return true; }
450constexpr bool operator!=(monostate, monostate) noexcept { return false; }
451
452
453//------------------------------------------------------------------------------
454// `absl::variant` Template Definition
455//------------------------------------------------------------------------------
456template <typename T0, typename... Tn>
457class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
458 static_assert(absl::conjunction<std::is_object<T0>,
459 std::is_object<Tn>...>::value,
460 "Attempted to instantiate a variant containing a non-object "
461 "type.");
462 // Intentionally not qualifying `negation` with `absl::` to work around a bug
463 // in MSVC 2015 with inline namespace and variadic template.
464 static_assert(absl::conjunction<negation<std::is_array<T0> >,
465 negation<std::is_array<Tn> >...>::value,
466 "Attempted to instantiate a variant containing an array type.");
467 static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
468 std::is_nothrow_destructible<Tn>...>::value,
469 "Attempted to instantiate a variant containing a non-nothrow "
470 "destructible type.");
471
472 friend struct variant_internal::VariantCoreAccess;
473
474 private:
475 using Base = variant_internal::VariantBase<T0, Tn...>;
476
477 public:
478 // Constructors
479
480 // Constructs a variant holding a default-initialized value of the first
481 // alternative type.
482 constexpr variant() /*noexcept(see 111above)*/ = default;
483
484 // Copy constructor, standard semantics
485 variant(const variant& other) = default;
486
487 // Move constructor, standard semantics
488 variant(variant&& other) /*noexcept(see above)*/ = default;
489
490 // Constructs a variant of an alternative type specified by overload
491 // resolution of the provided forwarding arguments through
492 // direct-initialization.
493 //
494 // Note: If the selected constructor is a constexpr constructor, this
495 // constructor shall be a constexpr constructor.
496 //
497 // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
498 // has been voted passed the design phase in the C++ standard meeting in Mar
499 // 2018. It will be implemented and integrated into `absl::variant`.
500 template <
501 class T,
502 std::size_t I = std::enable_if<
503 variant_internal::IsNeitherSelfNorInPlace<variant,
504 absl::decay_t<T>>::value,
505 variant_internal::IndexOfConstructedType<variant, T>>::type::value,
506 class Tj = absl::variant_alternative_t<I, variant>,
507 absl::enable_if_t<std::is_constructible<Tj, T>::value>* =
508 nullptr>
509 constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value)
510 : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}
511
512 // Constructs a variant of an alternative type from the arguments through
513 // direct-initialization.
514 //
515 // Note: If the selected constructor is a constexpr constructor, this
516 // constructor shall be a constexpr constructor.
517 template <class T, class... Args,
518 typename std::enable_if<std::is_constructible<
519 variant_internal::UnambiguousTypeOfT<variant, T>,
520 Args...>::value>::type* = nullptr>
521 constexpr explicit variant(in_place_type_t<T>, Args&&... args)
522 : Base(variant_internal::EmplaceTag<
523 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
524 absl::forward<Args>(args)...) {}
525
526 // Constructs a variant of an alternative type from an initializer list
527 // and other arguments through direct-initialization.
528 //
529 // Note: If the selected constructor is a constexpr constructor, this
530 // constructor shall be a constexpr constructor.
531 template <class T, class U, class... Args,
532 typename std::enable_if<std::is_constructible<
533 variant_internal::UnambiguousTypeOfT<variant, T>,
534 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
535 constexpr explicit variant(in_place_type_t<T>, std::initializer_list<U> il,
536 Args&&... args)
537 : Base(variant_internal::EmplaceTag<
538 variant_internal::UnambiguousIndexOf<variant, T>::value>(),
539 il, absl::forward<Args>(args)...) {}
540
541 // Constructs a variant of an alternative type from a provided index,
542 // through value-initialization using the provided forwarded arguments.
543 template <std::size_t I, class... Args,
544 typename std::enable_if<std::is_constructible<
545 variant_internal::VariantAlternativeSfinaeT<I, variant>,
546 Args...>::value>::type* = nullptr>
547 constexpr explicit variant(in_place_index_t<I>, Args&&... args)
548 : Base(variant_internal::EmplaceTag<I>(), absl::forward<Args>(args)...) {}
549
550 // Constructs a variant of an alternative type from a provided index,
551 // through value-initialization of an initializer list and the provided
552 // forwarded arguments.
553 template <std::size_t I, class U, class... Args,
554 typename std::enable_if<std::is_constructible<
555 variant_internal::VariantAlternativeSfinaeT<I, variant>,
556 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
557 constexpr explicit variant(in_place_index_t<I>, std::initializer_list<U> il,
558 Args&&... args)
559 : Base(variant_internal::EmplaceTag<I>(), il,
560 absl::forward<Args>(args)...) {}
561
562 // Destructors
563
564 // Destroys the variant's currently contained value, provided that
565 // `absl::valueless_by_exception()` is false.
566 ~variant() = default;
567
568 // Assignment Operators
569
570 // Copy assignment operator
571 variant& operator=(const variant& other) = default;
572
573 // Move assignment operator
574 variant& operator=(variant&& other) /*noexcept(see above)*/ = default;
575
576 // Converting assignment operator
577 //
578 // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0608r1.html
579 // has been voted passed the design phase in the C++ standard meeting in Mar
580 // 2018. It will be implemented and integrated into `absl::variant`.
581 template <
582 class T,
583 std::size_t I = std::enable_if<
584 !std::is_same<absl::decay_t<T>, variant>::value,
585 variant_internal::IndexOfConstructedType<variant, T>>::type::value,
586 class Tj = absl::variant_alternative_t<I, variant>,
587 typename std::enable_if<std::is_assignable<Tj&, T>::value &&
588 std::is_constructible<Tj, T>::value>::type* =
589 nullptr>
590 variant& operator=(T&& t) noexcept(
591 std::is_nothrow_assignable<Tj&, T>::value&&
592 std::is_nothrow_constructible<Tj, T>::value) {
593 variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
594 variant_internal::VariantCoreAccess::MakeConversionAssignVisitor(
595 this, absl::forward<T>(t)),
596 index());
597
598 return *this;
599 }
600
601
602 // emplace() Functions
603
604 // Constructs a value of the given alternative type T within the variant.
605 //
606 // Example:
607 //
608 // absl::variant<std::vector<int>, int, std::string> v;
609 // v.emplace<int>(99);
610 // v.emplace<std::string>("abc");
611 template <
612 class T, class... Args,
613 typename std::enable_if<std::is_constructible<
614 absl::variant_alternative_t<
615 variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
616 Args...>::value>::type* = nullptr>
617 T& emplace(Args&&... args) {
618 return variant_internal::VariantCoreAccess::Replace<
619 variant_internal::UnambiguousIndexOf<variant, T>::value>(
620 this, absl::forward<Args>(args)...);
621 }
622
623 // Constructs a value of the given alternative type T within the variant using
624 // an initializer list.
625 //
626 // Example:
627 //
628 // absl::variant<std::vector<int>, int, std::string> v;
629 // v.emplace<std::vector<int>>({0, 1, 2});
630 template <
631 class T, class U, class... Args,
632 typename std::enable_if<std::is_constructible<
633 absl::variant_alternative_t<
634 variant_internal::UnambiguousIndexOf<variant, T>::value, variant>,
635 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
636 T& emplace(std::initializer_list<U> il, Args&&... args) {
637 return variant_internal::VariantCoreAccess::Replace<
638 variant_internal::UnambiguousIndexOf<variant, T>::value>(
639 this, il, absl::forward<Args>(args)...);
640 }
641
642 // Destroys the current value of the variant (provided that
643 // `absl::valueless_by_exception()` is false, and constructs a new value at
644 // the given index.
645 //
646 // Example:
647 //
648 // absl::variant<std::vector<int>, int, int> v;
649 // v.emplace<1>(99);
650 // v.emplace<2>(98);
651 // v.emplace<int>(99); // Won't compile. 'int' isn't a unique type.
652 template <std::size_t I, class... Args,
653 typename std::enable_if<
654 std::is_constructible<absl::variant_alternative_t<I, variant>,
655 Args...>::value>::type* = nullptr>
656 absl::variant_alternative_t<I, variant>& emplace(Args&&... args) {
657 return variant_internal::VariantCoreAccess::Replace<I>(
658 this, absl::forward<Args>(args)...);
659 }
660
661 // Destroys the current value of the variant (provided that
662 // `absl::valueless_by_exception()` is false, and constructs a new value at
663 // the given index using an initializer list and the provided arguments.
664 //
665 // Example:
666 //
667 // absl::variant<std::vector<int>, int, int> v;
668 // v.emplace<0>({0, 1, 2});
669 template <std::size_t I, class U, class... Args,
670 typename std::enable_if<std::is_constructible<
671 absl::variant_alternative_t<I, variant>,
672 std::initializer_list<U>&, Args...>::value>::type* = nullptr>
673 absl::variant_alternative_t<I, variant>& emplace(std::initializer_list<U> il,
674 Args&&... args) {
675 return variant_internal::VariantCoreAccess::Replace<I>(
676 this, il, absl::forward<Args>(args)...);
677 }
678
679 // variant::valueless_by_exception()
680 //
681 // Returns false if and only if the variant currently holds a valid value.
682 constexpr bool valueless_by_exception() const noexcept {
683 return this->index_ == absl::variant_npos;
684 }
685
686 // variant::index()
687 //
688 // Returns the index value of the variant's currently selected alternative
689 // type.
690 constexpr std::size_t index() const noexcept { return this->index_; }
691
692 // variant::swap()
693 //
694 // Swaps the values of two variant objects.
695 //
696 void swap(variant& rhs) noexcept(
697 absl::conjunction<
698 std::is_nothrow_move_constructible<T0>,
699 std::is_nothrow_move_constructible<Tn>...,
700 type_traits_internal::IsNothrowSwappable<T0>,
701 type_traits_internal::IsNothrowSwappable<Tn>...>::value) {
702 return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
703 variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
704 }
705};
706
707// We need a valid declaration of variant<> for SFINAE and overload resolution
708// to work properly above, but we don't need a full declaration since this type
709// will never be constructed. This declaration, though incomplete, suffices.
710template <>
711class variant<>;
712
713//------------------------------------------------------------------------------
714// Relational Operators
715//------------------------------------------------------------------------------
716//
717// If neither operand is in the `variant::valueless_by_exception` state:
718//
719// * If the index of both variants is the same, the relational operator
720// returns the result of the corresponding relational operator for the
721// corresponding alternative type.
722// * If the index of both variants is not the same, the relational operator
723// returns the result of that operation applied to the value of the left
724// operand's index and the value of the right operand's index.
725// * If at least one operand is in the valueless_by_exception state:
726// - A variant in the valueless_by_exception state is only considered equal
727// to another variant in the valueless_by_exception state.
728// - If exactly one operand is in the valueless_by_exception state, the
729// variant in the valueless_by_exception state is less than the variant
730// that is not in the valueless_by_exception state.
731//
732// Note: The value 1 is added to each index in the relational comparisons such
733// that the index corresponding to the valueless_by_exception state wraps around
734// to 0 (the lowest value for the index type), and the remaining indices stay in
735// the same relative order.
736
737// Equal-to operator
738template <typename... Types>
739constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==(
740 const variant<Types...>& a, const variant<Types...>& b) {
741 return (a.index() == b.index()) &&
742 variant_internal::VisitIndices<sizeof...(Types)>::Run(
743 variant_internal::EqualsOp<Types...>{&a, &b}, a.index());
744}
745
746// Not equal operator
747template <typename... Types>
748constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=(
749 const variant<Types...>& a, const variant<Types...>& b) {
750 return (a.index() != b.index()) ||
751 variant_internal::VisitIndices<sizeof...(Types)>::Run(
752 variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index());
753}
754
755// Less-than operator
756template <typename... Types>
757constexpr variant_internal::RequireAllHaveLessThanT<Types...> operator<(
758 const variant<Types...>& a, const variant<Types...>& b) {
759 return (a.index() != b.index())
760 ? (a.index() + 1) < (b.index() + 1)
761 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
762 variant_internal::LessThanOp<Types...>{&a, &b}, a.index());
763}
764
765// Greater-than operator
766template <typename... Types>
767constexpr variant_internal::RequireAllHaveGreaterThanT<Types...> operator>(
768 const variant<Types...>& a, const variant<Types...>& b) {
769 return (a.index() != b.index())
770 ? (a.index() + 1) > (b.index() + 1)
771 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
772 variant_internal::GreaterThanOp<Types...>{&a, &b},
773 a.index());
774}
775
776// Less-than or equal-to operator
777template <typename... Types>
778constexpr variant_internal::RequireAllHaveLessThanOrEqualT<Types...> operator<=(
779 const variant<Types...>& a, const variant<Types...>& b) {
780 return (a.index() != b.index())
781 ? (a.index() + 1) < (b.index() + 1)
782 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
783 variant_internal::LessThanOrEqualsOp<Types...>{&a, &b},
784 a.index());
785}
786
787// Greater-than or equal-to operator
788template <typename... Types>
789constexpr variant_internal::RequireAllHaveGreaterThanOrEqualT<Types...>
790operator>=(const variant<Types...>& a, const variant<Types...>& b) {
791 return (a.index() != b.index())
792 ? (a.index() + 1) > (b.index() + 1)
793 : variant_internal::VisitIndices<sizeof...(Types)>::Run(
794 variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b},
795 a.index());
796}
797
798} // namespace absl
799
800namespace std {
801
802// hash()
803template <> // NOLINT
804struct hash<absl::monostate> {
805 std::size_t operator()(absl::monostate) const { return 0; }
806};
807
808template <class... T> // NOLINT
809struct hash<absl::variant<T...>>
810 : absl::variant_internal::VariantHashBase<absl::variant<T...>, void,
811 absl::remove_const_t<T>...> {};
812
813} // namespace std
814
815#endif // ABSL_HAVE_STD_VARIANT
816
817namespace absl {
818namespace variant_internal {
819
820// Helper visitor for converting a variant<Ts...>` into another type (mostly
821// variant) that can be constructed from any type.
822template <typename To>
823struct ConversionVisitor {
824 template <typename T>
825 To operator()(T&& v) const {
826 return To(std::forward<T>(v));
827 }
828};
829
830} // namespace variant_internal
831
832// ConvertVariantTo()
833//
834// Helper functions to convert an `absl::variant` to a variant of another set of
835// types, provided that the alternative type of the new variant type can be
836// converted from any type in the source variant.
837//
838// Example:
839//
840// absl::variant<name1, name2, float> InternalReq(const Req&);
841//
842// // name1 and name2 are convertible to name
843// absl::variant<name, float> ExternalReq(const Req& req) {
844// return absl::ConvertVariantTo<absl::variant<name, float>>(
845// InternalReq(req));
846// }
847template <typename To, typename Variant>
848To ConvertVariantTo(Variant&& variant) {
849 return absl::visit(variant_internal::ConversionVisitor<To>{},
850 std::forward<Variant>(variant));
851}
852
853} // namespace absl
854
855#endif // ABSL_TYPES_VARIANT_H_
856