From Jason Turner

[tuple]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpry53_gj8/{from.md → to.md} +107 -58
tmp/tmpry53_gj8/{from.md → to.md} RENAMED
@@ -17,19 +17,19 @@ namespace std {
17
 
18
  // [tuple.creation], tuple creation functions:
19
  const unspecified ignore;
20
 
21
  template <class... Types>
22
- tuple<VTypes...> make_tuple(Types&&...);
23
  template <class... Types>
24
- tuple<Types...> forward_as_tuple(Types&&...) noexcept;
25
 
26
  template<class... Types>
27
- tuple<Types&...> tie(Types&...) noexcept;
28
 
29
  template <class... Tuples>
30
- 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>;
@@ -42,31 +42,43 @@ namespace std {
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
  // [tuple.elem], element access:
48
  template <size_t I, class... Types>
49
- typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&) noexcept;
50
- template <size_t I, class... types>
51
- typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&&) noexcept;
52
- template <size_t I, class... types>
53
- typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>&) noexcept;
 
 
 
 
 
 
 
 
 
54
 
55
  // [tuple.rel], relational operators:
56
  template<class... TTypes, class... UTypes>
57
- bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
58
  template<class... TTypes, class... UTypes>
59
- bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);
60
  template<class... TTypes, class... UTypes>
61
- bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&);
62
  template<class... TTypes, class... UTypes>
63
- bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&);
64
  template<class... TTypes, class... UTypes>
65
- bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&);
66
  template<class... TTypes, class... UTypes>
67
- bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&);
68
 
69
  // [tuple.traits], allocator-related traits
70
  template <class... Types, class Alloc>
71
  struct uses_allocator<tuple<Types...>, Alloc>;
72
 
