From Jason Turner

[variant]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp76wkpqab/{from.md → to.md} +102 -80
tmp/tmp76wkpqab/{from.md → to.md} RENAMED
@@ -19,11 +19,11 @@ namespace std {
19
 
20
  // [variant.helper], variant helper classes
21
  template<class T> struct variant_size; // not defined
22
  template<class T> struct variant_size<const T>;
23
  template<class T>
24
- inline constexpr size_t variant_size_v = variant_size<T>::value;
25
 
26
  template<class... Types>
27
  struct variant_size<variant<Types...>>;
28
 
29
  template<size_t I, class T> struct variant_alternative; // not defined
@@ -102,11 +102,11 @@ namespace std {
102
  constexpr bool operator==(monostate, monostate) noexcept;
103
  constexpr strong_ordering operator<=>(monostate, monostate) noexcept;
104
 
105
  // [variant.specalg], specialized algorithms
106
  template<class... Types>
107
- void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
108
 
109
  // [variant.bad.access], class bad_variant_access
110
  class bad_variant_access;
111
 
112
  // [variant.hash], hash support
@@ -116,10 +116,12 @@ namespace std {
116
  }
117
  ```
118
 
119
  ### Class template `variant` <a id="variant.variant">[[variant.variant]]</a>
120
 
 
 
121
  ``` cpp
122
  namespace std {
123
  template<class... Types>
124
  class variant {
125
  public:
@@ -140,47 +142,46 @@ namespace std {
140
  constexpr explicit variant(in_place_index_t<I>, Args&&...);
141
  template<size_t I, class U, class... Args>
142
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);
143
 
144
  // [variant.dtor], destructor
145
- ~variant();
146
 
147
  // [variant.assign], assignment
148
  constexpr variant& operator=(const variant&);
149
  constexpr variant& operator=(variant&&) noexcept(see below);
150
 
151
- template<class T> variant& operator=(T&&) noexcept(see below);
152
 
153
  // [variant.mod], modifiers
154
  template<class T, class... Args>
155
- T& emplace(Args&&...);
156
  template<class T, class U, class... Args>
157
- T& emplace(initializer_list<U>, Args&&...);
158
  template<size_t I, class... Args>
159
- variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
160
  template<size_t I, class U, class... Args>
161
- variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...);
 
162
 
163
  // [variant.status], value status
164
  constexpr bool valueless_by_exception() const noexcept;
165
  constexpr size_t index() const noexcept;
166
 
167
  // [variant.swap], swap
168
- void swap(variant&) noexcept(see below);
169
  };
170
  }
171
  ```
172
 
173
  Any instance of `variant` at any given time either holds a value of one
174
  of its alternative types or holds no value. When an instance of
175
  `variant` holds a value of alternative type `T`, it means that a value
176
  of type `T`, referred to as the `variant` object’s *contained value*, is
177
  allocated within the storage of the `variant` object. Implementations
178
  are not permitted to use additional storage, such as dynamic memory, to
179
- allocate the contained value. The contained value shall be allocated in
180
- a region of the `variant` storage suitably aligned for all types in
181
- `Types`.
182
 
183
  All types in `Types` shall meet the *Cpp17Destructible* requirements (
184
  [[cpp17.destructible]]).
185
 
186
  A program that instantiates the definition of `variant` with no template
@@ -203,13 +204,13 @@ type `T₀`.
203
  *Ensures:* `valueless_by_exception()` is `false` and `index()` is `0`.
204
 
205
  *Throws:* Any exception thrown by the value-initialization of `T₀`.
206
 
207
  *Remarks:* This function is `constexpr` if and only if the
208
- value-initialization of the alternative type `T₀` would satisfy the
209
- requirements for a constexpr function. The expression inside `noexcept`
210
- is equivalent to `is_nothrow_default_constructible_v<``T₀``>`.
211
 
212
  [*Note 1*: See also class `monostate`. — *end note*]
213
 
214
  ``` cpp
215
  constexpr variant(const variant& w);
@@ -239,12 +240,12 @@ same alternative as `w` and direct-initializes the contained value with
239
  `get<j>(std::move(w))`, where `j` is `w.index()`. Otherwise, initializes
240
  the `variant` to not hold a value.
241
 
242
  *Throws:* Any exception thrown by move-constructing any `Tᵢ` for all i.
243
 
244
- *Remarks:* The expression inside `noexcept` is equivalent to the logical
245
- of `is_nothrow_move_constructible_v<``Tᵢ``>` for all i. If
246
  `is_trivially_move_constructible_v<``Tᵢ``>` is `true` for all i, this
247
  constructor is trivial.
248
 
249
  ``` cpp
250
  template<class T> constexpr variant(T&& t) noexcept(see below);
@@ -272,19 +273,19 @@ which is the type of the contained value after construction.
272
  is ill-formed, as both alternative types have an equally viable
273
  constructor for the argument.
274
  — *end note*]
275
 
276
  *Effects:* Initializes `*this` to hold the alternative type `Tⱼ` and
277
- direct-initializes the contained value as if
278
- direct-non-list-initializing it with `std::forward<T>(t)`.
279
 
280
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`.
281
 
282
  *Throws:* Any exception thrown by the initialization of the selected
283
  alternative `Tⱼ`.
284
 
285
- *Remarks:* The expression inside `noexcept` is equivalent to
286
  `is_nothrow_constructible_v<``Tⱼ``, T>`. If `Tⱼ`’s selected constructor
287
  is a constexpr constructor, this constructor is a constexpr constructor.
288
 
289
  ``` cpp
290
  template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
@@ -293,13 +294,12 @@ template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>,
293
  *Constraints:*
294
 
295
  - There is exactly one occurrence of `T` in `Types...` and
296
  - `is_constructible_v<T, Args...>` is `true`.
297
 
298
- *Effects:* Initializes the contained value as if
299
- direct-non-list-initializing an object of type `T` with the arguments
300
- `std::forward<Args>(args)...`.
301
 
302
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
303
 
304
  *Throws:* Any exception thrown by calling the selected constructor of
305
  `T`.
@@ -315,13 +315,12 @@ template<class T, class U, class... Args>
315
  *Constraints:*
316
 
317
  - There is exactly one occurrence of `T` in `Types...` and
318
  - `is_constructible_v<T, initializer_list<U>&, Args...>` is `true`.
319
 
320
- *Effects:* Initializes the contained value as if
321
- direct-non-list-initializing an object of type `T` with the arguments
322
- `il, std::forward<Args>(args)...`.
323
 
324
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
325
 
326
  *Throws:* Any exception thrown by calling the selected constructor of
327
  `T`.
@@ -336,13 +335,12 @@ template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>
336
  *Constraints:*
337
 
338
  - `I` is less than `sizeof...(Types)` and
339
  - `is_constructible_v<``T_I``, Args...>` is `true`.
340
 
341
- *Effects:* Initializes the contained value as if
342
- direct-non-list-initializing an object of type `T_I` with the arguments
343
- `std::forward<Args>(args)...`.
344
 
345
  *Ensures:* `index()` is `I`.
346
 
347
  *Throws:* Any exception thrown by calling the selected constructor of
348
  `T_I`.
@@ -359,23 +357,22 @@ template<size_t I, class U, class... Args>
359
 
360
  - `I` is less than `sizeof...(Types)` and
361
  - `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is
362
  `true`.
363
 
364
- *Effects:* Initializes the contained value as if
365
- direct-non-list-initializing an object of type `T_I` with the arguments
366
- `il, std::forward<Args>(args)...`.
367
 
368
  *Ensures:* `index()` is `I`.
369
 
370
  *Remarks:* If `T_I`’s selected constructor is a constexpr constructor,
371
  this constructor is a constexpr constructor.
372
 
373
  #### Destructor <a id="variant.dtor">[[variant.dtor]]</a>
374
 
375
  ``` cpp
376
- ~variant();
377
  ```
378
 
379
  *Effects:* If `valueless_by_exception()` is `false`, destroys the
380
  currently contained value.
381
 
@@ -400,14 +397,14 @@ Let j be `rhs.index()`.
400
  - Otherwise, if either `is_nothrow_copy_constructible_v<``Tⱼ``>` is
401
  `true` or `is_nothrow_move_constructible_v<``Tⱼ``>` is `false`,
402
  equivalent to `emplace<`j`>(get<`j`>(rhs))`.
403
  - Otherwise, equivalent to `operator=(variant(rhs))`.
404
 
405
- *Returns:* `*this`.
406
-
407
  *Ensures:* `index() == rhs.index()`.
408
 
 
 
409
  *Remarks:* This operator is defined as deleted unless
410
  `is_copy_constructible_v<``Tᵢ``> &&` `is_copy_assignable_v<``Tᵢ``>` is
411
  `true` for all i. If `is_trivially_copy_constructible_v<``Tᵢ``> &&`
412
  `is_trivially_copy_assignable_v<``Tᵢ``> &&`
413
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
@@ -434,23 +431,23 @@ Let j be `rhs.index()`.
434
  *Returns:* `*this`.
435
 
436
  *Remarks:* If `is_trivially_move_constructible_v<``Tᵢ``> &&`
437
  `is_trivially_move_assignable_v<``Tᵢ``> &&`
438
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
439
- assignment operator is trivial. The expression inside `noexcept` is
440
- equivalent to:
441
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_move_assignable_v<``Tᵢ``>`
442
  for all i.
443
 
444
  - If an exception is thrown during the call to `Tⱼ`’s move construction
445
  (with j being `rhs.index()`), the `variant` will hold no value.
446
  - If an exception is thrown during the call to `Tⱼ`’s move assignment,
447
  the state of the contained value is as defined by the exception safety
448
  guarantee of `Tⱼ`’s move assignment; `index()` will be j.
449
 
450
  ``` cpp
451
- template<class T> variant& operator=(T&& t) noexcept(see below);
452
  ```
453
 
454
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
455
  function *FUN*(Tᵢ) for each alternative type `Tᵢ` for which `Tᵢ`` x[] =`
456
  `{std::forward<T>(t)};` is well-formed for some invented variable `x`.
@@ -478,18 +475,18 @@ which is the type of the contained value after assignment.
478
  - If `*this` holds a `Tⱼ`, assigns `std::forward<T>(t)` to the value
479
  contained in `*this`.
480
  - Otherwise, if `is_nothrow_constructible_v<``Tⱼ``, T> ||`
481
  `!is_nothrow_move_constructible_v<``Tⱼ``>` is `true`, equivalent to
482
  `emplace<`j`>(std::forward<T>(t))`.
483
- - Otherwise, equivalent to `operator=(variant(std::forward<T>(t)))`.
484
 
485
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`, with `Tⱼ`
486
  selected by the imaginary function overload resolution described above.
487
 
488
  *Returns:* `*this`.
489
 
490
- *Remarks:* The expression inside `noexcept` is equivalent to:
491
 
492
  ``` cpp
493
  is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
494
  ```
495
 
@@ -497,16 +494,16 @@ is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
497
  `std::forward<T>(t)` to the value contained in `*this`, the state of
498
  the contained value and `t` are as defined by the exception safety
499
  guarantee of the assignment expression; `valueless_by_exception()`
500
  will be `false`.
501
  - If an exception is thrown during the initialization of the contained
502
- value, the `variant` object might not hold a value.
503
 
504
  #### Modifiers <a id="variant.mod">[[variant.mod]]</a>
505
 
506
  ``` cpp
507
- template<class T, class... Args> T& emplace(Args&&... args);
508
  ```
509
 
510
  *Constraints:* `is_constructible_v<T, Args...>` is `true`, and `T`
511
  occurs exactly once in `Types`.
512
 
@@ -517,11 +514,12 @@ return emplace<I>(std::forward<Args>(args)...);
517
  ```
518
 
519
  where I is the zero-based index of `T` in `Types`.
520
 
521
  ``` cpp
522
- template<class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
 
523
  ```
524
 
525
  *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
526
  `true`, and `T` occurs exactly once in `Types`.
527
 
@@ -533,56 +531,57 @@ return emplace<I>(il, std::forward<Args>(args)...);
533
 
534
  where I is the zero-based index of `T` in `Types`.
535
 
536
  ``` cpp
537
  template<size_t I, class... Args>
538
- variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
539
  ```
540
 
541
  *Mandates:* `I` < `sizeof...(Types)`.
542
 
543
  *Constraints:* `is_constructible_v<``T_I``, Args...>` is `true`.
544
 
545
  *Effects:* Destroys the currently contained value if
546
- `valueless_by_exception()` is `false`. Then initializes the contained
547
- value as if direct-non-list-initializing a value of type `T_I` with the
548
- arguments `std::forward<Args>(args)...`.
549
 
550
  *Ensures:* `index()` is `I`.
551
 
552
  *Returns:* A reference to the new contained value.
553
 
554
  *Throws:* Any exception thrown during the initialization of the
555
  contained value.
556
 
557
  *Remarks:* If an exception is thrown during the initialization of the
558
- contained value, the `variant` might not hold a value.
559
 
560
  ``` cpp
561
  template<size_t I, class U, class... Args>
562
- variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
 
563
  ```
564
 
565
  *Mandates:* `I` < `sizeof...(Types)`.
566
 
567
  *Constraints:*
568
  `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is `true`.
569
 
570
  *Effects:* Destroys the currently contained value if
571
- `valueless_by_exception()` is `false`. Then initializes the contained
572
- value as if direct-non-list-initializing a value of type `T_I` with the
573
- arguments `il, std::forward<Args>(args)...`.
574
 
575
  *Ensures:* `index()` is `I`.
576
 
577
  *Returns:* A reference to the new contained value.
578
 
579
  *Throws:* Any exception thrown during the initialization of the
580
  contained value.
581
 
582
  *Remarks:* If an exception is thrown during the initialization of the
583
- contained value, the `variant` might not hold a value.
584
 
585
  #### Value status <a id="variant.status">[[variant.status]]</a>
586
 
587
  ``` cpp
588
  constexpr bool valueless_by_exception() const noexcept;
@@ -590,14 +589,14 @@ constexpr bool valueless_by_exception() const noexcept;
590
 
591
  *Effects:* Returns `false` if and only if the `variant` holds a value.
592
 
593
  [*Note 1*:
594
 
595
- A `variant` might not hold a value if an exception is thrown during a
596
- type-changing assignment or emplacement. The latter means that even a
597
- `variant<float, int>` can become `valueless_by_exception()`, for
598
- instance by
599
 
600
  ``` cpp
601
  struct S { operator int() { throw 42; }};
602
  variant<float, int> v{12.f};
603
  v.emplace<1>(S());
@@ -614,17 +613,17 @@ constexpr size_t index() const noexcept;
614
  alternative of the contained value.
615
 
616
  #### Swap <a id="variant.swap">[[variant.swap]]</a>
617
 
618
  ``` cpp
619
- void swap(variant& rhs) noexcept(see below);
620
  ```
621
 
622
  *Mandates:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
623
 
624
- *Preconditions:* Lvalues of type `Tᵢ` are
625
- swappable [[swappable.requirements]].
626
 
627
  *Effects:*
628
 
629
  - If `valueless_by_exception() && rhs.valueless_by_exception()` no
630
  effect.
@@ -642,11 +641,11 @@ with i being `index()` and j being `rhs.index()`.
642
  values of `*this` and of `rhs` are determined by the exception safety
643
  guarantee of `swap` for lvalues of `Tᵢ` with i being `index()`. If an
644
  exception is thrown during the exchange of the values of `*this` and
645
  `rhs`, the states of the values of `*this` and of `rhs` are determined
646
  by the exception safety guarantee of `variant`’s move constructor. The
647
- expression inside `noexcept` is equivalent to the logical of
648
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_swappable_v<``Tᵢ``>`
649
  for all i.
650
 
651
  ### `variant` helper classes <a id="variant.helper">[[variant.helper]]</a>
652
 
@@ -657,11 +656,11 @@ template<class T> struct variant_size;
657
  All specializations of `variant_size` meet the *Cpp17UnaryTypeTrait*
658
  requirements [[meta.rqmts]] with a base characteristic of
659
  `integral_constant<size_t, N>` for some `N`.
660
 
661
  ``` cpp
662
- template<class T> class variant_size<const T>;
663
  ```
664
 
665
  Let `VS` denote `variant_size<T>` of the cv-unqualified type `T`. Then
666
  each specialization of the template meets the *Cpp17UnaryTypeTrait*
667
  requirements [[meta.rqmts]] with a base characteristic of
@@ -671,11 +670,11 @@ requirements [[meta.rqmts]] with a base characteristic of
671
  template<class... Types>
672
  struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
673
  ```
674
 
675
  ``` cpp
676
- template<size_t I, class T> class variant_alternative<I, const T>;
677
  ```
678
 
679
  Let `VA` denote `variant_alternative<I, T>` of the cv-unqualified type
680
  `T`. Then each specialization of the template meets the
681
  *Cpp17TransformationTrait* requirements [[meta.rqmts]] with a member
@@ -864,41 +863,62 @@ template<class Visitor, class... Variants>
864
  constexpr see below visit(Visitor&& vis, Variants&&... vars);
865
  template<class R, class Visitor, class... Variants>
866
  constexpr R visit(Visitor&& vis, Variants&&... vars);
867
  ```
868
 
869
- Let n be `sizeof...(Variants)`. Let `m` be a pack of n values of type
870
- `size_t`. Such a pack is called valid if 0 ≤
871
- `mᵢ` < `variant_size_v<remove_reference_t<Variantsᵢ``>>` for all
872
- 0 ≤ i < n. For each valid pack `m`, let e(`m`) denote the expression:
873
 
874
  ``` cpp
875
- INVOKE(std::forward<Visitor>(vis), get<m>(std::forward<Variants>(vars))...) // see [func.require]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876
  ```
877
 
878
  for the first form and
879
 
880
  ``` cpp
881
- INVOKE<R>(std::forward<Visitor>(vis), get<m>(std::forward<Variants>(vars))...) // see [func.require]
882
  ```
883
 
884
  for the second form.
885
 
886
- *Mandates:* For each valid pack `m`, e(`m`) is a valid expression. All
887
- such expressions are of the same type and value category.
888
 
889
- *Returns:* e(`m`), where `m` is the pack for which `mᵢ` is
890
- `vars`ᵢ`.index()` for all 0 ≤ i < n. The return type is
891
- `decltype(`e(`m`)`)` for the first form.
892
 
893
- *Throws:* `bad_variant_access` if any `variant` in `vars` is
894
- `valueless_by_exception()`.
895
 
896
  *Complexity:* For n ≤ 1, the invocation of the callable object is
897
  implemented in constant time, i.e., for n = 1, it does not depend on the
898
- number of alternative types of `Variants₀`. For n > 1, the invocation of
899
- the callable object has no complexity requirements.
900
 
901
  ### Class `monostate` <a id="variant.monostate">[[variant.monostate]]</a>
902
 
903
  ``` cpp
904
  struct monostate{};
@@ -920,30 +940,32 @@ always compare equal. — *end note*]
920
 
