From Jason Turner

[pairs.pair]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpro6bwcej/{from.md → to.md} +180 -58
tmp/tmpro6bwcej/{from.md → to.md} RENAMED
@@ -12,28 +12,45 @@ namespace std {
12
 
13
  pair(const pair&) = default;
14
  pair(pair&&) = default;
15
  constexpr explicit(see below) pair();
16
  constexpr explicit(see below) pair(const T1& x, const T2& y);
17
- template<class U1, class U2>
18
  constexpr explicit(see below) pair(U1&& x, U2&& y);
 
 
19
  template<class U1, class U2>
20
  constexpr explicit(see below) pair(const pair<U1, U2>& p);
21
  template<class U1, class U2>
22
  constexpr explicit(see below) pair(pair<U1, U2>&& p);
 
 
 
 
23
  template<class... Args1, class... Args2>
24
  constexpr pair(piecewise_construct_t,
25
  tuple<Args1...> first_args, tuple<Args2...> second_args);
26
 
27
  constexpr pair& operator=(const pair& p);
 
28
  template<class U1, class U2>
29
  constexpr pair& operator=(const pair<U1, U2>& p);
 
 
30
  constexpr pair& operator=(pair&& p) noexcept(see below);
 
31
  template<class U1, class U2>
32
  constexpr pair& operator=(pair<U1, U2>&& p);
 
 
 
 
 
 
33
 
34
  constexpr void swap(pair& p) noexcept(see below);
 
35
  };
36
 
37
  template<class T1, class T2>
38
  pair(T1, T2) -> pair<T1, T2>;
39
  }
@@ -43,12 +60,12 @@ Constructors and member functions of `pair` do not throw exceptions
43
  unless one of the element-wise operations specified to be called for
44
  that operation throws an exception.
45
 
46
  The defaulted move and copy constructor, respectively, of `pair` is a
47
  constexpr function if and only if all required element-wise
48
- initializations for move and copy, respectively, would satisfy the
49
- requirements for a constexpr function.
50
 
51
  If
52
  `(is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>)`
53
  is `true`, then the destructor of `pair` is trivial.
54
 
@@ -62,135 +79,168 @@ template-argument-equivalent [[temp.type]] if and only if `p1.first` and
62
  constexpr explicit(see below) pair();
63
  ```
64
 
65
  *Constraints:*
66
 
67
- - `is_default_constructible_v<first_type>` is `true` and
68
- - `is_default_constructible_v<second_type>` is `true`.
69
 
70
  *Effects:* Value-initializes `first` and `second`.
71
 
72
  *Remarks:* The expression inside `explicit` evaluates to `true` if and
73
- only if either `first_type` or `second_type` is not implicitly
74
- default-constructible.
75
 
76
  [*Note 1*: This behavior can be implemented with a trait that checks
77
- whether a `const first_type&` or a `const second_type&` can be
78
- initialized with `{}`. — *end note*]
79
 
80
  ``` cpp
81
  constexpr explicit(see below) pair(const T1& x, const T2& y);
82
  ```
83
 
84
  *Constraints:*
85
 
86
- - `is_copy_constructible_v<first_type>` is `true` and
87
- - `is_copy_constructible_v<second_type>` is `true`.
88
 
89
  *Effects:* Initializes `first` with `x` and `second` with `y`.
90
 
91
  *Remarks:* The expression inside `explicit` is equivalent to:
92
 
93
  ``` cpp
94
- !is_convertible_v<const first_type&, first_type> ||
95
- !is_convertible_v<const second_type&, second_type>
96
  ```
97
 
98
  ``` cpp
99
- template<class U1, class U2> constexpr explicit(see below) pair(U1&& x, U2&& y);
100
  ```
101
 
102
  *Constraints:*
103
 
104
- - `is_constructible_v<first_type, U1>` is `true` and
105
- - `is_constructible_v<second_type, U2>` is `true`.
106
 
107
  *Effects:* Initializes `first` with `std::forward<U1>(x)` and `second`
108
  with `std::forward<U2>(y)`.
109
 
110
  *Remarks:* The expression inside `explicit` is equivalent to:
111
 
112
  ``` cpp
113
- !is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
114
  ```
115
 
 
 
 
 
116
  ``` cpp
 
117
  template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
118
- ```
119
-
120
- *Constraints:*
121
-
122
- - `is_constructible_v<first_type, const U1&>` is `true` and
123
- - `is_constructible_v<second_type, const U2&>` is `true`.
124
-
125
- *Effects:* Initializes members from the corresponding members of the
126
- argument.
127
-
128
- *Remarks:* The expression inside explicit is equivalent to:
129
-
130
- ``` cpp
131
- !is_convertible_v<const U1&, first_type> || !is_convertible_v<const U2&, second_type>
132
- ```
133
-
134
- ``` cpp
135
  template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
 
 
