From Jason Turner

[utility.requirements]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpa68jsqso/{from.md → to.md} +491 -101
tmp/tmpa68jsqso/{from.md → to.md} RENAMED
@@ -1,7 +1,9 @@
1
  ### Requirements on types and expressions <a id="utility.requirements">[[utility.requirements]]</a>
2
 
 
 
3
  [[utility.arg.requirements]] describes requirements on types and
4
  expressions used to instantiate templates defined in the C++ standard
5
  library. [[swappable.requirements]] describes the requirements on
6
  swappable types and swappable expressions.
7
  [[nullablepointer.requirements]] describes the requirements on
@@ -13,33 +15,38 @@ allocators.
13
  #### Template argument requirements <a id="utility.arg.requirements">[[utility.arg.requirements]]</a>
14
 
15
  The template definitions in the C++ standard library refer to various
16
  named requirements whose details are set out in Tables 
17
  [[tab:cpp17.equalitycomparable]]– [[tab:cpp17.destructible]]. In these
18
- tables, `T` is an object or reference type to be supplied by a C++
19
- program instantiating a template; `a`, `b`, and `c` are values of type
20
- (possibly `const`) `T`; `s` and `t` are modifiable lvalues of type `T`;
21
- `u` denotes an identifier; `rv` is an rvalue of type `T`; and `v` is an
22
- lvalue of type (possibly `const`) `T` or an rvalue of type `const T`.
 
 
 
 
 
23
 
24
  In general, a default constructor is not required. Certain container
25
  class member function signatures specify `T()` as a default argument.
26
  `T()` shall be a well-defined expression [[dcl.init]] if one of those
27
  signatures is called using the default argument [[dcl.fct.default]].
28
 
29
  **Table: Cpp17EqualityComparable requirements** <a id="cpp17.equalitycomparable">[cpp17.equalitycomparable]</a>
30
 
31
  | Expression | Return type |
32
  | ---------- | ----------- |
33
- | `a == b` | convertible to `bool` | `==` is an equivalence relation, that is, it has the following properties: For all `a`, `a == a`.; If `a == b`, then `b == a`.; If `a == b` and `b == c`, then `a == c`. |
34
 
35
 
36
  **Table: Cpp17LessThanComparable requirements** <a id="cpp17.lessthancomparable">[cpp17.lessthancomparable]</a>
37
 
38
  | Expression | Return type | Requirement |
39
- | ---------- | --------------------- | ------------------------------------------------------ |
40
- | `a < b` | convertible to `bool` | `<` is a strict weak ordering relation [[alg.sorting]] |
41
 
42
 
43
  **Table: Cpp17DefaultConstructible requirements** <a id="cpp17.defaultconstructible">[cpp17.defaultconstructible]</a>
44
 
45
  | Expression | Post-condition |
@@ -47,37 +54,49 @@ signatures is called using the default argument [[dcl.fct.default]].
47
  | `T t;` | object `t` is default-initialized |
48
  | `T u{};` | object `u` is value-initialized or aggregate-initialized |
49
  | `T()`<br>`T{}` | an object of type `T` is value-initialized or aggregate-initialized |
50
 
51
 
52
- [*Note 1*: `rv` must still meet the requirements of the library
53
- component that is using it. The operations listed in those requirements
54
- must work as specified whether `rv` has been moved from or
55
- not. *end note*]
 
 
 
 
56
 
57
  **Table: Cpp17CopyConstructible requirements (in addition to Cpp17MoveConstructible)** <a id="cpp17.copyconstructible">[cpp17.copyconstructible]</a>
58
 
59
  | Expression | Post-condition |
60
  | ---------- | --------------------------------------------------------- |
61
  | `T u = v;` | the value of `v` is unchanged and is equivalent to ` u` |
62
  | `T(v)` | the value of `v` is unchanged and is equivalent to `T(v)` |
63
 
64
 
65
- [*Note 2*:  `rv` must still meet the requirements of the library
66
- component that is using it, whether or not `t` and `rv` refer to the
67
- same object. The operations listed in those requirements must work as
68
- specified whether `rv` has been moved from or not. — *end note*]
 
 
 
69
 
70
  **Table: Cpp17CopyAssignable requirements (in addition to Cpp17MoveAssignable)** <a id="cpp17.copyassignable">[cpp17.copyassignable]</a>
71
 
72
  | Expression | Return type | Return value | Post-condition |
73
  | ---------- | ----------- | ------------ | ------------------------------------------------------- |
74
  | `t = v` | `T&` | `t` | `t` is equivalent to `v`, the value of `v` is unchanged |
75
 
76
 
77
- [*Note 3*: Array types and non-object types are not
78
- *Cpp17Destructible*. — *end note*]
 
 
 
 
 
79
 
80
  #### Swappable requirements <a id="swappable.requirements">[[swappable.requirements]]</a>
81
 
82
  This subclause provides definitions for swappable types and expressions.
83
  In these definitions, let `t` denote an expression of type `T`, and let
@@ -111,44 +130,48 @@ swappable requirement includes the header `<utility>` to ensure an
111
  appropriate evaluation context. — *end note*]
112
 
113
  An rvalue or lvalue `t` is *swappable* if and only if `t` is swappable
114
  with any rvalue or lvalue, respectively, of type `T`.
115
 
 
 
 
116
  A type `X` meeting any of the iterator requirements
117
  [[iterator.requirements]] meets the *Cpp17ValueSwappable* requirements
118
  if, for any dereferenceable object `x` of type `X`, `*x` is swappable.
119
 