921
  ### Specialized algorithms <a id="variant.specalg">[[variant.specalg]]</a>
922
 
923
  ``` cpp
924
  template<class... Types>
925
- void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
926
  ```
927
 
928
  *Constraints:*
929
  `is_move_constructible_v<``Tᵢ``> && is_swappable_v<``Tᵢ``>` is `true`
930
  for all i.
931
 
932
  *Effects:* Equivalent to `v.swap(w)`.
933
 
934
- *Remarks:* The expression inside `noexcept` is equivalent to
935
  `noexcept(v.swap(w))`.
936
 
937
  ### Class `bad_variant_access` <a id="variant.bad.access">[[variant.bad.access]]</a>
938
 
939
  ``` cpp
 
940
  class bad_variant_access : public exception {
941
  public:
942
  // see [exception] for the specification of the special member functions
943
  const char* what() const noexcept override;
944
  };
 
945
  ```
946
 
947
  Objects of type `bad_variant_access` are thrown to report invalid
948
  accesses to the value of a `variant` object.
949
 
 
19
 
20
  // [variant.helper], variant helper classes
21
  template<class T> struct variant_size; // not defined
22
  template<class T> struct variant_size<const T>;
23
  template<class T>
24
+ constexpr size_t variant_size_v = variant_size<T>::value;
25
 
