From Jason Turner

[variant]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpjj1lp8ab/{from.md → to.md} +129 -61
tmp/tmpjj1lp8ab/{from.md → to.md} RENAMED
@@ -1,17 +1,21 @@
1
  ## Variants <a id="variant">[[variant]]</a>
2
 
3
- ### In general <a id="variant.general">[[variant.general]]</a>
4
 
5
  A variant object holds and manages the lifetime of a value. If the
6
  `variant` holds a value, that value’s type has to be one of the template
7
  argument types given to `variant`. These template arguments are called
8
  alternatives.
9
 
 
 
 
10
  ### Header `<variant>` synopsis <a id="variant.syn">[[variant.syn]]</a>
11
 
12
  ``` cpp
 
13
  #include <compare> // see [compare.syn]
14
 
15
  namespace std {
16
  // [variant.variant], class template variant
17
  template<class... Types>
@@ -27,11 +31,11 @@ namespace std {
27
  struct variant_size<variant<Types...>>;
28
 
29
  template<size_t I, class T> struct variant_alternative; // not defined
30
  template<size_t I, class T> struct variant_alternative<I, const T>;
31
  template<size_t I, class T>
32
- using variant_alternative_t = typename variant_alternative<I, T>::type;
33
 
34
  template<size_t I, class... Types>
35
  struct variant_alternative<I, variant<Types...>>;
36
 
37
  inline constexpr size_t variant_npos = -1;
@@ -39,26 +43,30 @@ namespace std {
39
  // [variant.get], value access
40
  template<class T, class... Types>
41
  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
42
 
43
  template<size_t I, class... Types>
44
- constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&);
 
45
  template<size_t I, class... Types>
46
- constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&);
 
47
  template<size_t I, class... Types>
48
- constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&);
 
49
  template<size_t I, class... Types>
50
- constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&);
 
51
 
52
  template<class T, class... Types>
53
- constexpr T& get(variant<Types...>&);
54
  template<class T, class... Types>
55
- constexpr T&& get(variant<Types...>&&);
56
  template<class T, class... Types>
57
- constexpr const T& get(const variant<Types...>&);
58
  template<class T, class... Types>
59
- constexpr const T&& get(const variant<Types...>&&);
60
 
61
  template<size_t I, class... Types>
62
  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
63
  get_if(variant<Types...>*) noexcept;
64
  template<size_t I, class... Types>
@@ -167,28 +175,35 @@ namespace std {
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
188
  arguments is ill-formed.
189
 
 
 
 
190
  #### Constructors <a id="variant.ctor">[[variant.ctor]]</a>
191
 
192
  In the descriptions that follow, let i be in the range \[`0`,
193
  `sizeof...(Types)`), and `Tᵢ` be the iᵗʰ type in `Types`.
194
 
@@ -216,11 +231,11 @@ equivalent to `is_nothrow_default_constructible_v<``T₀``>`.
216
  constexpr variant(const variant& w);
217
  ```
218
 
219
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
220
  same alternative as `w` and direct-initializes the contained value with
221
- `get<j>(w)`, where `j` is `w.index()`. Otherwise, initializes the
222
  `variant` to not hold a value.
223
 
224
  *Throws:* Any exception thrown by direct-initializing any `Tᵢ` for all
225
  i.
226
 
@@ -235,12 +250,12 @@ constexpr variant(variant&& w) noexcept(see below);
235
 
236
  *Constraints:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
237
 
238
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
239
  same alternative as `w` and direct-initializes the contained value with
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
@@ -394,11 +409,11 @@ Let j be `rhs.index()`.
394
  value contained in `*this` and sets `*this` to not hold a value.
395
  - Otherwise, if `index() == `j, assigns the value contained in `rhs` to
