This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

889
cppdraft/variant/variant.md Normal file
View File

@@ -0,0 +1,889 @@
[variant.variant]
# 22 General utilities library [[utilities]](./#utilities)
## 22.6 Variants [[variant]](variant#variant)
### 22.6.3 Class template variant [variant.variant]
#### [22.6.3.1](#general) General [[variant.variant.general]](variant.variant.general)
namespace std {template<class... Types>class variant {public:// [[variant.ctor]](#variant.ctor "22.6.3.2Constructors"), constructorsconstexpr variant() noexcept(*see below*); constexpr variant(const variant&); constexpr variant(variant&&) noexcept(*see below*); template<class T>constexpr variant(T&&) noexcept(*see below*); template<class T, class... Args>constexpr explicit variant(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args>constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...); template<size_t I, class... Args>constexpr explicit variant(in_place_index_t<I>, Args&&...); template<size_t I, class U, class... Args>constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...); // [[variant.dtor]](#variant.dtor "22.6.3.3Destructor"), destructorconstexpr ~variant(); // [[variant.assign]](#variant.assign "22.6.3.4Assignment"), assignmentconstexpr variant& operator=(const variant&); constexpr variant& operator=(variant&&) noexcept(*see below*); template<class T> constexpr variant& operator=(T&&) noexcept(*see below*); // [[variant.mod]](#variant.mod "22.6.3.5Modifiers"), modifierstemplate<class T, class... Args>constexpr T& emplace(Args&&...); template<class T, class U, class... Args>constexpr T& emplace(initializer_list<U>, Args&&...); template<size_t I, class... Args>constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...); template<size_t I, class U, class... Args>constexpr variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...); // [[variant.status]](#variant.status "22.6.3.6Value status"), value statusconstexpr bool valueless_by_exception() const noexcept; constexpr size_t index() const noexcept; // [[variant.swap]](#variant.swap "22.6.3.7Swap"), swapconstexpr void swap(variant&) noexcept(*see below*); // [[variant.visit]](variant.visit "22.6.7Visitation"), visitationtemplate<class Self, class Visitor>constexpr decltype(auto) visit(this Self&&, Visitor&&); template<class R, class Self, class Visitor>constexpr R visit(this Self&&, Visitor&&); };}
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5722)
Any instance of variant at any given time either holds a value
of one of its alternative types or holds no value[.](#general-1.sentence-1)
When an instance of variant holds a value of alternative type T,
it means that a value of type T, referred to as the variant object's [*contained value*](#def:contained_value,variant "22.6.3.1General[variant.variant.general]"),
is nested within ([[intro.object]](intro.object "6.8.2Object model")) thevariant object[.](#general-1.sentence-2)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5731)
All types in Types shall meet
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#general-2.sentence-1)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5735)
A program that instantiates the definition of variant with
no template arguments is ill-formed[.](#general-3.sentence-1)
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5739)
If a program declares an explicit or partial specialization of variant,
the program is ill-formed, no diagnostic required[.](#general-4.sentence-1)
#### [22.6.3.2](#variant.ctor) Constructors [[variant.ctor]](variant.ctor)
[1](#variant.ctor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5745)
In the descriptions that follow, let i be in the range [0, sizeof...(Types)),
and Ti be the ith type in Types[.](#variant.ctor-1.sentence-1)
[🔗](#lib:variant,constructor)
`constexpr variant() noexcept(see below);
`
[2](#variant.ctor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5755)
*Constraints*: is_default_constructible_v<T0> is true[.](#variant.ctor-2.sentence-1)
[3](#variant.ctor-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5759)
*Effects*: Constructs a variant holding a value-initialized value of type T0[.](#variant.ctor-3.sentence-1)
[4](#variant.ctor-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5763)
*Postconditions*: valueless_by_exception() is false and index() is 0[.](#variant.ctor-4.sentence-1)
[5](#variant.ctor-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5767)
*Throws*: Any exception thrown by the value-initialization of T0[.](#variant.ctor-5.sentence-1)
[6](#variant.ctor-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5771)
*Remarks*: This function is constexpr if and only if the
value-initialization of the alternative type T0 would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6The constexpr and consteval specifiers"))[.](#variant.ctor-6.sentence-1)
The exception specification is equivalent tois_nothrow_default_constructible_v<T0>[.](#variant.ctor-6.sentence-2)
[*Note [1](#variant.ctor-note-1)*:
See also class monostate[.](#variant.ctor-6.sentence-3)
— *end note*]
[🔗](#lib:variant,constructor_)
`constexpr variant(const variant& w);
`
[7](#variant.ctor-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5789)
*Effects*: If w holds a value, initializes the variant to hold the same
alternative as w and direct-initializes the contained value
with *GET*<j>(w), where j is w.index()[.](#variant.ctor-7.sentence-1)
Otherwise, initializes the variant to not hold a value[.](#variant.ctor-7.sentence-2)
[8](#variant.ctor-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5796)
*Throws*: Any exception thrown by direct-initializing any Ti for all i[.](#variant.ctor-8.sentence-1)
[9](#variant.ctor-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5800)
*Remarks*: This constructor is defined as deleted unlessis_copy_constructible_v<Ti> is true for all i[.](#variant.ctor-9.sentence-1)
If is_trivially_copy_constructible_v<Ti> is true for all i, this constructor is trivial[.](#variant.ctor-9.sentence-2)
[🔗](#lib:variant,constructor__)
`constexpr variant(variant&& w) noexcept(see below);
`
[10](#variant.ctor-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5814)
*Constraints*: is_move_constructible_v<Ti> is true for all i[.](#variant.ctor-10.sentence-1)
[11](#variant.ctor-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5818)
*Effects*: If w holds a value, initializes the variant to hold the same
alternative as w and direct-initializes the contained value with*GET*<j>(std::move(w)), where j is w.index()[.](#variant.ctor-11.sentence-1)
Otherwise, initializes the variant to not hold a value[.](#variant.ctor-11.sentence-2)
[12](#variant.ctor-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5825)
*Throws*: Any exception thrown by move-constructing any Ti for all i[.](#variant.ctor-12.sentence-1)
[13](#variant.ctor-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5829)
*Remarks*: The exception specification is equivalent to the logical and ofis_nothrow_move_constructible_v<Ti> for all i[.](#variant.ctor-13.sentence-1)
If is_trivially_move_constructible_v<Ti> is true for all i, this constructor is trivial[.](#variant.ctor-13.sentence-2)
[🔗](#lib:variant,constructor___)
`template<class T> constexpr variant(T&& t) noexcept(see below);
`
[14](#variant.ctor-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5843)
Let Tj be a type that is determined as follows:
build an imaginary function *FUN*(Ti) for each alternative type Ti for which Ti x[] = {std::forward<T>(t)}; is well-formed for some invented variable x[.](#variant.ctor-14.sentence-1)
The overload *FUN*(Tj) selected by overload
resolution for the expression *FUN*(std::forward<T>(t)) defines
the alternative Tj which is the type of the contained value after
construction[.](#variant.ctor-14.sentence-2)
[15](#variant.ctor-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5854)
*Constraints*:
- [(15.1)](#variant.ctor-15.1)
sizeof...(Types) is nonzero,
- [(15.2)](#variant.ctor-15.2)
is_same_v<remove_cvref_t<T>, variant> is false,
- [(15.3)](#variant.ctor-15.3)
remove_cvref_t<T> is neither
a specialization of in_place_type_t nor
a specialization of in_place_index_t,
- [(15.4)](#variant.ctor-15.4)
is_constructible_v<Tj, T> is true, and
- [(15.5)](#variant.ctor-15.5)
the expression *FUN*(std::forward<T>(t)) (with *FUN* being the above-mentioned set of
imaginary functions) is well-formed[.](#variant.ctor-15.sentence-1)
[*Note [2](#variant.ctor-note-2)*:
variant<string, string> v("abc"); is ill-formed, as both alternative types have an equally viable constructor
for the argument[.](#variant.ctor-15.5.sentence-2)
— *end note*]
[16](#variant.ctor-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5884)
*Effects*: Initializes *this to hold the alternative type Tj and
direct-non-list-initializes the contained value with std::forward<T>(t)[.](#variant.ctor-16.sentence-1)
[17](#variant.ctor-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5889)
*Postconditions*: holds_alternative<Tj>(*this) is true[.](#variant.ctor-17.sentence-1)
[18](#variant.ctor-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5893)
*Throws*: Any exception thrown by the initialization of the selected alternative Tj[.](#variant.ctor-18.sentence-1)
[19](#variant.ctor-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5897)
*Remarks*: The exception specification is equivalent tois_nothrow_constructible_v<Tj, T>[.](#variant.ctor-19.sentence-1)
If Tj's selected constructor is a constexpr constructor,
this constructor is a constexpr constructor[.](#variant.ctor-19.sentence-2)
[🔗](#lib:variant,constructor____)
`template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
`
[20](#variant.ctor-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5911)
*Constraints*:
- [(20.1)](#variant.ctor-20.1)
There is exactly one occurrence of T in Types... and
- [(20.2)](#variant.ctor-20.2)
is_constructible_v<T, Args...> is true[.](#variant.ctor-20.sentence-1)
[21](#variant.ctor-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5918)
*Effects*: Direct-non-list-initializes the contained value of type T with std::forward<Args>(args)...[.](#variant.ctor-21.sentence-1)
[22](#variant.ctor-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5923)
*Postconditions*: holds_alternative<T>(*this) is true[.](#variant.ctor-22.sentence-1)
[23](#variant.ctor-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5927)
*Throws*: Any exception thrown by calling the selected constructor of T[.](#variant.ctor-23.sentence-1)
[24](#variant.ctor-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5931)
*Remarks*: If T's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#variant.ctor-24.sentence-1)
[🔗](#lib:variant,constructor_____)
`template<class T, class U, class... Args>
constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
`
[25](#variant.ctor-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5944)
*Constraints*:
- [(25.1)](#variant.ctor-25.1)
There is exactly one occurrence of T in Types... and
- [(25.2)](#variant.ctor-25.2)
is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#variant.ctor-25.sentence-1)
[26](#variant.ctor-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5951)
*Effects*: Direct-non-list-initializes the contained value of type T with il, std::forward<Args>(args)...[.](#variant.ctor-26.sentence-1)
[27](#variant.ctor-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5956)
*Postconditions*: holds_alternative<T>(*this) is true[.](#variant.ctor-27.sentence-1)
[28](#variant.ctor-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5960)
*Throws*: Any exception thrown by calling the selected constructor of T[.](#variant.ctor-28.sentence-1)
[29](#variant.ctor-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5964)
*Remarks*: If T's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#variant.ctor-29.sentence-1)
[🔗](#lib:variant,constructor______)
`template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
`
[30](#variant.ctor-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5976)
*Constraints*:
- [(30.1)](#variant.ctor-30.1)
I is less than sizeof...(Types) and
- [(30.2)](#variant.ctor-30.2)
is_constructible_v<TI, Args...> is true[.](#variant.ctor-30.sentence-1)
[31](#variant.ctor-31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5985)
*Effects*: Direct-non-list-initializes the contained value of type TI with std::forward<Args>(args)...[.](#variant.ctor-31.sentence-1)
[32](#variant.ctor-32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5990)
*Postconditions*: index() is I[.](#variant.ctor-32.sentence-1)
[33](#variant.ctor-33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5994)
*Throws*: Any exception thrown by calling the selected constructor of TI[.](#variant.ctor-33.sentence-1)
[34](#variant.ctor-34)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5998)
*Remarks*: If TI's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#variant.ctor-34.sentence-1)
[🔗](#lib:variant,constructor_______)
`template<size_t I, class U, class... Args>
constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
`
[35](#variant.ctor-35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6011)
*Constraints*:
- [(35.1)](#variant.ctor-35.1)
I is less than sizeof...(Types) and
- [(35.2)](#variant.ctor-35.2)
is_constructible_v<TI, initializer_list<U>&, Args...> is true[.](#variant.ctor-35.sentence-1)
[36](#variant.ctor-36)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6020)
*Effects*: Direct-non-list-initializes the contained value of type TI with il, std::forward<Args>(args)...[.](#variant.ctor-36.sentence-1)
[37](#variant.ctor-37)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6025)
*Postconditions*: index() is I[.](#variant.ctor-37.sentence-1)
[38](#variant.ctor-38)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6029)
*Remarks*: If TI's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#variant.ctor-38.sentence-1)
#### [22.6.3.3](#variant.dtor) Destructor [[variant.dtor]](variant.dtor)
[🔗](#lib:variant,destructor)
`constexpr ~variant();
`
[1](#variant.dtor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6043)
*Effects*: If valueless_by_exception() is false,
destroys the currently contained value[.](#variant.dtor-1.sentence-1)
[2](#variant.dtor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6048)
*Remarks*: If is_trivially_destructible_v<Ti> is true for all Ti,
then this destructor is trivial[.](#variant.dtor-2.sentence-1)
#### [22.6.3.4](#variant.assign) Assignment [[variant.assign]](variant.assign)
[🔗](#lib:operator=,variant)
`constexpr variant& operator=(const variant& rhs);
`
[1](#variant.assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6062)
Let j be rhs.index()[.](#variant.assign-1.sentence-1)
[2](#variant.assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6065)
*Effects*:
- [(2.1)](#variant.assign-2.1)
If neither *this nor rhs holds a value, there is no effect[.](#variant.assign-2.1.sentence-1)
- [(2.2)](#variant.assign-2.2)
Otherwise, if *this holds a value but rhs does not, destroys the value
contained in *this and sets *this to not hold a value[.](#variant.assign-2.2.sentence-1)
- [(2.3)](#variant.assign-2.3)
Otherwise, if index() == j, assigns the value contained in rhs to the value contained in *this[.](#variant.assign-2.3.sentence-1)
- [(2.4)](#variant.assign-2.4)
Otherwise, if either is_nothrow_copy_constructible_v<Tj> is true oris_nothrow_move_constructible_v<Tj> is false,
equivalent to emplace<j>(*GET*<j>(rhs))[.](#variant.assign-2.4.sentence-1)
- [(2.5)](#variant.assign-2.5)
Otherwise, equivalent to operator=(variant(rhs))[.](#variant.assign-2.5.sentence-1)
[3](#variant.assign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6085)
*Postconditions*: index() == rhs.index()[.](#variant.assign-3.sentence-1)
[4](#variant.assign-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6089)
*Returns*: *this[.](#variant.assign-4.sentence-1)
[5](#variant.assign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6093)
*Remarks*: This operator is defined as deleted unlessis_copy_constructible_v<Ti> &&is_copy_assignable_v<Ti> is true for all i[.](#variant.assign-5.sentence-1)
If is_trivially_copy_constructible_v<Ti> &&is_trivially_copy_assignable_v<Ti> &&is_trivially_destructible_v<Ti> is true for all i, this assignment operator is trivial[.](#variant.assign-5.sentence-2)
[🔗](#lib:operator=,variant_)
`constexpr variant& operator=(variant&& rhs) noexcept(see below);
`
[6](#variant.assign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6111)
Let j be rhs.index()[.](#variant.assign-6.sentence-1)
[7](#variant.assign-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6114)
*Constraints*: is_move_constructible_v<Ti> &&is_move_assignable_v<Ti> istrue for all i[.](#variant.assign-7.sentence-1)
[8](#variant.assign-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6120)
*Effects*:
- [(8.1)](#variant.assign-8.1)
If neither *this nor rhs holds a value, there is no effect[.](#variant.assign-8.1.sentence-1)
- [(8.2)](#variant.assign-8.2)
Otherwise, if *this holds a value but rhs does not, destroys the value
contained in *this and sets *this to not hold a value[.](#variant.assign-8.2.sentence-1)
- [(8.3)](#variant.assign-8.3)
Otherwise, if index() == j, assigns *GET*<j>(std::move(rhs)) to
the value contained in *this[.](#variant.assign-8.3.sentence-1)
- [(8.4)](#variant.assign-8.4)
Otherwise, equivalent to emplace<j>(*GET*<j>(std::move(rhs)))[.](#variant.assign-8.4.sentence-1)
[9](#variant.assign-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6135)
*Returns*: *this[.](#variant.assign-9.sentence-1)
[10](#variant.assign-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6139)
*Remarks*: If is_trivially_move_constructible_v<Ti> &&is_trivially_move_assignable_v<Ti> &&is_trivially_destructible_v<Ti> is true for all i, this assignment operator is trivial[.](#variant.assign-10.sentence-1)
The exception specification is equivalent tois_nothrow_move_constructible_v<Ti> && is_nothrow_move_assignable_v<Ti> for all i[.](#variant.assign-10.sentence-2)
- [(10.1)](#variant.assign-10.1)
If an exception is thrown during the call to Tj's move construction
(with j being rhs.index()), the variant will hold no value[.](#variant.assign-10.1.sentence-1)
- [(10.2)](#variant.assign-10.2)
If an exception is thrown during the call to Tj's move assignment,
the state of the contained value is as defined by the exception safety
guarantee of Tj's move assignment; index() will be j[.](#variant.assign-10.2.sentence-1)
[🔗](#lib:operator=,variant__)
`template<class T> constexpr variant& operator=(T&& t) noexcept(see below);
`
[11](#variant.assign-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6162)
Let Tj be a type that is determined as follows:
build an imaginary function *FUN*(Ti) for each alternative type Ti for which Ti x[] = {std::forward<T>(t)}; is well-formed for some invented variable x[.](#variant.assign-11.sentence-1)
The overload *FUN*(Tj) selected by overload
resolution for the expression *FUN*(std::forward<T>(t)) defines
the alternative Tj which is the type of the contained value after
assignment[.](#variant.assign-11.sentence-2)
[12](#variant.assign-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6173)
*Constraints*:
- [(12.1)](#variant.assign-12.1)
is_same_v<remove_cvref_t<T>, variant> is false,
- [(12.2)](#variant.assign-12.2)
is_assignable_v<Tj&, T> && is_constructible_v<Tj, T> is true, and
- [(12.3)](#variant.assign-12.3)
the expression *FUN*(std::forward<T>(t)) (with *FUN* being the above-mentioned set
of imaginary functions) is well-formed[.](#variant.assign-12.sentence-1)
[*Note [1](#variant.assign-note-1)*:
variant<string, string> v;
v = "abc"; is ill-formed, as both alternative types have an equally viable constructor
for the argument[.](#variant.assign-12.3.sentence-2)
— *end note*]
[13](#variant.assign-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6197)
*Effects*:
- [(13.1)](#variant.assign-13.1)
If *this holds a Tj, assigns std::forward<T>(t) to
the value contained in *this[.](#variant.assign-13.1.sentence-1)
- [(13.2)](#variant.assign-13.2)
Otherwise, if is_nothrow_constructible_v<Tj, T> ||!is_nothrow_move_constructible_v<Tj> is true,
equivalent to emplace<j>(std::forward<T>(t))[.](#variant.assign-13.2.sentence-1)
- [(13.3)](#variant.assign-13.3)
Otherwise, equivalent to emplace<j>(Tj(std::forward<T>(t)))[.](#variant.assign-13.3.sentence-1)
[14](#variant.assign-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6211)
*Postconditions*: holds_alternative<Tj>(*this) is true, with Tj selected by the imaginary function overload resolution described above[.](#variant.assign-14.sentence-1)
[15](#variant.assign-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6216)
*Returns*: *this[.](#variant.assign-15.sentence-1)
[16](#variant.assign-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6220)
*Remarks*: The exception specification is equivalent to:is_nothrow_assignable_v<Tj&, T> && is_nothrow_constructible_v<Tj, T>
- [(16.1)](#variant.assign-16.1)
If an exception is thrown during the assignment of std::forward<T>(t) to the value contained in *this, the state of the contained value andt are as defined by the exception safety guarantee of the assignment
expression; valueless_by_exception() will be false[.](#variant.assign-16.1.sentence-1)
- [(16.2)](#variant.assign-16.2)
If an exception is thrown during the initialization of the contained value,
the variant object is permitted to not hold a value[.](#variant.assign-16.2.sentence-1)
#### [22.6.3.5](#variant.mod) Modifiers [[variant.mod]](variant.mod)
[🔗](#lib:emplace,variant)
`template<class T, class... Args> constexpr T& emplace(Args&&... args);
`
[1](#variant.mod-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6244)
*Constraints*: is_constructible_v<T, Args...> is true, andT occurs exactly once in Types[.](#variant.mod-1.sentence-1)
[2](#variant.mod-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6249)
*Effects*: Equivalent to:return emplace<I>(std::forward<Args>(args)...); where I is the zero-based index of T in Types[.](#variant.mod-2.sentence-1)
[🔗](#lib:emplace,variant_)
`template<class T, class U, class... Args>
constexpr T& emplace(initializer_list<U> il, Args&&... args);
`
[3](#variant.mod-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6265)
*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true,
and T occurs exactly once in Types[.](#variant.mod-3.sentence-1)
[4](#variant.mod-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6270)
*Effects*: Equivalent to:return emplace<I>(il, std::forward<Args>(args)...); where I is the zero-based index of T in Types[.](#variant.mod-4.sentence-1)
[🔗](#lib:emplace,variant__)
`template<size_t I, class... Args>
constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
`
[5](#variant.mod-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6286)
*Mandates*: I < sizeof...(Types)[.](#variant.mod-5.sentence-1)
[6](#variant.mod-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6290)
*Constraints*: is_constructible_v<TI, Args...> is true[.](#variant.mod-6.sentence-1)
[7](#variant.mod-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6294)
*Effects*: Destroys the currently contained value if valueless_by_exception() is false[.](#variant.mod-7.sentence-1)
Then direct-non-list-initializes the contained value of type TI with the arguments std::forward<Args>(args)...[.](#variant.mod-7.sentence-2)
[8](#variant.mod-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6301)
*Postconditions*: index() is I[.](#variant.mod-8.sentence-1)
[9](#variant.mod-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6305)
*Returns*: A reference to the new contained value[.](#variant.mod-9.sentence-1)
[10](#variant.mod-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6309)
*Throws*: Any exception thrown during the initialization of the contained value[.](#variant.mod-10.sentence-1)
[11](#variant.mod-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6313)
*Remarks*: If an exception is thrown during the initialization of the contained value,
the variant is permitted to not hold a value[.](#variant.mod-11.sentence-1)
[🔗](#lib:emplace,variant___)
`template<size_t I, class U, class... Args>
constexpr variant_alternative_t<I, variant<Types...>>&
emplace(initializer_list<U> il, Args&&... args);
`
[12](#variant.mod-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6327)
*Mandates*: I < sizeof...(Types)[.](#variant.mod-12.sentence-1)
[13](#variant.mod-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6331)
*Constraints*: is_constructible_v<TI, initializer_list<U>&, Args...> is true[.](#variant.mod-13.sentence-1)
[14](#variant.mod-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6335)
*Effects*: Destroys the currently contained value if valueless_by_exception() is false[.](#variant.mod-14.sentence-1)
Then direct-non-list-initializes the contained value of type TI with il, std::forward<Args>(args)...[.](#variant.mod-14.sentence-2)
[15](#variant.mod-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6342)
*Postconditions*: index() is I[.](#variant.mod-15.sentence-1)
[16](#variant.mod-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6346)
*Returns*: A reference to the new contained value[.](#variant.mod-16.sentence-1)
[17](#variant.mod-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6350)
*Throws*: Any exception thrown during the initialization of the contained value[.](#variant.mod-17.sentence-1)
[18](#variant.mod-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6354)
*Remarks*: If an exception is thrown during the initialization of the contained value,
the variant is permitted to not hold a value[.](#variant.mod-18.sentence-1)
#### [22.6.3.6](#variant.status) Value status [[variant.status]](variant.status)
[🔗](#lib:valueless_by_exception,variant)
`constexpr bool valueless_by_exception() const noexcept;
`
[1](#variant.status-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6368)
*Effects*: Returns false if and only if the variant holds a value[.](#variant.status-1.sentence-1)
[2](#variant.status-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6372)
[*Note [1](#variant.status-note-1)*:
It is possible for a variant to hold no value
if an exception is thrown during a
type-changing assignment or emplacement[.](#variant.status-2.sentence-1)
The latter means that even avariant<float, int> can become valueless_by_exception(), for
instance bystruct S { operator int() { throw 42; }};
variant<float, int> v{12.f};
v.emplace<1>(S());
— *end note*]
[🔗](#lib:index,variant)
`constexpr size_t index() const noexcept;
`
[3](#variant.status-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6393)
*Effects*: If valueless_by_exception() is true, returns variant_npos[.](#variant.status-3.sentence-1)
Otherwise, returns the zero-based index of the alternative of the contained value[.](#variant.status-3.sentence-2)
#### [22.6.3.7](#variant.swap) Swap [[variant.swap]](variant.swap)
[🔗](#lib:swap,variant)
`constexpr void swap(variant& rhs) noexcept(see below);
`
[1](#variant.swap-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6407)
*Mandates*: is_move_constructible_v<Ti> is true for all i[.](#variant.swap-1.sentence-1)
[2](#variant.swap-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6411)
*Preconditions*: Each Ti meets the [*Cpp17Swappable*](swappable.requirements#:Cpp17Swappable "16.4.4.3Swappable requirements[swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3Swappable requirements"))[.](#variant.swap-2.sentence-1)
[3](#variant.swap-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6415)
*Effects*:
- [(3.1)](#variant.swap-3.1)
If valueless_by_exception() && rhs.valueless_by_exception() no effect[.](#variant.swap-3.1.sentence-1)
- [(3.2)](#variant.swap-3.2)
Otherwise, if index() == rhs.index(), calls swap(*GET*<i>(*this), *GET*<i>(rhs)) where i is index()[.](#variant.swap-3.2.sentence-1)
- [(3.3)](#variant.swap-3.3)
Otherwise, exchanges values of rhs and *this[.](#variant.swap-3.3.sentence-1)
[4](#variant.swap-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6426)
*Throws*: If index() == rhs.index(),
any exception thrown by swap(*GET*<i>(*this), *GET*<i>(rhs)) with i being index()[.](#variant.swap-4.sentence-1)
Otherwise, any exception thrown by the move constructor
of Ti or Tj with i being index() and j being rhs.index()[.](#variant.swap-4.sentence-2)
[5](#variant.swap-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6435)
*Remarks*: If an exception is thrown during the call to function swap(*GET*<i>(*this), *GET*<i>(rhs)),
the states of the contained values of *this and of rhs are
determined by the exception safety guarantee of swap for lvalues ofTi with i being index()[.](#variant.swap-5.sentence-1)
If an exception is thrown during the exchange of the values of *this and rhs, the states of the values of *this and of rhs are determined by the exception safety guarantee of variant's move constructor[.](#variant.swap-5.sentence-2)
The exception specification is equivalent to the logical and ofis_nothrow_move_constructible_v<Ti> && is_nothrow_swappable_v<Ti> for all i[.](#variant.swap-5.sentence-3)