26
  template<class... Types>
27
  struct variant_size<variant<Types...>>;
28
 
29
  template<size_t I, class T> struct variant_alternative; // not defined
 
102
  constexpr bool operator==(monostate, monostate) noexcept;
103
  constexpr strong_ordering operator<=>(monostate, monostate) noexcept;
104
 
105
  // [variant.specalg], specialized algorithms
106
  template<class... Types>
107
+ constexpr void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
108
 
109
  // [variant.bad.access], class bad_variant_access
110
  class bad_variant_access;
111
 
112
  // [variant.hash], hash support
 
116
  }
117
  ```
118
 
119
  ### Class template `variant` <a id="variant.variant">[[variant.variant]]</a>
120
 
121
+ #### General <a id="variant.variant.general">[[variant.variant.general]]</a>
122
+
123
  ``` cpp
124
  namespace std {
125
  template<class... Types>
126
  class variant {
127
  public:
 
142
  constexpr explicit variant(in_place_index_t<I>, Args&&...);
143
  template<size_t I, class U, class... Args>
144
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);
145
 
146
  // [variant.dtor], destructor
147
+ constexpr ~variant();
148
 
149
  // [variant.assign], assignment
150
  constexpr variant& operator=(const variant&);
151
  constexpr variant& operator=(variant&&) noexcept(see below);
152
 
153
+ template<class T> constexpr variant& operator=(T&&) noexcept(see below);
154
 
155
  // [variant.mod], modifiers
156
  template<class T, class... Args>
157
+ constexpr T& emplace(Args&&...);
158
  template<class T, class U, class... Args>
159
+ constexpr T& emplace(initializer_list<U>, Args&&...);
160
  template<size_t I, class... Args>
161
+ constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
162
  template<size_t I, class U, class... Args>
163
+ constexpr variant_alternative_t<I, variant<Types...>>&
164
+ emplace(initializer_list<U>, Args&&...);
165
 
166
  // [variant.status], value status
167
  constexpr bool valueless_by_exception() const noexcept;
168
  constexpr size_t index() const noexcept;
169
 
170
  // [variant.swap], swap
171
+ constexpr void swap(variant&) noexcept(see below);
172
  };
