From Jason Turner

[tuple]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpn_lpasmn/{from.md → to.md} +386 -252
tmp/tmpn_lpasmn/{from.md → to.md} RENAMED
@@ -8,65 +8,78 @@ arguments. Each template argument specifies the type of an element in
8
  the `tuple`. Consequently, tuples are heterogeneous, fixed-size
9
  collections of values. An instantiation of `tuple` with two arguments is
10
  similar to an instantiation of `pair` with the same two arguments. See 
11
  [[pairs]].
12
 
 
 
13
  ``` cpp
14
  namespace std {
15
- // [tuple.tuple], class template tuple:
16
- template <class... Types> class tuple;
 
17
 
18
- // [tuple.creation], tuple creation functions:
19
- const unspecified ignore;
20
 
21
- template <class... Types>
22
- constexpr tuple<VTypes...> make_tuple(Types&&...);
23
- template <class... Types>
24
- constexpr tuple<Types&&...> forward_as_tuple(Types&&...) noexcept;
25
 
26
- template<class... Types>
27
- constexpr tuple<Types&...> tie(Types&...) noexcept;
 
 
 
28
 
29
  template <class... Tuples>
30
- constexpr tuple<Ctypes...> tuple_cat(Tuples&&...);
31
 
32
- // [tuple.helper], tuple helper classes:
33
- template <class T> class tuple_size; // undefined
 
 
 
 
 
 
 
34
  template <class T> class tuple_size<const T>;
35
  template <class T> class tuple_size<volatile T>;
36
  template <class T> class tuple_size<const volatile T>;
37
 
38
  template <class... Types> class tuple_size<tuple<Types...>>;
39
 
40
- template <size_t I, class T> class tuple_element; // undefined
41
  template <size_t I, class T> class tuple_element<I, const T>;
42
  template <size_t I, class T> class tuple_element<I, volatile T>;
43
  template <size_t I, class T> class tuple_element<I, const volatile T>;
44
 
45
- template <size_t I, class... Types> class tuple_element<I, tuple<Types...> >;
 
46
 
47
  template <size_t I, class T>
48
  using tuple_element_t = typename tuple_element<I, T>::type;
49
 
50
- // [tuple.elem], element access:
51
  template <size_t I, class... Types>
52
- constexpr tuple_element_t<I, tuple<Types...>>&
53
- get(tuple<Types...>&) noexcept;
54
  template <size_t I, class... Types>
55
- constexpr tuple_element_t<I, tuple<Types...>>&&
56
- get(tuple<Types...>&&) noexcept;
57
  template <size_t I, class... Types>
58
- constexpr const tuple_element_t<I, tuple<Types...>>&
59
- get(const tuple<Types...>&) noexcept;
 
60
  template <class T, class... Types>
61
  constexpr T& get(tuple<Types...>& t) noexcept;
62
  template <class T, class... Types>
63
  constexpr T&& get(tuple<Types...>&& t) noexcept;
64
  template <class T, class... Types>
65
  constexpr const T& get(const tuple<Types...>& t) noexcept;
 
 
66
 
67
- // [tuple.rel], relational operators:
68
  template<class... TTypes, class... UTypes>
69
  constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
70
  template<class... TTypes, class... UTypes>
71
  constexpr bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);
72
  template<class... TTypes, class... UTypes>
@@ -80,62 +93,65 @@ namespace std {
80
 
81
  // [tuple.traits], allocator-related traits
82
  template <class... Types, class Alloc>
83
  struct uses_allocator<tuple<Types...>, Alloc>;
84
 
85
- // [tuple.special], specialized algorithms:
86
  template <class... Types>
87
  void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
 
 
 
 
88
  }
89
  ```
90
 
91
  ### Class template `tuple` <a id="tuple.tuple">[[tuple.tuple]]</a>
92
 
93
  ``` cpp
94
  namespace std {
95
  template <class... Types>
96
  class tuple {
97
  public:
98
-
99
  // [tuple.cnstr], tuple construction
100
- constexpr tuple();
101
- constexpr explicit tuple(const Types&...);
102
  template <class... UTypes>
103
- constexpr explicit tuple(UTypes&&...);
104
 
105
  tuple(const tuple&) = default;
106
  tuple(tuple&&) = default;
107
 
108
  template <class... UTypes>
109
- constexpr tuple(const tuple<UTypes...>&);
110
  template <class... UTypes>
111
- constexpr tuple(tuple<UTypes...>&&);
112
 
113
  template <class U1, class U2>
114
- constexpr tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2
115
  template <class U1, class U2>
116
- constexpr tuple(pair<U1, U2>&&); // only if sizeof...(Types) == 2
117
 
118
  // allocator-extended constructors
119
  template <class Alloc>
120
  tuple(allocator_arg_t, const Alloc& a);
121
  template <class Alloc>
122
- tuple(allocator_arg_t, const Alloc& a, const Types&...);
123
  template <class Alloc, class... UTypes>
124
- tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
125
  template <class Alloc>
126
  tuple(allocator_arg_t, const Alloc& a, const tuple&);
127
  template <class Alloc>
128
  tuple(allocator_arg_t, const Alloc& a, tuple&&);
129
  template <class Alloc, class... UTypes>
130
- tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
131
  template <class Alloc, class... UTypes>
132
- tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
133
  template <class Alloc, class U1, class U2>
134
- tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
135
  template <class Alloc, class U1, class U2>
136
- tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
137
 
138
  // [tuple.assign], tuple assignment
139
  tuple& operator=(const tuple&);
140
  tuple& operator=(tuple&&) noexcept(see below);
141
 
@@ -150,158 +166,194 @@ namespace std {
150
  tuple& operator=(pair<U1, U2>&&); // only if sizeof...(Types) == 2
151
 
152
  // [tuple.swap], tuple swap
153
  void swap(tuple&) noexcept(see below);
154
  };
 
 
 
 
 
 
 
 
 
 
 
155
  }
156
  ```
157
 
158
  #### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
159
 
160
  For each `tuple` constructor, an exception is thrown only if the
161
  construction of one of the types in `Types` throws an exception.
162
 
163
  The defaulted move and copy constructor, respectively, of `tuple` shall
164
- be a `constexpr` function if and only if all required element-wise
165
  initializations for copy and move, respectively, would satisfy the
166
- requirements for a `constexpr` function. The defaulted move and copy
167
- constructor of `tuple<>` shall be `constexpr` functions.
 
 
 
168
 
169
  In the constructor descriptions that follow, let i be in the range
170
- \[`0`, `sizeof...(Types)`) in order, Tᵢ be the iᵗʰ type in `Types`, and
171
- Uᵢ be the iᵗʰ type in a template parameter pack named `UTypes`, where
172
- indexing is zero-based.
173
 
174
  ``` cpp
175
- constexpr tuple();
176
  ```
177
 
178
- *Requires:* `is_default_constructible<`Tᵢ`>::value` is true for all i.
179
 
180
- *Effects:* Value initializes each element.
 
 
 
 
 
 
 
 
 
 
181
 
182
  ``` cpp
183
- constexpr explicit tuple(const Types&...);
184
  ```
185
 
186
- *Requires:* `is_copy_constructible<`Tᵢ`>::value` is true for all i.
187
-
188
  *Effects:* Initializes each element with the value of the corresponding
189
  parameter.
190
 
 
 
 
 
 
191
  ``` cpp
192
- template <class... UTypes>
193
- constexpr explicit tuple(UTypes&&... u);
194
  ```
195
 
196
- *Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
197
- `is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
198
-
199
  *Effects:* Initializes the elements in the tuple with the corresponding
200
  value in `std::forward<UTypes>(u)`.
201
 
202
- This constructor shall not participate in overload resolution unless
203
- each type in `UTypes` is implicitly convertible to its corresponding
204
- type in `Types`.
 
 
205
 
206
  ``` cpp
207
  tuple(const tuple& u) = default;
208
  ```
209
 
210
- *Requires:* `is_copy_constructible<`Tᵢ`>::value` is `true` for all i.
211
 
212
  *Effects:* Initializes each element of `*this` with the corresponding
213
  element of `u`.
214
 
215
  ``` cpp
