From Jason Turner

[allocator.requirements]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpal19vx0g/{from.md → to.md} +435 -67
tmp/tmpal19vx0g/{from.md → to.md} RENAMED
@@ -1,97 +1,467 @@
1
  #### *Cpp17Allocator* requirements <a id="allocator.requirements">[[allocator.requirements]]</a>
2
 
 
 
3
  The library describes a standard set of requirements for *allocators*,
4
  which are class-type objects that encapsulate the information about an
5
  allocation model. This information includes the knowledge of pointer
6
  types, the type of their difference, the type of the size of objects in
7
  this allocation model, as well as the memory allocation and deallocation
8
  primitives for it. All of the string types [[strings]], containers
9
  [[containers]] (except `array`), string buffers and string streams
10
  [[input.output]], and `match_results` [[re]] are parameterized in terms
11
  of allocators.
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  The class template `allocator_traits` [[allocator.traits]] supplies a
14
- uniform interface to all allocator types. [[allocator.req.var]]
15
- describes the types manipulated through allocators. [[cpp17.allocator]]
16
- describes the requirements on allocator types and thus on types used to
17
- instantiate `allocator_traits`. A requirement is optional if the last
18
- column of [[cpp17.allocator]] specifies a default for a given
19
- expression. Within the standard library `allocator_traits` template, an
20
- optional requirement that is not supplied by an allocator is replaced by
21
- the specified default expression. A user specialization of
22
- `allocator_traits` may provide different defaults and may provide
23
- defaults for different requirements than the primary template. Within
24
- Tables  [[tab:allocator.req.var]] and  [[tab:cpp17.allocator]], the use
25
- of `move` and `forward` always refers to `std::move` and `std::forward`,
26
- respectively.
27
-
28
- [*Note 1*: If `n == 0`, the return value is unspecified. — *end note*]
29
-
30
- Note A: The member class template `rebind` in the table above is
31
- effectively a typedef template.
32
-
33
- [*Note 2*: In general, if the name `Allocator` is bound to
34
- `SomeAllocator<T>`, then `Allocator::rebind<U>::other` is the same type
35
- as `SomeAllocator<U>`, where `SomeAllocator<T>::value_type` is `T` and
36
- `SomeAllocator<U>::{}value_type` is `U`. — *end note*]
37
-
38
- If `Allocator` is a class template instantiation of the form
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  `SomeAllocator<T, Args>`, where `Args` is zero or more type arguments,
40
  and `Allocator` does not supply a `rebind` member template, the standard
41
  `allocator_traits` template uses `SomeAllocator<U, Args>` in place of
42
- `Allocator::{}rebind<U>::other` by default. For allocator types that are
43
  not template instantiations of the above form, no default is provided.
44
 
45
- Note B: If `X::propagate_on_container_copy_assignment::value` is `true`,
46
- `X` shall meet the *Cpp17CopyAssignable* requirements (
47
- [[cpp17.copyassignable]]) and the copy operation shall not throw
48
- exceptions. If `X::propagate_on_container_move_assignment::value` is
49
- `true`, `X` shall meet the *Cpp17MoveAssignable* requirements (
50
- [[cpp17.moveassignable]]) and the move operation shall not throw
51
- exceptions. If `X::propagate_on_container_swap::value` is `true`,
52
- lvalues of type `X` shall be swappable [[swappable.requirements]] and
53
- the `swap` operation shall not throw exceptions.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  An allocator type `X` shall meet the *Cpp17CopyConstructible*
56
- requirements ([[cpp17.copyconstructible]]). The `X::pointer`,
57
- `X::const_pointer`, `X::void_pointer`, and `X::const_void_pointer` types
58
- shall meet the *Cpp17NullablePointer* requirements (
59
- [[cpp17.nullablepointer]]). No constructor, comparison function, copy
60
- operation, move operation, or swap operation on these pointer types
61
- shall exit via an exception. `X::pointer` and `X::const_pointer` shall
62
- also meet the requirements for a *Cpp17RandomAccessIterator*
63
- [[random.access.iterators]] and the additional requirement that, when
64
- `a` and `(a + n)` are dereferenceable pointer values for some integral
65
- value `n`,
66
 
67
  ``` cpp
68
- addressof(*(a + n)) == addressof(*a) + n
69
  ```
70
 
71
  is `true`.
72
 
73
  Let `x1` and `x2` denote objects of (possibly different) types
