From Jason Turner

[pairs]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpiqzbsat_/{from.md → to.md} +156 -154
tmp/tmpiqzbsat_/{from.md → to.md} RENAMED
@@ -9,203 +9,217 @@ as if they were `tuple` objects (see  [[tuple.helper]] and 
9
  [[tuple.elem]]).
10
 
11
  ### Class template `pair` <a id="pairs.pair">[[pairs.pair]]</a>
12
 
13
  ``` cpp
14
- // defined in header <utility>
15
-
16
  namespace std {
17
  template <class T1, class T2>
18
  struct pair {
19
- typedef T1 first_type;
20
- typedef T2 second_type;
21
 
22
  T1 first;
23
  T2 second;
 
24
  pair(const pair&) = default;
25
  pair(pair&&) = default;
26
- constexpr pair();
27
- constexpr pair(const T1& x, const T2& y);
28
- template<class U, class V> constexpr pair(U&& x, V&& y);
29
- template<class U, class V> constexpr pair(const pair<U, V>& p);
30
- template<class U, class V> constexpr pair(pair<U, V>&& p);
31
  template <class... Args1, class... Args2>
32
- pair(piecewise_construct_t,
33
- tuple<Args1...> first_args, tuple<Args2...> second_args);
34
 
35
  pair& operator=(const pair& p);
36
- template<class U, class V> pair& operator=(const pair<U, V>& p);
37
  pair& operator=(pair&& p) noexcept(see below);
38
- template<class U, class V> pair& operator=(pair<U, V>&& p);
39
 
40
  void swap(pair& p) noexcept(see below);
41
  };
 
 
 
42
  }
43
  ```
44
 
45
  Constructors and member functions of `pair` shall not throw exceptions
46
  unless one of the element-wise operations specified to be called for
47
  that operation throws an exception.
48
 
49
- The defaulted move and copy constructor, respectively, of pair shall be
50
- a `constexpr` function if and only if all required element-wise
51
  initializations for copy and move, respectively, would satisfy the
52
- requirements for a `constexpr` function.
 
 
 
53
 
54
  ``` cpp
55
- constexpr pair();
56
  ```
57
 
58
- *Requires:* `is_default_constructible<first_type>::value` is `true` and
59
- `is_default_construct-`
60
- `ible<second_type>::value` is `true`.
61
-
62
  *Effects:* Value-initializes `first` and `second`.
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  ``` cpp
65
- constexpr pair(const T1& x, const T2& y);
66
  ```
67
 
68
- *Requires:* `is_copy_constructible<first_type>::value` is `true` and
69
- `is_copy_constructible<second_type>::value` is `true`.
70
 
71
- *Effects:* The constructor initializes `first` with `x` and `second`
72
- with `y`.
 
 
 
 
73
 
74
  ``` cpp
75
- template<class U, class V> constexpr pair(U&& x, V&& y);
76
  ```
77
 
78
- *Requires:* `is_constructible<first_type, U&&>::value` is `true` and
79
- `is_constructible<second_type, V&&>::value` is `true`.
80
-
81
- *Effects:* The constructor initializes `first` with `std::forward<U>(x)`
82
- and `second` with `std::forward<V>(y)`.
83
 
84
- *Remarks:* If `U` is not implicitly convertible to `first_type` or `V`
85
- is not implicitly convertible to `second_type` this constructor shall
86
- not participate in overload resolution.
 
 
87
 
88
  ``` cpp
89
- template<class U, class V> constexpr pair(const pair<U, V>& p);
90
  ```
91
 
92
- *Requires:* `is_constructible<first_type, const U&>::value` is `true`
93
- and `is_constructible<second_type, const V&>::value` is `true`.
94
-
95
  *Effects:* Initializes members from the corresponding members of the
96
  argument.
97
 
98
- This constructor shall not participate in overload resolution unless
99
- `const U&` is implicitly convertible to `first_type` and `const V&` is
100
- implicitly convertible to `second_type`.
 
 
101
 
102
  ``` cpp
103
- template<class U, class V> constexpr pair(pair<U, V>&& p);
104
  ```
105
 
106
- *Requires:* `is_constructible<first_type, U&&>::value` is `true` and
107
- `is_constructible<second_type, V&&>::value` is `true`.
108
 
109
- *Effects:* The constructor initializes `first` with
110
- `std::forward<U>(p.first)` and `second` with
111
- `std::forward<V>(p.second)`.
112
-
113
- This constructor shall not participate in overload resolution unless `U`
114
- is implicitly convertible to `first_type` and `V` is implicitly
115
- convertible to `second_type`.
116
 
117
  ``` cpp
118
  template<class... Args1, class... Args2>
119
- pair(piecewise_construct_t,
120
- tuple<Args1...> first_args, tuple<Args2...> second_args);
121
  ```
122
 
123
- *Requires:* `is_constructible<first_type, Args1&&...>::value` is `true`
124
- and `is_constructible<second_type, Args2&&...>::value` is `true`.
125
 