216
  tuple(tuple&& u) = default;
217
  ```
218
 
219
- *Requires:* `is_move_constructible<`Tᵢ`>::value` is `true` for all i.
220
 
221
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
222
- `std::forward<`Tᵢ`>(get<`i`>(u))`.
223
 
224
  ``` cpp
225
- template <class... UTypes> constexpr tuple(const tuple<UTypes...>& u);
226
  ```
227
 
228
- *Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
229
- `is_constructible<`Tᵢ`, const `Uᵢ`&>::value` is `true` for all i.
230
-
231
- *Effects:* Constructs each element of `*this` with the corresponding
232
  element of `u`.
233
 
234
- This constructor shall not participate in overload resolution unless
235
- `const `Uᵢ`&` is implicitly convertible to Tᵢ for all i.
 
 
 
 
 
 
 
 
 
 
236
 
237
  ``` cpp
238
- template <class... UTypes> constexpr tuple(tuple<UTypes...>&& u);
239
  ```
240
 
241
- *Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
242
- `is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
243
-
244
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
245
- `std::forward<`Uᵢ`>(get<`i`>(u))`.
246
 
247
- This constructor shall not participate in overload resolution unless
248
- each type in `UTypes` is implicitly convertible to its corresponding
249
- type in `Types`.
 
 
 
 
 
 
 
 
 
250
 
251
  ``` cpp
252
- template <class U1, class U2> constexpr tuple(const pair<U1, U2>& u);
253
  ```
254
 
255
- *Requires:* `sizeof...(Types) == 2`.
256
- `is_constructible<`T₀`, const U1&>::value` is `true` for the first type
257
- T₀ in `Types` and `is_constructible<`T₁`, const U2&>::value` is `true`
258
- for the second type T₁ in `Types`.
259
-
260
- *Effects:* Constructs the first element with `u.first` and the second
261
  element with `u.second`.
262
 
263
- This constructor shall not participate in overload resolution unless
264
- `const U1&` is implicitly convertible to T₀ and `const U2&` is
265
- implicitly convertible to T₁.
 
 
 
 
266
 
267
  ``` cpp
268
- template <class U1, class U2> constexpr tuple(pair<U1, U2>&& u);
269
  ```
270
 
271
- *Requires:* `sizeof...(Types) == 2`.
272
- `is_constructible<`T₀`, U1&&>::value` is `true` for the first type T₀ in
273
- `Types` and `is_constructible<`T₁`, U2&&>::value` is `true` for the
274
- second type T₁ in `Types`.
275
-
276
  *Effects:* Initializes the first element with
277
  `std::forward<U1>(u.first)` and the second element with
278
  `std::forward<U2>(u.second)`.
279
 
280
- This constructor shall not participate in overload resolution unless
281
- `U1` is implicitly convertible to T₀ and `U2` is implicitly convertible
282
- to T₁.
 
 
 
 
283
 
284
  ``` cpp
285
  template <class Alloc>
286
  tuple(allocator_arg_t, const Alloc& a);
287
  template <class Alloc>
288
- tuple(allocator_arg_t, const Alloc& a, const Types&...);
289
  template <class Alloc, class... UTypes>
290
- tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
291
  template <class Alloc>
292
  tuple(allocator_arg_t, const Alloc& a, const tuple&);
293
  template <class Alloc>
294
  tuple(allocator_arg_t, const Alloc& a, tuple&&);
295
  template <class Alloc, class... UTypes>
296
- tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
297
  template <class Alloc, class... UTypes>
298
- tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
299
  template <class Alloc, class U1, class U2>
300
- tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
301
  template <class Alloc, class U1, class U2>
302
- tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
303
  ```
304
 
305
  *Requires:* `Alloc` shall meet the requirements for an
306
  `Allocator` ([[allocator.requirements]]).
307
 
@@ -312,240 +364,300 @@ construction ([[allocator.uses.construction]]).
312
  #### Assignment <a id="tuple.assign">[[tuple.assign]]</a>
313
 
314
  For each `tuple` assignment operator, an exception is thrown only if the
315
  assignment of one of the types in `Types` throws an exception. In the
316
  function descriptions that follow, let i be in the range \[`0`,
317
- `sizeof...(Types)`) in order, Tᵢ be the iᵗʰ type in `Types`, and Uᵢ be
318
- the iᵗʰ type in a template parameter pack named `UTypes`, where indexing
319
- is zero-based.
320
 
321
  ``` cpp
322
  tuple& operator=(const tuple& u);
323
  ```
324
 
325
- *Requires:* `is_copy_assignable<`Tᵢ`>::value` is `true` for all i.
326
-
327
  *Effects:* Assigns each element of `u` to the corresponding element of
328
  `*this`.
329
 
330
- *Returns:* `*this`
 
 
 
331
 
332
  ``` cpp
333
  tuple& operator=(tuple&& u) noexcept(see below);
334
  ```
335
 
336
- The expression inside `noexcept` is equivalent to the logical
 
 
 
 
 
 
337
  <span class="smallcaps">and</span> of the following expressions:
338
 
339
  ``` cpp
340
- is_nothrow_move_assignable<Tᵢ>::value
341
  ```
342
 
343
  where Tᵢ is the iᵗʰ type in `Types`.
344
 
345
- *Requires:* `is_move_assignable<`Tᵢ`>::value` is `true` for all i.
346
-
347
- *Effects:* For all i, assigns `std::forward<`Tᵢ`>(get<`i`>(u))` to
348
- `get<`i`>(*this)`.
349
-
350
  *Returns:* `*this`.
351
 
352
  ``` cpp
353
- template <class... UTypes>
354
- tuple& operator=(const tuple<UTypes...>& u);
355
  ```
356
 
357
- *Requires:* `sizeof...(Types) == sizeof...(UTypes)` and
358
- `is_assignable<`Tᵢ`&, const `Uᵢ`&>::value` is `true` for all i.
359
-
360
  *Effects:* Assigns each element of `u` to the corresponding element of
361
  `*this`.
362
 
363
- *Returns:* `*this`
 
 
 
 
364
 
365
  ``` cpp
366
- template <class... UTypes>
367
- tuple& operator=(tuple<UTypes...>&& u);
368
  ```
369
 
370
- *Requires:* `is_assignable<Ti&, Ui&&>::value == true` for all `i`.
371
- `sizeof...(Types)` `==`
372
- `sizeof...(UTypes)`.
373
-
374
- *Effects:* For all i, assigns `std::forward<`Uᵢ`>(get<`i`)>(u))` to
375
  `get<`i`>(*this)`.
376
 
 
 
 
 
377
  *Returns:* `*this`.
378
 
379
  ``` cpp
380
  template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
381
  ```
382
 
383
- *Requires:* `sizeof...(Types) == 2`.
384
- `is_assignable<`T₀`&, const U1&>::value` is `true` for the first type T₀
385
- in `Types` and `is_assignable<`T₁`&, const U2&>::value` is `true` for
386
- the second type T₁ in `Types`.
387
-
388
  *Effects:* Assigns `u.first` to the first element of `*this` and
389
  `u.second` to the second element of `*this`.
390
 
391
- *Returns:* `*this`
 
 
 
 
 
 
392
 
393
  ``` cpp
394
  template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
395
  ```
396
 
397
- *Requires:* `sizeof...(Types) == 2`. `is_assignable<`T₀`&, U1&&>::value`
398
- is `true` for the first type T₀ in `Types` and
399
- `is_assignable<`T₁`&, U2&&>::value` is `true` for the second type T₁ in
400
- `Types`.
401
-
402
  *Effects:* Assigns `std::forward<U1>(u.first)` to the first element of
403
  `*this` and
404
  `std::forward<U2>(u.second)` to the second element of `*this`.
405
 
 
 
 
 
 
 
406
  *Returns:* `*this`.
407
 
408
  #### `swap` <a id="tuple.swap">[[tuple.swap]]</a>
409
 
