From Jason Turner

[variant.variant]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp0wwx_uby/{from.md → to.md} +181 -221
tmp/tmp0wwx_uby/{from.md → to.md} RENAMED
@@ -5,12 +5,12 @@ namespace std {
5
  template<class... Types>
6
  class variant {
7
  public:
8
  // [variant.ctor], constructors
9
  constexpr variant() noexcept(see below);
10
- variant(const variant&);
11
- variant(variant&&) noexcept(see below);
12
 
13
  template<class T>
14
  constexpr variant(T&&) noexcept(see below);
15
 
16
  template<class T, class... Args>
@@ -21,36 +21,16 @@ namespace std {
21
  template<size_t I, class... Args>
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
- // allocator-extended constructors
27
- template <class Alloc>
28
- variant(allocator_arg_t, const Alloc&);
29
- template <class Alloc>
30
- variant(allocator_arg_t, const Alloc&, const variant&);
31
- template <class Alloc>
32
- variant(allocator_arg_t, const Alloc&, variant&&);
33
- template <class Alloc, class T>
34
- variant(allocator_arg_t, const Alloc&, T&&);
35
- template <class Alloc, class T, class... Args>
36
- variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, Args&&...);
37
- template <class Alloc, class T, class U, class... Args>
38
- variant(allocator_arg_t, const Alloc&, in_place_type_t<T>,
39
- initializer_list<U>, Args&&...);
40
- template <class Alloc, size_t I, class... Args>
41
- variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, Args&&...);
42
- template <class Alloc, size_t I, class U, class... Args>
43
- variant(allocator_arg_t, const Alloc&, in_place_index_t<I>,
44
- initializer_list<U>, Args&&...);
45
-
46
  // [variant.dtor], destructor
47
  ~variant();
48
 
49
  // [variant.assign], assignment
50
- variant& operator=(const variant&);
51
- variant& operator=(variant&&) noexcept(see below);
52
 
53
  template<class T> variant& operator=(T&&) noexcept(see below);
54
 
55
  // [variant.mod], modifiers
56
  template<class T, class... Args>
@@ -71,352 +51,327 @@ namespace std {
71
  };
72
  }
73
  ```
74
 
75
  Any instance of `variant` at any given time either holds a value of one
76
- of its alternative types, or it holds no value. When an instance of
77
  `variant` holds a value of alternative type `T`, it means that a value
78
  of type `T`, referred to as the `variant` object’s *contained value*, is
79
  allocated within the storage of the `variant` object. Implementations
80
  are not permitted to use additional storage, such as dynamic memory, to
81
  allocate the contained value. The contained value shall be allocated in
82
  a region of the `variant` storage suitably aligned for all types in
83
- `Types...`. It is *implementation-defined* whether over-aligned types
84
- are supported.
85
 
86
- All types in `Types...` shall be (possibly cv-qualified) object types
87
- that are not arrays.
88
 
89
  A program that instantiates the definition of `variant` with no template
90
  arguments is ill-formed.
91
 
92
  #### Constructors <a id="variant.ctor">[[variant.ctor]]</a>
93
 
94
  In the descriptions that follow, let i be in the range \[`0`,
95
- `sizeof...(Types)`), and `Tᵢ` be the iᵗʰ type in `Types...`.
96
 
97
  ``` cpp
98
  constexpr variant() noexcept(see below);
99
  ```
100
 
 
 
101
  *Effects:* Constructs a `variant` holding a value-initialized value of
102
  type `T₀`.
103
 
104
- *Postconditions:* `valueless_by_exception()` is `false` and `index()` is
105
- `0`.
106
 
107
  *Throws:* Any exception thrown by the value-initialization of `T₀`.
108
 
109
- *Remarks:* This function shall be `constexpr` if and only if the
110
  value-initialization of the alternative type `T₀` would satisfy the
111
  requirements for a constexpr function. The expression inside `noexcept`
112
- is equivalent to `is_nothrow_default_constructible_v<``T₀``>`. This
113
- function shall not participate in overload resolution unless
114
- `is_default_constructible_v<``T₀``>` is `true`.
115
 
116
  [*Note 1*: See also class `monostate`. — *end note*]
117
 
118
  ``` cpp