74
- `X::void_pointer`, `X::const_void_pointer`, `X::pointer`, or
75
- `X::const_pointer`. Then, `x1` and `x2` are *equivalently-valued*
76
  pointer values, if and only if both `x1` and `x2` can be explicitly
77
  converted to the two corresponding objects `px1` and `px2` of type
78
- `X::const_pointer`, using a sequence of `static_cast`s using only these
79
  four types, and the expression `px1 == px2` evaluates to `true`.
80
 
81
- Let `w1` and `w2` denote objects of type `X::void_pointer`. Then for the
82
- expressions
83
 
84
  ``` cpp
85
  w1 == w2
86
  w1 != w2
87
  ```
88
 
89
  either or both objects may be replaced by an equivalently-valued object
90
- of type `X::const_void_pointer` with no change in semantics.
91
 
92
- Let `p1` and `p2` denote objects of type `X::pointer`. Then for the
93
  expressions
94
 
95
  ``` cpp
96
  p1 == p2
97
  p1 != p2
@@ -101,11 +471,11 @@ p1 >= p2
101
  p1 > p2
102
  p1 - p2
103
  ```
104
 
105
  either or both objects may be replaced by an equivalently-valued object
106
- of type `X::const_pointer` with no change in semantics.
107
 
108
  An allocator may constrain the types on which it can be instantiated and
109
  the arguments for which its `construct` or `destroy` members may be
110
  called. If a type cannot be used with a particular allocator, the
111
  allocator class or the call to `construct` or `destroy` may fail to
@@ -114,34 +484,32 @@ instantiate.
114
  If the alignment associated with a specific over-aligned type is not
115
  supported by an allocator, instantiation of the allocator for that type
116
  may fail. The allocator also may silently ignore the requested
117
  alignment.
118
 
119
- [*Note 3*: Additionally, the member function `allocate` for that type
120
- may fail by throwing an object of type `bad_alloc`. — *end note*]
121
 
122
  [*Example 1*:
123
 
124
  The following is an allocator class template supporting the minimal
125
- interface that meets the requirements of [[cpp17.allocator]]:
 
126
 
127
  ``` cpp
128
- template<class Tp>
129
  struct SimpleAllocator {
130
- typedef Tp value_type;
131
  SimpleAllocator(ctor args);
132
 
133
- template<class T> SimpleAllocator(const SimpleAllocator<T>& other);
134
 
135
- [[nodiscard]] Tp* allocate(std::size_t n);
136
- void deallocate(Tp* p, std::size_t n);
 
 
137
  };
138
-
139
- template<class T, class U>
140
- bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
141
- template<class T, class U>
142
- bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
143
  ```
144
 
145
  — *end example*]
146
 
147
  ##### Allocator completeness requirements <a id="allocator.requirements.completeness">[[allocator.requirements.completeness]]</a>
 
1
  #### *Cpp17Allocator* requirements <a id="allocator.requirements">[[allocator.requirements]]</a>
2
 
3
+ ##### General <a id="allocator.requirements.general">[[allocator.requirements.general]]</a>
4
+
5
  The library describes a standard set of requirements for *allocators*,
6
  which are class-type objects that encapsulate the information about an
7
  allocation model. This information includes the knowledge of pointer
8
  types, the type of their difference, the type of the size of objects in
9
  this allocation model, as well as the memory allocation and deallocation
10
  primitives for it. All of the string types [[strings]], containers
11
  [[containers]] (except `array`), string buffers and string streams
12
  [[input.output]], and `match_results` [[re]] are parameterized in terms
13
  of allocators.
14
 
15
+ In subclause [[allocator.requirements]],
16
+
17
+ - `T`, `U`, `C` denote any cv-unqualified object type
18
+ [[term.object.type]],
19
+ - `X` denotes an allocator class for type `T`,
20
+ - `Y` denotes the corresponding allocator class for type `U`,
21
+ - `XX` denotes the type `allocator_traits<X>`,
22
+ - `YY` denotes the type `allocator_traits<Y>`,
23
+ - `a`, `a1`, `a2` denote lvalues of type `X`,
24
+ - `u` denotes the name of a variable being declared,
25
+ - `b` denotes a value of type `Y`,
26
+ - `c` denotes a pointer of type `C*` through which indirection is valid,
27
+ - `p` denotes a value of type `XX::pointer` obtained by calling
28
+ `a1.allocate`, where `a1 == a`,
29
+ - `q` denotes a value of type `XX::const_pointer` obtained by conversion
30
+ from a value `p`,
31
+ - `r` denotes a value of type `T&` obtained by the expression `*p`,
32
+ - `w` denotes a value of type `XX::void_pointer` obtained by conversion
33
+ from a value `p`,
34
+ - `x` denotes a value of type `XX::const_void_pointer` obtained by
35
+ conversion from a value `q` or a value `w`,
36
+ - `y` denotes a value of type `XX::const_void_pointer` obtained by
37
+ conversion from a result value of `YY::allocate`, or else a value of
38
+ type (possibly const) `std::nullptr_t`,
39
+ - `n` denotes a value of type `XX::size_type`,
40
+ - `Args` denotes a template parameter pack, and
41
+ - `args` denotes a function parameter pack with the pattern `Args&&`.
42
+
43
  The class template `allocator_traits` [[allocator.traits]] supplies a