410
  ``` cpp
411
  void swap(tuple& rhs) noexcept(see below);
412
  ```
413
 
414
- The expression inside `noexcept` is equivalent to the logical
415
- <span class="smallcaps">and</span> of the following expressions:
416
-
417
- ``` cpp
418
- noexcept(swap(declval<Tᵢ&>>(), declval<Tᵢ&>()))
419
- ```
420
-
421
- where Tᵢ is the iᵗʰ type in `Types`.
422
-
423
  *Requires:* Each element in `*this` shall be swappable
424
  with ([[swappable.requirements]]) the corresponding element in `rhs`.
425
 
426
  *Effects:* Calls `swap` for each element in `*this` and its
427
  corresponding element in `rhs`.
428
 
 
 
 
 
 
 
 
 
 
429
  *Throws:* Nothing unless one of the element-wise `swap` calls throws an
430
  exception.
431
 
432
  #### Tuple creation functions <a id="tuple.creation">[[tuple.creation]]</a>
433
 
434
- In the function descriptions that follow, let i be in the range \[`0`,
435
- `sizeof...(TTypes)`) in order and let Tbe the iᵗʰ type in a template
436
- parameter pack named `TTypes`; let j be in the range \[`0`,
437
- `sizeof...(UTypes)`) in order and Uⱼ be the jᵗʰ type in a template
438
- parameter pack named `UTypes`, where indexing is zero-based.
439
 
440
  ``` cpp
441
- template<class... Types>
442
- constexpr tuple<VTypes...> make_tuple(Types&&... t);
443
  ```
444
 
445
- Let Uᵢ be `decay_t<`Tᵢ`>` for each Tᵢ in `Types`. Then each Vᵢ in
446
- `VTypes` is `X&` if Uᵢ equals `reference_wrapper<X>`, otherwise Vᵢ is
447
- Uᵢ.
 
448
 
449
- *Returns:* `tuple<VTypes...>(std::forward<Types>(t)...)`.
 
 
450
 
451
  ``` cpp
452
  int i; float j;
453
  make_tuple(1, ref(i), cref(j))
454
  ```
455
 
456
- creates a tuple of type
457
 
458
- ``` cpp
459
- tuple<int, int&, const float&>
460
- ```
461
 
462
  ``` cpp
463
- template<class... Types>
464
- constexpr tuple<Types&&...> forward_as_tuple(Types&&... t) noexcept;
465
  ```
466
 
467
  *Effects:* Constructs a tuple of references to the arguments in `t`
468
  suitable for forwarding as arguments to a function. Because the result
469
  may contain references to temporary variables, a program shall ensure
470
  that the return value of this function does not outlive any of its
471
- arguments. (e.g., the program should typically not store the result in a
472
  named variable).
473
 
474
- *Returns:* `tuple<Types&&...>(std::forward<Types>(t)...)`
475
 
476
  ``` cpp
477
- template<class... Types>
478
- constexpr tuple<Types&...> tie(Types&... t) noexcept;
479
  ```
480
 
481
- *Returns:* `tuple<Types&...>(t...)`. When an argument in `t` is
482
  `ignore`, assigning any value to the corresponding tuple element has no
483
  effect.
484
 
 
 
485
  `tie` functions allow one to create tuples that unpack tuples into
486
  variables. `ignore` can be used for elements that are not needed:
487
 
488
  ``` cpp
489
  int i; std::string s;
490
  tie(i, ignore, s) = make_tuple(42, 3.14, "C++");
491
  // i == 42, s == "C++"
492
  ```
493
 
 
 
494
  ``` cpp
495
  template <class... Tuples>
496
  constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
497
  ```
498
 
499
- In the following paragraphs, let Tᵢ be the iᵗʰ type in `Tuples`, Uᵢ be
500
- `remove_reference_t<Ti>`, and tpᵢ be the iᵗʰ parameter in the function
501
- parameter pack `tpls`, where all indexing is zero-based.
502
 
503
- *Requires:* For all i, Uᵢ shall be the type cvᵢ `tuple<`Argsᵢ...`>`,
504
- where cvᵢ is the (possibly empty) iᵗʰ cv-qualifier-seq and Argsᵢ is the
505
- parameter pack representing the element types in Uᵢ. Let {Aᵢₖ} be the
506
- kᵗʰ type in Argsᵢ. For all Aᵢₖ the following requirements shall be
507
- satisfied: If Tᵢ is deduced as an lvalue reference type, then
508
- `is_constructible<`Aᵢₖ`, `cvᵢ` `Aᵢₖ`&>::value == true`, otherwise
509
- `is_constructible<`Aᵢₖ`, `cvᵢ Aᵢₖ`&&>::value == true`.
510
 
511
- *Remarks:* The types in *`Ctypes`* shall be equal to the ordered
512
- sequence of the extended types Args₀`..., `Args₁`...,` ... Argsₙ₋₁`...`,
513
- where n is equal to `sizeof...(Tuples)`. Let eᵢ`...` be the iᵗʰ ordered
514
- sequence of tuple elements of the resulting `tuple` object corresponding
515
- to the type sequence Argsᵢ.
 
 
 
 
516
 
517
  *Returns:* A `tuple` object constructed by initializing the kᵢᵗʰ type
518
- element eᵢₖ in eᵢ`...` with
519
- `get<`kᵢ`>(std::forward<`Tᵢ`>(`tpᵢ`))` for each valid kᵢ and each group
520
- eᵢ in order.
521
 
522
- *Note:* An implementation may support additional types in the parameter
523
- pack `Tuples` that support the `tuple`-like protocol, such as `pair` and
524
- `array`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
 
526
  #### Tuple helper classes <a id="tuple.helper">[[tuple.helper]]</a>
527
 
528
  ``` cpp
529
  template <class T> struct tuple_size;
530
  ```
531
 
532
- *Remarks:* All specializations of `tuple_size<T>` shall meet the
533
- `UnaryTypeTrait` requirements ([[meta.rqmts]]) with a
534
- `BaseCharacteristic` of `integral_constant<size_t, N>` for some `N`.
535
 
536
  ``` cpp
537
  template <class... Types>
538
- class tuple_size<tuple<Types...> >
539
- : public integral_constant<size_t, sizeof...(Types)> { };
540
  ```
541
 
542
  ``` cpp
543
  template <size_t I, class... Types>
544
  class tuple_element<I, tuple<Types...>> {
545
  public:
546
- typedef TI type;
547
  };
548
  ```
549
 
550
  *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
551
  out of bounds.
@@ -557,101 +669,119 @@ is zero-based.
557
  template <class T> class tuple_size<const T>;
558
  template <class T> class tuple_size<volatile T>;
559
  template <class T> class tuple_size<const volatile T>;
560
  ```
561
 
562
- Let *TS* denote `tuple_size<T>` of the cv-unqualified type `T`. Then
563
- each of the three templates shall meet the `UnaryTypeTrait`
564
- requirements ([[meta.rqmts]]) with a `BaseCharacteristic` of
 
 
565
 
566
  ``` cpp
567
  integral_constant<size_t, TS::value>
568
  ```
569
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  ``` cpp
571
  template <size_t I, class T> class tuple_element<I, const T>;
572
  template <size_t I, class T> class tuple_element<I, volatile T>;
573
  template <size_t I, class T> class tuple_element<I, const volatile T>;
574
  ```
575
 
576
- Let *TE* denote `tuple_element<I, T>` of the cv-unqualified type `T`.
577
- Then each of the three templates shall meet the `TransformationTrait`
578
- requirements ([[meta.rqmts]]) with a member typedef `type` that names
579
- the following type:
580
 
581
- - for the first specialization, `add_const_t<`*`TE`*`::type>`,
582
- - for the second specialization, `add_volatile_t<`*`TE`*`::type>`, and
583
- - for the third specialization, `add_cv_t<`*`TE`*`::type>`.
 
 
 
 
584
 
585
  #### Element access <a id="tuple.elem">[[tuple.elem]]</a>
586
 
587
  ``` cpp
588
  template <size_t I, class... Types>