173
  }
174
  ```
175
 
176
  Any instance of `variant` at any given time either holds a value of one
177
  of its alternative types or holds no value. When an instance of
178
  `variant` holds a value of alternative type `T`, it means that a value
179
  of type `T`, referred to as the `variant` object’s *contained value*, is
180
  allocated within the storage of the `variant` object. Implementations
181
  are not permitted to use additional storage, such as dynamic memory, to
182
+ allocate the contained value.
 
 
183
 
184
  All types in `Types` shall meet the *Cpp17Destructible* requirements (
185
  [[cpp17.destructible]]).
186
 
187
  A program that instantiates the definition of `variant` with no template
 
204
  *Ensures:* `valueless_by_exception()` is `false` and `index()` is `0`.
205
 
206
  *Throws:* Any exception thrown by the value-initialization of `T₀`.
207
 
208
  *Remarks:* This function is `constexpr` if and only if the
209
+ value-initialization of the alternative type `T₀` would be
210
+ constexpr-suitable [[dcl.constexpr]]. The exception specification is
211
+ equivalent to `is_nothrow_default_constructible_v<``T₀``>`.
212
 
213
  [*Note 1*: See also class `monostate`. — *end note*]
214
 
215
  ``` cpp
216
  constexpr variant(const variant& w);
 