126
- *Effects:* The constructor initializes `first` with arguments of types
127
- `Args1...` obtained by forwarding the elements of `first_args` and
128
- initializes `second` with arguments of types `Args2...` obtained by
129
- forwarding the elements of `second_args`. (Here, forwarding an element
130
- `x` of type `U` within a `tuple` object means calling
131
- `std::forward<U>(x)`.) This form of construction, whereby constructor
132
- arguments for `first` and `second` are each provided in a separate
133
- `tuple` object, is called *piecewise construction*.
134
 
135
  ``` cpp
136
  pair& operator=(const pair& p);
137
  ```
138
 
139
- *Requires:* `is_copy_assignable<first_type>::value` is `true` and
140
- `is_copy_assignable<second_type>::value` is `true`.
141
-
142
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
143
 
 
 
 
 
144
  *Returns:* `*this`.
145
 
146
  ``` cpp
147
- template<class U, class V> pair& operator=(const pair<U, V>& p);
148
  ```
149
 
150
- *Requires:* `is_assignable<first_type&, const U&>::value` is `true` and
151
- `is_assignable<second_type&, const V&>::value` is `true`.
152
-
153
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
154
 
 
 
 
 
155
  *Returns:* `*this`.
156
 
157
  ``` cpp
158
  pair& operator=(pair&& p) noexcept(see below);
159
  ```
160
 
161
- *Remarks:* The expression inside `noexcept` is equivalent to:
162
-
163
- ``` cpp
164
- is_nothrow_move_assignable<T1>::value &&
165
- is_nothrow_move_assignable<T2>::value
166
- ```
167
-
168
- *Requires:* `is_move_assignable<first_type>::value` is `true` and
169
- `is_move_assignable<second_type>::value` is `true`.
170
-
171
  *Effects:* Assigns to `first` with `std::forward<first_type>(p.first)`
172
  and to `second` with
173
  `std::forward<second_type>(p.second)`.
174
 
 
 
 
 
 
 
 
 
 
 
175
  *Returns:* `*this`.
176
 
177
  ``` cpp
178
- template<class U, class V> pair& operator=(pair<U, V>&& p);
179
  ```
180
 
181
- *Requires:* `is_assignable<first_type&, U&&>::value` is `true` and
182
- `is_assignable<second_type&, V&&>::value` is `true`.
183
-
184
  *Effects:* Assigns to `first` with `std::forward<U>(p.first)` and to
185
  `second` with
186
  `std::forward<V>(p.second)`.
187
 
 
 
 
 
188
  *Returns:* `*this`.
189
 
190
  ``` cpp
191
  void swap(pair& p) noexcept(see below);
192
  ```
193
 
194
- *Remarks:* The expression inside `noexcept` is equivalent to:
195
-
196
- ``` cpp
197
- noexcept(swap(first, p.first)) &&
198
- noexcept(swap(second, p.second))
199
- ```
200
-
201
  *Requires:* `first` shall be swappable
202
  with ([[swappable.requirements]]) `p.first` and `second` shall be
203
  swappable with `p.second`.
204
 
205
  *Effects:* Swaps `first` with `p.first` and `second` with `p.second`.
206
 
 
 
 
 
 
 
207
  ### Specialized algorithms <a id="pairs.spec">[[pairs.spec]]</a>
208
 
209
  ``` cpp
210
  template <class T1, class T2>
211
  constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
@@ -224,50 +238,55 @@ template <class T1, class T2>
224
  ``` cpp
225
  template <class T1, class T2>
226
  constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
227
  ```
228
 
229
- *Returns:* `!(x == y)`
230
 
231
  ``` cpp
232
  template <class T1, class T2>
233
  constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
234
  ```
235
 
236
- *Returns:* `y < x`
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> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
254
  noexcept(noexcept(x.swap(y)));
255
  ```
256
 
257
- *Effects:* `x.swap(y)`
 
 
 
 
258
 
259
  ``` cpp
260
  template <class T1, class T2>
261
  constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
262
  ```
263
 
264
- *Returns:* `pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y))`;
265
-
266
  where `V1` and `V2` are determined as follows: Let `Ui` be `decay_t<Ti>`
267
- for each `Ti`. Then each `Vi` is `X&` if `Ui` equals
268
- `reference_wrapper<X>`, otherwise `Vi` is `Ui`.
 
 
269
 
270
  In place of:
271
 
272
  ``` cpp
273
  return pair<int, double>(5, 3.1415926); // explicit types
@@ -277,101 +296,84 @@ a C++program may contain:
277
 
278
  ``` cpp
279
  return make_pair(5, 3.1415926); // types are deduced
280
  ```
281
 
 
 
282
  ### Tuple-like access to pair <a id="pair.astuple">[[pair.astuple]]</a>
283
 
284
  ``` cpp
285
  template <class T1, class T2>