44
+ uniform interface to all allocator types. This subclause describes the
45
+ requirements on allocator types and thus on types used to instantiate
46
+ `allocator_traits`. A requirement is optional if a default for a given
47
+ type or expression is specified. Within the standard library
48
+ `allocator_traits` template, an optional requirement that is not
49
+ supplied by an allocator is replaced by the specified default type or
50
+ expression.
51
+
52
+ [*Note 1*: There are no program-defined specializations of
53
+ `allocator_traits`. *end note*]
54
+
55
+ ``` cpp
56
+ typename X::pointer
57
+ ```
58
+
59
+ *Remarks:* Default: `T*`
60
+
61
+ ``` cpp
62
+ typename X::const_pointer
63
+ ```
64
+
65
+ *Mandates:* `XX::pointer` is convertible to `XX::const_pointer`.
66
+
67
+ *Remarks:* Default: `pointer_traits<XX::pointer>::rebind<const T>`
68
+
69
+ ``` cpp
70
+ typename X::void_pointer
71
+ typename Y::void_pointer
72
+ ```
73
+
74
+ *Mandates:* `XX::pointer` is convertible to `XX::void_pointer`.
75
+ `XX::void_pointer` and `YY::void_pointer` are the same type.
76
+
77
+ *Remarks:* Default: `pointer_traits<XX::pointer>::rebind<void>`
78
+
79
+ ``` cpp
80
+ typename X::const_void_pointer
81
+ typename Y::const_void_pointer
82
+ ```
83
+
84
+ *Mandates:* `XX::pointer`, `XX::const_pointer`, and `XX::void_pointer`
85
+ are convertible to `XX::const_void_pointer`. `XX::const_void_pointer`
86
+ and `YY::const_void_pointer` are the same type.
87
+
88
+ *Remarks:* Default: `pointer_traits<XX::pointer>::rebind<const void>`
89
+
90
+ ``` cpp
91
+ typename X::value_type
92
+ ```
93
+
94
+ *Result:* Identical to `T`.
95
+
96
+ ``` cpp
97
+ typename X::size_type
98
+ ```
99
+
100
+ *Result:* An unsigned integer type that can represent the size of the
101
+ largest object in the allocation model.
102
+
103
+ *Remarks:* Default: `make_unsigned_t<XX::difference_type>`
104
+
105
+ ``` cpp
106
+ typename X::difference_type
107
+ ```
108
+
109
+ *Result:* A signed integer type that can represent the difference
110
+ between any two pointers in the allocation model.
111
+
112
+ *Remarks:* Default: `pointer_traits<XX::pointer>::difference_type`
113
+
114
+ ``` cpp
115
+ typename X::template rebind<U>::other
116
+ ```
117
+
118
+ *Result:* `Y`
119
+
120
+ *Ensures:* For all `U` (including `T`), `YY::rebind_alloc<T>` is `X`.
121
+
122
+ *Remarks:* If `Allocator` is a class template instantiation of the form
123
  `SomeAllocator<T, Args>`, where `Args` is zero or more type arguments,
124
  and `Allocator` does not supply a `rebind` member template, the standard
125
  `allocator_traits` template uses `SomeAllocator<U, Args>` in place of
126
+ `Allocator::rebind<U>::other` by default. For allocator types that are
127
  not template instantiations of the above form, no default is provided.
128
 
