From Jason Turner

[pairs]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpixptdx7d/{from.md → to.md} +162 -145
tmp/tmpixptdx7d/{from.md → to.md} RENAMED
@@ -20,122 +20,157 @@ namespace std {
20
  T1 first;
21
  T2 second;
22
 
23
  pair(const pair&) = default;
24
  pair(pair&&) = default;
25
- \EXPLICIT constexpr pair();
26
- \EXPLICIT constexpr pair(const T1& x, const T2& y);
27
- template<class U1, class U2> \EXPLICIT constexpr pair(U1&& x, U2&& y);
28
- template<class U1, class U2> \EXPLICIT constexpr pair(const pair<U1, U2>& p);
29
- template<class U1, class U2> \EXPLICIT constexpr pair(pair<U1, U2>&& p);
 
 
 
30
  template<class... Args1, class... Args2>
31
- pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
 
32
 
33
- pair& operator=(const pair& p);
34
- template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
35
- pair& operator=(pair&& p) noexcept(see below);
36
- template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
 
 
37
 
38
- void swap(pair& p) noexcept(see below);
39
  };
40
 
41
  template<class T1, class T2>
42
  pair(T1, T2) -> pair<T1, T2>;
43
  }
44
  ```
45
 
46
- Constructors and member functions of `pair` shall not throw exceptions
47
  unless one of the element-wise operations specified to be called for
48
  that operation throws an exception.
49
 
50
- The defaulted move and copy constructor, respectively, of `pair` shall
51
- be a constexpr function if and only if all required element-wise
52
- initializations for copy and move, respectively, would satisfy the
53
- requirements for a constexpr function. The destructor of `pair` shall be
54
- a trivial destructor if
 
55
  `(is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>)`
56
- is `true`.
 
 
 
 
 
 
57
 
58
  ``` cpp
59
- \EXPLICIT constexpr pair();
60
  ```
61
 
 
 
 
 
 
62
  *Effects:* Value-initializes `first` and `second`.
63
 
64
- *Remarks:* This constructor shall not participate in overload resolution
65
- unless `is_default_constructible_v<first_type>` is `true` and
66
- `is_default_constructible_v<second_type>` is `true`.
67
 
68
- [*Note 1*: This behavior can be implemented by a constructor template
69
- with default template arguments. — *end note*]
70
-
71
- The constructor is explicit if and only if either `first_type` or
72
- `second_type` is not implicitly default-constructible.
73
-
74
- [*Note 2*: This behavior can be implemented with a trait that checks
75
  whether a `const first_type&` or a `const second_type&` can be
76
  initialized with `{}`. — *end note*]
77
 
78
  ``` cpp
79
- \EXPLICIT constexpr pair(const T1& x, const T2& y);
80
  ```
81
 
 
 
 
 
 
82
  *Effects:* Initializes `first` with `x` and `second` with `y`.
83
 
84
- *Remarks:* This constructor shall not participate in overload resolution
85
- unless `is_copy_constructible_v<first_type>` is `true` and
86
- `is_copy_constructible_v<second_type>` is `true`. The constructor is
87
- explicit if and only if
88
- `is_convertible_v<const first_type&, first_type>` is `false` or
89
- `is_convertible_v<const second_type&, second_type>` is `false`.
90
 
91
  ``` cpp
92
- template<class U1, class U2> \EXPLICIT constexpr pair(U1&& x, U2&& y);
 
93
  ```
94
 
 
 
 
 
 
 
 
 
 
95
  *Effects:* Initializes `first` with `std::forward<U1>(x)` and `second`
96
  with `std::forward<U2>(y)`.
97
 
98
- *Remarks:* This constructor shall not participate in overload resolution
99
- unless `is_constructible_v<first_type, U1&&>` is `true` and
100
- `is_constructible_v<second_type, U2&&>` is `true`. The constructor is
101
- explicit if and only if `is_convertible_v<U1&&, first_type>` is `false`
102
- or `is_convertible_v<U2&&, second_type>` is `false`.
103
 
104
  ``` cpp
105
- template<class U1, class U2> \EXPLICIT constexpr pair(const pair<U1, U2>& p);
106
  ```
107
 
 
 
 
 
 
 
 
 
 
108
  *Effects:* Initializes members from the corresponding members of the
109
  argument.
110
 
111
- *Remarks:* This constructor shall not participate in overload resolution
112
- unless `is_constructible_v<first_type, const U1&>` is `true` and
113
- `is_constructible_v<second_type, const U2&>` is `true`. The constructor
114
- is explicit if and only if `is_convertible_v<const U1&, first_type>` is
115
- `false` or `is_convertible_v<const U2&, second_type>` is `false`.
116
 
117
  ``` cpp