136
  ```
137
 
 
 
138
  *Constraints:*
139
 
140
- - `is_constructible_v<first_type, U1>` is `true` and
141
- - `is_constructible_v<second_type, U2>` is `true`.
 
 
 
142
 
143
- *Effects:* Initializes `first` with `std::forward<U1>(p.first)` and
144
- `second` with `std::forward<U2>(p.second)`.
145
 
146
- *Remarks:* The expression inside explicit is equivalent to:
147
 
148
  ``` cpp
149
- !is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
 
150
  ```
151
 
 
 
 
 
 
 
 
 
 
152
  ``` cpp
153
  template<class... Args1, class... Args2>
154
  constexpr pair(piecewise_construct_t,
155
  tuple<Args1...> first_args, tuple<Args2...> second_args);
156
  ```
157
 
158
  *Mandates:*
159
 
160
- - `is_constructible_v<first_type, Args1...>` is `true` and
161
- - `is_constructible_v<second_type, Args2...>` is `true`.
162
 
163
  *Effects:* Initializes `first` with arguments of types `Args1...`
164
  obtained by forwarding the elements of `first_args` and initializes
165
  `second` with arguments of types `Args2...` obtained by forwarding the
166
  elements of `second_args`. (Here, forwarding an element `x` of type `U`
167
  within a `tuple` object means calling `std::forward<U>(x)`.) This form
168
  of construction, whereby constructor arguments for `first` and `second`
169
  are each provided in a separate `tuple` object, is called *piecewise
170
  construction*.
171
 
 
 
 
 
172
  ``` cpp
173
  constexpr pair& operator=(const pair& p);
174
  ```
175
 
176
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
177
 
 
 
178
  *Remarks:* This operator is defined as deleted unless
179
- `is_copy_assignable_v<first_type>` is `true` and
180
- `is_copy_assignable_v<second_type>` is `true`.
 
 
 
 
 
 
 
 
 
 
 
181
 
182
  *Returns:* `*this`.
183
 
184
  ``` cpp
185
  template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
186
  ```
187
 
188
  *Constraints:*
189
 
190
- - `is_assignable_v<first_type&, const U1&>` is `true` and
191
- - `is_assignable_v<second_type&, const U2&>` is `true`.
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
194
 
195
  *Returns:* `*this`.
196
 
@@ -198,50 +248,122 @@ template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
198
  constexpr pair& operator=(pair&& p) noexcept(see below);
199
  ```
200
 
201
  *Constraints:*
202
 
203
- - `is_move_assignable_v<first_type>` is `true` and
204
- - `is_move_assignable_v<second_type>` is `true`.
205
 
206
- *Effects:* Assigns to `first` with `std::forward<first_type>(p.first)`
207
- and to `second` with
208
- `std::forward<second_type>(p.second)`.
209
 
210
  *Returns:* `*this`.
211
 
212
- *Remarks:* The expression inside `noexcept` is equivalent to:
213
 
214
  ``` cpp
215
  is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
216
  ```
217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  ``` cpp
219
  template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
220
  ```
221
 
222
  *Constraints:*
223
 
224
- - `is_assignable_v<first_type&, U1>` is `true` and
225
- - `is_assignable_v<second_type&, U2>` is `true`.
226
 
227
  *Effects:* Assigns to `first` with `std::forward<U1>(p.first)` and to
228
  `second` with
229
  `std::forward<U2>(p.second)`.
230
 
231
  *Returns:* `*this`.
232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  ``` cpp
234
  constexpr void swap(pair& p) noexcept(see below);
 
235
  ```
236
 
 
 
 
 
 
 
 
237
  *Preconditions:* `first` is swappable with [[swappable.requirements]]
238
  `p.first` and `second` is swappable with `p.second`.
239
 
240
  *Effects:* Swaps `first` with `p.first` and `second` with `p.second`.
241
 
242
- *Remarks:* The expression inside `noexcept` is equivalent to:
243
 
244
- ``` cpp
245
- is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>
246
- ```
 
247
 
 
12
 
13
  pair(const pair&) = default;
14
  pair(pair&&) = default;
15
  constexpr explicit(see below) pair();
16
  constexpr explicit(see below) pair(const T1& x, const T2& y);
17
+ template<class U1 = T1, class U2 = T2>
18
  constexpr explicit(see below) pair(U1&& x, U2&& y);