119
- variant(const variant& w);
120
  ```
121
 
122
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
123
  same alternative as `w` and direct-initializes the contained value with
124
  `get<j>(w)`, where `j` is `w.index()`. Otherwise, initializes the
125
  `variant` to not hold a value.
126
 
127
  *Throws:* Any exception thrown by direct-initializing any `Tᵢ` for all
128
  i.
129
 
130
- *Remarks:* This function shall not participate in overload resolution
131
- unless `is_copy_constructible_v<``Tᵢ``>` is `true` for all i.
 
 
132
 
133
  ``` cpp
134
- variant(variant&& w) noexcept(see below);
135
  ```
136
 
 
 
137
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
138
  same alternative as `w` and direct-initializes the contained value with
139
  `get<j>(std::move(w))`, where `j` is `w.index()`. Otherwise, initializes
140
  the `variant` to not hold a value.
141
 
142
  *Throws:* Any exception thrown by move-constructing any `Tᵢ` for all i.
143
 
144
  *Remarks:* The expression inside `noexcept` is equivalent to the logical
145
- AND of `is_nothrow_move_constructible_v<``Tᵢ``>` for all i. This
146
- function shall not participate in overload resolution unless
147
- `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
148
 
149
  ``` cpp
150
  template<class T> constexpr variant(T&& t) noexcept(see below);
151
  ```
152
 
153
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
154
- function *FUN*(Tᵢ) for each alternative type `Tᵢ`. The overload
155
- *FUN*(T) selected by overload resolution for the expression
156
- *FUN*(std::forward\<T\>(t)) defines the alternative `Tⱼ` which is the
157
- type of the contained value after construction.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  *Effects:* Initializes `*this` to hold the alternative type `Tⱼ` and
160
  direct-initializes the contained value as if
161
  direct-non-list-initializing it with `std::forward<T>(t)`.
162
 
163
- *Postconditions:* `holds_alternative<``Tⱼ``>(*this)` is `true`.
164
 
165
  *Throws:* Any exception thrown by the initialization of the selected
166
  alternative `Tⱼ`.
167
 