396
  the value contained in `*this`.
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`.
@@ -422,13 +437,14 @@ Let j be `rhs.index()`.
422
  *Effects:*
423
 
424
  - If neither `*this` nor `rhs` holds a value, there is no effect.
425
  - Otherwise, if `*this` holds a value but `rhs` does not, destroys the
426
  value contained in `*this` and sets `*this` to not hold a value.
427
- - Otherwise, if `index() == `j, assigns `get<`j`>(std::move(rhs))` to
428
- the value contained in `*this`.
429
- - Otherwise, equivalent to `emplace<`j`>(get<`j`>(std::move(rhs)))`.
 
430
 
431
  *Returns:* `*this`.
432
 
433
  *Remarks:* If `is_trivially_move_constructible_v<``Tᵢ``> &&`
434
  `is_trivially_move_assignable_v<``Tᵢ``> &&`
@@ -626,26 +642,27 @@ requirements [[swappable.requirements]].
626
  *Effects:*
627
 
628
  - If `valueless_by_exception() && rhs.valueless_by_exception()` no
629
  effect.
630
  - Otherwise, if `index() == rhs.index()`, calls
631
- `swap(get<`i`>(*this), get<`i`>(rhs))` where i is `index()`.
 
632
  - Otherwise, exchanges values of `rhs` and `*this`.
633
 
634
  *Throws:* If `index() == rhs.index()`, any exception thrown by
635
- `swap(get<`i`>(*this), get<`i`>(rhs))` with i being `index()`.
636
- Otherwise, any exception thrown by the move constructor of `Tᵢ` or `Tⱼ`
637
- with i being `index()` and j being `rhs.index()`.
638
 
639
  *Remarks:* If an exception is thrown during the call to function
640
- `swap(get<`i`>(*this), get<`i`>(rhs))`, the states of the contained
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
 
@@ -676,19 +693,19 @@ 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
681
- typedef `type` that names the type `add_const_t<VA::type>`.
682
 
683
  ``` cpp
684
  variant_alternative<I, variant<Types...>>::type
685
  ```
686
 
687
  *Mandates:* `I` < `sizeof...(Types)`.
688
 
689
- *Type:* The type `T_I`.
690
 
691
  ### Value access <a id="variant.get">[[variant.get]]</a>
692
 
693
  ``` cpp
694
  template<class T, class... Types>
@@ -698,10 +715,31 @@ template<class T, class... Types>
698
  *Mandates:* The type `T` occurs exactly once in `Types`.
699
 
700
  *Returns:* `true` if `index()` is equal to the zero-based index of `T`
701
  in `Types`.
702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
  ``` cpp
704
  template<size_t I, class... Types>
705
  constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v);
706
  template<size_t I, class... Types>
707
  constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v);
@@ -762,81 +800,83 @@ zero-based index of `T` in `Types`.
762
  ``` cpp
763
  template<class... Types>
764
  constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
765
  ```
766
 
767
- *Mandates:* `get<`i`>(v) == get<`i`>(w)` is a valid expression that is
768
- convertible to `bool`, for all i.
769
 
770
  *Returns:* If `v.index() != w.index()`, `false`; otherwise if
771
  `v.valueless_by_exception()`, `true`; otherwise
772
- `get<`i`>(v) == get<`i`>(w)` with i being `v.index()`.
773
 
774
  ``` cpp
775
  template<class... Types>
776
  constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
777
  ```
778
 
779
- *Mandates:* `get<`i`>(v) != get<`i`>(w)` is a valid expression that is
780
- convertible to `bool`, for all i.
781
 
782
  *Returns:* If `v.index() != w.index()`, `true`; otherwise if
783
  `v.valueless_by_exception()`, `false`; otherwise
784
- `get<`i`>(v) != get<`i`>(w)` with i being `v.index()`.
785
 
786
  ``` cpp
787
  template<class... Types>
788
  constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
789
  ```
790
 
791
- *Mandates:* `get<`i`>(v) < get<`i`>(w)` is a valid expression that is
792
- convertible to `bool`, for all i.
793
 
794
  *Returns:* If `w.valueless_by_exception()`, `false`; otherwise if
795
  `v.valueless_by_exception()`, `true`; otherwise, if
796
  `v.index() < w.index()`, `true`; otherwise if `v.index() > w.index()`,
797
- `false`; otherwise `get<`i`>(v) < get<`i`>(w)` with i being `v.index()`.
 
798
 
799
  ``` cpp
800
  template<class... Types>
801
  constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
802
  ```
803
 
804
- *Mandates:* `get<`i`>(v) > get<`i`>(w)` is a valid expression that is
805
- convertible to `bool`, for all i.
806
 
807
  *Returns:* If `v.valueless_by_exception()`, `false`; otherwise if
808
  `w.valueless_by_exception()`, `true`; otherwise, if
809
  `v.index() > w.index()`, `true`; otherwise if `v.index() < w.index()`,
810
- `false`; otherwise `get<`i`>(v) > get<`i`>(w)` with i being `v.index()`.
 
811
 
812
  ``` cpp