19
+ template<class U1, class U2>
20
+ constexpr explicit(see below) pair(pair<U1, U2>& p);
21
  template<class U1, class U2>
22
  constexpr explicit(see below) pair(const pair<U1, U2>& p);
23
  template<class U1, class U2>
24
  constexpr explicit(see below) pair(pair<U1, U2>&& p);
25
+ template<class U1, class U2>
26
+ constexpr explicit(see below) pair(const pair<U1, U2>&& p);
27
+ template<pair-like P>
28
+ constexpr explicit(see below) pair(P&& p);
29
  template<class... Args1, class... Args2>
30
  constexpr pair(piecewise_construct_t,
31
  tuple<Args1...> first_args, tuple<Args2...> second_args);
32
 
33
  constexpr pair& operator=(const pair& p);
34
+ constexpr const pair& operator=(const pair& p) const;
35
  template<class U1, class U2>
36
  constexpr pair& operator=(const pair<U1, U2>& p);
37
+ template<class U1, class U2>
38
+ constexpr const pair& operator=(const pair<U1, U2>& p) const;
39
  constexpr pair& operator=(pair&& p) noexcept(see below);
40
+ constexpr const pair& operator=(pair&& p) const;
41
  template<class U1, class U2>
42
  constexpr pair& operator=(pair<U1, U2>&& p);
43
+ template<class U1, class U2>
44
+ constexpr const pair& operator=(pair<U1, U2>&& p) const;
45
+ template<pair-like P>
46
+ constexpr pair& operator=(P&& p);
47
+ template<pair-like P>
48
+ constexpr const pair& operator=(P&& p) const;
49
 
50
  constexpr void swap(pair& p) noexcept(see below);
51
+ constexpr void swap(const pair& p) const noexcept(see below);
52
  };
53
 
54
  template<class T1, class T2>
55
  pair(T1, T2) -> pair<T1, T2>;
56
  }
 
60
  unless one of the element-wise operations specified to be called for
61
  that operation throws an exception.
62
 
63
  The defaulted move and copy constructor, respectively, of `pair` is a
64
  constexpr function if and only if all required element-wise
65
+ initializations for move and copy, respectively, would be
66
+ constexpr-suitable [[dcl.constexpr]].
67
 
68
  If
69
  `(is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>)`
70
  is `true`, then the destructor of `pair` is trivial.
71
 
 
79
  constexpr explicit(see below) pair();
80
  ```
81
 
82
  *Constraints:*
83
 
84
+ - `is_default_constructible_v<T1>` is `true` and
85
+ - `is_default_constructible_v<T2>` is `true`.
86
 
87
  *Effects:* Value-initializes `first` and `second`.
88
 
89
  *Remarks:* The expression inside `explicit` evaluates to `true` if and
90
+ only if either `T1` or `T2` is not implicitly default-constructible.
 
91
 
92
  [*Note 1*: This behavior can be implemented with a trait that checks
93
+ whether a `const T1&` or a `const T2&` can be initialized with
94
+ `{}`. — *end note*]
95
 
96
  ``` cpp
97
  constexpr explicit(see below) pair(const T1& x, const T2& y);
98
  ```
99
 
100
  *Constraints:*
101
 
102
+ - `is_copy_constructible_v<T1>` is `true` and
103
+ - `is_copy_constructible_v<T2>` is `true`.
104
 
105
  *Effects:* Initializes `first` with `x` and `second` with `y`.
106
 
107
  *Remarks:* The expression inside `explicit` is equivalent to:
108
 
109
  ``` cpp
110
+ !is_convertible_v<const T1&, T1> || !is_convertible_v<const T2&, T2>
 
111
  ```
112
 
113
  ``` cpp
114
+ template<class U1 = T1, class U2 = T2> constexpr explicit(see below) pair(U1&& x, U2&& y);
115
  ```
116
 
117
  *Constraints:*
118
 
119
+ - `is_constructible_v<T1, U1>` is `true` and
120
+ - `is_constructible_v<T2, U2>` is `true`.
121
 
122
  *Effects:* Initializes `first` with `std::forward<U1>(x)` and `second`
123
  with `std::forward<U2>(y)`.
124
 
125
  *Remarks:* The expression inside `explicit` is equivalent to:
126
 
127
  ``` cpp
128
+ !is_convertible_v<U1, T1> || !is_convertible_v<U2, T2>
129
  ```
130
 
131
+ This constructor is defined as deleted if
132
+ `reference_constructs_from_temporary_v<first_type, U1&&>` is `true` or
133
+ `reference_constructs_from_temporary_v<second_type, U2&&>` is `true`.
134
+
135
  ``` cpp
136
+ template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p);
137
  template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