168
- *Remarks:* This function shall not participate in overload resolution
169
- unless `is_same_v<decay_t<T>, variant>` is `false`, unless `decay_t<T>`
170
- is neither a specialization of `in_place_type_t` nor a specialization of
171
- `in_place_index_t`, unless `is_constructible_v<``Tⱼ``, T>` is `true`,
172
- and unless the expression *FUN*(`std::forward<T>(t))` (with *FUN* being
173
- the above-mentioned set of imaginary functions) is well formed.
174
-
175
- [*Note 2*:
176
-
177
- ``` cpp
178
- variant<string, string> v("abc");
179
- ```
180
-
181
- is ill-formed, as both alternative types have an equally viable
182
- constructor for the argument.
183
-
184
- — *end note*]
185
-
186
- The expression inside `noexcept` is equivalent to
187
  `is_nothrow_constructible_v<``Tⱼ``, T>`. If `Tⱼ`’s selected constructor
188
- is a constexpr constructor, this constructor shall be a constexpr
189
- constructor.
190
 
191
  ``` cpp
192
  template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
193
  ```
194
 
 
 
 
 
 
195
  *Effects:* Initializes the contained value as if
196
  direct-non-list-initializing an object of type `T` with the arguments
197
  `std::forward<Args>(args)...`.
198
 
199
- *Postconditions:* `holds_alternative<T>(*this)` is `true`.
200
 
201
  *Throws:* Any exception thrown by calling the selected constructor of
202
  `T`.
203
 
204
- *Remarks:* This function shall not participate in overload resolution
205
- unless there is exactly one occurrence of `T` in `Types...` and
206
- `is_constructible_v<T, Args...>` is `true`. If `T`’s selected
207
- constructor is a constexpr constructor, this constructor shall be a
208
- constexpr constructor.
209
 
210
  ``` cpp
211
  template<class T, class U, class... Args>
212
  constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
213
  ```
214
 
 
 
 
 
 
215
  *Effects:* Initializes the contained value as if
216
  direct-non-list-initializing an object of type `T` with the arguments
217
  `il, std::forward<Args>(args)...`.
218
 
219
- *Postconditions:* `holds_alternative<T>(*this)` is `true`.
220
 
221
  *Throws:* Any exception thrown by calling the selected constructor of
222
  `T`.
223
 
224
- *Remarks:* This function shall not participate in overload resolution
225
- unless there is exactly one occurrence of `T` in `Types...` and
226
- `is_constructible_v<T, initializer_list<U>&, Args...>` is `true`. If
227
- `T`’s selected constructor is a constexpr constructor, this constructor
228
- shall be a constexpr constructor.
229
 
230
  ``` cpp
231
  template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
232
  ```
233
 
234
- *Effects:* Initializes the contained value as if
235
- direct-non-list-initializing an object of type `T_I` with the arguments
236
- `std::forward<Args>(args)...`.
237
-
238
- *Postconditions:* `index()` is `I`.
239
-
240
- *Throws:* Any exception thrown by calling the selected constructor of
241
- `T_I`.
242
-
243
- *Remarks:* This function shall not participate in overload resolution
244
- unless
245
 
246
  - `I` is less than `sizeof...(Types)` and
247
  - `is_constructible_v<``T_I``, Args...>` is `true`.
248
 
249
- If `T_I`’s selected constructor is a constexpr constructor, this
250
- constructor shall be a constexpr constructor.
 
 
 
 
 
 
 
 
 
251
 
252
  ``` cpp
253
  template<size_t I, class U, class... Args>
254
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
255
  ```
256
 
257
- *Effects:* Initializes the contained value as if
258
- direct-non-list-initializing an object of type `T_I` with the arguments
259
- `il, std::forward<Args>(args)...`.
260
-
261
- *Postconditions:* `index()` is `I`.
262
-
263
- *Remarks:* This function shall not participate in overload resolution
264
- unless
265
 
266
  - `I` is less than `sizeof...(Types)` and
267
  - `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is
268
  `true`.
269
 
270
- If `T_I`’s selected constructor is a constexpr constructor, this
271
- constructor shall be a constexpr constructor.
 
272
 
273
- ``` cpp
274
- // allocator-extended constructors
275
- template <class Alloc>
276
- variant(allocator_arg_t, const Alloc& a);
277
- template <class Alloc>
278
- variant(allocator_arg_t, const Alloc& a, const variant& v);
279
- template <class Alloc>
280
- variant(allocator_arg_t, const Alloc& a, variant&& v);
281
- template <class Alloc, class T>
282
- variant(allocator_arg_t, const Alloc& a, T&& t);
283
- template <class Alloc, class T, class... Args>
284
- variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, Args&&... args);
285
- template <class Alloc, class T, class U, class... Args>
286
- variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>,
287
- initializer_list<U> il, Args&&... args);
288
- template <class Alloc, size_t I, class... Args>
289
- variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, Args&&... args);
290
- template <class Alloc, size_t I, class U, class... Args>
291
- variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>,
292
- initializer_list<U> il, Args&&... args);
293
- ```
294
 
295
- *Requires:* `Alloc` shall meet the requirements for an
296
- Allocator ([[allocator.requirements]]).
297
-
298
- *Effects:* Equivalent to the preceding constructors except that the
299
- contained value is constructed with uses-allocator
300
- construction ([[allocator.uses.construction]]).
301
 
302
  #### Destructor <a id="variant.dtor">[[variant.dtor]]</a>
303
 
304
  ``` cpp
305
  ~variant();
306
  ```
307
 
308
  *Effects:* If `valueless_by_exception()` is `false`, destroys the
309
  currently contained value.
310
 
311
- *Remarks:* If `is_trivially_destructible_v<``Tᵢ``> == true` for all `Tᵢ`
312
- then this destructor shall be a trivial destructor.
313
 
314
  #### Assignment <a id="variant.assign">[[variant.assign]]</a>
315
 
316
  ``` cpp
