From Jason Turner

[variant.variant]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpq_16yexh/{from.md → to.md} +58 -59
tmp/tmpq_16yexh/{from.md → to.md} RENAMED
@@ -1,7 +1,9 @@
1
  ### Class template `variant` <a id="variant.variant">[[variant.variant]]</a>
2
 
 
 
3
  ``` cpp
4
  namespace std {
5
  template<class... Types>
6
  class variant {
7
  public:
@@ -22,47 +24,46 @@ namespace std {
22
  constexpr explicit variant(in_place_index_t<I>, Args&&...);
23
  template<size_t I, class U, class... Args>
24
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);
25
 
26
  // [variant.dtor], destructor
27
- ~variant();
28
 
29
  // [variant.assign], assignment
30
  constexpr variant& operator=(const variant&);
31
  constexpr variant& operator=(variant&&) noexcept(see below);
32
 
33
- template<class T> variant& operator=(T&&) noexcept(see below);
34
 
35
  // [variant.mod], modifiers
36
  template<class T, class... Args>
37
- T& emplace(Args&&...);
38
  template<class T, class U, class... Args>
39
- T& emplace(initializer_list<U>, Args&&...);
40
  template<size_t I, class... Args>
41
- variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
42
  template<size_t I, class U, class... Args>
43
- variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...);
 
44
 
45
  // [variant.status], value status
46
  constexpr bool valueless_by_exception() const noexcept;
47
  constexpr size_t index() const noexcept;
48
 
49
  // [variant.swap], swap
50
- void swap(variant&) noexcept(see below);
51
  };
52
  }
53
  ```
54
 
55
  Any instance of `variant` at any given time either holds a value of one
56
  of its alternative types or holds no value. When an instance of
57
  `variant` holds a value of alternative type `T`, it means that a value
58
  of type `T`, referred to as the `variant` object’s *contained value*, is
59
  allocated within the storage of the `variant` object. Implementations
60
  are not permitted to use additional storage, such as dynamic memory, to
61
- allocate the contained value. The contained value shall be allocated in
62
- a region of the `variant` storage suitably aligned for all types in
63
- `Types`.
64
 
65
  All types in `Types` shall meet the *Cpp17Destructible* requirements (
66
  [[cpp17.destructible]]).
67
 
68
  A program that instantiates the definition of `variant` with no template
@@ -85,13 +86,13 @@ type `T₀`.
85
  *Ensures:* `valueless_by_exception()` is `false` and `index()` is `0`.
86
 
87
  *Throws:* Any exception thrown by the value-initialization of `T₀`.
88
 
89
  *Remarks:* This function is `constexpr` if and only if the
90
- value-initialization of the alternative type `T₀` would satisfy the
91
- requirements for a constexpr function. The expression inside `noexcept`
92
- is equivalent to `is_nothrow_default_constructible_v<``T₀``>`.
93
 
94
  [*Note 1*: See also class `monostate`. — *end note*]
95
 
96
  ``` cpp
97
  constexpr variant(const variant& w);
@@ -121,12 +122,12 @@ same alternative as `w` and direct-initializes the contained value with
121
  `get<j>(std::move(w))`, where `j` is `w.index()`. Otherwise, initializes
122
  the `variant` to not hold a value.
123
 
124
  *Throws:* Any exception thrown by move-constructing any `Tᵢ` for all i.
125
 
126
- *Remarks:* The expression inside `noexcept` is equivalent to the logical
127
- of `is_nothrow_move_constructible_v<``Tᵢ``>` for all i. If
128
  `is_trivially_move_constructible_v<``Tᵢ``>` is `true` for all i, this
129
  constructor is trivial.
130
 
131
  ``` cpp
132
  template<class T> constexpr variant(T&& t) noexcept(see below);
@@ -154,19 +155,19 @@ which is the type of the contained value after construction.
154
  is ill-formed, as both alternative types have an equally viable
155
  constructor for the argument.
156
  — *end note*]
157
 
158
  *Effects:* Initializes `*this` to hold the alternative type `Tⱼ` and
159
- direct-initializes the contained value as if
160
- direct-non-list-initializing it with `std::forward<T>(t)`.
161
 