589
- constexpr tuple_element_t<I, tuple<Types...> >& get(tuple<Types...>& t) noexcept;
 
 
 
 
 
 
 
 
 
590
  ```
591
 
592
  *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
593
  out of bounds.
594
 
595
  *Returns:* A reference to the `I`th element of `t`, where indexing is
596
  zero-based.
597
 
598
- ``` cpp
599
- template <size_t I, class... Types>
600
- constexpr tuple_element_t<I, tuple<Types...> >&& get(tuple<Types...>&& t) noexcept;
601
- ```
602
-
603
- *Effects:* Equivalent to
604
- `return std::forward<typename tuple_element<I, tuple<Types...> >`
605
- `::type&&>(get<I>(t));`
606
-
607
- *Note:* if a `T` in `Types` is some reference type `X&`, the return type
608
- is `X&`, not `X&&`. However, if the element type is a non-reference type
609
- `T`, the return type is `T&&`.
610
-
611
- ``` cpp
612
- template <size_t I, class... Types>
613
- constexpr tuple_element_t<I, tuple<Types...> > const& get(const tuple<Types...>& t) noexcept;
614
- ```
615
-
616
- *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
617
- out of bounds.
618
-
619
- *Returns:* A const reference to the `I`th element of `t`, where indexing
620
- is zero-based.
621
-
622
- Constness is shallow. If a `T` in `Types` is some reference type `X&`,
623
- the return type is `X&`, not `const X&`. However, if the element type is
624
- non-reference type `T`, the return type is `const T&`. This is
625
- consistent with how constness is defined to work for member variables of
626
- reference type.
627
 
628
  ``` cpp
629
  template <class T, class... Types>
630
  constexpr T& get(tuple<Types...>& t) noexcept;
631
  template <class T, class... Types>
632
  constexpr T&& get(tuple<Types...>&& t) noexcept;
633
  template <class T, class... Types>
634
  constexpr const T& get(const tuple<Types...>& t) noexcept;
 
 
635
  ```
636
 
637
  *Requires:* The type `T` occurs exactly once in `Types...`. Otherwise,
638
  the program is ill-formed.
639
 
640
  *Returns:* A reference to the element of `t` corresponding to the type
641
  `T` in `Types...`.
642
 
 
 
643
  ``` cpp
644
  const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6);
645
  const int& i1 = get<int>(t); // OK. Not ambiguous. i1 == 1
646
  const int& i2 = get<const int>(t); // OK. Not ambiguous. i2 == 2
647
  const double& d = get<double>(t); // ERROR. ill-formed
648
  ```
649
 
650
- The reason `get` is a nonmember function is that if this functionality
651
- had been provided as a member function, code where the type depended on
652
- a template parameter would have required using the `template` keyword.
 
 
 
653
 
654
  #### Relational operators <a id="tuple.rel">[[tuple.rel]]</a>
655
 
656
  ``` cpp
657
  template<class... TTypes, class... UTypes>
@@ -674,11 +804,11 @@ after the first equality comparison that evaluates to `false`.
674
  template<class... TTypes, class... UTypes>
675
  constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
676
  ```
677
 
678
  *Requires:* For all `i`, where `0 <= i` and `i < sizeof...(TTypes)`,
679
- `get<i>(t) < get<i>(u)` and `get<i>(u) < get<i>(t)` are valid
680
  expressions returning types that are convertible to `bool`.
681
  `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
682
 
683
  *Returns:* The result of a lexicographical comparison between `t` and
684
  `u`. The result is defined as:
@@ -704,24 +834,25 @@ template<class... TTypes, class... UTypes>
704
  ``` cpp
705
  template<class... TTypes, class... UTypes>
706
  constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
707
  ```
708
 
709
- *Returns:* `!(u < t)`
710
 
711
  ``` cpp
712
  template<class... TTypes, class... UTypes>
713
  constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
714
  ```
715
 
716
- *Returns:* `!(t < u)`
717
 
718
- The above definitions for comparison operators do not require `tₜₐᵢₗ`
719
- (or `uₜₐᵢₗ`) to be constructed. It may not even be possible, as `t` and
720
- `u` are not required to be copy constructible. Also, all comparison
721
- operators are short circuited; they do not perform element accesses
722
- beyond what is required to determine the result of the comparison.
 
723
 
724
  #### Tuple traits <a id="tuple.traits">[[tuple.traits]]</a>
725
 
726
  ``` cpp
727
  template <class... Types, class Alloc>
@@ -729,24 +860,27 @@ template <class... Types, class Alloc>
729
  ```
730
 
731
  *Requires:* `Alloc` shall be an
732
  `Allocator` ([[allocator.requirements]]).
733
 
734
- Specialization of this trait informs other library components that
735
- `tuple` can be constructed with an allocator, even though it does not
736
- have a nested `allocator_type`.
737
 
738
  #### Tuple specialized algorithms <a id="tuple.special">[[tuple.special]]</a>
739
 
740
  ``` cpp
741
  template <class... Types>
742
  void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
743
  ```
744
 
745
- The expression inside `noexcept` is equivalent to:
 
 
 
746
 
747
  ``` cpp
748
  noexcept(x.swap(y))
749
  ```
750
 
751
- *Effects:* `x.swap(y)`
752
 
 
8
  the `tuple`. Consequently, tuples are heterogeneous, fixed-size
9
  collections of values. An instantiation of `tuple` with two arguments is
10
  similar to an instantiation of `pair` with the same two arguments. See 
11
  [[pairs]].
12
 
13
+ ### Header `<tuple>` synopsis <a id="tuple.syn">[[tuple.syn]]</a>
14
+
15
  ``` cpp
16
  namespace std {
17
+ // [tuple.tuple], class template tuple
18
+ template <class... Types>
19
+ class tuple;
20
 
21
+ // [tuple.creation], tuple creation functions
22
+ inline constexpr unspecified ignore;
23
 
24
+ template <class... TTypes>
25
+ constexpr tuple<VTypes...> make_tuple(TTypes&&...);
 
 
26
 
27
+ template <class... TTypes>
28
+ constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;
29
+
30
+ template<class... TTypes>
31
+ constexpr tuple<TTypes&...> tie(TTypes&...) noexcept;
32
 
33
  template <class... Tuples>
34
+ constexpr tuple<CTypes...> tuple_cat(Tuples&&...);
35
 
36
+ // [tuple.apply], calling a function with a tuple of arguments
37
+ template <class F, class Tuple>
38
+ constexpr decltype(auto) apply(F&& f, Tuple&& t);
39
+
40
+ template <class T, class Tuple>
41
+ constexpr T make_from_tuple(Tuple&& t);
42
+
43
+ // [tuple.helper], tuple helper classes
44
+ template <class T> class tuple_size; // not defined
45
  template <class T> class tuple_size<const T>;
46
  template <class T> class tuple_size<volatile T>;
47
  template <class T> class tuple_size<const volatile T>;
48
 
49
  template <class... Types> class tuple_size<tuple<Types...>>;
50
 
51
+ template <size_t I, class T> class tuple_element; // not defined
52
  template <size_t I, class T> class tuple_element<I, const T>;
53
  template <size_t I, class T> class tuple_element<I, volatile T>;
54
  template <size_t I, class T> class tuple_element<I, const volatile T>;
55
 
56
+ template <size_t I, class... Types>
57
+ class tuple_element<I, tuple<Types...>>;
58
 
59
  template <size_t I, class T>
60
  using tuple_element_t = typename tuple_element<I, T>::type;
61
 
62
+ // [tuple.elem], element access
63
  template <size_t I, class... Types>
64
+ constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept;
 
65
  template <size_t I, class... Types>
66
+ constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept;
 
67
  template <size_t I, class... Types>
68
+ constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&) noexcept;
69
+ template <size_t I, class... Types>
70
+ constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept;
71
  template <class T, class... Types>
72
  constexpr T& get(tuple<Types...>& t) noexcept;
73
  template <class T, class... Types>
74
  constexpr T&& get(tuple<Types...>&& t) noexcept;
75
  template <class T, class... Types>
76
  constexpr const T& get(const tuple<Types...>& t) noexcept;
77
+ template <class T, class... Types>
78
+ constexpr const T&& get(const tuple<Types...>&& t) noexcept;
79
 
80
+ // [tuple.rel], relational operators
81
  template<class... TTypes, class... UTypes>
82
  constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
83
  template<class... TTypes, class... UTypes>
84
  constexpr bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);
85
  template<class... TTypes, class... UTypes>
 
93
 
94
  // [tuple.traits], allocator-related traits
95
  template <class... Types, class Alloc>
96
  struct uses_allocator<tuple<Types...>, Alloc>;
97
 
98
+ // [tuple.special], specialized algorithms
99
  template <class... Types>
100
  void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
101
+
102
+ // [tuple.helper], tuple helper classes
103
+ template <class T>
104
+ inline constexpr size_t tuple_size_v = tuple_size<T>::value;
105
  }
106
  ```