240
  `get<j>(std::move(w))`, where `j` is `w.index()`. Otherwise, initializes
241
  the `variant` to not hold a value.
242
 
243
  *Throws:* Any exception thrown by move-constructing any `Tᵢ` for all i.
244
 
245
+ *Remarks:* The exception specification is equivalent to the logical of
246
+ `is_nothrow_move_constructible_v<``Tᵢ``>` for all i. If
247
  `is_trivially_move_constructible_v<``Tᵢ``>` is `true` for all i, this
248
  constructor is trivial.
249
 
250
  ``` cpp
251
  template<class T> constexpr variant(T&& t) noexcept(see below);
 
273
  is ill-formed, as both alternative types have an equally viable
274
  constructor for the argument.
275
  — *end note*]
276
 
277
  *Effects:* Initializes `*this` to hold the alternative type `Tⱼ` and
278
+ direct-non-list-initializes the contained value with
279
+ `std::forward<T>(t)`.
280
 
281
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`.
282
 
283
  *Throws:* Any exception thrown by the initialization of the selected
284
  alternative `Tⱼ`.
285
 
286
+ *Remarks:* The exception specification is equivalent to
287
  `is_nothrow_constructible_v<``Tⱼ``, T>`. If `Tⱼ`’s selected constructor
288
  is a constexpr constructor, this constructor is a constexpr constructor.