162
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`.
163
 
164
  *Throws:* Any exception thrown by the initialization of the selected
165
  alternative `Tⱼ`.
166
 
167
- *Remarks:* The expression inside `noexcept` is equivalent to
168
  `is_nothrow_constructible_v<``Tⱼ``, T>`. If `Tⱼ`’s selected constructor
169
  is a constexpr constructor, this constructor is a constexpr constructor.
170
 
171
  ``` cpp
172
  template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
@@ -175,13 +176,12 @@ template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>,
175
  *Constraints:*
176
 
177
  - There is exactly one occurrence of `T` in `Types...` and
178
  - `is_constructible_v<T, Args...>` is `true`.
179
 
180
- *Effects:* Initializes the contained value as if
181
- direct-non-list-initializing an object of type `T` with the arguments
182
- `std::forward<Args>(args)...`.
183
 
184
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
185
 
186
  *Throws:* Any exception thrown by calling the selected constructor of
187
  `T`.
@@ -197,13 +197,12 @@ template<class T, class U, class... Args>
197
  *Constraints:*
198
 
199
  - There is exactly one occurrence of `T` in `Types...` and
200
  - `is_constructible_v<T, initializer_list<U>&, Args...>` is `true`.
201
 
202
- *Effects:* Initializes the contained value as if
203
- direct-non-list-initializing an object of type `T` with the arguments
204
- `il, std::forward<Args>(args)...`.
205
 
206
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
207
 
208
  *Throws:* Any exception thrown by calling the selected constructor of
209
  `T`.
@@ -218,13 +217,12 @@ template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>
218
  *Constraints:*
219
 
220
  - `I` is less than `sizeof...(Types)` and
221
  - `is_constructible_v<``T_I``, Args...>` is `true`.
222
 
223
- *Effects:* Initializes the contained value as if
224
- direct-non-list-initializing an object of type `T_I` with the arguments
225
- `std::forward<Args>(args)...`.
226
 
227
  *Ensures:* `index()` is `I`.
228
 
229
  *Throws:* Any exception thrown by calling the selected constructor of
230
  `T_I`.
@@ -241,23 +239,22 @@ template<size_t I, class U, class... Args>
241
 
242
  - `I` is less than `sizeof...(Types)` and
243
  - `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is
244
  `true`.
245
 
246
- *Effects:* Initializes the contained value as if
247
- direct-non-list-initializing an object of type `T_I` with the arguments
248
- `il, std::forward<Args>(args)...`.
249
 
250
  *Ensures:* `index()` is `I`.
251
 
252
  *Remarks:* If `T_I`’s selected constructor is a constexpr constructor,
253
  this constructor is a constexpr constructor.
254
 
255
  #### Destructor <a id="variant.dtor">[[variant.dtor]]</a>
256
 
257
  ``` cpp
258
- ~variant();
259
  ```
260
 
261
  *Effects:* If `valueless_by_exception()` is `false`, destroys the
262
  currently contained value.
263
 
@@ -282,14 +279,14 @@ Let j be `rhs.index()`.
282
  - Otherwise, if either `is_nothrow_copy_constructible_v<``Tⱼ``>` is
283
  `true` or `is_nothrow_move_constructible_v<``Tⱼ``>` is `false`,
284
  equivalent to `emplace<`j`>(get<`j`>(rhs))`.
285
  - Otherwise, equivalent to `operator=(variant(rhs))`.
286
 
287
- *Returns:* `*this`.
288
-
289
  *Ensures:* `index() == rhs.index()`.
290
 
 
 
291
  *Remarks:* This operator is defined as deleted unless
292
  `is_copy_constructible_v<``Tᵢ``> &&` `is_copy_assignable_v<``Tᵢ``>` is
293
  `true` for all i. If `is_trivially_copy_constructible_v<``Tᵢ``> &&`
294
  `is_trivially_copy_assignable_v<``Tᵢ``> &&`
295
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
@@ -316,23 +313,23 @@ Let j be `rhs.index()`.
316
  *Returns:* `*this`.
317
 
318
  *Remarks:* If `is_trivially_move_constructible_v<``Tᵢ``> &&`
319
  `is_trivially_move_assignable_v<``Tᵢ``> &&`
320
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
321
- assignment operator is trivial. The expression inside `noexcept` is
322
- equivalent to:
323
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_move_assignable_v<``Tᵢ``>`
324
  for all i.