118
- template<class U1, class U2> \EXPLICIT constexpr pair(pair<U1, U2>&& p);
119
  ```
120
 
 
 
 
 
 
 
 
 
 
121
  *Effects:* Initializes `first` with `std::forward<U1>(p.first)` and
122
  `second` with `std::forward<U2>(p.second)`.
123
 
124
- *Remarks:* This constructor shall not participate in overload resolution
125
- unless `is_constructible_v<first_type, U1&&>` is `true` and
126
- `is_constructible_v<second_type, U2&&>` is `true`. The constructor is
127
- explicit if and only if `is_convertible_v<U1&&, first_type>` is `false`
128
- or `is_convertible_v<U2&&, second_type>` is `false`.
129
 
130
  ``` cpp
131
  template<class... Args1, class... Args2>
132
- pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
 
133
  ```
134
 
135
- *Requires:* `is_constructible_v<first_type, Args1&&...>` is `true` and
136
- `is_constructible_v<second_type, Args2&&...>` is `true`.
 
 
137
 
138
  *Effects:* Initializes `first` with arguments of types `Args1...`
139
  obtained by forwarding the elements of `first_args` and initializes
140
  `second` with arguments of types `Args2...` obtained by forwarding the
141
  elements of `second_args`. (Here, forwarding an element `x` of type `U`
@@ -143,74 +178,76 @@ within a `tuple` object means calling `std::forward<U>(x)`.) This form
143
  of construction, whereby constructor arguments for `first` and `second`
144
  are each provided in a separate `tuple` object, is called *piecewise
145
  construction*.
146
 
147
  ``` cpp
148
- pair& operator=(const pair& p);
149
  ```
150
 
151
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
152
 
153
- *Remarks:* This operator shall be defined as deleted unless
154
  `is_copy_assignable_v<first_type>` is `true` and
155
  `is_copy_assignable_v<second_type>` is `true`.
156
 
157
  *Returns:* `*this`.
158
 
159
  ``` cpp
160
- template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
161
  ```
162
 
 
 
 
 
 
163
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
164
 
165
- *Remarks:* This operator shall not participate in overload resolution
166
- unless `is_assignable_v<first_type&, const U1&>` is `true` and
167
- `is_assignable_v<second_type&, const U2&>` is `true`.
168
-
169
  *Returns:* `*this`.
170
 
171
  ``` cpp
172
- pair& operator=(pair&& p) noexcept(see below);
173
  ```
174
 
 
 
 
 
 
175
  *Effects:* Assigns to `first` with `std::forward<first_type>(p.first)`
176
  and to `second` with
177
  `std::forward<second_type>(p.second)`.
178
 
179
- *Remarks:* This operator shall be defined as deleted unless
180
- `is_move_assignable_v<first_type>` is `true` and
181
- `is_move_assignable_v<second_type>` is `true`.
182
 
183
  *Remarks:* The expression inside `noexcept` is equivalent to:
184
 
185
  ``` cpp
186
  is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
187
  ```
188
 
189
- *Returns:* `*this`.
190
-
191
  ``` cpp
192
- template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
193
  ```
194
 
195
- *Effects:* Assigns to `first` with `std::forward<U>(p.first)` and to
 
 
 
 
 
196
  `second` with
197
- `std::forward<V>(p.second)`.
198
-
199
- *Remarks:* This operator shall not participate in overload resolution
200
- unless `is_assignable_v<first_type&, U1&&>` is `true` and
201
- `is_assignable_v<second_type&, U2&&>` is `true`.
202
 
203
  *Returns:* `*this`.
204
 
205
  ``` cpp
206
- void swap(pair& p) noexcept(see below);
207
  ```
208
 
209
- *Requires:* `first` shall be swappable
210
- with ([[swappable.requirements]]) `p.first` and `second` shall be
211
- swappable with `p.second`.
212
 
213
  *Effects:* Swaps `first` with `p.first` and `second` with `p.second`.
214
 
215
  *Remarks:* The expression inside `noexcept` is equivalent to:
216
 
@@ -227,65 +264,44 @@ template <class T1, class T2>
227
 
228
  *Returns:* `x.first == y.first && x.second == y.second`.
229
 
230
  ``` cpp