317
- variant& operator=(const variant& rhs);
318
  ```
319
 
320
  Let j be `rhs.index()`.
321
 
322
  *Effects:*
323
 
324
  - If neither `*this` nor `rhs` holds a value, there is no effect.
325
- Otherwise,
326
- - if `*this` holds a value but `rhs` does not, destroys the value
327
- contained in `*this` and sets `*this` to not hold a value. Otherwise,
328
- - if `index() == `j, assigns the value contained in `rhs` to the value
329
- contained in `*this`. Otherwise,
330
- - if either `is_nothrow_copy_constructible_v<``Tⱼ``>` or
331
- `!is_nothrow_move_constructible_v<``Tⱼ``>` is `true`, equivalent to
332
- `emplace<`j`>(get<`j`>(rhs))`. Otherwise,
333
- - equivalent to `operator=(variant(rhs))`.
334
 
335
  *Returns:* `*this`.
336
 
337
- *Postconditions:* `index() == rhs.index()`.
338
 
339
- *Remarks:* This function shall not participate in overload resolution
340
- unless `is_copy_constructible_v<``Tᵢ``> &&`
341
- `is_copy_assignable_v<``Tᵢ``>` is `true` for all i.
 
 
 
342
 
343
  ``` cpp
344
- variant& operator=(variant&& rhs) noexcept(see below);
345
  ```
346
 
347
  Let j be `rhs.index()`.
348
 
 
 
 
349
  *Effects:*
350
 
351
  - If neither `*this` nor `rhs` holds a value, there is no effect.
352
- Otherwise,
353
- - if `*this` holds a value but `rhs` does not, destroys the value
354
- contained in `*this` and sets `*this` to not hold a value. Otherwise,
355
- - if `index() == `j, assigns `get<`j`>(std::move(rhs))` to the value
356
- contained in `*this`. Otherwise,
357
- - equivalent to `emplace<`j`>(get<`j`>(std::move(rhs)))`.
358
 
359
  *Returns:* `*this`.
360
 
361
- *Remarks:* This function shall not participate in overload resolution
362
- unless `is_move_constructible_v<``Tᵢ``> && is_move_assignable_v<``Tᵢ``>`
363
- is `true` for all i. The expression inside `noexcept` is equivalent to:
 
 
364
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_move_assignable_v<``Tᵢ``>`
365
  for all i.
366
 
367
  - If an exception is thrown during the call to `Tⱼ`’s move construction