325
 
326
  - If an exception is thrown during the call to `Tⱼ`’s move construction
327
  (with j being `rhs.index()`), the `variant` will hold no value.
328
  - If an exception is thrown during the call to `Tⱼ`’s move assignment,
329
  the state of the contained value is as defined by the exception safety
330
  guarantee of `Tⱼ`’s move assignment; `index()` will be j.
331
 
332
  ``` cpp
333
- template<class T> variant& operator=(T&& t) noexcept(see below);
334
  ```
335
 
336
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
337
  function *FUN*(Tᵢ) for each alternative type `Tᵢ` for which `Tᵢ`` x[] =`
338
  `{std::forward<T>(t)};` is well-formed for some invented variable `x`.
@@ -360,18 +357,18 @@ which is the type of the contained value after assignment.
360
  - If `*this` holds a `Tⱼ`, assigns `std::forward<T>(t)` to the value
361
  contained in `*this`.
362
  - Otherwise, if `is_nothrow_constructible_v<``Tⱼ``, T> ||`
363
  `!is_nothrow_move_constructible_v<``Tⱼ``>` is `true`, equivalent to
364
  `emplace<`j`>(std::forward<T>(t))`.
365
- - Otherwise, equivalent to `operator=(variant(std::forward<T>(t)))`.
366
 
367
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`, with `Tⱼ`
368
  selected by the imaginary function overload resolution described above.
369
 
370
  *Returns:* `*this`.
371
 
372
- *Remarks:* The expression inside `noexcept` is equivalent to:
373
 
374
  ``` cpp
375
  is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
376
  ```
377
 
@@ -379,16 +376,16 @@ is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
379
  `std::forward<T>(t)` to the value contained in `*this`, the state of
380
  the contained value and `t` are as defined by the exception safety
381
  guarantee of the assignment expression; `valueless_by_exception()`
382
  will be `false`.
383
  - If an exception is thrown during the initialization of the contained
384
- value, the `variant` object might not hold a value.
385
 
386
  #### Modifiers <a id="variant.mod">[[variant.mod]]</a>
387
 
388
  ``` cpp
389
- template<class T, class... Args> T& emplace(Args&&... args);
390
  ```
391
 
392
  *Constraints:* `is_constructible_v<T, Args...>` is `true`, and `T`
393
  occurs exactly once in `Types`.
394
 
@@ -399,11 +396,12 @@ return emplace<I>(std::forward<Args>(args)...);
399
  ```
400
 
401
  where I is the zero-based index of `T` in `Types`.
402
 
403
  ``` cpp
404
- template<class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
 
405
  ```
406
 
407
  *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
408
  `true`, and `T` occurs exactly once in `Types`.
409
 
@@ -415,56 +413,57 @@ return emplace<I>(il, std::forward<Args>(args)...);
415
 
416
  where I is the zero-based index of `T` in `Types`.
417
 
418
  ``` cpp
419
  template<size_t I, class... Args>
420
- variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
421
  ```
422
 
423
  *Mandates:* `I` < `sizeof...(Types)`.
424
 
425
  *Constraints:* `is_constructible_v<``T_I``, Args...>` is `true`.
426
 
427
  *Effects:* Destroys the currently contained value if
428
- `valueless_by_exception()` is `false`. Then initializes the contained
429
- value as if direct-non-list-initializing a value of type `T_I` with the
430
- arguments `std::forward<Args>(args)...`.
431
 
432
  *Ensures:* `index()` is `I`.
433
 
434
  *Returns:* A reference to the new contained value.
435
 
436
  *Throws:* Any exception thrown during the initialization of the
437
  contained value.
438
 
439
  *Remarks:* If an exception is thrown during the initialization of the
440
- contained value, the `variant` might not hold a value.
441
 
442
  ``` cpp
443
  template<size_t I, class U, class... Args>
444
- variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
 
445
  ```
446
 
447
  *Mandates:* `I` < `sizeof...(Types)`.
448
 
449
  *Constraints:*