231
  template<class T1, class T2>
232
- constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  ```
234
 
235
  *Returns:*
236
- `x.first < y.first || (!(y.first < x.first) && x.second < y.second)`.
237
 
238
  ``` cpp
239
- template <class T1, class T2>
240
- constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
241
  ```
242
 
243
- *Returns:* `!(x == y)`.
244
-
245
- ``` cpp
246
- template <class T1, class T2>
247
- constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
248
- ```
249
-
250
- *Returns:* `y < x`.
251
-
252
- ``` cpp
253
- template <class T1, class T2>
254
- constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
255
- ```
256
-
257
- *Returns:* `!(x < y)`.
258
-
259
- ``` cpp
260
- template <class T1, class T2>
261
- constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
262
- ```
263
-
264
- *Returns:* `!(y < x)`.
265
-
266
- ``` cpp
267
- template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
268
- noexcept(noexcept(x.swap(y)));
269
- ```
270
-
271
- *Effects:* As if by `x.swap(y)`.
272
-
273
- *Remarks:* This function shall not participate in overload resolution
274
- unless `is_swappable_v<T1>` is `true` and `is_swappable_v<T2>` is
275
- `true`.
276
-
277
- ``` cpp
278
- template <class T1, class T2>
279
- constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
280
- ```
281
-
282
- *Returns:* `pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y))`,
283
- where `V1` and `V2` are determined as follows: Let `Ui` be `decay_t<Ti>`
284
- for each `Ti`. If `Ui` is a specialization of `reference_wrapper`, then
285
- `Vi` is `Ui::type&`, otherwise `Vi` is `Ui`.
286
-
287
  [*Example 1*:
288
 
289
  In place of:
290
 
291
  ``` cpp
@@ -306,20 +322,19 @@ a C++program may contain:
306
  template<class T1, class T2>
307
  struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
308
  ```
309
 
310
  ``` cpp
311
- tuple_element<0, pair<T1, T2>>::type
 
 
 
312
  ```
313
 
314
- *Value:* The type `T1`.
315
 
316
- ``` cpp
317
- tuple_element<1, pair<T1, T2>>::type
318
- ```
319
-
320
- *Value:* The type T2.
321
 
322
  ``` cpp
323
  template<size_t I, class T1, class T2>
324
  constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept;
325
  template<size_t I, class T1, class T2>
@@ -328,12 +343,16 @@ template<size_t I, class T1, class T2>
328
  constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept;
329
  template<size_t I, class T1, class T2>
330
  constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
331
  ```
332
 
333
- *Returns:* If `I == 0` returns a reference to `p.first`; if `I == 1`
334
- returns a reference to `p.second`; otherwise the program is ill-formed.
 
 
 
 
335
 
336
  ``` cpp
337
  template<class T1, class T2>
338
  constexpr T1& get(pair<T1, T2>& p) noexcept;
339
  template<class T1, class T2>
@@ -342,12 +361,11 @@ template <class T1, class T2>
342
  constexpr T1&& get(pair<T1, T2>&& p) noexcept;
343
  template<class T1, class T2>
344
  constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
345
  ```
346
 
347
- *Requires:* `T1` and `T2` are distinct types. Otherwise, the program is
348
- ill-formed.
349
 
350
  *Returns:* A reference to `p.first`.
351
 
352
  ``` cpp
353
  template<class T2, class T1>
@@ -358,12 +376,11 @@ template <class T2, class T1>
358
  constexpr T2&& get(pair<T1, T2>&& p) noexcept;
359
  template<class T2, class T1>
360
  constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
361
  ```
362
 
363
- *Requires:* `T1` and `T2` are distinct types. Otherwise, the program is
364
- ill-formed.
365
 
366
  *Returns:* A reference to `p.second`.
367
 
368
  ### Piecewise construction <a id="pair.piecewise">[[pair.piecewise]]</a>
369
 
@@ -372,12 +389,12 @@ struct piecewise_construct_t {
372
  explicit piecewise_construct_t() = default;
373
  };
374
  inline constexpr piecewise_construct_t piecewise_construct{};
375
  ```
376
 