129
+ [*Note 1*: The member class template `rebind` of `X` is effectively a
130
+ typedef template. In general, if the name `Allocator` is bound to
131
+ `SomeAllocator<T>`, then `Allocator::rebind<U>::other` is the same type
132
+ as `SomeAllocator<U>`, where `SomeAllocator<T>::value_type` is `T` and
133
+ `SomeAllocator<U>::value_type` is `U`. *end note*]
134
+
135
+ ``` cpp
136
+ *p
137
+ ```
138
+
139
+ *Result:* `T&`
140
+
141
+ ``` cpp
142
+ *q
143
+ ```
144
+
145
+ *Result:* `const T&`
146
+
147
+ *Ensures:* `*q` refers to the same object as `*p`.
148
+
149
+ ``` cpp
150
+ p->m
151
+ ```
152
+
153
+ *Result:* Type of `T::m`.
154
+
155
+ *Preconditions:* `(*p).m` is well-defined.
156
+
157
+ *Effects:* Equivalent to `(*p).m`.
158
+
159
+ ``` cpp
160
+ q->m
161
+ ```
162
+
163
+ *Result:* Type of `T::m`.
164
+
165
+ *Preconditions:* `(*q).m` is well-defined.
166
+
167
+ *Effects:* Equivalent to `(*q).m`.
168
+
169
+ ``` cpp
170
+ static_cast<XX::pointer>(w)
171
+ ```
172
+
173
+ *Result:* `XX::pointer`
174
+
175
+ *Ensures:* `static_cast<XX::pointer>(w) == p`.
176
+
177
+ ``` cpp
178
+ static_cast<XX::const_pointer>(x)
179
+ ```
180
+
181
+ *Result:* `XX::const_pointer`
182
+
183
+ *Ensures:* `static_cast<XX::const_pointer>(x) == q`.
184
+
185
+ ``` cpp
186
+ pointer_traits<XX::pointer>::pointer_to(r)
187
+ ```
188
+
189
+ *Result:* `XX::pointer`
190
+
191
+ *Ensures:* Same as `p`.
192
+
193
+ ``` cpp
194
+ a.allocate(n)
195
+ ```
196
+
197
+ *Result:* `XX::pointer`
198
+
199
+ *Effects:* Memory is allocated for an array of `n` `T` and such an
200
+ object is created but array elements are not constructed.
201
+
202
+ [*Example 1*: When reusing storage denoted by some pointer value `p`,
203
+ `launder(reinterpret_cast<T*>(new (p) byte[n * sizeof(T)]))` can be used
204
+ to implicitly create a suitable array object and obtain a pointer to
205
+ it. — *end example*]
206
+
207
+ *Throws:* `allocate` may throw an appropriate exception.
208
+
209
+ [*Note 2*: It is intended that `a.allocate` be an efficient means of
210
+ allocating a single object of type `T`, even when `sizeof(T)` is small.
211
+ That is, there is no need for a container to maintain its own free
212
+ list. — *end note*]
213
+
214
+ *Remarks:* If `n == 0`, the return value is unspecified.
215
+
216
+ ``` cpp
217
+ a.allocate(n, y)
218
+ ```
219
+
220
+ *Result:* `XX::pointer`
221
+
222
+ *Effects:* Same as `a.allocate(n)`. The use of `y` is unspecified, but
223
+ it is intended as an aid to locality.
224
+
225
+ *Remarks:* Default: `a.allocate(n)`
226
+
227
+ ``` cpp
228
+ a.allocate_at_least(n)
229
+ ```
230
+
231
+ *Result:* `allocation_result<XX::pointer, XX::size_type>`
232
+
233
+ *Returns:* `allocation_result<XX::pointer, XX::size_type>{ptr, count}`
234
+ where `ptr` is memory allocated for an array of `count` `T` and such an
235
+ object is created but array elements are not constructed, such that
236
+ `count` ≥ `n`. If `n == 0`, the return value is unspecified.
237
+
238
+ *Throws:* `allocate_at_least` may throw an appropriate exception.
239
+
240
+ *Remarks:* Default: `{a.allocate(n), n}`.
241
+
242
+ ``` cpp
243
+ a.deallocate(p, n)
244
+ ```
245
+
246
+ *Result:* (not used)
247
+
248
+ *Preconditions:*
249
+
250
+ - If `p` is memory that was obtained by a call to `a.allocate_at_least`,
251
+ let `ret` be the value returned and `req` be the value passed as the
252
+ first argument of that call. `p` is equal to `ret.ptr` and `n` is a
253
+ value such that `req` ≤ `n` ≤ `ret.count`.
254
+ - Otherwise, `p` is a pointer value obtained from `allocate`. `n` equals
255
+ the value passed as the first argument to the invocation of `allocate`
256
+ which returned `p`.
257
+
258
+ `p` has not been invalidated by an intervening call to `deallocate`.
259
+
260
+ *Throws:* Nothing.
261
+
262
+ ``` cpp
263
+ a.max_size()
264
+ ```
265
+
266
+ *Result:* `XX::size_type`
267
+
268
+ *Returns:* The largest value `n` that can meaningfully be passed to
269
+ `a.allocate(n)`.
270
+
271
+ *Remarks:* Default:
272
+ `numeric_limits<size_type>::max() / sizeof(value_type)`
273
+
274
+ ``` cpp
275
+ a1 == a2
276
+ ```
277
+
278
+ *Result:* `bool`
279
+
280
+ *Returns:* `true` only if storage allocated from each can be deallocated
281
+ via the other.
282
+
283
+ *Throws:* Nothing.
284
+
285
+ *Remarks:* `operator==` shall be reflexive, symmetric, and transitive.
286
+
287
+ ``` cpp
288
+ a1 != a2
289
+ ```
290
+
291
+ *Result:* `bool`
292
+
293
+ *Returns:* `!(a1 == a2)`.
294
+
295
+ ``` cpp
296
+ a == b
297
+ ```
298
+
299
+ *Result:* `bool`
300
+
301
+ *Returns:* `a == YY::rebind_alloc<T>(b)`.
302
+
303
+ ``` cpp
304
+ a != b
305
+ ```
306
+
307
+ *Result:* `bool`
308
+
309
+ *Returns:* `!(a == b)`.
310
+
311
+ ``` cpp
312
+ X u(a);
313
+ X u = a;
314
+ ```
315
+
316
+ *Ensures:* `u == a`
317
+
318
+ *Throws:* Nothing.
319
+
320
+ ``` cpp
321
+ X u(b);
322
+ ```
323
+
324
+ *Ensures:* `Y(u) == b` and `u == X(b)`.
325
+
326
+ *Throws:* Nothing.
327
+
328
+ ``` cpp
329
+ X u(std::move(a));
330
+ X u = std::move(a);
331
+ ```
332
+
333
+ *Ensures:* The value of `a` is unchanged and is equal to `u`.
334
+
335
+ *Throws:* Nothing.
336
+
337
+ ``` cpp
338
+ X u(std::move(b));
339
+ ```
340
+
341
+ *Ensures:* `u` is equal to the prior value of `X(b)`.
342
+
343
+ *Throws:* Nothing.
344
+
345
+ ``` cpp
346
+ a.construct(c, args)
347
+ ```
348
+
349
+ *Result:* (not used)
350
+
351
+ *Effects:* Constructs an object of type `C` at `c`.
352
+
353
+ *Remarks:* Default: `construct_at(c, std::forward<Args>(args)...)`
354
+
355
+ ``` cpp
356
+ a.destroy(c)
357
+ ```
358
+
359
+ *Result:* (not used)
360
+
361
+ *Effects:* Destroys the object at `c`.
362
+
363
+ *Remarks:* Default: `destroy_at(c)`
364
+
365
+ ``` cpp
366
+ a.select_on_container_copy_construction()
367
+ ```
368
+
369
+ *Result:* `X`
370
+
371
+ *Returns:* Typically returns either `a` or `X()`.
372
+
373
+ *Remarks:* Default: `return a;`
374
+
375
+ ``` cpp
376
+ typename X::propagate_on_container_copy_assignment
377
+ ```
378
+
379
+ *Result:* Identical to or derived from `true_type` or `false_type`.
380
+
381
+ *Returns:* `true_type` only if an allocator of type `X` should be copied
382
+ when the client container is copy-assigned; if so, `X` shall meet the
383
+ *Cpp17CopyAssignable* requirements ([[cpp17.copyassignable]]) and the
384
+ copy operation shall not throw exceptions.
385
+
386
+ *Remarks:* Default: `false_type`
387
+
388
+ ``` cpp
389
+ typename X::propagate_on_container_move_assignment
390
+ ```
391
+
392
+ *Result:* Identical to or derived from `true_type` or `false_type`.
393
+
394
+ *Returns:* `true_type` only if an allocator of type `X` should be moved
395
+ when the client container is move-assigned; if so, `X` shall meet the
396
+ *Cpp17MoveAssignable* requirements ([[cpp17.moveassignable]]) and the
397
+ move operation shall not throw exceptions.
398
+
399
+ *Remarks:* Default: `false_type`
400
+
401
+ ``` cpp
402
+ typename X::propagate_on_container_swap
403
+ ```
404
+
405
+ *Result:* Identical to or derived from `true_type` or `false_type`.
406
+
407
+ *Returns:* `true_type` only if an allocator of type `X` should be
408
+ swapped when the client container is swapped; if so, `X` shall meet the
409
+ *Cpp17Swappable* requirements [[swappable.requirements]] and the `swap`
410
+ operation shall not throw exceptions.
411
+
412
+ *Remarks:* Default: `false_type`
413
+
414
+ ``` cpp
415
+ typename X::is_always_equal
416
+ ```
417
+
418
+ *Result:* Identical to or derived from `true_type` or `false_type`.
419
+
420
+ *Returns:* `true_type` only if the expression `a1 == a2` is guaranteed
421
+ to be `true` for any two (possibly const) values `a1`, `a2` of type `X`.
422
+
423
+ *Remarks:* Default: `is_empty<X>::type`
424
 