286
- struct tuple_size<pair<T1, T2>>
287
- : integral_constant<size_t, 2> { };
288
  ```
289
 
290
  ``` cpp
291
  tuple_element<0, pair<T1, T2>>::type
292
  ```
293
 
294
- *Value:* the type `T1`.
295
 
296
  ``` cpp
297
  tuple_element<1, pair<T1, T2>>::type
298
  ```
299
 
300
- *Value:* the type T2.
301
 
302
  ``` cpp
303
  template<size_t I, class T1, class T2>
304
- constexpr tuple_element_t<I, pair<T1, T2>>&
305
- get(pair<T1, T2>& p) noexcept;
306
  template<size_t I, class T1, class T2>
307
- constexpr const tuple_element_t<I, pair<T1, T2>>&
308
- get(const pair<T1, T2>& p) noexcept;
309
- ```
310
-
311
- *Returns:* If `I == 0` returns `p.first`; if `I == 1` returns
312
- `p.second`; otherwise the program is ill-formed.
313
-
314
- ``` cpp
315
  template<size_t I, class T1, class T2>
316
- constexpr tuple_element_t<I, pair<T1, T2>>&&
317
- get(pair<T1, T2>&& p) noexcept;
318
- ```
319
-
320
- *Returns:* If `I == 0` returns `std::forward<T1&&>(p.first)`; if
321
- `I == 1` returns `std::forward<T2&&>(p.second)`; otherwise the program
322
- is ill-formed.
323
-
324
- ``` cpp
325
- template <class T, class U>
326
- constexpr T& get(pair<T, U>& p) noexcept;
327
- template <class T, class U>
328
- constexpr const T& get(const pair<T, U>& p) noexcept;
329
- ```
330
-
331
- *Requires:* `T` and `U` are distinct types. Otherwise, the program is
332
- ill-formed.
333
-
334
- *Returns:* `get<0>(p);`
335
-
336
- ``` cpp
337
- template <class T, class U>
338
- constexpr T&& get(pair<T, U>&& p) noexcept;
339
  ```
340
 
341
- *Requires:* `T` and `U` are distinct types. Otherwise, the program is
342
- ill-formed.
343
-
344
- *Returns:* `get<0>(std::move(p));`
345
 
346
  ``` cpp
347
- template <class T, class U>
348
- constexpr T& get(pair<U, T>& p) noexcept;
349
- template <class T, class U>
350
- constexpr const T& get(const pair<U, T>& p) noexcept;
 
 
 
 
351
  ```
352
 
353
- *Requires:* `T` and `U` are distinct types. Otherwise, the program is
354
  ill-formed.
355
 
356
- *Returns:* `get<1>(p);`
357
 
358
  ``` cpp
359
- template <class T, class U>
360
- constexpr T&& get(pair<U, T>&& p) noexcept;
 
 
 
 
 
 
361
  ```
362
 
363
- *Requires:* `T` and `U` are distinct types. Otherwise, the program is
364
  ill-formed.
365
 
366
- *Returns:* `get<1>(std::move(p));`
367
 
368
  ### Piecewise construction <a id="pair.piecewise">[[pair.piecewise]]</a>
369
 
370
  ``` cpp
371
- struct piecewise_construct_t { };
372
- constexpr piecewise_construct_t piecewise_construct{};
 
 
373
  ```
374
 
375
  The `struct` `piecewise_construct_t` is an empty structure type used as
376
  a unique type to disambiguate constructor and function overloading.
377
  Specifically, `pair` has a constructor with `piecewise_construct_t` as
 
9
  [[tuple.elem]]).
10
 
11
  ### Class template `pair` <a id="pairs.pair">[[pairs.pair]]</a>
12
 
13
  ``` cpp
 
 
14
  namespace std {
15
  template <class T1, class T2>
16
  struct pair {
17
+ using first_type = T1;
18
+ using second_type = T2;
19
 
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`
142
+ 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
+
217
+ ``` cpp
218
+ is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>
219
+ ```
220
+
221
  ### Specialized algorithms <a id="pairs.spec">[[pairs.spec]]</a>
222
 
223
  ``` cpp
224
  template <class T1, class T2>
225
  constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
 
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
292
  return pair<int, double>(5, 3.1415926); // explicit types
 
296
 
297
  ``` cpp
298
  return make_pair(5, 3.1415926); // types are deduced
299
  ```
300
 
301
+ — *end example*]
302
+
303
  ### Tuple-like access to pair <a id="pair.astuple">[[pair.astuple]]</a>
304
 
305
  ``` cpp
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>
326
+ constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept;
 
 
 
 
 
 
 
327
  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>
340
+ constexpr const T1& get(const pair<T1, T2>& p) noexcept;
341
+ 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>
354
+ constexpr T2& get(pair<T1, T2>& p) noexcept;
355
+ template <class T2, class T1>
356
+ constexpr const T2& get(const pair<T1, T2>& p) noexcept;
357
+ 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
 
370
  ``` cpp
371
+ 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