450
  `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is `true`.
451
 
452
  *Effects:* Destroys the currently contained value if
453
- `valueless_by_exception()` is `false`. Then initializes the contained
454
- value as if direct-non-list-initializing a value of type `T_I` with the
455
- arguments `il, std::forward<Args>(args)...`.
456
 
457
  *Ensures:* `index()` is `I`.
458
 
459
  *Returns:* A reference to the new contained value.
460
 
461
  *Throws:* Any exception thrown during the initialization of the
462
  contained value.
463
 
464
  *Remarks:* If an exception is thrown during the initialization of the
465
- contained value, the `variant` might not hold a value.
466
 
467
  #### Value status <a id="variant.status">[[variant.status]]</a>
468
 
469
  ``` cpp
470
  constexpr bool valueless_by_exception() const noexcept;
@@ -472,14 +471,14 @@ constexpr bool valueless_by_exception() const noexcept;
472
 
473
  *Effects:* Returns `false` if and only if the `variant` holds a value.
474
 
475
  [*Note 1*:
476
 
477
- A `variant` might not hold a value if an exception is thrown during a
478
- type-changing assignment or emplacement. The latter means that even a
479
- `variant<float, int>` can become `valueless_by_exception()`, for
480
- instance by
481
 
482
  ``` cpp
483
  struct S { operator int() { throw 42; }};
484
  variant<float, int> v{12.f};
485
  v.emplace<1>(S());
@@ -496,17 +495,17 @@ constexpr size_t index() const noexcept;
496
  alternative of the contained value.
497
 
498
  #### Swap <a id="variant.swap">[[variant.swap]]</a>
499
 
500
  ``` cpp
501
- void swap(variant& rhs) noexcept(see below);
502
  ```
503
 
504
  *Mandates:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
505
 
506
- *Preconditions:* Lvalues of type `Tᵢ` are
507
- swappable [[swappable.requirements]].
508
 
509
  *Effects:*
510
 
511
  - If `valueless_by_exception() && rhs.valueless_by_exception()` no
512
  effect.
@@ -524,9 +523,9 @@ with i being `index()` and j being `rhs.index()`.
524
  values of `*this` and of `rhs` are determined by the exception safety
525
  guarantee of `swap` for lvalues of `Tᵢ` with i being `index()`. If an
526
  exception is thrown during the exchange of the values of `*this` and
527
  `rhs`, the states of the values of `*this` and of `rhs` are determined
528
  by the exception safety guarantee of `variant`’s move constructor. The
529
- expression inside `noexcept` is equivalent to the logical of
530
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_swappable_v<``Tᵢ``>`
531
  for all i.
532
 
 
1
  ### Class template `variant` <a id="variant.variant">[[variant.variant]]</a>
2
 
3
+ #### General <a id="variant.variant.general">[[variant.variant.general]]</a>
4
+
5
  ``` cpp
6
  namespace std {
7
  template<class... Types>
8
  class variant {
9
  public:
 
24
  constexpr explicit variant(in_place_index_t<I>, Args&&...);
25
  template<size_t I, class U, class... Args>
26
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);
27
 
28
  // [variant.dtor], destructor
29
+ constexpr ~variant();
30
 
31
  // [variant.assign], assignment
32
  constexpr variant& operator=(const variant&);
33
  constexpr variant& operator=(variant&&) noexcept(see below);
34
 
35
+ template<class T> constexpr variant& operator=(T&&) noexcept(see below);
36
 
37
  // [variant.mod], modifiers
38
  template<class T, class... Args>
39
+ constexpr T& emplace(Args&&...);
40
  template<class T, class U, class... Args>
41
+ constexpr T& emplace(initializer_list<U>, Args&&...);
42
  template<size_t I, class... Args>
43
+ constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
44
  template<size_t I, class U, class... Args>
45
+ constexpr variant_alternative_t<I, variant<Types...>>&
46
+ emplace(initializer_list<U>, Args&&...);
47
 
48
  // [variant.status], value status
49
  constexpr bool valueless_by_exception() const noexcept;
50
  constexpr size_t index() const noexcept;
51
 
52
  // [variant.swap], swap
53
+ constexpr void swap(variant&) noexcept(see below);
54
  };
55
  }
56
  ```
57
 
58
  Any instance of `variant` at any given time either holds a value of one
59
  of its alternative types or holds no value. When an instance of
60
  `variant` holds a value of alternative type `T`, it means that a value
61
  of type `T`, referred to as the `variant` object’s *contained value*, is
62
  allocated within the storage of the `variant` object. Implementations
63
  are not permitted to use additional storage, such as dynamic memory, to
64
+ allocate the contained value.
 
 
65
 
66
  All types in `Types` shall meet the *Cpp17Destructible* requirements (
67
  [[cpp17.destructible]]).
68
 
69
  A program that instantiates the definition of `variant` with no template
 
86
  *Ensures:* `valueless_by_exception()` is `false` and `index()` is `0`.
87
 
88
  *Throws:* Any exception thrown by the value-initialization of `T₀`.
89
 
90
  *Remarks:* This function is `constexpr` if and only if the
91
+ value-initialization of the alternative type `T₀` would be
92
+ constexpr-suitable [[dcl.constexpr]]. The exception specification is
93
+ equivalent to `is_nothrow_default_constructible_v<``T₀``>`.
94
 
95
  [*Note 1*: See also class `monostate`. — *end note*]
96
 
97
  ``` cpp
98
  constexpr variant(const variant& w);
 
122
  `get<j>(std::move(w))`, where `j` is `w.index()`. Otherwise, initializes
123
  the `variant` to not hold a value.
124
 
125
  *Throws:* Any exception thrown by move-constructing any `Tᵢ` for all i.
126
 
127
+ *Remarks:* The exception specification is equivalent to the logical of
128
+ `is_nothrow_move_constructible_v<``Tᵢ``>` for all i. If
129
  `is_trivially_move_constructible_v<``Tᵢ``>` is `true` for all i, this
130
  constructor is trivial.
131
 
132
  ``` cpp
133
  template<class T> constexpr variant(T&& t) noexcept(see below);
 
155
  is ill-formed, as both alternative types have an equally viable
156
  constructor for the argument.
157
  — *end note*]