813
  template<class... Types>
814
  constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
815
  ```
816
 
817
- *Mandates:* `get<`i`>(v) <= get<`i`>(w)` is a valid expression that is
818
- convertible to `bool`, for all i.
819
 
820
  *Returns:* If `v.valueless_by_exception()`, `true`; otherwise if
821
  `w.valueless_by_exception()`, `false`; otherwise, if
822
  `v.index() < w.index()`, `true`; otherwise if `v.index() > w.index()`,
823
- `false`; otherwise `get<`i`>(v) <= get<`i`>(w)` with i being
824
  `v.index()`.
825
 
826
  ``` cpp
827
  template<class... Types>
828
  constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
829
  ```
830
 
831
- *Mandates:* `get<`i`>(v) >= get<`i`>(w)` is a valid expression that is
832
- convertible to `bool`, for all i.
833
 
834
  *Returns:* If `w.valueless_by_exception()`, `true`; otherwise if
835
  `v.valueless_by_exception()`, `false`; otherwise, if
836
  `v.index() > w.index()`, `true`; otherwise if `v.index() < w.index()`,
837
- `false`; otherwise `get<`i`>(v) >= get<`i`>(w)` with i being
838
  `v.index()`.
839
 
840
  ``` cpp
841
  template<class... Types> requires (three_way_comparable<Types> && ...)
842
  constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
@@ -849,11 +889,11 @@ template<class... Types> requires (three_way_comparable<Types> && ...)
849
  if (v.valueless_by_exception() && w.valueless_by_exception())
850
  return strong_ordering::equal;
851
  if (v.valueless_by_exception()) return strong_ordering::less;
852
  if (w.valueless_by_exception()) return strong_ordering::greater;
853
  if (auto c = v.index() <=> w.index(); c != 0) return c;
854
- return get<i>(v) <=> get<i>(w);
855
  ```
856
 
857
  with i being `v.index()`.
858
 
859
  ### Visitation <a id="variant.visit">[[variant.visit]]</a>
@@ -868,17 +908,17 @@ template<class R, class Visitor, class... Variants>
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ᵢ``)``))`.
@@ -890,17 +930,17 @@ Let `V` denote the pack of types `Vᵢ`.
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
@@ -916,10 +956,37 @@ expressions are of the same type and value category.
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{};
925
  ```
@@ -959,23 +1026,24 @@ for all i.
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
 
972
  ``` cpp
973
- const char* what() const noexcept override;
974
  ```
975
 
976
- *Returns:* An *implementation-defined* NTBS.
 
977
 
978
  ### Hash support <a id="variant.hash">[[variant.hash]]</a>
979
 
980
  ``` cpp
981
  template<class... Types> struct hash<variant<Types...>>;
 
1
  ## Variants <a id="variant">[[variant]]</a>
2
 
3
+ ### General <a id="variant.general">[[variant.general]]</a>
4
 
5
  A variant object holds and manages the lifetime of a value. If the
6
  `variant` holds a value, that value’s type has to be one of the template
7
  argument types given to `variant`. These template arguments are called
8
  alternatives.
9
 
10
+ In [[variant]], *`GET`* denotes a set of exposition-only function
11
+ templates [[variant.get]].
12
+
13
  ### Header `<variant>` synopsis <a id="variant.syn">[[variant.syn]]</a>
14
 