107
 
108
  ### Class template `tuple` <a id="tuple.tuple">[[tuple.tuple]]</a>
109
 
110
  ``` cpp
111
  namespace std {
112
  template <class... Types>
113
  class tuple {
114
  public:
 
115
  // [tuple.cnstr], tuple construction
116
+ \EXPLICIT constexpr tuple();
117
+ \EXPLICIT constexpr tuple(const Types&...); // only if sizeof...(Types) >= 1
118
  template <class... UTypes>
119
+ \EXPLICIT constexpr tuple(UTypes&&...); // only if sizeof...(Types) >= 1
120
 
121
  tuple(const tuple&) = default;
122
  tuple(tuple&&) = default;
123
 
124
  template <class... UTypes>
125
+ \EXPLICIT constexpr tuple(const tuple<UTypes...>&);
126
  template <class... UTypes>
127
+ \EXPLICIT constexpr tuple(tuple<UTypes...>&&);
128
 
129
  template <class U1, class U2>
130
+ \EXPLICIT constexpr tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2
131
  template <class U1, class U2>
132
+ \EXPLICIT constexpr tuple(pair<U1, U2>&&); // only if sizeof...(Types) == 2
133
 
134
  // allocator-extended constructors
135
  template <class Alloc>
136
  tuple(allocator_arg_t, const Alloc& a);
137
  template <class Alloc>
138
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
139
  template <class Alloc, class... UTypes>
140
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
141
  template <class Alloc>
142
  tuple(allocator_arg_t, const Alloc& a, const tuple&);
143
  template <class Alloc>
144
  tuple(allocator_arg_t, const Alloc& a, tuple&&);
145
  template <class Alloc, class... UTypes>
146
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
147
  template <class Alloc, class... UTypes>
148
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
149
  template <class Alloc, class U1, class U2>
150
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
151
  template <class Alloc, class U1, class U2>
152
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
153
 
154
  // [tuple.assign], tuple assignment
155
  tuple& operator=(const tuple&);
156
  tuple& operator=(tuple&&) noexcept(see below);
157
 
 
166
  tuple& operator=(pair<U1, U2>&&); // only if sizeof...(Types) == 2
167
 
168
  // [tuple.swap], tuple swap
169
  void swap(tuple&) noexcept(see below);
170
  };
171
+
172
+ template<class... UTypes>
173
+ tuple(UTypes...) -> tuple<UTypes...>;
174
+ template<class T1, class T2>
175
+ tuple(pair<T1, T2>) -> tuple<T1, T2>;
176
+ template<class Alloc, class... UTypes>
177
+ tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>;
178
+ template<class Alloc, class T1, class T2>
179
+ tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;
180
+ template<class Alloc, class... UTypes>
181
+ tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
182
  }
183
  ```
184
 
185
  #### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
186
 
187
  For each `tuple` constructor, an exception is thrown only if the
188
  construction of one of the types in `Types` throws an exception.
189
 
190
  The defaulted move and copy constructor, respectively, of `tuple` shall
191
+ be a constexpr function if and only if all required element-wise
192
  initializations for copy and move, respectively, would satisfy the
193
+ requirements for a constexpr function. The defaulted move and copy
194
+ constructor of `tuple<>` shall be constexpr functions.
195
+
196
+ The destructor of tuple shall be a trivial destructor if
197
+ `(is_trivially_destructible_v<Types> && ...)` is `true`.
198
 
199
  In the constructor descriptions that follow, let i be in the range
200
+ \[`0`, `sizeof...(Types)`) in order, `Tᵢ` be the iᵗʰ type in `Types`,
201
+ and `Uᵢ` be the iᵗʰ type in a template parameter pack named `UTypes`,
202
+ where indexing is zero-based.
203
 
204
  ``` cpp
205
+ \EXPLICIT constexpr tuple();
206
  ```
207
 
208
+ *Effects:* Value-initializes each element.
209
 
210
+ *Remarks:* This constructor shall not participate in overload resolution
211
+ unless `is_default_constructible_v<``Tᵢ``>` is `true` for all i.
212
+
213
+ [*Note 1*: This behavior can be implemented by a constructor template
214
+ with default template arguments. — *end note*]
215
+
216
+ The constructor is explicit if and only if `Tᵢ` is not implicitly
217
+ default-constructible for at least one i.
218
+
219
+ [*Note 2*: This behavior can be implemented with a trait that checks
220
+ whether a `const ``Tᵢ``&` can be initialized with `{}`. — *end note*]
221
 
222
  ``` cpp
223
+ \EXPLICIT constexpr tuple(const Types&...);
224
  ```
225
 
 
 
226
  *Effects:* Initializes each element with the value of the corresponding
227
  parameter.
228
 
229
+ *Remarks:* This constructor shall not participate in overload resolution
230
+ unless `sizeof...(Types) >= 1` and `is_copy_constructible_v<``Tᵢ``>` is
231
+ `true` for all i. The constructor is explicit if and only if
232
+ `is_convertible_v<const ``Tᵢ``&, ``Tᵢ``>` is `false` for at least one i.
233
+
234
  ``` cpp
235
+ template <class... UTypes> \EXPLICIT constexpr tuple(UTypes&&... u);
 
236
  ```
237
 
 
 
 
238
  *Effects:* Initializes the elements in the tuple with the corresponding
239
  value in `std::forward<UTypes>(u)`.
240
 
241
+ *Remarks:* This constructor shall not participate in overload resolution
242
+ unless `sizeof...(Types)` `==` `sizeof...(UTypes)` and
243
+ `sizeof...(Types) >= 1` and `is_constructible_v<``Tᵢ``, ``Uᵢ``&&>` is
244
+ `true` for all i. The constructor is explicit if and only if
245
+ `is_convertible_v<``Uᵢ``&&, ``Tᵢ``>` is `false` for at least one i.
246
 
247
  ``` cpp
248
  tuple(const tuple& u) = default;
249
  ```
250
 
251
+ *Requires:* `is_copy_constructible_v<``Tᵢ``>` is `true` for all i.
252
 
253
  *Effects:* Initializes each element of `*this` with the corresponding
254
  element of `u`.
255
 
256
  ``` cpp
257
  tuple(tuple&& u) = default;
258
  ```
259
 
260
+ *Requires:* `is_move_constructible_v<``Tᵢ``>` is `true` for all i.
261
 
262
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
263
+ `std::forward<``Tᵢ``>(get<`i`>(u))`.
264
 
265
  ``` cpp
266
+ template <class... UTypes> \EXPLICIT constexpr tuple(const tuple<UTypes...>& u);
267
  ```
268
 
269
+ *Effects:* Initializes each element of `*this` with the corresponding
 
 
 
270
  element of `u`.
271
 
272
+ *Remarks:* This constructor shall not participate in overload resolution
273
+ unless
274
+
275
+ - `sizeof...(Types)` `==` `sizeof...(UTypes)` and
276
+ - `is_constructible_v<``Tᵢ``, const ``Uᵢ``&>` is `true` for all i, and
277
+ - `sizeof...(Types) != 1`, or (when `Types...` expands to `T` and
278
+ `UTypes...` expands to `U`)
279
+ `!is_convertible_v<const tuple<U>&, T> && !is_constructible_v<T, const tuple<U>&>&& !is_same_v<T, U>`
280
+ is `true`.
281
+
282
+ The constructor is explicit if and only if
283
+ `is_convertible_v<const ``Uᵢ``&, ``Tᵢ``>` is `false` for at least one i.
284
 