368
- (with j being `rhs.index())`, the `variant` will hold no value.
369
  - If an exception is thrown during the call to `Tⱼ`’s move assignment,
370
  the state of the contained value is as defined by the exception safety
371
  guarantee of `Tⱼ`’s move assignment; `index()` will be j.
372
 
373
  ``` cpp
374
  template<class T> variant& operator=(T&& t) noexcept(see below);
375
  ```
376
 
377
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
378
- function *FUN*(Tᵢ) for each alternative type `Tᵢ`. The overload
379
- *FUN*(T) selected by overload resolution for the expression
380
- *FUN*(std::forward\<T\>(t)) defines the alternative `Tⱼ` which is the
381
- type of the contained value after assignment.
382
-
383
- *Effects:*
384
-
385
- - If `*this` holds a `Tⱼ`, assigns `std::forward<T>(t)` to the value
386
- contained in `*this`. Otherwise,
387
- - if `is_nothrow_constructible_v<``Tⱼ``, T> ||`
388
- `!is_nothrow_move_constructible_v<``Tⱼ``>` is `true`, equivalent to
389
- `emplace<`j`>(std::forward<T>(t))`. Otherwise,
390
- - equivalent to `operator=(variant(std::forward<T>(t)))`.
391
-
392
- *Postconditions:* `holds_alternative<``Tⱼ``>(*this)` is `true`, with
393
- `Tⱼ` selected by the imaginary function overload resolution described
394
- above.
395
-
396
- *Returns:* `*this`.
397
-
398
- *Remarks:* This function shall not participate in overload resolution
399
- unless `is_same_v<decay_t<T>, variant>` is `false`, unless
400
- `is_assignable_v<``Tⱼ``&, T> && is_constructible_v<``Tⱼ``, T>` is
401
- `true`, and unless the expression *FUN*(std::forward\<T\>(t)) (with
402
- *FUN* being the above-mentioned set of imaginary functions) is well
403
- formed.
404
-
405
- [*Note 1*:
406
-
407
- ``` cpp
408
  variant<string, string> v;
409
  v = "abc";
410
- ```
411
 
412
  is ill-formed, as both alternative types have an equally viable
413
  constructor for the argument.
414
-
415
  — *end note*]
416
 
417
- The expression inside `noexcept` is equivalent to:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
 
419
  ``` cpp
420
  is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
421
  ```
422
 
@@ -432,78 +387,83 @@ is_nothrow_assignable_v<Tⱼ&, T> && is_nothrow_constructible_v<Tⱼ, T>
432
 
433
  ``` cpp
434
  template<class T, class... Args> T& emplace(Args&&... args);
435
  ```
436
 
437
- Let I be the zero-based index of `T` in `Types...`.
 
438
 
439
  *Effects:* Equivalent to:
440
- `return emplace<`I`>(std::forward<Args>(args)...);`
441
 
442
- *Remarks:* This function shall not participate in overload resolution
443
- unless `is_constructible_v<T, Args...>` is `true`, and `T` occurs
444
- exactly once in `Types...`.
 
 
445
 
446
  ``` cpp
447
  template<class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
448
  ```
449
 
450
- Let I be the zero-based index of `T` in `Types...`.
 
451
 
452
  *Effects:* Equivalent to:
453
- `return emplace<`I`>(il, std::forward<Args>(args)...);`
454
 
455
- *Remarks:* This function shall not participate in overload resolution
456
- unless `is_constructible_v<T, initializer_list<U>&, Args...>` is `true`,
457
- and `T` occurs exactly once in `Types...`.
 
 
458
 
459
  ``` cpp
460
  template<size_t I, class... Args>
461
  variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
462
  ```
463
 
464
- *Requires:* `I < sizeof...(Types)`.
 
 
465
 
466
  *Effects:* Destroys the currently contained value if
467
  `valueless_by_exception()` is `false`. Then initializes the contained
468
  value as if direct-non-list-initializing a value of type `T_I` with the
469
  arguments `std::forward<Args>(args)...`.
470
 
471
- *Postconditions:* `index()` is `I`.
472
 
473
  *Returns:* A reference to the new contained value.
474
 
475
  *Throws:* Any exception thrown during the initialization of the
476
  contained value.
477
 
478
- *Remarks:* This function shall not participate in overload resolution
479
- unless `is_constructible_v<``T_I``, Args...>` is `true`. If an exception
480
- is thrown during the initialization of the contained value, the
481
- `variant` might not hold a value.
482
 
483
  ``` cpp
484
  template<size_t I, class U, class... Args>
485
  variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
486
  ```
487
 
488
- *Requires:* `I < sizeof...(Types)`.
 
 
 
489
 
490
  *Effects:* Destroys the currently contained value if
491
  `valueless_by_exception()` is `false`. Then initializes the contained
492
  value as if direct-non-list-initializing a value of type `T_I` with the
493
  arguments `il, std::forward<Args>(args)...`.
494
 
495
- *Postconditions:* `index()` is `I`.
496
 
497
  *Returns:* A reference to the new contained value.
498
 
499
  *Throws:* Any exception thrown during the initialization of the
500
  contained value.
501
 
502
- *Remarks:* This function shall not participate in overload resolution
503
- unless `is_constructible_v<``T_I``, initializer_list<U>&, Args...>` is
504
- `true`. If an exception is thrown during the initialization of the
505
  contained value, the `variant` might not hold a value.
506
 
507
  #### Value status <a id="variant.status">[[variant.status]]</a>
508
 
509
  ``` cpp
@@ -539,22 +499,22 @@ alternative of the contained value.
539
 
540
  ``` cpp
541
  void swap(variant& rhs) noexcept(see below);
542
  ```
543
 
544
- *Requires:* Lvalues of type `Tᵢ` shall be
545
- swappable ([[swappable.requirements]]) and
546
- `is_move_constructible_v<``Tᵢ``>` shall be `true` for all i.
 
547
 
548
  *Effects:*
549
 
550
- - if `valueless_by_exception() && rhs.valueless_by_exception()` no
551
- effect. Otherwise,
552
- - if `index() == rhs.index()`, calls
553
  `swap(get<`i`>(*this), get<`i`>(rhs))` where i is `index()`.
554
- Otherwise,
555
- - exchanges values of `rhs` and `*this`.
556
 
557
  *Throws:* If `index() == rhs.index()`, any exception thrown by
558
  `swap(get<`i`>(*this), get<`i`>(rhs))` with i being `index()`.
559
  Otherwise, any exception thrown by the move constructor of `Tᵢ` or `Tⱼ`
560
  with i being `index()` and j being `rhs.index()`.
@@ -564,9 +524,9 @@ with i being `index()` and j being `rhs.index()`.
564
  values of `*this` and of `rhs` are determined by the exception safety
565
  guarantee of `swap` for lvalues of `Tᵢ` with i being `index()`. If an
566
  exception is thrown during the exchange of the values of `*this` and
567
  `rhs`, the states of the values of `*this` and of `rhs` are determined
568
  by the exception safety guarantee of `variant`’s move constructor. The
569
- expression inside `noexcept` is equivalent to the logical AND of
570
  `is_nothrow_move_constructible_v<``Tᵢ``> && is_nothrow_swappable_v<``Tᵢ``>`
571
  for all i.
572
 
 
5
  template<class... Types>
6
  class variant {
7
  public:
8
  // [variant.ctor], constructors
9
  constexpr variant() noexcept(see below);
10
+ constexpr variant(const variant&);
11
+ constexpr variant(variant&&) noexcept(see below);
12
 
13
  template<class T>
14
  constexpr variant(T&&) noexcept(see below);
15
 
16
  template<class T, class... Args>
 
21
  template<size_t I, class... Args>
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>
 
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
69
  arguments is ill-formed.
70
 
71
  #### Constructors <a id="variant.ctor">[[variant.ctor]]</a>
72
 
73
  In the descriptions that follow, let i be in the range \[`0`,
74
+ `sizeof...(Types)`), and `Tᵢ` be the iᵗʰ type in `Types`.
75
 
76
  ``` cpp
77
  constexpr variant() noexcept(see below);
78
  ```
79
 
80
+ *Constraints:* `is_default_constructible_v<``T₀``>` is `true`.
81
+
82
  *Effects:* Constructs a `variant` holding a value-initialized value of
83
  type `T₀`.
84
 
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);
98
  ```
99
 
100
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
101
  same alternative as `w` and direct-initializes the contained value with
102
  `get<j>(w)`, where `j` is `w.index()`. Otherwise, initializes the
103
  `variant` to not hold a value.
104
 
105
  *Throws:* Any exception thrown by direct-initializing any `Tᵢ` for all
106
  i.
107
 
108
+ *Remarks:* This constructor is defined as deleted unless
109
+ `is_copy_constructible_v<``Tᵢ``>` is `true` for all i. If
110
+ `is_trivially_copy_constructible_v<``Tᵢ``>` is `true` for all i, this
111
+ constructor is trivial.
112
 
113
  ``` cpp
114
+ constexpr variant(variant&& w) noexcept(see below);
115
  ```
116
 
117
+ *Constraints:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
118
+
119
  *Effects:* If `w` holds a value, initializes the `variant` to hold the
120
  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);