139
+ template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p);
140
+ template<pair-like P> constexpr explicit(see below) pair(P&& p);
141
  ```
142
 
143
+ Let *`FWD`*`(u)` be `static_cast<decltype(u)>(u)`.
144
+
145
  *Constraints:*
146
 
147
+ - For the last overload, `remove_cvref_t<P>` is not a specialization of
148
+ `ranges::subrange`,
149
+ - `is_constructible_v<T1, decltype(get<0>(`*`FWD`*`(p)))>` is `true`,
150
+ and
151
+ - `is_constructible_v<T2, decltype(get<1>(`*`FWD`*`(p)))>` is `true`.
152
 
153
+ *Effects:* Initializes `first` with `get<0>(`*`FWD`*`(p))` and `second`
154
+ with `get<1>(`*`FWD`*`(p))`.
155
 
156
+ *Remarks:* The expression inside `explicit` is equivalent to:
157
 
158
  ``` cpp
159
+ !is_convertible_v<decltype(get<0>(FWD(p))), T1> ||
160
+ !is_convertible_v<decltype(get<1>(FWD(p))), T2>
161
  ```
162
 
163
+ The constructor is defined as deleted if
164
+
165
+ ``` cpp
166
+ reference_constructs_from_temporary_v<first_type, decltype(get<0>(FWD(p)))> ||
167
+ reference_constructs_from_temporary_v<second_type, decltype(get<1>(FWD(p)))>
168
+ ```
169
+
170
+ is `true`.
171
+
172
  ``` cpp
173
  template<class... Args1, class... Args2>
174
  constexpr pair(piecewise_construct_t,
175
  tuple<Args1...> first_args, tuple<Args2...> second_args);
176
  ```
177
 
178
  *Mandates:*
179
 
180
+ - `is_constructible_v<T1, Args1...>` is `true` and
181
+ - `is_constructible_v<T2, Args2...>` is `true`.
182
 
183
  *Effects:* Initializes `first` with arguments of types `Args1...`
184
  obtained by forwarding the elements of `first_args` and initializes
185
  `second` with arguments of types `Args2...` obtained by forwarding the
186
  elements of `second_args`. (Here, forwarding an element `x` of type `U`
187
  within a `tuple` object means calling `std::forward<U>(x)`.) This form
188
  of construction, whereby constructor arguments for `first` and `second`
189
  are each provided in a separate `tuple` object, is called *piecewise
190
  construction*.
191
 
192
+ [*Note 2*: If a data member of `pair` is of reference type and its
193
+ initialization binds it to a temporary object, the program is
194
+ ill-formed [[class.base.init]]. — *end note*]
195
+
196
  ``` cpp
197
  constexpr pair& operator=(const pair& p);
198
  ```
199
 
200
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
201
 
202
+ *Returns:* `*this`.
203
+
204
  *Remarks:* This operator is defined as deleted unless
205
+ `is_copy_assignable_v<T1>` is `true` and `is_copy_assignable_v<T2>` is
206
+ `true`.
207
+
208
+ ``` cpp
209
+ constexpr const pair& operator=(const pair& p) const;
210
+ ```
211
+
212
+ *Constraints:*
213
+
214
+ - `is_copy_assignable_v<const T1>` is `true` and
215
+ - `is_copy_assignable_v<const T2>` is `true`.
216
+
217
+ *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
218
 
219
  *Returns:* `*this`.
220
 
221
  ``` cpp
222
  template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
223
  ```
224
 
225
  *Constraints:*
226
 
227
+ - `is_assignable_v<T1&, const U1&>` is `true` and
228
+ - `is_assignable_v<T2&, const U2&>` is `true`.
229
+
230
+ *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
231
+
232
+ *Returns:* `*this`.
233
+
234
+ ``` cpp
235
+ template<class U1, class U2> constexpr const pair& operator=(const pair<U1, U2>& p) const;
236
+ ```
237
+
238
+ *Constraints:*
239
+
240
+ - `is_assignable_v<const T1&, const U1&>` is `true`, and
241
+ - `is_assignable_v<const T2&, const U2&>` is `true`.
242
 
243
  *Effects:* Assigns `p.first` to `first` and `p.second` to `second`.
244
 
245
  *Returns:* `*this`.
246
 
 
248
  constexpr pair& operator=(pair&& p) noexcept(see below);
249
  ```
250
 
251
  *Constraints:*
252
 
253
+ - `is_move_assignable_v<T1>` is `true` and
254
+ - `is_move_assignable_v<T2>` is `true`.
255
 
256
+ *Effects:* Assigns to `first` with `std::forward<T1>(p.first)` and to
257
+ `second` with `std::forward<T2>(p.second)`.
 