377
- The `struct` `piecewise_construct_t` is an empty structure type used as
378
- a unique type to disambiguate constructor and function overloading.
379
  Specifically, `pair` has a constructor with `piecewise_construct_t` as
380
- the first argument, immediately followed by two `tuple` ([[tuple]])
381
  arguments used for piecewise construction of the elements of the `pair`
382
  object.
383
 
 
20
  T1 first;
21
  T2 second;
22
 
23
  pair(const pair&) = default;
24
  pair(pair&&) = default;
25
+ constexpr explicit(see below) pair();
26
+ constexpr explicit(see below) pair(const T1& x, const T2& y);
27
+ template<class U1, class U2>
28
+ constexpr explicit(see below) pair(U1&& x, U2&& y);
29
+ template<class U1, class U2>
30
+ constexpr explicit(see below) pair(const pair<U1, U2>& p);
31
+ template<class U1, class U2>
32
+ constexpr explicit(see below) pair(pair<U1, U2>&& p);
33
  template<class... Args1, class... Args2>
34
+ constexpr pair(piecewise_construct_t,
35
+ tuple<Args1...> first_args, tuple<Args2...> second_args);
36
 
37
+ constexpr pair& operator=(const pair& p);
38
+ template<class U1, class U2>
39
+ constexpr pair& operator=(const pair<U1, U2>& p);
40
+ constexpr pair& operator=(pair&& p) noexcept(see below);
41
+ template<class U1, class U2>
42
+ constexpr pair& operator=(pair<U1, U2>&& p);
43
 
44
+ constexpr void swap(pair& p) noexcept(see below);
45
  };
46
 
47
  template<class T1, class T2>
48
  pair(T1, T2) -> pair<T1, T2>;
49
  }
50
  ```
51
 
52
+ Constructors and member functions of `pair` do not throw exceptions
53
  unless one of the element-wise operations specified to be called for
54
  that operation throws an exception.
55
 
56
+ The defaulted move and copy constructor, respectively, of `pair` is a
57
+ constexpr function if and only if all required element-wise
58
+ initializations for move and copy, respectively, would satisfy the
59
+ requirements for a constexpr function.
60
+
61
+ If
62
  `(is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>)`
63
+ is `true`, then the destructor of `pair` is trivial.
64
+
65
+ `pair<T, U>` is a structural type [[temp.param]] if `T` and `U` are both
66
+ structural types. Two values `p1` and `p2` of type `pair<T, U>` are
67
+ template-argument-equivalent [[temp.type]] if and only if `p1.first` and
68
+ `p2.first` are template-argument-equivalent and `p1.second` and
69
+ `p2.second` are template-argument-equivalent.
70
 
71
  ``` cpp
72
+ constexpr explicit(see below) pair();
73
  ```
74
 
75
+ *Constraints:*
76
+
77
+ - `is_default_constructible_v<first_type>` is `true` and
78
+ - `is_default_constructible_v<second_type>` is `true`.
79
+
80
  *Effects:* Value-initializes `first` and `second`.
81
 
82
+ *Remarks:* The expression inside `explicit` evaluates to `true` if and
83
+ only if either `first_type` or `second_type` is not implicitly
84
+ default-constructible.
85
 
86
+ [*Note 1*: This behavior can be implemented with a trait that checks
 
 
 
 
 
 
87
  whether a `const first_type&` or a `const second_type&` can be
88
  initialized with `{}`. — *end note*]
89
 
90
  ``` cpp
91
+ constexpr explicit(see below) pair(const T1& x, const T2& y);
92
  ```
93
 
94
+ *Constraints:*
95
+
96
+ - `is_copy_constructible_v<first_type>` is `true` and
97
+ - `is_copy_constructible_v<second_type>` is `true`.
98
+
99
  *Effects:* Initializes `first` with `x` and `second` with `y`.
100
 
101
+ *Remarks:* The expression inside `explicit` is equivalent to:
 
 
 
 
 
102
 
103
  ``` cpp
104
+ !is_convertible_v<const first_type&, first_type> ||
105
+ !is_convertible_v<const second_type&, second_type>
106
  ```
107
 
108
+ ``` cpp
109
+ template<class U1, class U2> constexpr explicit(see below) pair(U1&& x, U2&& y);
110
+ ```
111
+
112
+ *Constraints:*
113
+
114
+ - `is_constructible_v<first_type, U1>` is `true` and
115
+ - `is_constructible_v<second_type, U2>` is `true`.
116
+
117
  *Effects:* Initializes `first` with `std::forward<U1>(x)` and `second`
118
  with `std::forward<U2>(y)`.
119
 
120
+ *Remarks:* The expression inside `explicit` is equivalent to:
 
 
 
 
121
 
122
  ``` cpp