158
 
159
  *Effects:* Initializes `*this` to hold the alternative type `Tⱼ` and
160
+ direct-non-list-initializes the contained value with
161
+ `std::forward<T>(t)`.
162
 
163
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`.
164
 
165
  *Throws:* Any exception thrown by the initialization of the selected
166
  alternative `Tⱼ`.
167
 
168
+ *Remarks:* The exception specification is equivalent to
169
  `is_nothrow_constructible_v<``Tⱼ``, T>`. If `Tⱼ`’s selected constructor
170
  is a constexpr constructor, this constructor is a constexpr constructor.
171
 
172
  ``` cpp
173
  template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
 
176
  *Constraints:*
177
 
178
  - There is exactly one occurrence of `T` in `Types...` and
179
  - `is_constructible_v<T, Args...>` is `true`.
180
 
181
+ *Effects:* Direct-non-list-initializes the contained value of type `T`
182
+ with `std::forward<Args>(args)...`.
 
183
 
184
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
185
 
186
  *Throws:* Any exception thrown by calling the selected constructor of
187
  `T`.
 
197
  *Constraints:*
198
 
199
  - There is exactly one occurrence of `T` in `Types...` and
200
  - `is_constructible_v<T, initializer_list<U>&, Args...>` is `true`.
201
 
202
+ *Effects:* Direct-non-list-initializes the contained value of type `T`
203
+ with `il, std::forward<Args>(args)...`.
 
204
 
205
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
206
 
207
  *Throws:* Any exception thrown by calling the selected constructor of
208
  `T`.
 
217
  *Constraints:*
218
 
219
  - `I` is less than `sizeof...(Types)` and
220
  - `is_constructible_v<``T_I``, Args...>` is `true`.
221
 
222
+ *Effects:* Direct-non-list-initializes the contained value of type `T_I`
223
+ with `std::forward<Args>(args)...`.
 
224
 
225
  *Ensures:* `index()` is `I`.
226
 
227
  *Throws:* Any exception thrown by calling the selected constructor of
228
  `T_I`.
 
239
 
240
  - `I` is less than `sizeof...(Types)` and