15
  ``` cpp
16
+ // mostly freestanding
17
  #include <compare> // see [compare.syn]
18
 
19
  namespace std {
20
  // [variant.variant], class template variant
21
  template<class... Types>
 
31
  struct variant_size<variant<Types...>>;
32
 
33
  template<size_t I, class T> struct variant_alternative; // not defined
34
  template<size_t I, class T> struct variant_alternative<I, const T>;
35
  template<size_t I, class T>
36
+ using variant_alternative_t = variant_alternative<I, T>::type;
37
 
38
  template<size_t I, class... Types>
39
  struct variant_alternative<I, variant<Types...>>;
40
 
41
  inline constexpr size_t variant_npos = -1;
 
43
  // [variant.get], value access
44
  template<class T, class... Types>
45
  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
46
 
47
  template<size_t I, class... Types>
48
+ constexpr variant_alternative_t<I, variant<Types...>>&
49
+ get(variant<Types...>&); // freestanding-deleted
50
  template<size_t I, class... Types>
51
+ constexpr variant_alternative_t<I, variant<Types...>>&&
52
+ get(variant<Types...>&&); // freestanding-deleted
53
  template<size_t I, class... Types>
54
+ constexpr const variant_alternative_t<I, variant<Types...>>&
55
+ get(const variant<Types...>&); // freestanding-deleted
56
  template<size_t I, class... Types>
57
+ constexpr const variant_alternative_t<I, variant<Types...>>&&
58
+ get(const variant<Types...>&&); // freestanding-deleted
59
 
60
  template<class T, class... Types>
61
+ constexpr T& get(variant<Types...>&); // freestanding-deleted
62
  template<class T, class... Types>
63
+ constexpr T&& get(variant<Types...>&&); // freestanding-deleted
64
  template<class T, class... Types>
65
+ constexpr const T& get(const variant<Types...>&); // freestanding-deleted
66
  template<class T, class... Types>
67
+ constexpr const T&& get(const variant<Types...>&&); // freestanding-deleted
68
 
69
  template<size_t I, class... Types>
70
  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
71
  get_if(variant<Types...>*) noexcept;
72
  template<size_t I, class... Types>
 
175
  constexpr bool valueless_by_exception() const noexcept;
176
  constexpr size_t index() const noexcept;
177
 
178
  // [variant.swap], swap
179
  constexpr void swap(variant&) noexcept(see below);
180
+
181
+ // [variant.visit], visitation
182
+ template<class Self, class Visitor>
183
+ constexpr decltype(auto) visit(this Self&&, Visitor&&);
184
+ template<class R, class Self, class Visitor>
185
+ constexpr R visit(this Self&&, Visitor&&);
186
  };
187
  }
188
  ```
189
 
190
  Any instance of `variant` at any given time either holds a value of one
191
  of its alternative types or holds no value. When an instance of
192
  `variant` holds a value of alternative type `T`, it means that a value
193
  of type `T`, referred to as the `variant` object’s *contained value*, is
194
+ nested within [[intro.object]] the `variant` object.
 
 
195
 
196
  All types in `Types` shall meet the *Cpp17Destructible* requirements (
197
  [[cpp17.destructible]]).
198
 
199
  A program that instantiates the definition of `variant` with no template
200
  arguments is ill-formed.
201
 
202
+ If a program declares an explicit or partial specialization of
203
+ `variant`, the program is ill-formed, no diagnostic required.
204
+
205
  #### Constructors <a id="variant.ctor">[[variant.ctor]]</a>
206
 
207
  In the descriptions that follow, let i be in the range \[`0`,
208
  `sizeof...(Types)`), and `Tᵢ` be the iᵗʰ type in `Types`.
209
 
 
231
  constexpr variant(const variant& w);