133
  ```
134
 
135
  Let `Tⱼ` be a type that is determined as follows: build an imaginary
136
+ function *FUN*(Tᵢ) for each alternative type `Tᵢ` for which `Tᵢ`` x[] =`
137
+ `{std::forward<T>(t)};` is well-formed for some invented variable `x`.
138
+ The overload *FUN*(T) selected by overload resolution for the
139
+ expression *FUN*(std::forward\<T\>(t)) defines the alternative `Tⱼ`
140
+ which is the type of the contained value after construction.
141
+
142
+ *Constraints:*
143
+
144
+ - `sizeof...(Types)` is nonzero,
145
+ - `is_same_v<remove_cvref_t<T>, variant>` is `false`,
146
+ - `remove_cvref_t<T>` is neither a specialization of `in_place_type_t`
147
+ nor a specialization of `in_place_index_t`,
148
+ - `is_constructible_v<``Tⱼ``, T>` is `true`, and
149
+ - the expression *FUN*(`std::forward<T>(t))` (with *FUN* being the
150
+ above-mentioned set of imaginary functions) is well-formed.
151
+ \[*Note 1*:
152
+ variant<string, string> v("abc");
153
+
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);
173
  ```
174
 
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`.
188
 
189
+ *Remarks:* If `T`’s selected constructor is a constexpr constructor,
190
+ this constructor is a constexpr constructor.
 
 
 
191
 
192
  ``` cpp