241
  - `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is
242
  `true`.
243
 
244
+ *Effects:* Direct-non-list-initializes the contained value of type `T_I`
245
+ with `il, std::forward<Args>(args)...`.
 
246
 
247
  *Ensures:* `index()` is `I`.
248
 
249
  *Remarks:* If `T_I`’s selected constructor is a constexpr constructor,
250
  this constructor is a constexpr constructor.
251
 
252
  #### Destructor <a id="variant.dtor">[[variant.dtor]]</a>
253
 
254
  ``` cpp
255
+ constexpr ~variant();
256
  ```
257
 
258
  *Effects:* If `valueless_by_exception()` is `false`, destroys the
259
  currently contained value.
260
 
 
279
  - Otherwise, if either `is_nothrow_copy_constructible_v<``Tⱼ``>` is
280
  `true` or `is_nothrow_move_constructible_v<``Tⱼ``>` is `false`,
281
  equivalent to `emplace<`j`>(get<`j`>(rhs))`.
282
  - Otherwise, equivalent to `operator=(variant(rhs))`.
283
 
 
 
284
  *Ensures:* `index() == rhs.index()`.
285
 
286
+ *Returns:* `*this`.
287
+
288
  *Remarks:* This operator is defined as deleted unless
289
  `is_copy_constructible_v<``Tᵢ``> &&` `is_copy_assignable_v<``Tᵢ``>` is
290
  `true` for all i. If `is_trivially_copy_constructible_v<``Tᵢ``> &&`
291
  `is_trivially_copy_assignable_v<``Tᵢ``> &&`
292
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
 
313
  *Returns:* `*this`.
314
 
315
  *Remarks:* If `is_trivially_move_constructible_v<``Tᵢ``> &&`
316
  `is_trivially_move_assignable_v<``Tᵢ``> &&`
317
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
318
+ assignment operator is trivial. The exception specification is
319
+ equivalent to
320
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_move_assignable_v<``Tᵢ``>`
321
  for all i.
322
 
323
  - If an exception is thrown during the call to `Tⱼ`’s move construction
324
  (with j being `rhs.index()`), the `variant` will hold no value.
325
  - If an exception is thrown during the call to `Tⱼ`’s move assignment,
326
  the state of the contained value is as defined by the exception safety
327
  guarantee of `Tⱼ`’s move assignment; `index()` will be j.
328
 
329
  ``` cpp
330
+ template<class T> constexpr variant& operator=(T&& t) noexcept(see below);
331
  ```
332
 
333
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
334
  function *FUN*(Tᵢ) for each alternative type `Tᵢ` for which `Tᵢ`` x[] =`
335
  `{std::forward<T>(t)};` is well-formed for some invented variable `x`.
 
357
  - If `*this` holds a `Tⱼ`, assigns `std::forward<T>(t)` to the value
358
  contained in `*this`.
359
  - Otherwise, if `is_nothrow_constructible_v<``Tⱼ``, T> ||`
360
  `!is_nothrow_move_constructible_v<``Tⱼ``>` is `true`, equivalent to
361
  `emplace<`j`>(std::forward<T>(t))`.
362
+ - Otherwise, equivalent to `emplace<`j`>(``Tⱼ``(std::forward<T>(t)))`.
363
 
364
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`, with `Tⱼ`
365
  selected by the imaginary function overload resolution described above.
366
 
367
  *Returns:* `*this`.
368
 
369
+ *Remarks:* The exception specification is equivalent to:
370
 
371
  ``` cpp
372
  is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
373
  ```
374
 
 
376
  `std::forward<T>(t)` to the value contained in `*this`, the state of
377
  the contained value and `t` are as defined by the exception safety
378
  guarantee of the assignment expression; `valueless_by_exception()`
379
  will be `false`.
380
  - If an exception is thrown during the initialization of the contained
381
+ value, the `variant` object is permitted to not hold a value.
382
 
383
  #### Modifiers <a id="variant.mod">[[variant.mod]]</a>
384
 
385
  ``` cpp
386
+ template<class T, class... Args> constexpr T& emplace(Args&&... args);
387
  ```
388
 
389
  *Constraints:* `is_constructible_v<T, Args...>` is `true`, and `T`
390
  occurs exactly once in `Types`.
391
 
 
396
  ```