425
  An allocator type `X` shall meet the *Cpp17CopyConstructible*
426
+ requirements ([[cpp17.copyconstructible]]). The `XX::pointer`,
427
+ `XX::const_pointer`, `XX::void_pointer`, and `XX::const_void_pointer`
428
+ types shall meet the *Cpp17NullablePointer* requirements (
429
+ [[cpp17.nullablepointer]]). No constructor, comparison operator
430
+ function, copy operation, move operation, or swap operation on these
431
+ pointer types shall exit via an exception. `XX::pointer` and
432
+ `XX::const_pointer` shall also meet the requirements for a
433
+ *Cpp17RandomAccessIterator* [[random.access.iterators]] and the
434
+ additional requirement that, when `p` and `(p + n)` are dereferenceable
435
+ pointer values for some integral value `n`,
436
 
437
  ``` cpp
438
+ addressof(*(p + n)) == addressof(*p) + n
439
  ```
440
 
441
  is `true`.
442
 
443
  Let `x1` and `x2` denote objects of (possibly different) types
444
+ `XX::void_pointer`, `XX::const_void_pointer`, `XX::pointer`, or
445
+ `XX::const_pointer`. Then, `x1` and `x2` are *equivalently-valued*
446
  pointer values, if and only if both `x1` and `x2` can be explicitly