123
+ !is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
124
  ```
125
 
126
+ ``` cpp
127
+ template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
128
+ ```
129
+
130
+ *Constraints:*
131
+
132
+ - `is_constructible_v<first_type, const U1&>` is `true` and
133
+ - `is_constructible_v<second_type, const U2&>` is `true`.
134
+
135
  *Effects:* Initializes members from the corresponding members of the
136
  argument.
137
 
138
+ *Remarks:* The expression inside explicit is equivalent to:
 
 
 
 
139
 
140
  ``` cpp
141
+ !is_convertible_v<const U1&, first_type> || !is_convertible_v<const U2&, second_type>
142
  ```
143
 
144
+ ``` cpp
145
+ template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
146
+ ```
147
+
148
+ *Constraints:*
149
+
150
+ - `is_constructible_v<first_type, U1>` is `true` and
151
+ - `is_constructible_v<second_type, U2>` is `true`.
152
+
153
  *Effects:* Initializes `first` with `std::forward<U1>(p.first)` and
154
  `second` with `std::forward<U2>(p.second)`.
155
 
156
+ *Remarks:* The expression inside explicit is equivalent to:
157
+
158
+ ``` cpp
159
+ !is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
160
+ ```
161
 
162
  ``` cpp
163
  template<class... Args1, class... Args2>
164
+ constexpr pair(piecewise_construct_t,
165
+ tuple<Args1...> first_args, tuple<Args2...> second_args);
166
  ```
167
 
168
+ *Mandates:*
169
+
170
+ - `is_constructible_v<first_type, Args1...>` is `true` and
171
+ - `is_constructible_v<second_type, Args2...>` is `true`.
172
 
173
  *Effects:* Initializes `first` with arguments of types `Args1...`
174
  obtained by forwarding the elements of `first_args` and initializes
175
  `second` with arguments of types `Args2...` obtained by forwarding the
176
  elements of `second_args`. (Here, forwarding an element `x` of type `U`
 
178
  of construction, whereby constructor arguments for `first` and `second`
179
  are each provided in a separate `tuple` object, is called *piecewise
180
  construction*.
181
 
182
  ``` cpp
183
+ constexpr pair& operator=(const pair& p);
184
  ```
185
 
186
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
187
 
188
+ *Remarks:* This operator is defined as deleted unless
189
  `is_copy_assignable_v<first_type>` is `true` and
190
  `is_copy_assignable_v<second_type>` is `true`.
191
 
192
  *Returns:* `*this`.
193
 
194
  ``` cpp
195
+ template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
196
  ```
197
 
198
+ *Constraints:*
199
+
200
+ - `is_assignable_v<first_type&, const U1&>` is `true` and
201
+ - `is_assignable_v<second_type&, const U2&>` is `true`.
202
+
203
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
204
 
 
 
 
 
205
  *Returns:* `*this`.
206
 
207
  ``` cpp
208
+ constexpr pair& operator=(pair&& p) noexcept(see below);
209
  ```
210
 
211
+ *Constraints:*
212
+
213
+ - `is_move_assignable_v<first_type>` is `true` and
214
+ - `is_move_assignable_v<second_type>` is `true`.
215
+
216
  *Effects:* Assigns to `first` with `std::forward<first_type>(p.first)`
217
  and to `second` with
218
  `std::forward<second_type>(p.second)`.
219
 
220
+ *Returns:* `*this`.
 
 
221
 
222
  *Remarks:* The expression inside `noexcept` is equivalent to:
223
 
224
  ``` cpp
225
  is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
226
  ```
227
 
 
 
228
  ``` cpp
229
+ template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
230
  ```
231
 
232
+ *Constraints:*
233
+
234
+ - `is_assignable_v<first_type&, U1>` is `true` and
235
+ - `is_assignable_v<second_type&, U2>` is `true`.
236
+
237
+ *Effects:* Assigns to `first` with `std::forward<U1>(p.first)` and to
238
  `second` with
239
+ `std::forward<U2>(p.second)`.
 
 
 
 
240
 
241
  *Returns:* `*this`.
242
 
243
  ``` cpp