397
 
398
  where I is the zero-based index of `T` in `Types`.
399
 
400
  ``` cpp
401
+ template<class T, class U, class... Args>
402
+ constexpr T& emplace(initializer_list<U> il, Args&&... args);
403
  ```
404
 
405
  *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
406
  `true`, and `T` occurs exactly once in `Types`.
407
 
 
413
 
414
  where I is the zero-based index of `T` in `Types`.
415
 
416
  ``` cpp
417
  template<size_t I, class... Args>
418
+ constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
419
  ```
420
 
421
  *Mandates:* `I` < `sizeof...(Types)`.
422
 
423
  *Constraints:* `is_constructible_v<``T_I``, Args...>` is `true`.
424
 
425
  *Effects:* Destroys the currently contained value if
426
+ `valueless_by_exception()` is `false`. Then direct-non-list-initializes
427
+ the contained value of type `T_I` with the arguments
428
+ `std::forward<Args>(args)...`.
429
 
430
  *Ensures:* `index()` is `I`.
431
 
432
  *Returns:* A reference to the new contained value.
433
 
434
  *Throws:* Any exception thrown during the initialization of the
435
  contained value.
436
 
437
  *Remarks:* If an exception is thrown during the initialization of the
438
+ contained value, the `variant` is permitted to not hold a value.
439
 
440
  ``` cpp
441
  template<size_t I, class U, class... Args>
442
+ constexpr variant_alternative_t<I, variant<Types...>>&
443
+ emplace(initializer_list<U> il, Args&&... args);
444
  ```
445
 
446
  *Mandates:* `I` < `sizeof...(Types)`.
447
 
448
  *Constraints:*
449
  `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is `true`.
450
 
451
  *Effects:* Destroys the currently contained value if
452
+ `valueless_by_exception()` is `false`. Then direct-non-list-initializes
453
+ the contained value of type `T_I` with
454
+ `il, std::forward<Args>(args)...`.
455
 
456
  *Ensures:* `index()` is `I`.
457
 
458
  *Returns:* A reference to the new contained value.
459
 
460
  *Throws:* Any exception thrown during the initialization of the
461
  contained value.
462
 
463
  *Remarks:* If an exception is thrown during the initialization of the
464
+ contained value, the `variant` is permitted to not hold a value.
465
 
466
  #### Value status <a id="variant.status">[[variant.status]]</a>
467
 
468
  ``` cpp
469
  constexpr bool valueless_by_exception() const noexcept;
 
471
 
472
  *Effects:* Returns `false` if and only if the `variant` holds a value.
473
 
474
  [*Note 1*:
475
 
476
+ It is possible for a `variant` to hold no value if an exception is
477
+ thrown during a type-changing assignment or emplacement. The latter
478
+ means that even a `variant<float, int>` can become
479
+ `valueless_by_exception()`, for instance by
480
 
481
  ``` cpp
482
  struct S { operator int() { throw 42; }};
483
  variant<float, int> v{12.f};
484
  v.emplace<1>(S());
 
495
  alternative of the contained value.
496
 
497
  #### Swap <a id="variant.swap">[[variant.swap]]</a>
498
 
499
  ``` cpp
500
+ constexpr void swap(variant& rhs) noexcept(see below);
501
  ```
502
 
503
  *Mandates:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
504
 
505
+ *Preconditions:* Each `Tᵢ` meets the *Cpp17Swappable*
506
+ requirements [[swappable.requirements]].
507
 
508
  *Effects:*
509
 
510
  - If `valueless_by_exception() && rhs.valueless_by_exception()` no
511
  effect.
 
523
  values of `*this` and of `rhs` are determined by the exception safety
524
  guarantee of `swap` for lvalues of `Tᵢ` with i being `index()`. If an
525
  exception is thrown during the exchange of the values of `*this` and
526
  `rhs`, the states of the values of `*this` and of `rhs` are determined
527
  by the exception safety guarantee of `variant`’s move constructor. The
528
+ exception specification is equivalent to the logical of
529
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_swappable_v<``Tᵢ``>`
530
  for all i.
531