258
 
259
  *Returns:* `*this`.
260
 
261
+ *Remarks:* The exception specification is equivalent to:
262
 
263
  ``` cpp
264
  is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
265
  ```
266
 
267
+ ``` cpp
268
+ constexpr const pair& operator=(pair&& p) const;
269
+ ```
270
+
271
+ *Constraints:*
272
+
273
+ - `is_assignable_v<const T1&, T1>` is `true` and
274
+ - `is_assignable_v<const T2&, T2>` is `true`.
275
+
276
+ *Effects:* Assigns `std::forward<T1>(p.first)` to `first` and
277
+ `std::forward<T2>(p.second)` to `second`.
278
+
279
+ *Returns:* `*this`.
280
+
281
  ``` cpp
282
  template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
283
  ```
284
 
285
  *Constraints:*
286
 
287
+ - `is_assignable_v<T1&, U1>` is `true` and
288
+ - `is_assignable_v<T2&, U2>` is `true`.
289
 
290
  *Effects:* Assigns to `first` with `std::forward<U1>(p.first)` and to
291
  `second` with
292
  `std::forward<U2>(p.second)`.
293
 
294
  *Returns:* `*this`.
295
 
296
+ ``` cpp
297
+ template<pair-like P> constexpr pair& operator=(P&& p);
298
+ ```
299
+
300
+ *Constraints:*
301
+
302
+ - `different-from<P, pair>` [[range.utility.helpers]] is `true`,
303
+ - `remove_cvref_t<P>` is not a specialization of `ranges::subrange`,
304
+ - `is_assignable_v<T1&, decltype(get<0>(std::forward<P>(p)))>` is
305
+ `true`, and
306
+ - `is_assignable_v<T2&, decltype(get<1>(std::forward<P>(p)))>` is
307
+ `true`.
308
+
309
+ *Effects:* Assigns `get<0>(std::forward<P>(p))` to `first` and
310
+ `get<1>(std::forward<P>(p))` to `second`.
311
+
312
+ *Returns:* `*this`.
313
+
314
+ ``` cpp
315
+ template<pair-like P> constexpr const pair& operator=(P&& p) const;
316
+ ```
317
+
318
+ *Constraints:*
319
+
320
+ - `different-from<P, pair>` [[range.utility.helpers]] is `true`,
321
+ - `remove_cvref_t<P>` is not a specialization of `ranges::subrange`,
322
+ - `is_assignable_v<const T1&, decltype(get<0>(std::forward<P>(p)))>` is
323
+ `true`, and
324
+ - `is_assignable_v<const T2&, decltype(get<1>(std::forward<P>(p)))>` is
325
+ `true`.
326
+
327
+ *Effects:* Assigns `get<0>(std::forward<P>(p))` to `first` and
328
+ `get<1>(std::forward<P>(p))` to `second`.
329
+
330
+ *Returns:* `*this`.
331
+
332
+ ``` cpp
333
+ template<class U1, class U2> constexpr const pair& operator=(pair<U1, U2>&& p) const;
334
+ ```
335
+
336
+ *Constraints:*
337
+
338
+ - `is_assignable_v<const T1&, U1>` is `true`, and
339
+ - `is_assignable_v<const T2&, U2>` is `true`.
340
+
341
+ *Effects:* Assigns `std::forward<U1>(p.first)` to `first` and
342
+ `std::forward<U2>(u.second)` to `second`.
343
+
344
+ *Returns:* `*this`.
345
+
346
  ``` cpp
347
  constexpr void swap(pair& p) noexcept(see below);
348
+ constexpr void swap(const pair& p) const noexcept(see below);
349
  ```
350
 
351
+ *Mandates:*
352
+
353
+ - For the first overload, `is_swappable_v<T1>` is `true` and
354
+ `is_swappable_v<T2>` is `true`.
355
+ - For the second overload, `is_swappable_v<const T1>` is `true` and
356
+ `is_swappable_v<const T2>` is `true`.
357
+
358
  *Preconditions:* `first` is swappable with [[swappable.requirements]]
359
  `p.first` and `second` is swappable with `p.second`.
360
 
361
  *Effects:* Swaps `first` with `p.first` and `second` with `p.second`.
362
 
363
+ *Remarks:* The exception specification is equivalent to:
364
 
365
+ - `is_nothrow_swappable_v<T1> && is_nothrow_swappable_v<T2>` for the
366
+ first overload, and
367
+ - `is_nothrow_swappable_v<const T1> && is_nothrow_swappable_v<const T2>`
368
+ for the second overload.
369