285
  ``` cpp
286
+ template <class... UTypes> \EXPLICIT constexpr tuple(tuple<UTypes...>&& u);
287
  ```
288
 
 
 
 
289
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
290
+ `std::forward<``Uᵢ``>(get<`i`>(u))`.
291
 
292
+ *Remarks:* This constructor shall not participate in overload resolution
293
+ unless
294
+
295
+ - `sizeof...(Types)` `==` `sizeof...(UTypes)`, and
296
+ - `is_constructible_v<``Tᵢ``, ``Uᵢ``&&>` is `true` for all i, and
297
+ - `sizeof...(Types) != 1`, or (when `Types...` expands to `T` and
298
+ `UTypes...` expands to `U`)
299
+ `!is_convertible_v<tuple<U>, T> && !is_constructible_v<T, tuple<U>> &&!is_same_v<T, U>`
300
+ is `true`.
301
+
302
+ The constructor is explicit if and only if
303
+ `is_convertible_v<``Uᵢ``&&, ``Tᵢ``>` is `false` for at least one i.
304
 
305
  ``` cpp
306
+ template <class U1, class U2> \EXPLICIT constexpr tuple(const pair<U1, U2>& u);
307
  ```
308
 
309
+ *Effects:* Initializes the first element with `u.first` and the second
 
 
 
 
 
310
  element with `u.second`.
311
 
312
+ *Remarks:* This constructor shall not participate in overload resolution
313
+ unless `sizeof...(Types) == 2`, `is_constructible_v<``T₀``, const U1&>`
314
+ is `true` and `is_constructible_v<``T₁``, const U2&>` is `true`.
315
+
316
+ The constructor is explicit if and only if
317
+ `is_convertible_v<const U1&, ``T₀``>` is `false` or
318
+ `is_convertible_v<const U2&, ``T₁``>` is `false`.
319
 
320
  ``` cpp
321
+ template <class U1, class U2> \EXPLICIT constexpr tuple(pair<U1, U2>&& u);
322
  ```
323
 
 
 
 
 
 
324
  *Effects:* Initializes the first element with
325
  `std::forward<U1>(u.first)` and the second element with
326
  `std::forward<U2>(u.second)`.
327
 
328
+ *Remarks:* This constructor shall not participate in overload resolution
329
+ unless `sizeof...(Types) == 2`, `is_constructible_v<``T₀``, U1&&>` is
330
+ `true` and `is_constructible_v<``T₁``, U2&&>` is `true`.
331
+
332
+ The constructor is explicit if and only if
333
+ `is_convertible_v<U1&&, ``T₀``>` is `false` or
334
+ `is_convertible_v<U2&&, ``T₁``>` is `false`.
335
 
336
  ``` cpp
337
  template <class Alloc>
338
  tuple(allocator_arg_t, const Alloc& a);
339
  template <class Alloc>
340
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
341
  template <class Alloc, class... UTypes>
342
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
343
  template <class Alloc>
344
  tuple(allocator_arg_t, const Alloc& a, const tuple&);
345
  template <class Alloc>
346
  tuple(allocator_arg_t, const Alloc& a, tuple&&);
347
  template <class Alloc, class... UTypes>
348
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
349
  template <class Alloc, class... UTypes>
350
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
351
  template <class Alloc, class U1, class U2>
352
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
353
  template <class Alloc, class U1, class U2>
354
+ \EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
355
  ```
356
 
357
  *Requires:* `Alloc` shall meet the requirements for an
358
  `Allocator` ([[allocator.requirements]]).
359
 
 
364
  #### Assignment <a id="tuple.assign">[[tuple.assign]]</a>
365
 
366
  For each `tuple` assignment operator, an exception is thrown only if the
367
  assignment of one of the types in `Types` throws an exception. In the
368
  function descriptions that follow, let i be in the range \[`0`,
369
+ `sizeof...(Types)`) in order, `Tᵢ` be the iᵗʰ type in `Types`, and `Uᵢ`
370
+ be the iᵗʰ type in a template parameter pack named `UTypes`, where
371
+ indexing is zero-based.
372
 
373
  ``` cpp
374
  tuple& operator=(const tuple& u);
375
  ```
376
 
 
 
377
  *Effects:* Assigns each element of `u` to the corresponding element of
378
  `*this`.
379
 
380
+ *Remarks:* This operator shall be defined as deleted unless
381
+ `is_copy_assignable_v<``Tᵢ``>` is `true` for all i.
382
+
383
+ *Returns:* `*this`.
384
 
385
  ``` cpp
386
  tuple& operator=(tuple&& u) noexcept(see below);
387
  ```
388
 
389
+ *Effects:* For all i, assigns `std::forward<``Tᵢ``>(get<`i`>(u))` to
390
+ `get<`i`>(*this)`.
391
+
392
+ *Remarks:* This operator shall be defined as deleted unless
393
+ `is_move_assignable_v<``Tᵢ``>` is `true` for all i.
394
+
395
+ *Remarks:* The expression inside `noexcept` is equivalent to the logical
396
  <span class="smallcaps">and</span> of the following expressions:
397
 
398
  ``` cpp
399
+ is_nothrow_move_assignable_v<Tᵢ>
400
  ```
401
 
402
  where Tᵢ is the iᵗʰ type in `Types`.
403
 
 
 
 
 
 
404
  *Returns:* `*this`.
405
 
406
  ``` cpp
407
+ template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
 
408
  ```
409
 
 
 
 
410
  *Effects:* Assigns each element of `u` to the corresponding element of
411
  `*this`.
412
 
413
+ *Remarks:* This operator shall not participate in overload resolution
414
+ unless `sizeof...(Types) == sizeof...(UTypes)` and
415
+ `is_assignable_v<``Tᵢ``&, const ``Uᵢ``&>` is `true` for all i.
416
+
417
+ *Returns:* `*this`.
418
 
419
  ``` cpp
420
+ template <class... UTypes> tuple& operator=(tuple<UTypes...>&& u);
 
421
  ```
422
 
423
+ *Effects:* For all i, assigns `std::forward<``Uᵢ``>(get<`i`>(u))` to
 
 
 
 
424
  `get<`i`>(*this)`.
425
 
426
+ *Remarks:* This operator shall not participate in overload resolution
427
+ unless `is_assignable_v<``Tᵢ``&, ``Uᵢ``&&> == true` for all i and
428
+ `sizeof...(Types) == sizeof...(UTypes)`.
429
+
430
  *Returns:* `*this`.
431
 
432
  ``` cpp
433
  template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
434
  ```
435
 
 
 
 
 
 
436
  *Effects:* Assigns `u.first` to the first element of `*this` and
437
  `u.second` to the second element of `*this`.
438
 
439
+ *Remarks:* This operator shall not participate in overload resolution
440
+ unless `sizeof...(Types) == 2` and `is_assignable_v<``T₀``&, const U1&>`
441
+ is `true` for the first type `T₀` in `Types` and
442
+ `is_assignable_v<``T₁``&, const U2&>` is `true` for the second type `T₁`
443
+ in `Types`.
444
+
445
+ *Returns:* `*this`.
446
 
447
  ``` cpp
448
  template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
449
  ```
450
 
 
 
 
 
 
451
  *Effects:* Assigns `std::forward<U1>(u.first)` to the first element of
452
  `*this` and
453
  `std::forward<U2>(u.second)` to the second element of `*this`.
454
 
455
+ *Remarks:* This operator shall not participate in overload resolution
456
+ unless `sizeof...(Types) == 2` and `is_assignable_v<``T₀``&, U1&&>` is
457
+ `true` for the first type `T₀` in `Types` and
458
+ `is_assignable_v<``T₁``&, U2&&>` is `true` for the second type `T₁` in
459
+ `Types`.
460
+
461
  *Returns:* `*this`.