193
  template<class T, class U, class... Args>
194
  constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
195
  ```
196
 
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`.
210
 
211
+ *Remarks:* If `T`’s selected constructor is a constexpr constructor,
212
+ this constructor is a constexpr constructor.
 
 
 
213
 
214
  ``` cpp
215
  template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
216
  ```
217
 
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`.
231
+
232
+ *Remarks:* If `T_I`’s selected constructor is a constexpr constructor,
233
+ this constructor is a constexpr constructor.
234
 
235
  ``` cpp
236
  template<size_t I, class U, class... Args>
237
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
238
  ```
239
 
240
+ *Constraints:*
 
 
 
 
 
 
 
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
 
264
+ *Remarks:* If `is_trivially_destructible_v<``Tᵢ``>` is `true` for all
265
+ `Tᵢ`, then this destructor is trivial.
266
 
267
  #### Assignment <a id="variant.assign">[[variant.assign]]</a>
268
 
269
  ``` cpp
270
+ constexpr variant& operator=(const variant& rhs);
271
  ```
272
 
273
  Let j be `rhs.index()`.
274
 
275
  *Effects:*
276
 
277
  - If neither `*this` nor `rhs` holds a value, there is no effect.
278
+ - Otherwise, if `*this` holds a value but `rhs` does not, destroys the
279
+ value contained in `*this` and sets `*this` to not hold a value.
280
+ - Otherwise, if `index() == `j, assigns the value contained in `rhs` to
281
+ the value contained in `*this`.
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
296
+ assignment operator is trivial.
297
 
298
  ``` cpp
299
+ constexpr variant& operator=(variant&& rhs) noexcept(see below);
300
  ```
301
 
302
  Let j be `rhs.index()`.
303
 
304
+ *Constraints:* `is_move_constructible_v<``Tᵢ``> &&`
305
+ `is_move_assignable_v<``Tᵢ``>` is `true` for all i.
306
+
307
  *Effects:*
308
 
309
  - If neither `*this` nor `rhs` holds a value, there is no effect.
310
+ - Otherwise, if `*this` holds a value but `rhs` does not, destroys the
311
+ value contained in `*this` and sets `*this` to not hold a value.
312
+ - Otherwise, if `index() == `j, assigns `get<`j`>(std::move(rhs))` to
313
+ the value contained in `*this`.
314
+ - Otherwise, equivalent to `emplace<`j`>(get<`j`>(std::move(rhs)))`.
 
315
 
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`.
339
+ The overload *FUN*(T) selected by overload resolution for the
340
+ expression *FUN*(std::forward\<T\>(t)) defines the alternative `Tⱼ`
341
+ which is the type of the contained value after assignment.
342
+
343
+ *Constraints:*
344
+
345
+ - `is_same_v<remove_cvref_t<T>, variant>` is `false`,
346
+ - `is_assignable_v<``Tⱼ``&, T> && is_constructible_v<``Tⱼ``, T>` is
347
+ `true`, and
348
+ - the expression *FUN*(std::forward\<T\>(t)) (with *FUN* being the
349
+ above-mentioned set of imaginary functions) is well-formed.
350
+ \[*Note 1*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  variant<string, string> v;
352
  v = "abc";
 
353
 
354
  is ill-formed, as both alternative types have an equally viable
355
  constructor for the argument.
 
356
  — *end note*]
357
 
358
+ *Effects:*
359
+
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
 
 
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
 
395
  *Effects:* Equivalent to:
 
396
 
397
+ ``` cpp
398
+ 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
 
410
  *Effects:* Equivalent to:
 
411
 
412
+ ``` cpp
413
+ return emplace<I>(il, std::forward<Args>(args)...);
414
+ ```
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
 
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.
513
+ - Otherwise, if `index() == rhs.index()`, calls
514
  `swap(get<`i`>(*this), get<`i`>(rhs))` where i is `index()`.
515
+ - Otherwise, exchanges values of `rhs` and `*this`.
 
516
 
517
  *Throws:* If `index() == rhs.index()`, any exception thrown by
518
  `swap(get<`i`>(*this), get<`i`>(rhs))` with i being `index()`.
519
  Otherwise, any exception thrown by the move constructor of `Tᵢ` or `Tⱼ`
520
  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