289
 
290
  ``` cpp
291
  template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
 
294
  *Constraints:*
295
 
296
  - There is exactly one occurrence of `T` in `Types...` and
297
  - `is_constructible_v<T, Args...>` is `true`.
298
 
299
+ *Effects:* Direct-non-list-initializes the contained value of type `T`
300
+ with `std::forward<Args>(args)...`.
 
301
 
302
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
303
 
304
  *Throws:* Any exception thrown by calling the selected constructor of
305
  `T`.
 
315
  *Constraints:*
316
 
317
  - There is exactly one occurrence of `T` in `Types...` and
318
  - `is_constructible_v<T, initializer_list<U>&, Args...>` is `true`.
319
 
320
+ *Effects:* Direct-non-list-initializes the contained value of type `T`
321
+ with `il, std::forward<Args>(args)...`.
 
322
 
323
  *Ensures:* `holds_alternative<T>(*this)` is `true`.
324
 
325
  *Throws:* Any exception thrown by calling the selected constructor of
326
  `T`.
 
335
  *Constraints:*
336
 
337
  - `I` is less than `sizeof...(Types)` and
338
  - `is_constructible_v<``T_I``, Args...>` is `true`.
339
 
340
+ *Effects:* Direct-non-list-initializes the contained value of type `T_I`
341
+ with `std::forward<Args>(args)...`.
 
342
 
343
  *Ensures:* `index()` is `I`.
344
 
345
  *Throws:* Any exception thrown by calling the selected constructor of
346
  `T_I`.
 
357
 
358
  - `I` is less than `sizeof...(Types)` and
359
  - `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is
360
  `true`.
361
 
362
+ *Effects:* Direct-non-list-initializes the contained value of type `T_I`
363
+ with `il, std::forward<Args>(args)...`.
 
364
 
365
  *Ensures:* `index()` is `I`.
366
 
367
  *Remarks:* If `T_I`’s selected constructor is a constexpr constructor,
368
  this constructor is a constexpr constructor.
369
 
370
  #### Destructor <a id="variant.dtor">[[variant.dtor]]</a>
371
 
372
  ``` cpp
373
+ constexpr ~variant();
374
  ```
375
 
376
  *Effects:* If `valueless_by_exception()` is `false`, destroys the
377
  currently contained value.
378
 
 
397
  - Otherwise, if either `is_nothrow_copy_constructible_v<``Tⱼ``>` is
398
  `true` or `is_nothrow_move_constructible_v<``Tⱼ``>` is `false`,
399
  equivalent to `emplace<`j`>(get<`j`>(rhs))`.
400
  - Otherwise, equivalent to `operator=(variant(rhs))`.
401
 
 
 
402
  *Ensures:* `index() == rhs.index()`.
403
 
404
+ *Returns:* `*this`.
405
+
406
  *Remarks:* This operator is defined as deleted unless
407
  `is_copy_constructible_v<``Tᵢ``> &&` `is_copy_assignable_v<``Tᵢ``>` is
408
  `true` for all i. If `is_trivially_copy_constructible_v<``Tᵢ``> &&`
409
  `is_trivially_copy_assignable_v<``Tᵢ``> &&`
410
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
 
431
  *Returns:* `*this`.
432
 
433
  *Remarks:* If `is_trivially_move_constructible_v<``Tᵢ``> &&`
434
  `is_trivially_move_assignable_v<``Tᵢ``> &&`
435
  `is_trivially_destructible_v<``Tᵢ``>` is `true` for all i, this
436
+ assignment operator is trivial. The exception specification is
437
+ equivalent to
438
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_move_assignable_v<``Tᵢ``>`
439
  for all i.
440
 
441
  - If an exception is thrown during the call to `Tⱼ`’s move construction
442
  (with j being `rhs.index()`), the `variant` will hold no value.
443
  - If an exception is thrown during the call to `Tⱼ`’s move assignment,
444
  the state of the contained value is as defined by the exception safety
445
  guarantee of `Tⱼ`’s move assignment; `index()` will be j.
446
 
447
  ``` cpp
448
+ template<class T> constexpr variant& operator=(T&& t) noexcept(see below);
449
  ```
450
 
451
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
452
  function *FUN*(Tᵢ) for each alternative type `Tᵢ` for which `Tᵢ`` x[] =`
453
  `{std::forward<T>(t)};` is well-formed for some invented variable `x`.
 
475
  - If `*this` holds a `Tⱼ`, assigns `std::forward<T>(t)` to the value
476
  contained in `*this`.
477
  - Otherwise, if `is_nothrow_constructible_v<``Tⱼ``, T> ||`
478
  `!is_nothrow_move_constructible_v<``Tⱼ``>` is `true`, equivalent to
479
  `emplace<`j`>(std::forward<T>(t))`.
480
+ - Otherwise, equivalent to `emplace<`j`>(``Tⱼ``(std::forward<T>(t)))`.
481
 
482
  *Ensures:* `holds_alternative<``Tⱼ``>(*this)` is `true`, with `Tⱼ`
483
  selected by the imaginary function overload resolution described above.
484
 
485
  *Returns:* `*this`.
486
 
487
+ *Remarks:* The exception specification is equivalent to:
488
 
489
  ``` cpp