462
 
463
  #### `swap` <a id="tuple.swap">[[tuple.swap]]</a>
464
 
465
  ``` cpp
466
  void swap(tuple& rhs) noexcept(see below);
467
  ```
468
 
 
 
 
 
 
 
 
 
 
469
  *Requires:* Each element in `*this` shall be swappable
470
  with ([[swappable.requirements]]) the corresponding element in `rhs`.
471
 
472
  *Effects:* Calls `swap` for each element in `*this` and its
473
  corresponding element in `rhs`.
474
 
475
+ *Remarks:* The expression inside `noexcept` is equivalent to the logical
476
+ <span class="smallcaps">and</span> of the following expressions:
477
+
478
+ ``` cpp
479
+ is_nothrow_swappable_v<Tᵢ>
480
+ ```
481
+
482
+ where Tᵢ is the iᵗʰ type in `Types`.
483
+
484
  *Throws:* Nothing unless one of the element-wise `swap` calls throws an
485
  exception.
486
 
487
  #### Tuple creation functions <a id="tuple.creation">[[tuple.creation]]</a>
488
 
489
+ In the function descriptions that follow, the members of a parameter
490
+ pack `XTypes` are denoted by `X`for i in \[`0`,
491
+ `sizeof...(`*X*`Types)`) in order, where indexing is zero-based.
 
 
492
 
493
  ``` cpp
494
+ template<class... TTypes>
495
+ constexpr tuple<VTypes...> make_tuple(TTypes&&... t);
496
  ```
497
 
498
+ The pack `VTypes` is defined as follows. Let `U`ᵢ be `decay_t<T`ᵢ`>` for
499
+ each `T` in `TTypes`. If `U`is a specialization of
500
+ `reference_wrapper`, then `V`ᵢ in `VTypes` is `U``::type&`, otherwise
501
+ `V`ᵢ is `U`ᵢ.
502
 
503
+ *Returns:* `tuple<VTypes...>(std::forward<TTypes>(t)...)`.
504
+
505
+ [*Example 1*:
506
 
507
  ``` cpp
508
  int i; float j;
509
  make_tuple(1, ref(i), cref(j))
510
  ```
511
 
512
+ creates a tuple of type `tuple<int, int&, const float&>`.
513
 
514
+ *end example*]
 
 
515
 
516
  ``` cpp
517
+ template<class... TTypes>
518
+ constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&... t) noexcept;
519
  ```
520
 
521
  *Effects:* Constructs a tuple of references to the arguments in `t`
522
  suitable for forwarding as arguments to a function. Because the result
523
  may contain references to temporary variables, a program shall ensure
524
  that the return value of this function does not outlive any of its
525
+ arguments (e.g., the program should typically not store the result in a
526
  named variable).
527
 
528
+ *Returns:* `tuple<TTypes&&...>(std::forward<TTypes>(t)...)`.
529
 
530
  ``` cpp
531
+ template<class... TTypes>
532
+ constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
533
  ```
534
 
535
+ *Returns:* `tuple<TTypes&...>(t...)`. When an argument in `t` is
536
  `ignore`, assigning any value to the corresponding tuple element has no
537
  effect.
538
 
539
+ [*Example 2*:
540
+
541
  `tie` functions allow one to create tuples that unpack tuples into
542
  variables. `ignore` can be used for elements that are not needed:
543
 
544
  ``` cpp
545
  int i; std::string s;
546
  tie(i, ignore, s) = make_tuple(42, 3.14, "C++");
547
  // i == 42, s == "C++"
548
  ```
549
 
550
+ — *end example*]
551
+
552
  ``` cpp
553
  template <class... Tuples>
554
  constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
555
  ```
556
 
557
+ In the following paragraphs, let `Tᵢ` be the iᵗʰ type in `Tuples`, `Uᵢ`
558
+ be `remove_reference_t<T`ᵢ`>`, and `tpᵢ` be the iᵗʰ parameter in the
559
+ function parameter pack `tpls`, where all indexing is zero-based.
560
 
561
+ *Requires:* For all i, `Uᵢ` shall be the type cvᵢ `tuple<``Argsᵢ``...>`,
562
+ where cvᵢ is the (possibly empty) iᵗʰ *cv-qualifier-seq* and `Argsᵢ` is
563
+ the parameter pack representing the element types in `Uᵢ`. Let `A_ik` be
564
+ the kᵗʰ type in `Argsᵢ`. For all `A_ik` the following requirements shall
565
+ be satisfied:
 
 
566
 
567
+ - If `Tᵢ` is deduced as an lvalue reference type, then
568
+ `is_constructible_v<``A_ik``, `cvᵢ `A_ik``&> == true`, otherwise
569
+ - `is_constructible_v<``A_ik``, `cv `A_ik``&&> == true`.
570
+
571
+ *Remarks:* The types in `CTypes` shall be equal to the ordered sequence
572
+ of the extended types `Args₀``..., ``Args₁``..., `…`, ``Args_n-1``...`,
573
+ where n is equal to `sizeof...(Tuples)`. Let `eᵢ``...` be the iᵗʰ
574
+ ordered sequence of tuple elements of the resulting `tuple` object
575
+ corresponding to the type sequence `Argsᵢ`.
576
 
577
  *Returns:* A `tuple` object constructed by initializing the kᵢᵗʰ type
578
+ element `e_ik` in `eᵢ``...` with
 
 
579
 
580
+ ``` cpp
581
+ get<kᵢ>(std::forward<$T_i$>($tp_i$))
582
+ ```
583
+
584
+ for each valid kᵢ and each group `eᵢ` in order.
585
+
586
+ [*Note 1*: An implementation may support additional types in the
587
+ parameter pack `Tuples` that support the `tuple`-like protocol, such as
588
+ `pair` and `array`. — *end note*]
589
+
590
+ #### Calling a function with a `tuple` of arguments <a id="tuple.apply">[[tuple.apply]]</a>
591
+
592
+ ``` cpp
593
+ template <class F, class Tuple>
594
+ constexpr decltype(auto) apply(F&& f, Tuple&& t);
595
+ ```
596
+
597
+ *Effects:* Given the exposition-only function:
598
+
599
+ ``` cpp
600
+ template <class F, class Tuple, size_t... I>
601
+ constexpr decltype(auto)
602
+ apply_impl(F&& f, Tuple&& t, index_sequence<I...>) { // exposition only
603
+ return INVOKE(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
604
+ }
605
+ ```
606
+
607
+ Equivalent to:
608
+
609
+ ``` cpp
610
+ return apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
611
+ make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
612
+ ```
613
+
614
+ ``` cpp
615
+ template <class T, class Tuple>
616
+ constexpr T make_from_tuple(Tuple&& t);
617
+ ```
618
+
619
+ *Effects:* Given the exposition-only function:
620
+
621
+ ``` cpp
622
+ template <class T, class Tuple, size_t... I>
623
+ constexpr T make_from_tuple_impl(Tuple&& t, index_sequence<I...>) { // exposition only
624
+ return T(get<I>(std::forward<Tuple>(t))...);
625
+ }
626
+ ```
627
+
628
+ Equivalent to:
629
+
630
+ ``` cpp
631
+ return make_from_tuple_impl<T>(forward<Tuple>(t),
632
+ make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
633
+ ```
634
+
635
+ [*Note 1*: The type of `T` must be supplied as an explicit template
636
+ parameter, as it cannot be deduced from the argument
637
+ list. — *end note*]
638
 
639
  #### Tuple helper classes <a id="tuple.helper">[[tuple.helper]]</a>
640
 
641
  ``` cpp
642
  template <class T> struct tuple_size;
643
  ```
644
 
645
+ *Remarks:* All specializations of `tuple_size` shall meet the
646
+ `UnaryTypeTrait` requirements ([[meta.rqmts]]) with a base
647
+ characteristic of `integral_constant<size_t, N>` for some `N`.
648
 