120
  [*Example 1*:
121
 
122
  User code can ensure that the evaluation of `swap` calls is performed in
123
  an appropriate context under the various conditions as follows:
124
 
125
  ``` cpp
 
126
  #include <utility>
127
 
128
- // Requires: std::forward<T>(t) shall be swappable with std::forward<U>(u).
129
  template<class T, class U>
130
  void value_swap(T&& t, U&& u) {
131
  using std::swap;
132
- swap(std::forward<T>(t), std::forward<U>(u)); // OK: uses ``swappable with'' conditions
133
  // for rvalues and lvalues
134
  }
135
 
136
- // Requires: lvalues of T shall be swappable.
137
  template<class T>
138
  void lv_swap(T& t1, T& t2) {
139
  using std::swap;
140
- swap(t1, t2); // OK: uses swappable conditions for lvalues of type T
141
  }
142
 
143
  namespace N {
144
  struct A { int m; };
145
  struct Proxy { A* a; };
146
  Proxy proxy(A& a) { return Proxy{ &a }; }
147
 
148
  void swap(A& x, Proxy p) {
149
- std::swap(x.m, p.a->m); // OK: uses context equivalent to swappable
150
  // conditions for fundamental types
151
  }
152
  void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint
153
  }
154
 
@@ -169,22 +192,21 @@ int main() {
169
 
170
  A *Cpp17NullablePointer* type is a pointer-like type that supports null
171
  values. A type `P` meets the *Cpp17NullablePointer* requirements if:
172
 
173
  - `P` meets the *Cpp17EqualityComparable*, *Cpp17DefaultConstructible*,
174
- *Cpp17CopyConstructible*, *Cpp17CopyAssignable*, and
175
  *Cpp17Destructible* requirements,
176
- - lvalues of type `P` are swappable [[swappable.requirements]],
177
  - the expressions shown in [[cpp17.nullablepointer]] are valid and have
178
  the indicated semantics, and
179
  - `P` meets all the other requirements of this subclause.
180
 
181
  A value-initialized object of type `P` produces the null value of the
182
  type. The null value shall be equivalent only to itself. A
183
  default-initialized object of type `P` may have an indeterminate value.
184
 
185
- [*Note 1*: Operations involving indeterminate values may cause
186
  undefined behavior. — *end note*]
187
 
188
  An object `p` of type `P` can be contextually converted to `bool`
189
  [[conv]]. The effect shall be as if `p != nullptr` had been evaluated in
190
  place of `p`.
@@ -192,25 +214,25 @@ place of `p`.
192
  No operation which is part of the *Cpp17NullablePointer* requirements
193
  shall exit via an exception.
194
 
195
  In [[cpp17.nullablepointer]], `u` denotes an identifier, `t` denotes a
196
  non-`const` lvalue of type `P`, `a` and `b` denote values of type
197
- (possibly `const`) `P`, and `np` denotes a value of type (possibly
198
- `const`) `std::nullptr_t`.
199
 
200
  **Table: Cpp17NullablePointer requirements** <a id="cpp17.nullablepointer">[cpp17.nullablepointer]</a>
201
 
202
  | Expression | Return type | Operational semantics |
203
- | -------------- | ---------------------------------- | --------------------------- |
204
  | `P u(np);`<br> | | Ensures: `u == nullptr` |
205
  | `P u = np;` | | |
206
  | `P(np)` | | Ensures: `P(np) == nullptr` |
207
  | `t = np` | `P&` | Ensures: `t == nullptr` |
208
- | `a != b` | contextually convertible to `bool` | `!(a == b)` |
209
- | `a == np` | contextually convertible to `bool` | `a == P()` |
210
  | `np == a` | | |
211
- | `a != np` | contextually convertible to `bool` | `!(a == np)` |
212
  | `np != a` | | |
213
 
214
 
215
  #### *Cpp17Hash* requirements <a id="hash.requirements">[[hash.requirements]]</a>
216
 
@@ -221,110 +243,480 @@ A type `H` meets the requirements if:
221
  and *Cpp17Destructible* ([[cpp17.destructible]]) requirements, and
222
  - the expressions shown in [[cpp17.hash]] are valid and have the
223
  indicated semantics.
224
 
225
  Given `Key` is an argument type for function objects of type `H`, in
226
- [[cpp17.hash]] `h` is a value of type (possibly `const`) `H`, `u` is an
227
  lvalue of type `Key`, and `k` is a value of a type convertible to
228
- (possibly `const`) `Key`.
229
 
230
  [*Note 1*: Thus all evaluations of the expression `h(k)` with the same
231
  value for `k` yield the same result for a given execution of the
232
  program. — *end note*]
233
 
234
  #### *Cpp17Allocator* requirements <a id="allocator.requirements">[[allocator.requirements]]</a>
235
 
 
 
236
  The library describes a standard set of requirements for *allocators*,
237
  which are class-type objects that encapsulate the information about an
238
  allocation model. This information includes the knowledge of pointer
239
  types, the type of their difference, the type of the size of objects in
240
  this allocation model, as well as the memory allocation and deallocation
241
  primitives for it. All of the string types [[strings]], containers
242
  [[containers]] (except `array`), string buffers and string streams
243
  [[input.output]], and `match_results` [[re]] are parameterized in terms
244
  of allocators.
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  The class template `allocator_traits` [[allocator.traits]] supplies a
247
- uniform interface to all allocator types. [[allocator.req.var]]
248
- describes the types manipulated through allocators. [[cpp17.allocator]]
249
- describes the requirements on allocator types and thus on types used to
250
- instantiate `allocator_traits`. A requirement is optional if the last
251
- column of [[cpp17.allocator]] specifies a default for a given
252
- expression. Within the standard library `allocator_traits` template, an
253
- optional requirement that is not supplied by an allocator is replaced by
254
- the specified default expression. A user specialization of
255
- `allocator_traits` may provide different defaults and may provide
256
- defaults for different requirements than the primary template. Within
257
- Tables  [[tab:allocator.req.var]] and  [[tab:cpp17.allocator]], the use
258
- of `move` and `forward` always refers to `std::move` and `std::forward`,
259
- respectively.
260
-
261
- [*Note 1*: If `n == 0`, the return value is unspecified. — *end note*]
262
-
263
- Note A: The member class template `rebind` in the table above is
264
- effectively a typedef template.
265
-
266
- [*Note 2*: In general, if the name `Allocator` is bound to
267
- `SomeAllocator<T>`, then `Allocator::rebind<U>::other` is the same type
268
- as `SomeAllocator<U>`, where `SomeAllocator<T>::value_type` is `T` and
269
- `SomeAllocator<U>::{}value_type` is `U`. — *end note*]
270
-
271
- If `Allocator` is a class template instantiation of the form
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  `SomeAllocator<T, Args>`, where `Args` is zero or more type arguments,
273
  and `Allocator` does not supply a `rebind` member template, the standard
274
  `allocator_traits` template uses `SomeAllocator<U, Args>` in place of
275
- `Allocator::{}rebind<U>::other` by default. For allocator types that are
276
  not template instantiations of the above form, no default is provided.
277
 
278
- Note B: If `X::propagate_on_container_copy_assignment::value` is `true`,
279
- `X` shall meet the *Cpp17CopyAssignable* requirements (
280
- [[cpp17.copyassignable]]) and the copy operation shall not throw
281
- exceptions. If `X::propagate_on_container_move_assignment::value` is
282
- `true`, `X` shall meet the *Cpp17MoveAssignable* requirements (
283
- [[cpp17.moveassignable]]) and the move operation shall not throw
284
- exceptions. If `X::propagate_on_container_swap::value` is `true`,
285
- lvalues of type `X` shall be swappable [[swappable.requirements]] and
286
- the `swap` operation shall not throw exceptions.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
  An allocator type `X` shall meet the *Cpp17CopyConstructible*
289
- requirements ([[cpp17.copyconstructible]]). The `X::pointer`,
290
- `X::const_pointer`, `X::void_pointer`, and `X::const_void_pointer` types
291
- shall meet the *Cpp17NullablePointer* requirements (
292
- [[cpp17.nullablepointer]]). No constructor, comparison function, copy
293
- operation, move operation, or swap operation on these pointer types
294
- shall exit via an exception. `X::pointer` and `X::const_pointer` shall
295
- also meet the requirements for a *Cpp17RandomAccessIterator*
296
- [[random.access.iterators]] and the additional requirement that, when
297
- `a` and `(a + n)` are dereferenceable pointer values for some integral
298
- value `n`,
299
 
300
  ``` cpp
301
- addressof(*(a + n)) == addressof(*a) + n
302
  ```
303
 
304
  is `true`.
305
 
306
  Let `x1` and `x2` denote objects of (possibly different) types
307
- `X::void_pointer`, `X::const_void_pointer`, `X::pointer`, or
308
- `X::const_pointer`. Then, `x1` and `x2` are *equivalently-valued*
309
  pointer values, if and only if both `x1` and `x2` can be explicitly
310
  converted to the two corresponding objects `px1` and `px2` of type
311
- `X::const_pointer`, using a sequence of `static_cast`s using only these
312
  four types, and the expression `px1 == px2` evaluates to `true`.
313
 
314
- Let `w1` and `w2` denote objects of type `X::void_pointer`. Then for the
315
- expressions
316
 
317
  ``` cpp
318
  w1 == w2
319
  w1 != w2
320
  ```
321
 
322
  either or both objects may be replaced by an equivalently-valued object
323
- of type `X::const_void_pointer` with no change in semantics.
324
 
325
- Let `p1` and `p2` denote objects of type `X::pointer`. Then for the
326
  expressions
327
 
328
  ``` cpp
329
  p1 == p2
330
  p1 != p2
@@ -334,11 +726,11 @@ p1 >= p2
334
  p1 > p2
335
  p1 - p2
336
  ```
337
 
338
  either or both objects may be replaced by an equivalently-valued object
339
- of type `X::const_pointer` with no change in semantics.
340
 
341
  An allocator may constrain the types on which it can be instantiated and
342
  the arguments for which its `construct` or `destroy` members may be
343
  called. If a type cannot be used with a particular allocator, the
344
  allocator class or the call to `construct` or `destroy` may fail to
@@ -347,34 +739,32 @@ instantiate.
347
  If the alignment associated with a specific over-aligned type is not
348
  supported by an allocator, instantiation of the allocator for that type
349
  may fail. The allocator also may silently ignore the requested
350
  alignment.
351
 
352
- [*Note 3*: Additionally, the member function `allocate` for that type
353
- may fail by throwing an object of type `bad_alloc`. — *end note*]
354
 
355
  [*Example 1*:
356
 
357
  The following is an allocator class template supporting the minimal
358
- interface that meets the requirements of [[cpp17.allocator]]:
 
359
 
360
  ``` cpp
361
- template<class Tp>
362
  struct SimpleAllocator {
363
- typedef Tp value_type;
364
  SimpleAllocator(ctor args);
365
 
366
- template<class T> SimpleAllocator(const SimpleAllocator<T>& other);
367
 
368
- [[nodiscard]] Tp* allocate(std::size_t n);
369
- void deallocate(Tp* p, std::size_t n);
 
 
370
  };
371
-
372
- template<class T, class U>
373
- bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
374
- template<class T, class U>
375
- bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
376
  ```
377
 
378
  — *end example*]
379
 
380
  ##### Allocator completeness requirements <a id="allocator.requirements.completeness">[[allocator.requirements.completeness]]</a>
 
1
  ### Requirements on types and expressions <a id="utility.requirements">[[utility.requirements]]</a>
2
 
3
+ #### General <a id="utility.requirements.general">[[utility.requirements.general]]</a>
4
+
5
  [[utility.arg.requirements]] describes requirements on types and
6
  expressions used to instantiate templates defined in the C++ standard
7
  library. [[swappable.requirements]] describes the requirements on
8
  swappable types and swappable expressions.
9
  [[nullablepointer.requirements]] describes the requirements on
 
15
  #### Template argument requirements <a id="utility.arg.requirements">[[utility.arg.requirements]]</a>
16
 
17
  The template definitions in the C++ standard library refer to various
18
  named requirements whose details are set out in Tables 
19
  [[tab:cpp17.equalitycomparable]]– [[tab:cpp17.destructible]]. In these
20
+ tables,
21
+
22
+ - `T` denotes an object or reference type to be supplied by a C++
23
+ program instantiating a template,
24
+ - `a`, `b`, and `c` denote values of type (possibly const) `T`,
25
+ - `s` and `t` denote modifiable lvalues of type `T`,
26
+ - `u` denotes an identifier,
27
+ - `rv` denotes an rvalue of type `T`, and
28
+ - `v` denotes an lvalue of type (possibly const) `T` or an rvalue of
29
+ type `const T`.
30
 
31
  In general, a default constructor is not required. Certain container
32
  class member function signatures specify `T()` as a default argument.
33
  `T()` shall be a well-defined expression [[dcl.init]] if one of those
34
  signatures is called using the default argument [[dcl.fct.default]].
35
 
36
  **Table: Cpp17EqualityComparable requirements** <a id="cpp17.equalitycomparable">[cpp17.equalitycomparable]</a>
37
 
38
  | Expression | Return type |
39
  | ---------- | ----------- |
40
+ | `a == b` | `decltype(a == b)` models `boolean-testable` | `==` is an equivalence relation, that is, it has the following properties: For all `a`, `a == a`.; If `a == b`, then `b == a`.; If `a == b` and `b == c`, then `a == c`. |
41
 
42
 
43
  **Table: Cpp17LessThanComparable requirements** <a id="cpp17.lessthancomparable">[cpp17.lessthancomparable]</a>
44
 
45
  | Expression | Return type | Requirement |
46
+ | ---------- | ------------------------------------------- | ------------------------------------------------------ |
47
+ | `a < b` | `decltype(a < b)` models `boolean-testable` | `<` is a strict weak ordering relation [[alg.sorting]] |
48
 
49
 
50
  **Table: Cpp17DefaultConstructible requirements** <a id="cpp17.defaultconstructible">[cpp17.defaultconstructible]</a>
51
 
52
  | Expression | Post-condition |
 
54
  | `T t;` | object `t` is default-initialized |
55
  | `T u{};` | object `u` is value-initialized or aggregate-initialized |
56
  | `T()`<br>`T{}` | an object of type `T` is value-initialized or aggregate-initialized |
57
 
58
 
59
+ **Table: Cpp17MoveConstructible requirements** <a id="cpp17.moveconstructible">[cpp17.moveconstructible]</a>
60
+
61
+ | Expression | Post-condition |
62
+ | ----------- | ------------------------------------------------------------------ |
63
+ | `T u = rv;` | `u` is equivalent to the value of `rv` before the construction |
64
+ | `T(rv)` | `T(rv)` is equivalent to the value of `rv` before the construction |
65
+ | *[spans 2 columns]* `rv`'s state is unspecified *`rv` must still meet the requirements of the library component that is using it. The operations listed in those requirements must work as specified whether `rv` has been moved from or not.* |
66
+
67
 
68
  **Table: Cpp17CopyConstructible requirements (in addition to Cpp17MoveConstructible)** <a id="cpp17.copyconstructible">[cpp17.copyconstructible]</a>
69
 
70
  | Expression | Post-condition |
71
  | ---------- | --------------------------------------------------------- |
72
  | `T u = v;` | the value of `v` is unchanged and is equivalent to ` u` |
73
  | `T(v)` | the value of `v` is unchanged and is equivalent to `T(v)` |
74
 
75
 
76
+ **Table: Cpp17MoveAssignable requirements** <a id="cpp17.moveassignable">[cpp17.moveassignable]</a>
77
+
78
+ | Expression | Return type | Return value | Post-condition |
79
+ | ---------- | ----------- | ------------ | ------------------------------------------------------------------------------------------------------------- |
80
+ | `t = rv` | `T&` | `t` | If `t` and `rv` do not refer to the same object, `t` is equivalent to the value of `rv` before the assignment |
81
+ | *[spans 4 columns]* `rv`'s state is unspecified. *`rv` must still meet the requirements of the library component that is using it, whether or not `t` and `rv` refer to the same object. The operations listed in those requirements must work as specified whether `rv` has been moved from or not.* |
82
+
83
 
84
  **Table: Cpp17CopyAssignable requirements (in addition to Cpp17MoveAssignable)** <a id="cpp17.copyassignable">[cpp17.copyassignable]</a>
85
 
86
  | Expression | Return type | Return value | Post-condition |
87
  | ---------- | ----------- | ------------ | ------------------------------------------------------- |
88
  | `t = v` | `T&` | `t` | `t` is equivalent to `v`, the value of `v` is unchanged |
89
 
90
 
91
+ **Table: Cpp17Destructible requirements** <a id="cpp17.destructible">[cpp17.destructible]</a>
92
+
93
+ | Expression | Post-condition |
94
+ | ---------- | --------------------------------------------------------------------- |
95
+ | `u.~T()` | All resources owned by `u` are reclaimed, no exception is propagated. |
96
+ | *[spans 2 columns]* *Array types and non-object types are not Cpp17Destructible.* |
97
+
98
 
99
  #### Swappable requirements <a id="swappable.requirements">[[swappable.requirements]]</a>
100
 
101
  This subclause provides definitions for swappable types and expressions.
102
  In these definitions, let `t` denote an expression of type `T`, and let
 
130
  appropriate evaluation context. — *end note*]
131
 
132
  An rvalue or lvalue `t` is *swappable* if and only if `t` is swappable
133
  with any rvalue or lvalue, respectively, of type `T`.
134
 
135
+ A type `X` meets the *Cpp17Swappable* requirements if lvalues of type
136
+ `X` are swappable.
137
+
138
  A type `X` meeting any of the iterator requirements
139
  [[iterator.requirements]] meets the *Cpp17ValueSwappable* requirements
140
  if, for any dereferenceable object `x` of type `X`, `*x` is swappable.
141
 
142
  [*Example 1*:
143
 
144
  User code can ensure that the evaluation of `swap` calls is performed in
145
  an appropriate context under the various conditions as follows:
146
 
147
  ``` cpp
148
+ #include <cassert>
149
  #include <utility>
150
 
151
+ // Preconditions: std::forward<T>(t) is swappable with std::forward<U>(u).
152
  template<class T, class U>
153
  void value_swap(T&& t, U&& u) {
154
  using std::swap;
155
+ swap(std::forward<T>(t), std::forward<U>(u)); // OK, uses ``swappable with'' conditions
156
  // for rvalues and lvalues
157
  }
158
 
159
+ // Preconditions: T meets the Cpp17Swappable requirements.
160
  template<class T>
161
  void lv_swap(T& t1, T& t2) {
162
  using std::swap;
163
+ swap(t1, t2); // OK, uses swappable conditions for lvalues of type T
164
  }
165
 
166
  namespace N {
167
  struct A { int m; };
168
  struct Proxy { A* a; };
169
  Proxy proxy(A& a) { return Proxy{ &a }; }
170
 
171
  void swap(A& x, Proxy p) {
172
+ std::swap(x.m, p.a->m); // OK, uses context equivalent to swappable
173
  // conditions for fundamental types
174
  }
175
  void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint
176
  }
177
 
 
192
 
193
  A *Cpp17NullablePointer* type is a pointer-like type that supports null
194
  values. A type `P` meets the *Cpp17NullablePointer* requirements if:
195
 
196
  - `P` meets the *Cpp17EqualityComparable*, *Cpp17DefaultConstructible*,
197
+ *Cpp17CopyConstructible*, *Cpp17CopyAssignable*, *Cpp17Swappable*, and
198
  *Cpp17Destructible* requirements,
 
199
  - the expressions shown in [[cpp17.nullablepointer]] are valid and have
200
  the indicated semantics, and
201
  - `P` meets all the other requirements of this subclause.
202
 
203
  A value-initialized object of type `P` produces the null value of the
204
  type. The null value shall be equivalent only to itself. A
205
  default-initialized object of type `P` may have an indeterminate value.
206
 
207
+ [*Note 1*: Operations involving indeterminate values can cause
208
  undefined behavior. — *end note*]
209
 
210
  An object `p` of type `P` can be contextually converted to `bool`
211
  [[conv]]. The effect shall be as if `p != nullptr` had been evaluated in
212
  place of `p`.
 
214
  No operation which is part of the *Cpp17NullablePointer* requirements
215
  shall exit via an exception.
216
 
217
  In [[cpp17.nullablepointer]], `u` denotes an identifier, `t` denotes a
218
  non-`const` lvalue of type `P`, `a` and `b` denote values of type
219
+ (possibly const) `P`, and `np` denotes a value of type (possibly const)
220
+ `std::nullptr_t`.
221
 
222
  **Table: Cpp17NullablePointer requirements** <a id="cpp17.nullablepointer">[cpp17.nullablepointer]</a>
223
 
224
  | Expression | Return type | Operational semantics |
225
+ | -------------- | ------------------------------------------------------------------------- | --------------------------- |
226
  | `P u(np);`<br> | | Ensures: `u == nullptr` |
227
  | `P u = np;` | | |
228
  | `P(np)` | | Ensures: `P(np) == nullptr` |
229
  | `t = np` | `P&` | Ensures: `t == nullptr` |
230
+ | `a != b` | `decltype(a != b)` models `boolean-testable` | `!(a == b)` |
231
+ | `a == np` | `decltype(a == np)` and `decltype(np == a)` each model `boolean-testable` | `a == P()` |
232
  | `np == a` | | |
233
+ | `a != np` | `decltype(a != np)` and `decltype(np != a)` each model `boolean-testable` | `!(a == np)` |
234
  | `np != a` | | |
235
 
236
 
237
  #### *Cpp17Hash* requirements <a id="hash.requirements">[[hash.requirements]]</a>
238
 
 
243
  and *Cpp17Destructible* ([[cpp17.destructible]]) requirements, and
244
  - the expressions shown in [[cpp17.hash]] are valid and have the
245
  indicated semantics.
246
 
247
  Given `Key` is an argument type for function objects of type `H`, in
248
+ [[cpp17.hash]] `h` is a value of type (possibly const) `H`, `u` is an
249
  lvalue of type `Key`, and `k` is a value of a type convertible to
250
+ (possibly const) `Key`.
251
 
252
  [*Note 1*: Thus all evaluations of the expression `h(k)` with the same
253
  value for `k` yield the same result for a given execution of the
254
  program. — *end note*]
255
 
256
  #### *Cpp17Allocator* requirements <a id="allocator.requirements">[[allocator.requirements]]</a>
257
 
258
+ ##### General <a id="allocator.requirements.general">[[allocator.requirements.general]]</a>
259
+
260
  The library describes a standard set of requirements for *allocators*,
261
  which are class-type objects that encapsulate the information about an
262
  allocation model. This information includes the knowledge of pointer
263
  types, the type of their difference, the type of the size of objects in
264
  this allocation model, as well as the memory allocation and deallocation
265
  primitives for it. All of the string types [[strings]], containers
266
  [[containers]] (except `array`), string buffers and string streams
267
  [[input.output]], and `match_results` [[re]] are parameterized in terms
268
  of allocators.
269
 
270
+ In subclause [[allocator.requirements]],
271
+
272
+ - `T`, `U`, `C` denote any cv-unqualified object type
273
+ [[term.object.type]],
274
+ - `X` denotes an allocator class for type `T`,
275
+ - `Y` denotes the corresponding allocator class for type `U`,
276
+ - `XX` denotes the type `allocator_traits<X>`,
277
+ - `YY` denotes the type `allocator_traits<Y>`,
278
+ - `a`, `a1`, `a2` denote lvalues of type `X`,
279
+ - `u` denotes the name of a variable being declared,
280
+ - `b` denotes a value of type `Y`,
281
+ - `c` denotes a pointer of type `C*` through which indirection is valid,
282
+ - `p` denotes a value of type `XX::pointer` obtained by calling
283
+ `a1.allocate`, where `a1 == a`,
284
+ - `q` denotes a value of type `XX::const_pointer` obtained by conversion
285
+ from a value `p`,
286
+ - `r` denotes a value of type `T&` obtained by the expression `*p`,
287
+ - `w` denotes a value of type `XX::void_pointer` obtained by conversion
288
+ from a value `p`,
289
+ - `x` denotes a value of type `XX::const_void_pointer` obtained by
290
+ conversion from a value `q` or a value `w`,
291
+ - `y` denotes a value of type `XX::const_void_pointer` obtained by
292
+ conversion from a result value of `YY::allocate`, or else a value of
293
+ type (possibly const) `std::nullptr_t`,
294
+ - `n` denotes a value of type `XX::size_type`,
295
+ - `Args` denotes a template parameter pack, and
296
+ - `args` denotes a function parameter pack with the pattern `Args&&`.
297
+
298
  The class template `allocator_traits` [[allocator.traits]] supplies a
299
+ uniform interface to all allocator types. This subclause describes the
300
+ requirements on allocator types and thus on types used to instantiate
301
+ `allocator_traits`. A requirement is optional if a default for a given
302
+ type or expression is specified. Within the standard library
303
+ `allocator_traits` template, an optional requirement that is not
304
+ supplied by an allocator is replaced by the specified default type or
305
+ expression.
306
+
307
+ [*Note 1*: There are no program-defined specializations of
308
+ `allocator_traits`. *end note*]
309
+
310
+ ``` cpp
311
+ typename X::pointer
312
+ ```
313
+
314
+ *Remarks:* Default: `T*`
315
+
316
+ ``` cpp
317
+ typename X::const_pointer
318
+ ```
319
+
320
+ *Mandates:* `XX::pointer` is convertible to `XX::const_pointer`.
321
+
322
+ *Remarks:* Default: `pointer_traits<XX::pointer>::rebind<const T>`
323
+
324
+ ``` cpp
325
+ typename X::void_pointer
326
+ typename Y::void_pointer
327
+ ```
328
+
329
+ *Mandates:* `XX::pointer` is convertible to `XX::void_pointer`.
330
+ `XX::void_pointer` and `YY::void_pointer` are the same type.
331
+
332
+ *Remarks:* Default: `pointer_traits<XX::pointer>::rebind<void>`
333
+
334
+ ``` cpp
335
+ typename X::const_void_pointer
336
+ typename Y::const_void_pointer
337
+ ```
338
+
339
+ *Mandates:* `XX::pointer`, `XX::const_pointer`, and `XX::void_pointer`
340
+ are convertible to `XX::const_void_pointer`. `XX::const_void_pointer`
341
+ and `YY::const_void_pointer` are the same type.
342
+
343
+ *Remarks:* Default: `pointer_traits<XX::pointer>::rebind<const void>`
344
+
345
+ ``` cpp
346
+ typename X::value_type
347
+ ```
348
+
349
+ *Result:* Identical to `T`.
350
+
351
+ ``` cpp
352
+ typename X::size_type
353
+ ```
354
+
355
+ *Result:* An unsigned integer type that can represent the size of the
356
+ largest object in the allocation model.
357
+
358
+ *Remarks:* Default: `make_unsigned_t<XX::difference_type>`
359
+
360
+ ``` cpp
361
+ typename X::difference_type
362
+ ```
363
+
364
+ *Result:* A signed integer type that can represent the difference
365
+ between any two pointers in the allocation model.
366
+
367
+ *Remarks:* Default: `pointer_traits<XX::pointer>::difference_type`
368
+
369
+ ``` cpp
370
+ typename X::template rebind<U>::other
371
+ ```
372
+
373
+ *Result:* `Y`
374
+
375
+ *Ensures:* For all `U` (including `T`), `YY::rebind_alloc<T>` is `X`.
376
+
377
+ *Remarks:* If `Allocator` is a class template instantiation of the form
378
  `SomeAllocator<T, Args>`, where `Args` is zero or more type arguments,
379
  and `Allocator` does not supply a `rebind` member template, the standard
380
  `allocator_traits` template uses `SomeAllocator<U, Args>` in place of
381
+ `Allocator::rebind<U>::other` by default. For allocator types that are
382
  not template instantiations of the above form, no default is provided.
383
 
384
+ [*Note 1*: The member class template `rebind` of `X` is effectively a
385
+ typedef template. In general, if the name `Allocator` is bound to
386
+ `SomeAllocator<T>`, then `Allocator::rebind<U>::other` is the same type
387
+ as `SomeAllocator<U>`, where `SomeAllocator<T>::value_type` is `T` and
388
+ `SomeAllocator<U>::value_type` is `U`. *end note*]
389
+
390
+ ``` cpp
391
+ *p
392
+ ```
393
+
394
+ *Result:* `T&`
395
+
396
+ ``` cpp
397
+ *q
398
+ ```
399
+
400
+ *Result:* `const T&`
401
+
402
+ *Ensures:* `*q` refers to the same object as `*p`.
403
+
404
+ ``` cpp
405
+ p->m
406
+ ```
407
+
408
+ *Result:* Type of `T::m`.
409
+
410
+ *Preconditions:* `(*p).m` is well-defined.
411
+
412
+ *Effects:* Equivalent to `(*p).m`.
413
+
414
+ ``` cpp
415
+ q->m
416
+ ```
417
+
418
+ *Result:* Type of `T::m`.
419
+
420
+ *Preconditions:* `(*q).m` is well-defined.
421
+
422
+ *Effects:* Equivalent to `(*q).m`.
423
+
424
+ ``` cpp
425
+ static_cast<XX::pointer>(w)
426
+ ```
427
+
428
+ *Result:* `XX::pointer`
429
+
430
+ *Ensures:* `static_cast<XX::pointer>(w) == p`.
431
+
432
+ ``` cpp
433
+ static_cast<XX::const_pointer>(x)
434
+ ```
435
+
436
+ *Result:* `XX::const_pointer`
437
+
438
+ *Ensures:* `static_cast<XX::const_pointer>(x) == q`.
439
+
440
+ ``` cpp
441
+ pointer_traits<XX::pointer>::pointer_to(r)
442
+ ```
443
+
444
+ *Result:* `XX::pointer`
445
+
446
+ *Ensures:* Same as `p`.
447
+
448
+ ``` cpp
449
+ a.allocate(n)
450
+ ```
451
+
452
+ *Result:* `XX::pointer`
453
+
454
+ *Effects:* Memory is allocated for an array of `n` `T` and such an
455
+ object is created but array elements are not constructed.
456
+
457
+ [*Example 1*: When reusing storage denoted by some pointer value `p`,
458
+ `launder(reinterpret_cast<T*>(new (p) byte[n * sizeof(T)]))` can be used
459
+ to implicitly create a suitable array object and obtain a pointer to
460
+ it. — *end example*]
461
+
462
+ *Throws:* `allocate` may throw an appropriate exception.
463
+
464
+ [*Note 2*: It is intended that `a.allocate` be an efficient means of
465
+ allocating a single object of type `T`, even when `sizeof(T)` is small.
466
+ That is, there is no need for a container to maintain its own free
467
+ list. — *end note*]
468
+
469
+ *Remarks:* If `n == 0`, the return value is unspecified.
470
+
471
+ ``` cpp
472
+ a.allocate(n, y)
473
+ ```
474
+
475
+ *Result:* `XX::pointer`
476
+
477
+ *Effects:* Same as `a.allocate(n)`. The use of `y` is unspecified, but
478
+ it is intended as an aid to locality.
479
+
480
+ *Remarks:* Default: `a.allocate(n)`
481
+
482
+ ``` cpp
483
+ a.allocate_at_least(n)
484
+ ```
485
+
486
+ *Result:* `allocation_result<XX::pointer, XX::size_type>`
487
+
488
+ *Returns:* `allocation_result<XX::pointer, XX::size_type>{ptr, count}`
489
+ where `ptr` is memory allocated for an array of `count` `T` and such an
490
+ object is created but array elements are not constructed, such that
491
+ `count` ≥ `n`. If `n == 0`, the return value is unspecified.
492
+
493
+ *Throws:* `allocate_at_least` may throw an appropriate exception.
494
+
495
+ *Remarks:* Default: `{a.allocate(n), n}`.
496
+
497
+ ``` cpp
498
+ a.deallocate(p, n)
499
+ ```
500
+
501
+ *Result:* (not used)
502
+
503
+ *Preconditions:*
504
+
505
+ - If `p` is memory that was obtained by a call to `a.allocate_at_least`,
506
+ let `ret` be the value returned and `req` be the value passed as the
507
+ first argument of that call. `p` is equal to `ret.ptr` and `n` is a
508
+ value such that `req` ≤ `n` ≤ `ret.count`.
509
+ - Otherwise, `p` is a pointer value obtained from `allocate`. `n` equals
510
+ the value passed as the first argument to the invocation of `allocate`
511
+ which returned `p`.
512
+
513
+ `p` has not been invalidated by an intervening call to `deallocate`.
514
+
515
+ *Throws:* Nothing.
516
+
517
+ ``` cpp
518
+ a.max_size()
519
+ ```
520
+
521
+ *Result:* `XX::size_type`
522
+
523
+ *Returns:* The largest value `n` that can meaningfully be passed to
524
+ `a.allocate(n)`.
525
+
526
+ *Remarks:* Default:
527
+ `numeric_limits<size_type>::max() / sizeof(value_type)`
528
+
529
+ ``` cpp
530
+ a1 == a2
531
+ ```
532
+
533
+ *Result:* `bool`
534
+
535
+ *Returns:* `true` only if storage allocated from each can be deallocated
536
+ via the other.
537
+
538
+ *Throws:* Nothing.
539
+
540
+ *Remarks:* `operator==` shall be reflexive, symmetric, and transitive.
541
+
542
+ ``` cpp
543
+ a1 != a2
544
+ ```
545
+
546
+ *Result:* `bool`
547
+
548
+ *Returns:* `!(a1 == a2)`.
549
+
550
+ ``` cpp
551
+ a == b
552
+ ```
553
+
554
+ *Result:* `bool`
555
+
556
+ *Returns:* `a == YY::rebind_alloc<T>(b)`.
557
+
558
+ ``` cpp
559
+ a != b
560
+ ```
561
+
562
+ *Result:* `bool`
563
+
564
+ *Returns:* `!(a == b)`.
565
+
566
+ ``` cpp
567
+ X u(a);
568
+ X u = a;
569
+ ```
570
+
571
+ *Ensures:* `u == a`
572
+
573
+ *Throws:* Nothing.
574
+
575
+ ``` cpp
576
+ X u(b);
577
+ ```
578
+
579
+ *Ensures:* `Y(u) == b` and `u == X(b)`.
580
+
581
+ *Throws:* Nothing.
582
+
583
+ ``` cpp
584
+ X u(std::move(a));
585
+ X u = std::move(a);
586
+ ```
587
+
588
+ *Ensures:* The value of `a` is unchanged and is equal to `u`.
589
+
590
+ *Throws:* Nothing.
591
+
592
+ ``` cpp
593
+ X u(std::move(b));
594
+ ```
595
+
596
+ *Ensures:* `u` is equal to the prior value of `X(b)`.
597
+
598
+ *Throws:* Nothing.
599
+
600
+ ``` cpp
601
+ a.construct(c, args)
602
+ ```
603
+
604
+ *Result:* (not used)
605
+
606
+ *Effects:* Constructs an object of type `C` at `c`.
607
+
608
+ *Remarks:* Default: `construct_at(c, std::forward<Args>(args)...)`
609
+
610
+ ``` cpp
611
+ a.destroy(c)
612
+ ```
613
+
614
+ *Result:* (not used)
615
+
616
+ *Effects:* Destroys the object at `c`.
617
+
618
+ *Remarks:* Default: `destroy_at(c)`
619
+
620
+ ``` cpp
621
+ a.select_on_container_copy_construction()
622
+ ```
623
+
624
+ *Result:* `X`
625
+
626
+ *Returns:* Typically returns either `a` or `X()`.
627
+
628
+ *Remarks:* Default: `return a;`
629
+
630
+ ``` cpp
631
+ typename X::propagate_on_container_copy_assignment
632
+ ```
633
+
634
+ *Result:* Identical to or derived from `true_type` or `false_type`.
635
+
636
+ *Returns:* `true_type` only if an allocator of type `X` should be copied
637
+ when the client container is copy-assigned; if so, `X` shall meet the
638
+ *Cpp17CopyAssignable* requirements ([[cpp17.copyassignable]]) and the
639
+ copy operation shall not throw exceptions.
640
+
641
+ *Remarks:* Default: `false_type`
642
+
643
+ ``` cpp
644
+ typename X::propagate_on_container_move_assignment
645
+ ```
646
+
647
+ *Result:* Identical to or derived from `true_type` or `false_type`.
648
+
649
+ *Returns:* `true_type` only if an allocator of type `X` should be moved
650
+ when the client container is move-assigned; if so, `X` shall meet the
651
+ *Cpp17MoveAssignable* requirements ([[cpp17.moveassignable]]) and the
652
+ move operation shall not throw exceptions.
653
+
654
+ *Remarks:* Default: `false_type`
655
+
656
+ ``` cpp
657
+ typename X::propagate_on_container_swap
658
+ ```
659
+
660
+ *Result:* Identical to or derived from `true_type` or `false_type`.
661
+
662
+ *Returns:* `true_type` only if an allocator of type `X` should be
663
+ swapped when the client container is swapped; if so, `X` shall meet the
664
+ *Cpp17Swappable* requirements [[swappable.requirements]] and the `swap`
665
+ operation shall not throw exceptions.
666
+
667
+ *Remarks:* Default: `false_type`
668
+
669
+ ``` cpp
670
+ typename X::is_always_equal
671
+ ```
672
+
673
+ *Result:* Identical to or derived from `true_type` or `false_type`.
674
+
675
+ *Returns:* `true_type` only if the expression `a1 == a2` is guaranteed
676
+ to be `true` for any two (possibly const) values `a1`, `a2` of type `X`.
677
+
678
+ *Remarks:* Default: `is_empty<X>::type`
679
 
680
  An allocator type `X` shall meet the *Cpp17CopyConstructible*
681
+ requirements ([[cpp17.copyconstructible]]). The `XX::pointer`,
682
+ `XX::const_pointer`, `XX::void_pointer`, and `XX::const_void_pointer`
683
+ types shall meet the *Cpp17NullablePointer* requirements (
684
+ [[cpp17.nullablepointer]]). No constructor, comparison operator
685
+ function, copy operation, move operation, or swap operation on these
686
+ pointer types shall exit via an exception. `XX::pointer` and
687
+ `XX::const_pointer` shall also meet the requirements for a
688
+ *Cpp17RandomAccessIterator* [[random.access.iterators]] and the
689
+ additional requirement that, when `p` and `(p + n)` are dereferenceable
690
+ pointer values for some integral value `n`,
691
 
692
  ``` cpp
693
+ addressof(*(p + n)) == addressof(*p) + n
694
  ```
695
 
696
  is `true`.
697
 
698
  Let `x1` and `x2` denote objects of (possibly different) types
699
+ `XX::void_pointer`, `XX::const_void_pointer`, `XX::pointer`, or
700
+ `XX::const_pointer`. Then, `x1` and `x2` are *equivalently-valued*
701
  pointer values, if and only if both `x1` and `x2` can be explicitly
702
  converted to the two corresponding objects `px1` and `px2` of type
703
+ `XX::const_pointer`, using a sequence of `static_cast`s using only these
704
  four types, and the expression `px1 == px2` evaluates to `true`.
705
 
706
+ Let `w1` and `w2` denote objects of type `XX::void_pointer`. Then for
707
+ the expressions
708
 
709
  ``` cpp
710
  w1 == w2
711
  w1 != w2
712
  ```
713
 
714
  either or both objects may be replaced by an equivalently-valued object
715
+ of type `XX::const_void_pointer` with no change in semantics.
716
 
717
+ Let `p1` and `p2` denote objects of type `XX::pointer`. Then for the
718
  expressions
719
 
720
  ``` cpp
721
  p1 == p2
722
  p1 != p2
 
726
  p1 > p2
727
  p1 - p2
728
  ```
729
 
730
  either or both objects may be replaced by an equivalently-valued object
731
+ of type `XX::const_pointer` with no change in semantics.
732
 
733
  An allocator may constrain the types on which it can be instantiated and
734
  the arguments for which its `construct` or `destroy` members may be
735
  called. If a type cannot be used with a particular allocator, the
736
  allocator class or the call to `construct` or `destroy` may fail to
 
739
  If the alignment associated with a specific over-aligned type is not
740
  supported by an allocator, instantiation of the allocator for that type
741
  may fail. The allocator also may silently ignore the requested
742
  alignment.
743
 
744
+ [*Note 2*: Additionally, the member function `allocate` for that type
745
+ can fail by throwing an object of type `bad_alloc`. — *end note*]
746
 
747
  [*Example 1*:
748
 
749
  The following is an allocator class template supporting the minimal
750
+ interface that meets the requirements of
751
+ [[allocator.requirements.general]]:
752
 
753
  ``` cpp
754
+ template<class T>
755
  struct SimpleAllocator {
756
+ using value_type = T;
757
  SimpleAllocator(ctor args);
758
 
759
+ template<class U> SimpleAllocator(const SimpleAllocator<U>& other);
760
 
761
+ T* allocate(std::size_t n);
762
+ void deallocate(T* p, std::size_t n);
763
+
764
+ template<class U> bool operator==(const SimpleAllocator<U>& rhs) const;
765
  };
 
 
 
 
 
766
  ```
767
 
768
  — *end example*]
769
 
770
  ##### Allocator completeness requirements <a id="allocator.requirements.completeness">[[allocator.requirements.completeness]]</a>