244
+ constexpr void swap(pair& p) noexcept(see below);
245
  ```
246
 
247
+ *Preconditions:* `first` is swappable with [[swappable.requirements]]
248
+ `p.first` and `second` is swappable with `p.second`.
 
249
 
250
  *Effects:* Swaps `first` with `p.first` and `second` with `p.second`.
251
 
252
  *Remarks:* The expression inside `noexcept` is equivalent to:
253
 
 
264
 
265
  *Returns:* `x.first == y.first && x.second == y.second`.
266
 
267
  ``` cpp
268
  template<class T1, class T2>
269
+ constexpr common_comparison_category_t<synth-three-way-result<T1>,
270
+ synth-three-way-result<T2>>
271
+ operator<=>(const pair<T1, T2>& x, const pair<T1, T2>& y);
272
+ ```
273
+
274
+ *Effects:* Equivalent to:
275
+
276
+ ``` cpp
277
+ if (auto c = synth-three-way(x.first, y.first); c != 0) return c;
278
+ return synth-three-way(x.second, y.second);
279
+ ```
280
+
281
+ ``` cpp
282
+ template<class T1, class T2>
283
+ constexpr void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
284
+ ```
285
+
286
+ *Constraints:* `is_swappable_v<T1>` is `true` and `is_swappable_v<T2>`
287
+ is `true`.
288
+
289
+ *Effects:* Equivalent to `x.swap(y)`.
290
+
291
+ ``` cpp
292
+ template<class T1, class T2>
293
+ constexpr pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>> make_pair(T1&& x, T2&& y);
294
  ```
295
 
296
  *Returns:*
 
297
 
298
  ``` cpp
299
+ pair<unwrap_ref_decay_t<T1>,
300
+ unwrap_ref_decay_t<T2>>(std::forward<T1>(x), std::forward<T2>(y))
301
  ```
302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  [*Example 1*:
304
 
305
  In place of:
306
 
307
  ``` cpp
 
322
  template<class T1, class T2>
323
  struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
324
  ```
325
 
326
  ``` cpp
327
+ template<size_t I, class T1, class T2>
328
+ struct tuple_element<I, pair<T1, T2>> {
329
+ using type = see below ;
330
+ };
331
  ```
332
 
333
+ *Mandates:* `I` < 2.
334
 
335
+ *Type:* The type `T1` if `I` is 0, otherwise the type `T2`.
 
 
 
 
336
 
337
  ``` cpp
338
  template<size_t I, class T1, class T2>
339
  constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept;
340
  template<size_t I, class T1, class T2>
 
343
  constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept;
344
  template<size_t I, class T1, class T2>
345
  constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
346
  ```
347
 
348
+ *Mandates:* `I` < 2.
349
+
350
+ *Returns:*
351
+
352
+ - If `I` is 0, returns a reference to `p.first`.
353
+ - If `I` is 1, returns a reference to `p.second`.
354
 
355
  ``` cpp
356
  template<class T1, class T2>
357
  constexpr T1& get(pair<T1, T2>& p) noexcept;
358
  template<class T1, class T2>
 
361
  constexpr T1&& get(pair<T1, T2>&& p) noexcept;
362
  template<class T1, class T2>
363
  constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
364
  ```
365
 
366
+ *Mandates:* `T1` and `T2` are distinct types.
 
367
 
368
  *Returns:* A reference to `p.first`.
369
 
370
  ``` cpp
371
  template<class T2, class T1>
 
376
  constexpr T2&& get(pair<T1, T2>&& p) noexcept;
377
  template<class T2, class T1>
378
  constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
379
  ```
380
 
381
+ *Mandates:* `T1` and `T2` are distinct types.
 
382
 
383
  *Returns:* A reference to `p.second`.
384
 
385
  ### Piecewise construction <a id="pair.piecewise">[[pair.piecewise]]</a>
386
 
 
389
  explicit piecewise_construct_t() = default;
390
  };
391
  inline constexpr piecewise_construct_t piecewise_construct{};
392
  ```
393
 
394
+ The `struct` `piecewise_construct_t` is an empty class type used as a
395
+ unique type to disambiguate constructor and function overloading.
396
  Specifically, `pair` has a constructor with `piecewise_construct_t` as
397
+ the first argument, immediately followed by two `tuple` [[tuple]]
398
  arguments used for piecewise construction of the elements of the `pair`
399
  object.
400