649
  ``` cpp
650
  template <class... Types>
651
+ class tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
 
652
  ```
653
 
654
  ``` cpp
655
  template <size_t I, class... Types>
656
  class tuple_element<I, tuple<Types...>> {
657
  public:
658
+ using type = TI;
659
  };
660
  ```
661
 
662
  *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
663
  out of bounds.
 
669
  template <class T> class tuple_size<const T>;
670
  template <class T> class tuple_size<volatile T>;
671
  template <class T> class tuple_size<const volatile T>;
672
  ```
673
 
674
+ Let *`TS`* denote `tuple_size<T>` of the cv-unqualified type `T`. If the
675
+ expression *`TS`*`::value` is well-formed when treated as an unevaluated
676
+ operand, then each of the three templates shall meet the
677
+ `UnaryTypeTrait` requirements ([[meta.rqmts]]) with a base
678
+ characteristic of
679
 
680
  ``` cpp
681
  integral_constant<size_t, TS::value>
682
  ```
683
 
684
+ Otherwise, they shall have no member `value`.
685
+
686
+ Access checking is performed as if in a context unrelated to *`TS`* and
687
+ `T`. Only the validity of the immediate context of the expression is
688
+ considered.
689
+
690
+ [*Note 1*: The compilation of the expression can result in side effects
691
+ such as the instantiation of class template specializations and function
692
+ template specializations, the generation of implicitly-defined
693
+ functions, and so on. Such side effects are not in the “immediate
694
+ context” and can result in the program being ill-formed. — *end note*]
695
+
696
+ In addition to being available via inclusion of the `<tuple>` header,
697
+ the three templates are available when either of the headers `<array>`
698
+ or `<utility>` are included.
699
+
700
  ``` cpp
701
  template <size_t I, class T> class tuple_element<I, const T>;
702
  template <size_t I, class T> class tuple_element<I, volatile T>;
703
  template <size_t I, class T> class tuple_element<I, const volatile T>;
704
  ```
705
 
706
+ Let *`TE`* denote `tuple_element_t<I, T>` of the cv-unqualified type
707
+ `T`. Then each of the three templates shall meet the
708
+ `TransformationTrait` requirements ([[meta.rqmts]]) with a member
709
+ typedef `type` that names the following type:
710
 
711
+ - for the first specialization, `add_const_t<`*`TE`*`>`,
712
+ - for the second specialization, `add_volatile_t<`*`TE`*`>`, and
713
+ - for the third specialization, `add_cv_t<`*`TE`*`>`.
714
+
715
+ In addition to being available via inclusion of the `<tuple>` header,
716
+ the three templates are available when either of the headers `<array>`
717
+ or `<utility>` are included.
718
 
719
  #### Element access <a id="tuple.elem">[[tuple.elem]]</a>
720
 
721
  ``` cpp
722
  template <size_t I, class... Types>
723
+ constexpr tuple_element_t<I, tuple<Types...>>&
724
+ get(tuple<Types...>& t) noexcept;
725
+ template <size_t I, class... Types>
726
+ constexpr tuple_element_t<I, tuple<Types...>>&&
727
+ get(tuple<Types...>&& t) noexcept; // Note A
728
+ template <size_t I, class... Types>
729
+ constexpr const tuple_element_t<I, tuple<Types...>>&
730
+ get(const tuple<Types...>& t) noexcept; // Note B
731
+ template <size_t I, class... Types>
732
+ constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
733
  ```
734
 
735
  *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
736
  out of bounds.
737
 
738
  *Returns:* A reference to the `I`th element of `t`, where indexing is
739
  zero-based.
740
 
741
+ [*Note 1*: \[Note A\]If a `T` in `Types` is some reference type `X&`,
742
+ the return type is `X&`, not `X&&`. However, if the element type is a
743
+ non-reference type `T`, the return type is `T&&`. *end note*]
744
+
745
+ [*Note 2*: \[Note B\]Constness is shallow. If a `T` in `Types` is some
746
+ reference type `X&`, the return type is `X&`, not `const X&`. However,
747
+ if the element type is a non-reference type `T`, the return type is
748
+ `const T&`. This is consistent with how constness is defined to work for
749
+ member variables of reference type. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
750
 
751
  ``` cpp
752
  template <class T, class... Types>
753
  constexpr T& get(tuple<Types...>& t) noexcept;
754
  template <class T, class... Types>
755
  constexpr T&& get(tuple<Types...>&& t) noexcept;
756
  template <class T, class... Types>
757
  constexpr const T& get(const tuple<Types...>& t) noexcept;
758
+ template <class T, class... Types>
759
+ constexpr const T&& get(const tuple<Types...>&& t) noexcept;
760
  ```
761
 
762
  *Requires:* The type `T` occurs exactly once in `Types...`. Otherwise,
763
  the program is ill-formed.
764
 
765
  *Returns:* A reference to the element of `t` corresponding to the type
766
  `T` in `Types...`.
767
 
768
+ [*Example 1*:
769
+
770
  ``` cpp
771
  const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6);
772
  const int& i1 = get<int>(t); // OK. Not ambiguous. i1 == 1
773
  const int& i2 = get<const int>(t); // OK. Not ambiguous. i2 == 2
774
  const double& d = get<double>(t); // ERROR. ill-formed
775
  ```
776
 
777
+ *end example*]
778
+
779
+ [*Note 1*: The reason `get` is a non-member function is that if this
780
+ functionality had been provided as a member function, code where the
781
+ type depended on a template parameter would have required using the
782
+ `template` keyword. — *end note*]
783
 
784
  #### Relational operators <a id="tuple.rel">[[tuple.rel]]</a>
785
 
786
  ``` cpp
787
  template<class... TTypes, class... UTypes>
 
804
  template<class... TTypes, class... UTypes>
805
  constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
806
  ```
807
 
808
  *Requires:* For all `i`, where `0 <= i` and `i < sizeof...(TTypes)`,
809
+ both `get<i>(t) < get<i>(u)` and `get<i>(u) < get<i>(t)` are valid
810
  expressions returning types that are convertible to `bool`.
811
  `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
812
 
813
  *Returns:* The result of a lexicographical comparison between `t` and
814
  `u`. The result is defined as:
 
834
  ``` cpp
835
  template<class... TTypes, class... UTypes>
836
  constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
837
  ```
838
 
839
+ *Returns:* `!(u < t)`.
840
 
841
  ``` cpp
842
  template<class... TTypes, class... UTypes>
843
  constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
844
  ```
845
 
846
+ *Returns:* `!(t < u)`.
847
 
848
+ [*Note 1*: The above definitions for comparison functions do not
849
+ require `tₜₐᵢₗ` (or `uₜₐᵢₗ`) to be constructed. It may not even be
850
+ possible, as `t` and `u` are not required to be copy constructible.
851
+ Also, all comparison functions are short circuited; they do not perform
852
+ element accesses beyond what is required to determine the result of the
853
+ comparison. — *end note*]
854
 
855
  #### Tuple traits <a id="tuple.traits">[[tuple.traits]]</a>
856
 
857
  ``` cpp
858
  template <class... Types, class Alloc>
 
860
  ```
861
 
862
  *Requires:* `Alloc` shall be an
863
  `Allocator` ([[allocator.requirements]]).
864
 
865
+ [*Note 1*: Specialization of this trait informs other library
866
+ components that `tuple` can be constructed with an allocator, even
867
+ though it does not have a nested `allocator_type`. — *end note*]
868
 
869
  #### Tuple specialized algorithms <a id="tuple.special">[[tuple.special]]</a>
870
 
871
  ``` cpp
872
  template <class... Types>
873
  void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
874
  ```
875
 
876
+ *Remarks:* This function shall not participate in overload resolution
877
+ unless `is_swappable_v<``Tᵢ``>` is `true` for all i, where
878
+ 0 ≤ i < `sizeof...(Types)`. The expression inside `noexcept` is
879
+ equivalent to:
880
 
881
  ``` cpp
882
  noexcept(x.swap(y))
883
  ```
884
 
885
+ *Effects:* As if by `x.swap(y)`.
886