232
  ```
233
 
234
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
235
  same alternative as `w` and direct-initializes the contained value with
236
+ *`GET`*`<j>(w)`, where `j` is `w.index()`. Otherwise, initializes the
237
  `variant` to not hold a value.
238
 
239
  *Throws:* Any exception thrown by direct-initializing any `Tᵢ` for all
240
  i.
241
 
 
250
 
251
  *Constraints:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
252
 
253
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
254
  same alternative as `w` and direct-initializes the contained value with
255
+ *`GET`*`<j>(std::move(w))`, where `j` is `w.index()`. Otherwise,
256
+ initializes the `variant` to not hold a value.
257
 
258
  *Throws:* Any exception thrown by move-constructing any `Tᵢ` for all i.
259
 
260
  *Remarks:* The exception specification is equivalent to the logical of
261
  `is_nothrow_move_constructible_v<``Tᵢ``>` for all i. If
 
409
  value contained in `*this` and sets `*this` to not hold a value.
410
  - Otherwise, if `index() == `j, assigns the value contained in `rhs` to
411
  the value contained in `*this`.
412
  - Otherwise, if either `is_nothrow_copy_constructible_v<``Tⱼ``>` is
413
  `true` or `is_nothrow_move_constructible_v<``Tⱼ``>` is `false`,
414
+ equivalent to `emplace<`j`>(`*`GET`*`<`j`>(rhs))`.
415
  - Otherwise, equivalent to `operator=(variant(rhs))`.
416
 
417
  *Ensures:* `index() == rhs.index()`.
418
 
419
  *Returns:* `*this`.
 
437
  *Effects:*
438
 
439
  - If neither `*this` nor `rhs` holds a value, there is no effect.
440
  - Otherwise, if `*this` holds a value but `rhs` does not, destroys the
441
  value contained in `*this` and sets `*this` to not hold a value.
442
+ - Otherwise, if `index() == `j, assigns *`GET`*`<`j`>(std::move(rhs))`
443
+ to the value contained in `*this`.
444
+ - Otherwise, equivalent to
445
+ `emplace<`j`>(`*`GET`*`<`j`>(std::move(rhs)))`.
446
 
447
  *Returns:* `*this`.
448
 
449
  *Remarks:* If `is_trivially_move_constructible_v<``Tᵢ``> &&`
450
  `is_trivially_move_assignable_v<``Tᵢ``> &&`
 
642
  *Effects:*
643
 
644
  - If `valueless_by_exception() && rhs.valueless_by_exception()` no
645
  effect.
646
  - Otherwise, if `index() == rhs.index()`, calls
647
+ `swap(`*`GET`*`<`i`>(*this), `*`GET`*`<`i`>(rhs))` where i is
648
+ `index()`.
649
  - Otherwise, exchanges values of `rhs` and `*this`.
650
 
651
  *Throws:* If `index() == rhs.index()`, any exception thrown by
652
+ `swap(`*`GET`*`<`i`>(*this), `*`GET`*`<`i`>(rhs))` with i being
653
+ `index()`. Otherwise, any exception thrown by the move constructor of
654
+ `Tᵢ` or `Tⱼ` with i being `index()` and j being `rhs.index()`.
655
 
656
  *Remarks:* If an exception is thrown during the call to function
657
+ `swap(`*`GET`*`<`i`>(*this), `*`GET`*`<`i`>(rhs))`, the states of the
658
+ contained values of `*this` and of `rhs` are determined by the exception
659
+ safety guarantee of `swap` for lvalues of `Tᵢ` with i being `index()`.
660
+ If an exception is thrown during the exchange of the values of `*this`
661
+ and `rhs`, the states of the values of `*this` and of `rhs` are
662
+ determined by the exception safety guarantee of `variant`’s move
663
+ constructor. The exception specification is equivalent to the logical of
664
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_swappable_v<``Tᵢ``>`
665
  for all i.
666
 
667
  ### `variant` helper classes <a id="variant.helper">[[variant.helper]]</a>
668
 
 
693
  ```
694
 
695
  Let `VA` denote `variant_alternative<I, T>` of the cv-unqualified type
696
  `T`. Then each specialization of the template meets the
697
  *Cpp17TransformationTrait* requirements [[meta.rqmts]] with a member
698
+ typedef `type` that names the type `const VA::type`.
699
 
700
  ``` cpp
701
  variant_alternative<I, variant<Types...>>::type
702
  ```
703
 
704
  *Mandates:* `I` < `sizeof...(Types)`.
705
 
706
+ *Result:* The type `T_I`.
707
 
708
  ### Value access <a id="variant.get">[[variant.get]]</a>
709
 
710
  ``` cpp
711
  template<class T, class... Types>
 
715
  *Mandates:* The type `T` occurs exactly once in `Types`.
716
 
717
  *Returns:* `true` if `index()` is equal to the zero-based index of `T`
718
  in `Types`.
719
 
720
+ ``` cpp
721
+ template<size_t I, class... Types>
722
+ constexpr variant_alternative_t<I, variant<Types...>>&
723
+ GET(variant<Types...>& v); // exposition only
724
+ template<size_t I, class... Types>
725
+ constexpr variant_alternative_t<I, variant<Types...>>&&
726
+ GET(variant<Types...>&& v); // exposition only
727
+ template<size_t I, class... Types>
728
+ constexpr const variant_alternative_t<I, variant<Types...>>&
729
+ GET(const variant<Types...>& v); // exposition only
730
+ template<size_t I, class... Types>
731
+ constexpr const variant_alternative_t<I, variant<Types...>>&&
732
+ GET(const variant<Types...>&& v); // exposition only
733
+ ```
734
+
735
+ *Mandates:* `I` < `sizeof...(Types)`.
736
+
737
+ *Preconditions:* `v.index()` is `I`.
738
+
739
+ *Returns:* A reference to the object stored in the `variant`.
740
+
741
  ``` cpp
742
  template<size_t I, class... Types>
743
  constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v);
744
  template<size_t I, class... Types>
745
  constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v);
 
800
  ``` cpp