447
  converted to the two corresponding objects `px1` and `px2` of type
448
+ `XX::const_pointer`, using a sequence of `static_cast`s using only these
449
  four types, and the expression `px1 == px2` evaluates to `true`.
450
 
451
+ Let `w1` and `w2` denote objects of type `XX::void_pointer`. Then for
452
+ the expressions
453
 
454
  ``` cpp
455
  w1 == w2
456
  w1 != w2
457
  ```
458
 
459
  either or both objects may be replaced by an equivalently-valued object
460
+ of type `XX::const_void_pointer` with no change in semantics.
461
 
462
+ Let `p1` and `p2` denote objects of type `XX::pointer`. Then for the
463
  expressions
464
 
465
  ``` cpp
466
  p1 == p2
467
  p1 != p2
 
471
  p1 > p2
472
  p1 - p2
473
  ```
474
 
475
  either or both objects may be replaced by an equivalently-valued object
476
+ of type `XX::const_pointer` with no change in semantics.
477
 
478
  An allocator may constrain the types on which it can be instantiated and
479
  the arguments for which its `construct` or `destroy` members may be
480
  called. If a type cannot be used with a particular allocator, the
481
  allocator class or the call to `construct` or `destroy` may fail to
 
484
  If the alignment associated with a specific over-aligned type is not
485
  supported by an allocator, instantiation of the allocator for that type
486
  may fail. The allocator also may silently ignore the requested
487
  alignment.
488
 
489
+ [*Note 2*: Additionally, the member function `allocate` for that type
490
+ can fail by throwing an object of type `bad_alloc`. — *end note*]
491
 
492
  [*Example 1*:
493
 
494
  The following is an allocator class template supporting the minimal
495
+ interface that meets the requirements of
496
+ [[allocator.requirements.general]]:
497
 
498
  ``` cpp
499
+ template<class T>
500
  struct SimpleAllocator {
501
+ using value_type = T;
502
  SimpleAllocator(ctor args);
503
 
504
+ template<class U> SimpleAllocator(const SimpleAllocator<U>& other);
505
 
506
+ T* allocate(std::size_t n);
507
+ void deallocate(T* p, std::size_t n);
508
+
509
+ template<class U> bool operator==(const SimpleAllocator<U>& rhs) const;
510
  };
 
 
 
 
 
511
  ```
512
 
513
  — *end example*]
514
 
515
  ##### Allocator completeness requirements <a id="allocator.requirements.completeness">[[allocator.requirements.completeness]]</a>