@@ -84,26 +96,26 @@ namespace std {
84
  class tuple {
85
  public:
86
 
87
  // [tuple.cnstr], tuple construction
88
  constexpr tuple();
89
- explicit tuple(const Types&...);
90
  template <class... UTypes>
91
- explicit tuple(UTypes&&...);
92
 
93
  tuple(const tuple&) = default;
94
  tuple(tuple&&) = default;
95
 
96
  template <class... UTypes>
97
- tuple(const tuple<UTypes...>&);
98
  template <class... UTypes>
99
- tuple(tuple<UTypes...>&&);
100
 
101
  template <class U1, class U2>
102
- tuple(const pair<U1, U2>&); // iff sizeof...(Types) == 2
103
  template <class U1, class U2>
104
- tuple(pair<U1, U2>&&); // iff sizeof...(Types) == 2
105
 
106
  // allocator-extended constructors
107
  template <class Alloc>
108
  tuple(allocator_arg_t, const Alloc& a);
109
  template <class Alloc>
@@ -131,13 +143,13 @@ namespace std {
131
  tuple& operator=(const tuple<UTypes...>&);
132
  template <class... UTypes>
133
  tuple& operator=(tuple<UTypes...>&&);
134
 
135
  template <class U1, class U2>
136
- tuple& operator=(const pair<U1, U2>&); // iff sizeof...(Types) == 2
137
  template <class U1, class U2>
138
- tuple& operator=(pair<U1, U2>&&); // iff sizeof...(Types) == 2
139
 
140
  // [tuple.swap], tuple swap
141
  void swap(tuple&) noexcept(see below);
142
  };
143
  }
@@ -146,10 +158,16 @@ namespace std {
146
  #### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
147
 
148
  For each `tuple` constructor, an exception is thrown only if the
149
  construction of one of the types in `Types` throws an exception.
150
 
 
 
 
 
 
 
151
  In the constructor descriptions that follow, let i be in the range
152
  \[`0`, `sizeof...(Types)`) in order, Tᵢ be the iᵗʰ type in `Types`, and
153
  Uᵢ be the iᵗʰ type in a template parameter pack named `UTypes`, where
154
  indexing is zero-based.
155
 
@@ -160,21 +178,21 @@ constexpr tuple();
160
  *Requires:* `is_default_constructible<`Tᵢ`>::value` is true for all i.
161
 
162
  *Effects:* Value initializes each element.
163
 
164
  ``` cpp
165
- explicit tuple(const Types&...);
166
  ```
167
 
168
  *Requires:* `is_copy_constructible<`Tᵢ`>::value` is true for all i.
169
 
170
  *Effects:* Initializes each element with the value of the corresponding
171
  parameter.
172
 
173
  ``` cpp
174
  template <class... UTypes>
175
- explicit tuple(UTypes&&... u);
176
  ```
177
 
178
  *Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
179
  `is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
180
 
@@ -202,11 +220,11 @@ tuple(tuple&& u) = default;
202
 
203
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
204
  `std::forward<`Tᵢ`>(get<`i`>(u))`.
205
 
206
  ``` cpp
207
- template <class... UTypes> tuple(const tuple<UTypes...>& u);
208
  ```
209
 
210
  *Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
211
  `is_constructible<`Tᵢ`, const `Uᵢ`&>::value` is `true` for all i.
212
 
@@ -215,11 +233,11 @@ element of `u`.
215
 
216
  This constructor shall not participate in overload resolution unless
217
  `const `Uᵢ`&` is implicitly convertible to Tᵢ for all i.
218
 
219
  ``` cpp
220
- template <class... UTypes> tuple(tuple<UTypes...>&& u);
221
  ```
222
 
223
  *Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
224
  `is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
225
 
@@ -229,11 +247,11 @@ template <class... UTypes> tuple(tuple<UTypes...>&& u);
229
  This constructor shall not participate in overload resolution unless
230
  each type in `UTypes` is implicitly convertible to its corresponding
231
  type in `Types`.
232
 
233
  ``` cpp
234
- template <class U1, class U2> tuple(const pair<U1, U2>& u);
235
  ```
236
 
237
  *Requires:* `sizeof...(Types) == 2`.
238
  `is_constructible<`T₀`, const U1&>::value` is `true` for the first type
239
  T₀ in `Types` and `is_constructible<`T₁`, const U2&>::value` is `true`
@@ -245,11 +263,11 @@ element with `u.second`.
245
  This constructor shall not participate in overload resolution unless
246
  `const U1&` is implicitly convertible to T₀ and `const U2&` is
247
  implicitly convertible to T₁.
248
 
249
  ``` cpp
250
- template <class U1, class U2> tuple(pair<U1, U2>&& u);
251
  ```
252
 
253
  *Requires:* `sizeof...(Types) == 2`.
254
  `is_constructible<`T₀`, U1&&>::value` is `true` for the first type T₀ in
255
  `Types` and `is_constructible<`T₁`, U2&&>::value` is `true` for the
@@ -398,11 +416,11 @@ The expression inside `noexcept` is equivalent to the logical
398
 
399
  ``` cpp
400
  noexcept(swap(declval<Tᵢ&>>(), declval<Tᵢ&>()))
401
  ```
402
 
403
- where T is the iᵗʰ type in `Types`.
404
 
405
  *Requires:* Each element in `*this` shall be swappable
406
  with ([[swappable.requirements]]) the corresponding element in `rhs`.
407
 
408
  *Effects:* Calls `swap` for each element in `*this` and its
@@ -419,14 +437,14 @@ parameter pack named `TTypes`; let j be in the range \[`0`,
419
  `sizeof...(UTypes)`) in order and Uⱼ be the jᵗʰ type in a template
420
  parameter pack named `UTypes`, where indexing is zero-based.
421
 
422
  ``` cpp
423
  template<class... Types>
424
- tuple<VTypes...> make_tuple(Types&&... t);
425
  ```
426
 
427
- Let Uᵢ be `decay<`Tᵢ`>::type` for each Tᵢ in `Types`. Then each Vᵢ in
428
  `VTypes` is `X&` if Uᵢ equals `reference_wrapper<X>`, otherwise Vᵢ is
429
  Uᵢ.
430
 
431
  *Returns:* `tuple<VTypes...>(std::forward<Types>(t)...)`.
432
 
@@ -441,11 +459,11 @@ creates a tuple of type
441
  tuple<int, int&, const float&>
442
  ```
443
 
444
  ``` cpp
445
  template<class... Types>
446
- tuple<Types&&...> forward_as_tuple(Types&&... t) noexcept;
447
  ```
448
 
449
  *Effects:* Constructs a tuple of references to the arguments in `t`
450
  suitable for forwarding as arguments to a function. Because the result
451
  may contain references to temporary variables, a program shall ensure
@@ -455,15 +473,16 @@ named variable).
455
 
456
  *Returns:* `tuple<Types&&...>(std::forward<Types>(t)...)`
457
 
458
  ``` cpp
459
  template<class... Types>
460
- tuple<Types&...> tie(Types&... t) noexcept;
461
  ```
462
 
463
- *Returns:* `tuple<Types&>(t...)`. When an argument in `t` is `ignore`,
464
- assigning any value to the corresponding tuple element has no effect.
 
465
 
466
  `tie` functions allow one to create tuples that unpack tuples into
467
  variables. `ignore` can be used for elements that are not needed:
468
 
469
  ``` cpp
@@ -472,16 +491,16 @@ tie(i, ignore, s) = make_tuple(42, 3.14, "C++");
472
  // i == 42, s == "C++"
473
  ```
474
 
475
  ``` cpp
476
  template <class... Tuples>
477
- tuple<CTypes...> tuple_cat(Tuples&&... tpls);
478
  ```
479
 
480
  In the following paragraphs, let Tᵢ be the iᵗʰ type in `Tuples`, Uᵢ be
481
- `remove_reference<Ti>::type`, and tpᵢ be the iᵗʰ parameter in the
482
- function parameter pack `tpls`, where all indexing is zero-based.
483
 
484
  *Requires:* For all i, Uᵢ shall be the type cvᵢ `tuple<`Argsᵢ...`>`,
485
  where cvᵢ is the (possibly empty) iᵗʰ cv-qualifier-seq and Argsᵢ is the
486
  parameter pack representing the element types in Uᵢ. Let {Aᵢₖ} be the
487
  kᵢᵗʰ type in Argsᵢ. For all Aᵢₖ the following requirements shall be
@@ -504,10 +523,18 @@ eᵢ in order.
504
  pack `Tuples` that support the `tuple`-like protocol, such as `pair` and
505
  `array`.
506
 
507
  #### Tuple helper classes <a id="tuple.helper">[[tuple.helper]]</a>
508
 
 
 
 
 
 
 
 
 
509
  ``` cpp
510
  template <class... Types>
511
  class tuple_size<tuple<Types...> >
512
  : public integral_constant<size_t, sizeof...(Types)> { };
513
  ```
@@ -535,11 +562,11 @@ template <class T> class tuple_size<const volatile T>;
535
  Let *TS* denote `tuple_size<T>` of the cv-unqualified type `T`. Then
536
  each of the three templates shall meet the `UnaryTypeTrait`
537
  requirements ([[meta.rqmts]]) with a `BaseCharacteristic` of
538
 
539
  ``` cpp
540
- integral_constant<remove_cv<decltype(TS::value)>::type, TS::value>
541
  ```
542
 
543
  ``` cpp
544
  template <size_t I, class T> class tuple_element<I, const T>;
545
  template <size_t I, class T> class tuple_element<I, volatile T>;
@@ -549,31 +576,30 @@ template <size_t I, class T> class tuple_element<I, const volatile T>;
549
  Let *TE* denote `tuple_element<I, T>` of the cv-unqualified type `T`.
550
  Then each of the three templates shall meet the `TransformationTrait`
551
  requirements ([[meta.rqmts]]) with a member typedef `type` that names
552
  the following type:
553
 
554
- - for the first specialization, `add_const<`*`TE`*`::type>::type`,
555
- - for the second specialization, `add_volatile<`*`TE`*`::type>::type`,
556
- and
557
- - for the third specialization, `add_cv<`*`TE`*`::type>::type`.
558
 
559
  #### Element access <a id="tuple.elem">[[tuple.elem]]</a>
560
 
561
  ``` cpp
562
  template <size_t I, class... Types>
563
- typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>& t) noexcept;
564
  ```
565
 
566
  *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
567
  out of bounds.
568
 
569
  *Returns:* A reference to the `I`th element of `t`, where indexing is
570
  zero-based.
571
 
572
  ``` cpp
573
- template <size_t I, class... types>
574
- typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&& t) noexcept;
575
  ```
576
 
577
  *Effects:* Equivalent to
578
  `return std::forward<typename tuple_element<I, tuple<Types...> >`
579
  `::type&&>(get<I>(t));`
@@ -582,11 +608,11 @@ template <size_t I, class... types>
582
  is `X&`, not `X&&`. However, if the element type is a non-reference type
583
  `T`, the return type is `T&&`.
584
 
585
  ``` cpp
586
  template <size_t I, class... Types>
587
- typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>& t) noexcept;
588
  ```
589
 
590
  *Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
591
  out of bounds.
592
 
@@ -597,38 +623,61 @@ Constness is shallow. If a `T` in `Types` is some reference type `X&`,
597
  the return type is `X&`, not `const X&`. However, if the element type is
598
  non-reference type `T`, the return type is `const T&`. This is
599
  consistent with how constness is defined to work for member variables of
600
  reference type.
601
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  The reason `get` is a nonmember function is that if this functionality
603
  had been provided as a member function, code where the type depended on
604
  a template parameter would have required using the `template` keyword.
605
 
606
  #### Relational operators <a id="tuple.rel">[[tuple.rel]]</a>
607
 
608
  ``` cpp
609
  template<class... TTypes, class... UTypes>
610
- bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
611
  ```
612
 
613
- *Requires:* For all `i`, where `0 <= i` and `i < sizeof...(Types)`,
614
  `get<i>(t) == get<i>(u)` is a valid expression returning a type that is
615
  convertible to `bool`. `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
616
 
617
- *Returns:* `true` iff `get<i>(t) == get<i>(u)` for all `i`. For any two
618
- zero-length tuples `e` and `f`, `e == f` returns `true`.
 
619
 
620
  *Effects:* The elementary comparisons are performed in order from the
621
  zeroth index upwards. No comparisons or element accesses are performed
622
  after the first equality comparison that evaluates to `false`.
623
 
624
  ``` cpp
625
  template<class... TTypes, class... UTypes>
626
- bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
627
  ```
628
 
629
- *Requires:* For all `i`, where `0 <= i` and `i < sizeof...(Types)`,
630
  `get<i>(t) < get<i>(u)` and `get<i>(u) < get<i>(t)` are valid
631
  expressions returning types that are convertible to `bool`.
632
  `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
633
 
634
  *Returns:* The result of a lexicographical comparison between `t` and
@@ -638,32 +687,32 @@ where `r`ₜₐᵢₗ for some tuple `r` is a tuple containing all but the first
638
  element of `r`. For any two zero-length tuples `e` and `f`, `e < f`
639
  returns `false`.
640
 
641
  ``` cpp
642
  template<class... TTypes, class... UTypes>
643
- bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
644
  ```
645
 
646
  *Returns:* `!(t == u)`.
647
 
648
  ``` cpp
649
  template<class... TTypes, class... UTypes>
650
- bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
651
  ```
652
 
653
  *Returns:* `u < t`.
654
 
655
  ``` cpp
656
  template<class... TTypes, class... UTypes>
657
- bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
658
  ```
659
 
660
  *Returns:* `!(u < t)`
661
 
662
  ``` cpp
663
  template<class... TTypes, class... UTypes>
664
- bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
665
  ```
666
 
667
  *Returns:* `!(t < u)`
668
 
669
  The above definitions for comparison operators do not require `tₜₐᵢₗ`
 
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>;
 
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>
73
+ constexpr bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&);
74
  template<class... TTypes, class... UTypes>
75
+ constexpr bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&);
76
  template<class... TTypes, class... UTypes>