801
  template<class... Types>
802
  constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
803
  ```
804
 
805
+ *Constraints:* *`GET`*`<`i`>(v) == `*`GET`*`<`i`>(w)` is a valid
806
+ expression that is convertible to `bool`, for all i.
807
 
808
  *Returns:* If `v.index() != w.index()`, `false`; otherwise if
809
  `v.valueless_by_exception()`, `true`; otherwise
810
+ *`GET`*`<`i`>(v) == `*`GET`*`<`i`>(w)` with i being `v.index()`.
811
 
812
  ``` cpp
813
  template<class... Types>
814
  constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
815
  ```
816
 
817
+ *Constraints:* *`GET`*`<`i`>(v) != `*`GET`*`<`i`>(w)` is a valid
818
+ expression that is convertible to `bool`, for all i.
819
 
820
  *Returns:* If `v.index() != w.index()`, `true`; otherwise if
821
  `v.valueless_by_exception()`, `false`; otherwise
822
+ *`GET`*`<`i`>(v) != `*`GET`*`<`i`>(w)` with i being `v.index()`.
823
 
824
  ``` cpp
825
  template<class... Types>
826
  constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
827
  ```
828
 
829
+ *Constraints:* *`GET`*`<`i`>(v) < `*`GET`*`<`i`>(w)` is a valid
830
+ expression that is convertible to `bool`, for all i.
831
 
832
  *Returns:* If `w.valueless_by_exception()`, `false`; otherwise if
833
  `v.valueless_by_exception()`, `true`; otherwise, if
834
  `v.index() < w.index()`, `true`; otherwise if `v.index() > w.index()`,
835
+ `false`; otherwise *`GET`*`<`i`>(v) < `*`GET`*`<`i`>(w)` with i being
836
+ `v.index()`.
837
 
838
  ``` cpp
839
  template<class... Types>
840
  constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
841
  ```
842
 
843
+ *Constraints:* *`GET`*`<`i`>(v) > `*`GET`*`<`i`>(w)` is a valid
844
+ expression that is convertible to `bool`, for all i.
845
 
846
  *Returns:* If `v.valueless_by_exception()`, `false`; otherwise if
847
  `w.valueless_by_exception()`, `true`; otherwise, if
848
  `v.index() > w.index()`, `true`; otherwise if `v.index() < w.index()`,
849
+ `false`; otherwise *`GET`*`<`i`>(v) > `*`GET`*`<`i`>(w)` with i being
850
+ `v.index()`.
851
 
852
  ``` cpp
853
  template<class... Types>
854
  constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
855
  ```
856
 
857
+ *Constraints:* *`GET`*`<`i`>(v) <= `*`GET`*`<`i`>(w)` is a valid
858
+ expression that is convertible to `bool`, for all i.
859
 
860
  *Returns:* If `v.valueless_by_exception()`, `true`; otherwise if
861
  `w.valueless_by_exception()`, `false`; otherwise, if
862
  `v.index() < w.index()`, `true`; otherwise if `v.index() > w.index()`,
863
+ `false`; otherwise *`GET`*`<`i`>(v) <= `*`GET`*`<`i`>(w)` with i being
864
  `v.index()`.
865
 
866
  ``` cpp
867
  template<class... Types>
868
  constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
869
  ```
870
 
871
+ *Constraints:* *`GET`*`<`i`>(v) >= `*`GET`*`<`i`>(w)` is a valid
872
+ expression that is convertible to `bool`, for all i.
873
 
874
  *Returns:* If `w.valueless_by_exception()`, `true`; otherwise if
875
  `v.valueless_by_exception()`, `false`; otherwise, if
876
  `v.index() > w.index()`, `true`; otherwise if `v.index() < w.index()`,
877
+ `false`; otherwise *`GET`*`<`i`>(v) >= `*`GET`*`<`i`>(w)` with i being
878
  `v.index()`.
879
 
880
  ``` cpp
881
  template<class... Types> requires (three_way_comparable<Types> && ...)
882
  constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
 
889
  if (v.valueless_by_exception() && w.valueless_by_exception())
890
  return strong_ordering::equal;
891
  if (v.valueless_by_exception()) return strong_ordering::less;
892
  if (w.valueless_by_exception()) return strong_ordering::greater;
893
  if (auto c = v.index() <=> w.index(); c != 0) return c;