490
  is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
491
  ```
492
 
 
494
  `std::forward<T>(t)` to the value contained in `*this`, the state of
495
  the contained value and `t` are as defined by the exception safety
496
  guarantee of the assignment expression; `valueless_by_exception()`
497
  will be `false`.
498
  - If an exception is thrown during the initialization of the contained
499
+ value, the `variant` object is permitted to not hold a value.
500
 
501
  #### Modifiers <a id="variant.mod">[[variant.mod]]</a>
502
 
503
  ``` cpp
504
+ template<class T, class... Args> constexpr T& emplace(Args&&... args);
505
  ```
506
 
507
  *Constraints:* `is_constructible_v<T, Args...>` is `true`, and `T`
508
  occurs exactly once in `Types`.
509
 
 
514
  ```
515
 
516
  where I is the zero-based index of `T` in `Types`.
517
 
518
  ``` cpp
519
+ template<class T, class U, class... Args>
520
+ constexpr T& emplace(initializer_list<U> il, Args&&... args);
521
  ```
522
 
523
  *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
524
  `true`, and `T` occurs exactly once in `Types`.
525
 
 
531
 
532
  where I is the zero-based index of `T` in `Types`.
533
 
534
  ``` cpp
535
  template<size_t I, class... Args>
536
+ constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
537
  ```
538
 
539
  *Mandates:* `I` < `sizeof...(Types)`.
540
 
541
  *Constraints:* `is_constructible_v<``T_I``, Args...>` is `true`.
542
 
543
  *Effects:* Destroys the currently contained value if
544
+ `valueless_by_exception()` is `false`. Then direct-non-list-initializes
545
+ the contained value of type `T_I` with the arguments
546
+ `std::forward<Args>(args)...`.
547
 
548
  *Ensures:* `index()` is `I`.
549
 
550
  *Returns:* A reference to the new contained value.
551
 
552
  *Throws:* Any exception thrown during the initialization of the
553
  contained value.
554
 
555
  *Remarks:* If an exception is thrown during the initialization of the
556
+ contained value, the `variant` is permitted to not hold a value.
557
 
558
  ``` cpp
559
  template<size_t I, class U, class... Args>
560
+ constexpr variant_alternative_t<I, variant<Types...>>&
561
+ emplace(initializer_list<U> il, Args&&... args);
562
  ```
563
 
564
  *Mandates:* `I` < `sizeof...(Types)`.
565
 
566
  *Constraints:*
567
  `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is `true`.
568
 
569
  *Effects:* Destroys the currently contained value if
570
+ `valueless_by_exception()` is `false`. Then direct-non-list-initializes
571
+ the contained value of type `T_I` with
572
+ `il, std::forward<Args>(args)...`.
573
 
574
  *Ensures:* `index()` is `I`.
575
 
576
  *Returns:* A reference to the new contained value.
577
 
578
  *Throws:* Any exception thrown during the initialization of the
579
  contained value.
580
 
581
  *Remarks:* If an exception is thrown during the initialization of the
582
+ contained value, the `variant` is permitted to not hold a value.
583
 
584
  #### Value status <a id="variant.status">[[variant.status]]</a>
585
 
586
  ``` cpp
587
  constexpr bool valueless_by_exception() const noexcept;
 
589
 
590
  *Effects:* Returns `false` if and only if the `variant` holds a value.
591
 