77
+ constexpr bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&);
78
  template<class... TTypes, class... UTypes>
79
+ constexpr bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&);
80
 
81
  // [tuple.traits], allocator-related traits
82
  template <class... Types, class Alloc>
83
  struct uses_allocator<tuple<Types...>, Alloc>;
84
 
 
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>
 
143
  tuple& operator=(const tuple<UTypes...>&);
144
  template <class... UTypes>
145
  tuple& operator=(tuple<UTypes...>&&);
146
 
147
  template <class U1, class U2>
148
+ tuple& operator=(const pair<U1, U2>&); // only if sizeof...(Types) == 2
149
  template <class U1, class U2>
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
  }
 
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
 
 
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
 
 
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
 
 
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
 
 
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`
 
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
 
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
 
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
 
 
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
 
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
 
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
 
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
  ```
 
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>;
 
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));`
 
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
 
 
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>
658
+ constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
659
  ```
660
 
661
+ *Requires:* For all `i`, where `0 <= i` and `i < sizeof...(TTypes)`,
662
  `get<i>(t) == get<i>(u)` is a valid expression returning a type that is
663
  convertible to `bool`. `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
664
 
665
+ *Returns:* `true` if `get<i>(t) == get<i>(u)` for all `i`, otherwise
666
+ `false`. For any two zero-length tuples `e` and `f`, `e == f` returns
667
+ `true`.
668
 
669
  *Effects:* The elementary comparisons are performed in order from the
670
  zeroth index upwards. No comparisons or element accesses are performed
671
  after the first equality comparison that evaluates to `false`.
672
 
673
  ``` cpp
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
 
687
  element of `r`. For any two zero-length tuples `e` and `f`, `e < f`
688
  returns `false`.
689
 
690
  ``` cpp
691
  template<class... TTypes, class... UTypes>
692
+ constexpr bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
693
  ```
694
 
695
  *Returns:* `!(t == u)`.
696
 
697
  ``` cpp
698
  template<class... TTypes, class... UTypes>
699
+ constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
700
  ```
701
 
702
  *Returns:* `u < t`.
703
 
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ₜₐᵢₗ`