894
+ return GET<i>(v) <=> GET<i>(w);
895
  ```
896
 
897
  with i being `v.index()`.
898
 
899
  ### Visitation <a id="variant.visit">[[variant.visit]]</a>
 
908
  Let *as-variant* denote the following exposition-only function
909
  templates:
910
 
911
  ``` cpp
912
  template<class... Ts>
913
+ constexpr auto&& as-variant(variant<Ts...>& var) { return var; }
914
  template<class... Ts>
915
+ constexpr auto&& as-variant(const variant<Ts...>& var) { return var; }
916
  template<class... Ts>
917
+ constexpr auto&& as-variant(variant<Ts...>&& var) { return std::move(var); }
918
  template<class... Ts>
919
+ constexpr auto&& as-variant(const variant<Ts...>&& var) { return std::move(var); }
920
  ```
921
 
922
  Let n be `sizeof...(Variants)`. For each 0 ≤ i < n, let `Vᵢ` denote the
923
  type
924
  `decltype(`*`as-variant`*`(``std::forward<``Variantsᵢ``>(``varsᵢ``)``))`.
 
930
  Let m be a pack of n values of type `size_t`. Such a pack is valid if
931
  0 ≤ mᵢ < `variant_size_v<remove_reference_t<Vᵢ``>>` for all 0 ≤ i < n.
932
  For each valid pack m, let e(m) denote the expression:
933
 
934
  ``` cpp
935
+ INVOKE(std::forward<Visitor>(vis), GET<m>(std::forward<V>(vars))...) // see [func.require]
936
  ```
937
 
938
  for the first form and
939
 
940
  ``` cpp
941
+ INVOKE<R>(std::forward<Visitor>(vis), GET<m>(std::forward<V>(vars))...) // see [func.require]
942
  ```
943
 
944
  for the second form.
945
 
946
  *Mandates:* For each valid pack m, e(m) is a valid expression. All such
 
956
  *Complexity:* For n ≤ 1, the invocation of the callable object is
957
  implemented in constant time, i.e., for n = 1, it does not depend on the
958
  number of alternative types of `V₀`. For n > 1, the invocation of the
959
  callable object has no complexity requirements.
960
 
961
+ ``` cpp
962
+ template<class Self, class Visitor>
963
+ constexpr decltype(auto) visit(this Self&& self, Visitor&& vis);
964
+ ```
965
+
966
+ Let `V` be
967
+ *`OVERRIDE_REF`*`(Self&&, `*`COPY_CONST`*`(remove_reference_t<Self>, variant))`
968
+ [[forward]].
969
+
970
+ *Constraints:* The call to `visit` does not use an explicit
971
+ *template-argument-list* that begins with a type *template-argument*.
972
+
973
+ *Effects:* Equivalent to:
974
+ `return std::visit(std::forward<Visitor>(vis), (V)self);`
975
+
976
+ ``` cpp
977
+ template<class R, class Self, class Visitor>
978
+ constexpr R visit(this Self&& self, Visitor&& vis);
979
+ ```
980
+
981
+ Let `V` be
982
+ *`OVERRIDE_REF`*`(Self&&, `*`COPY_CONST`*`(remove_reference_t<Self>, variant))`
983
+ [[forward]].
984
+
985
+ *Effects:* Equivalent to:
986
+ `return std::visit<R>(std::forward<Visitor>(vis), (V)self);`
987
+
988
  ### Class `monostate` <a id="variant.monostate">[[variant.monostate]]</a>
989
 
990
  ``` cpp
991
  struct monostate{};
992
  ```
 
1026
  ``` cpp
1027
  namespace std {
1028
  class bad_variant_access : public exception {
1029
  public:
1030
  // see [exception] for the specification of the special member functions
1031
+ constexpr const char* what() const noexcept override;
1032
  };
1033
  }
1034
  ```
1035
 
1036
  Objects of type `bad_variant_access` are thrown to report invalid
1037
  accesses to the value of a `variant` object.
1038
 
1039
  ``` cpp
1040
+ constexpr const char* what() const noexcept override;
1041
  ```
1042
 
1043
+ *Returns:* An *implementation-defined* NTBS, which during constant
1044
+ evaluation is encoded with the ordinary literal encoding [[lex.ccon]].
1045
 
1046
  ### Hash support <a id="variant.hash">[[variant.hash]]</a>
1047
 
1048
  ``` cpp
1049
  template<class... Types> struct hash<variant<Types...>>;