592
  [*Note 1*:
593
 
594
+ It is possible for a `variant` to hold no value if an exception is
595
+ thrown during a type-changing assignment or emplacement. The latter
596
+ means that even a `variant<float, int>` can become
597
+ `valueless_by_exception()`, for instance by
598
 
599
  ``` cpp
600
  struct S { operator int() { throw 42; }};
601
  variant<float, int> v{12.f};
602
  v.emplace<1>(S());
 
613
  alternative of the contained value.
614
 
615
  #### Swap <a id="variant.swap">[[variant.swap]]</a>
616
 
617
  ``` cpp
618
+ constexpr void swap(variant& rhs) noexcept(see below);
619
  ```
620
 
621
  *Mandates:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
622
 
623
+ *Preconditions:* Each `Tᵢ` meets the *Cpp17Swappable*
624
+ requirements [[swappable.requirements]].
625
 
626
  *Effects:*
627
 
628
  - If `valueless_by_exception() && rhs.valueless_by_exception()` no
629
  effect.
 
641
  values of `*this` and of `rhs` are determined by the exception safety
642
  guarantee of `swap` for lvalues of `Tᵢ` with i being `index()`. If an
643
  exception is thrown during the exchange of the values of `*this` and
644
  `rhs`, the states of the values of `*this` and of `rhs` are determined
645
  by the exception safety guarantee of `variant`’s move constructor. The
646
+ exception specification is equivalent to the logical of
647
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_swappable_v<``Tᵢ``>`
648
  for all i.
649
 
650
  ### `variant` helper classes <a id="variant.helper">[[variant.helper]]</a>
651
 
 
656
  All specializations of `variant_size` meet the *Cpp17UnaryTypeTrait*
657
  requirements [[meta.rqmts]] with a base characteristic of
658
  `integral_constant<size_t, N>` for some `N`.
659
 
660
  ``` cpp
661
+ template<class T> struct variant_size<const T>;
662
  ```
663
 
664
  Let `VS` denote `variant_size<T>` of the cv-unqualified type `T`. Then
665
  each specialization of the template meets the *Cpp17UnaryTypeTrait*
666
  requirements [[meta.rqmts]] with a base characteristic of
 
670
  template<class... Types>
671
  struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
672
  ```
673
 
674
  ``` cpp
675
+ template<size_t I, class T> struct variant_alternative<I, const T>;
676
  ```
677
 
678
  Let `VA` denote `variant_alternative<I, T>` of the cv-unqualified type
679
  `T`. Then each specialization of the template meets the
680
  *Cpp17TransformationTrait* requirements [[meta.rqmts]] with a member
 
863
  constexpr see below visit(Visitor&& vis, Variants&&... vars);
864
  template<class R, class Visitor, class... Variants>
865
  constexpr R visit(Visitor&& vis, Variants&&... vars);
866
  ```
867
 
868
+ Let *as-variant* denote the following exposition-only function
869
+ templates:
 
 
870
 
871
  ``` cpp
872
+ template<class... Ts>
873
+ auto&& as-variant(variant<Ts...>& var) { return var; }
874
+ template<class... Ts>
875
+ auto&& as-variant(const variant<Ts...>& var) { return var; }
876
+ template<class... Ts>
877
+ auto&& as-variant(variant<Ts...>&& var) { return std::move(var); }
878
+ template<class... Ts>
879
+ auto&& as-variant(const variant<Ts...>&& var) { return std::move(var); }
880
+ ```
881
+
882
+ Let n be `sizeof...(Variants)`. For each 0 ≤ i < n, let `Vᵢ` denote the
883
+ type
884
+ `decltype(`*`as-variant`*`(``std::forward<``Variantsᵢ``>(``varsᵢ``)``))`.
885
+
886
+ *Constraints:* `Vᵢ` is a valid type for all 0 ≤ i < n.
887
+
888
+ Let `V` denote the pack of types `Vᵢ`.
889
+
890
+ Let m be a pack of n values of type `size_t`. Such a pack is valid if
891
+ 0 ≤ mᵢ < `variant_size_v<remove_reference_t<Vᵢ``>>` for all 0 ≤ i < n.
892
+ For each valid pack m, let e(m) denote the expression:
893
+
894
+ ``` cpp
895
+ INVOKE(std::forward<Visitor>(vis), get<m>(std::forward<V>(vars))...) // see [func.require]
896
  ```
897
 
898
  for the first form and
899
 
900
  ``` cpp
901
+ INVOKE<R>(std::forward<Visitor>(vis), get<m>(std::forward<V>(vars))...) // see [func.require]
902
  ```
903
 
904
  for the second form.
905
 
906
+ *Mandates:* For each valid pack m, e(m) is a valid expression. All such
907
+ expressions are of the same type and value category.
908
 
909
+ *Returns:* e(m), where m is the pack for which mᵢ is
910
+ *`as-variant`*`(vars`ᵢ`).index()` for all 0 ≤ i < n. The return type is
911
+ `decltype(`e(m)`)` for the first form.
912
 
913
+ *Throws:* `bad_variant_access` if
914
+ `(`*`as-variant`*`(vars).valueless_by_exception() || ...)` is `true`.
915
 
916
  *Complexity:* For n ≤ 1, the invocation of the callable object is
917
  implemented in constant time, i.e., for n = 1, it does not depend on the
918
+ number of alternative types of `V₀`. For n > 1, the invocation of the
919
+ callable object has no complexity requirements.
920
 
921
  ### Class `monostate` <a id="variant.monostate">[[variant.monostate]]</a>
922
 
923
  ``` cpp
924
  struct monostate{};
 
940
 
941
  ### Specialized algorithms <a id="variant.specalg">[[variant.specalg]]</a>
942
 
943
  ``` cpp
944
  template<class... Types>
945
+ constexpr void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
946
  ```
947
 
948
  *Constraints:*
949
  `is_move_constructible_v<``Tᵢ``> && is_swappable_v<``Tᵢ``>` is `true`
950
  for all i.
951
 
952
  *Effects:* Equivalent to `v.swap(w)`.
953
 
954
+ *Remarks:* The exception specification is equivalent to
955
  `noexcept(v.swap(w))`.
956
 
957
  ### Class `bad_variant_access` <a id="variant.bad.access">[[variant.bad.access]]</a>
958
 
959
  ``` cpp
960
+ namespace std {
961
  class bad_variant_access : public exception {
962
  public:
963
  // see [exception] for the specification of the special member functions
964
  const char* what() const noexcept override;
965
  };
966
+ }
967
  ```
968
 
969
  Objects of type `bad_variant_access` are thrown to report invalid
970
  accesses to the value of a `variant` object.
971