From Jason Turner

[memory]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpbhtmk4qq/{from.md → to.md} +690 -517
tmp/tmpbhtmk4qq/{from.md → to.md} RENAMED
@@ -1,245 +1,453 @@
1
  ## Memory <a id="memory">[[memory]]</a>
2
 
3
  ### In general <a id="memory.general">[[memory.general]]</a>
4
 
5
- This subclause describes the contents of the header `<memory>` (
6
- [[memory.syn]]) and some of the contents of the header `<cstdlib>` (
7
- [[cstdlib.syn]]).
8
 
9
  ### Header `<memory>` synopsis <a id="memory.syn">[[memory.syn]]</a>
10
 
11
  The header `<memory>` defines several types and function templates that
12
  describe properties of pointers and pointer-like types, manage memory
13
  for containers and other template types, destroy objects, and construct
14
- multiple objects in uninitialized memory buffers ([[pointer.traits]]–
15
- [[specialized.algorithms]]). The header also defines the templates
16
- `unique_ptr`, `shared_ptr`, `weak_ptr`, and various function templates
17
- that operate on objects of these types ([[smartptr]]).
 
18
 
19
  ``` cpp
 
 
20
  namespace std {
21
  // [pointer.traits], pointer traits
22
  template<class Ptr> struct pointer_traits;
23
  template<class T> struct pointer_traits<T*>;
24
 
25
- // [util.dynamic.safety], pointer safety
 
 
 
 
 
 
 
 
26
  enum class pointer_safety { relaxed, preferred, strict };
27
  void declare_reachable(void* p);
28
- template <class T> T* undeclare_reachable(T* p);
 
29
  void declare_no_pointers(char* p, size_t n);
30
  void undeclare_no_pointers(char* p, size_t n);
31
  pointer_safety get_pointer_safety() noexcept;
32
 
33
- // [ptr.align], pointer alignment function
34
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 
 
35
 
36
  // [allocator.tag], allocator argument tag
37
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
38
  inline constexpr allocator_arg_t allocator_arg{};
39
 
40
  // [allocator.uses], uses_allocator
41
  template<class T, class Alloc> struct uses_allocator;
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  // [allocator.traits], allocator traits
44
  template<class Alloc> struct allocator_traits;
45
 
46
  // [default.allocator], the default allocator
47
  template<class T> class allocator;
48
  template<class T, class U>
49
- bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
50
- template <class T, class U>
51
- bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
 
 
 
 
52
 
53
  // [specialized.algorithms], specialized algorithms
54
- template <class T> constexpr T* addressof(T& r) noexcept;
55
- template <class T> const T* addressof(const T&&) = delete;
56
- template <class ForwardIterator>
57
- void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
58
- template <class ExecutionPolicy, class ForwardIterator>
 
 
 
 
 
 
 
 
 
 
 
59
  void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
60
- ForwardIterator first, ForwardIterator last);
61
- template <class ForwardIterator, class Size>
62
- ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
63
- template <class ExecutionPolicy, class ForwardIterator, class Size>
64
- ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
65
- ForwardIterator first, Size n);
66
- template <class ForwardIterator>
67
- void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
68
- template <class ExecutionPolicy, class ForwardIterator>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
70
- ForwardIterator first, ForwardIterator last);
71
- template <class ForwardIterator, class Size>
72
- ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
73
- template <class ExecutionPolicy, class ForwardIterator, class Size>
74
- ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
75
- ForwardIterator first, Size n);
76
- template <class InputIterator, class ForwardIterator>
77
- ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
78
- ForwardIterator result);
79
- template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
80
- ForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  InputIterator first, InputIterator last,
82
- ForwardIterator result);
83
- template <class InputIterator, class Size, class ForwardIterator>
84
- ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
85
- ForwardIterator result);
86
- template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
87
- ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
88
  InputIterator first, Size n,
89
- ForwardIterator result);
90
- template <class InputIterator, class ForwardIterator>
91
- ForwardIterator uninitialized_move(InputIterator first, InputIterator last,
92
- ForwardIterator result);
93
- template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
94
- ForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  InputIterator first, InputIterator last,
96
- ForwardIterator result);
97
- template <class InputIterator, class Size, class ForwardIterator>
98
- pair<InputIterator, ForwardIterator>
99
- uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
100
- template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
101
- pair<InputIterator, ForwardIterator>
102
  uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
103
- InputIterator first, Size n, ForwardIterator result);
104
- template <class ForwardIterator, class T>
105
- void uninitialized_fill(ForwardIterator first, ForwardIterator last,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  const T& x);
107
- template <class ExecutionPolicy, class ForwardIterator, class T>
108
  void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
109
- ForwardIterator first, ForwardIterator last,
110
  const T& x);
111
- template <class ForwardIterator, class Size, class T>
112
- ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
113
- template <class ExecutionPolicy, class ForwardIterator, class Size, class T>
114
- ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
115
- ForwardIterator first, Size n, const T& x);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  template<class T>
117
- void destroy_at(T* location);
118
- template <class ForwardIterator>
119
- void destroy(ForwardIterator first, ForwardIterator last);
120
- template <class ExecutionPolicy, class ForwardIterator>
121
  void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
122
- ForwardIterator first, ForwardIterator last);
123
- template <class ForwardIterator, class Size>
124
- ForwardIterator destroy_n(ForwardIterator first, Size n);
125
- template <class ExecutionPolicy, class ForwardIterator, class Size>
126
- ForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
127
- ForwardIterator first, Size n);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
  // [unique.ptr], class template unique_ptr
130
  template<class T> struct default_delete;
131
  template<class T> struct default_delete<T[]>;
132
  template<class T, class D = default_delete<T>> class unique_ptr;
133
  template<class T, class D> class unique_ptr<T[], D>;
134
 
135
- template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
136
- template <class T> unique_ptr<T> make_unique(size_t n);
137
- template <class T, class... Args> unspecified make_unique(Args&&...) = delete;
 
 
 
138
 
139
- template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
 
 
 
 
 
 
 
 
140
 
141
  template<class T1, class D1, class T2, class D2>
142
  bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
143
- template <class T1, class D1, class T2, class D2>
144
- bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
145
  template<class T1, class D1, class T2, class D2>
146
  bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
147
- template <class T1, class D1, class T2, class D2>
148
- bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
149
  template<class T1, class D1, class T2, class D2>
150
  bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 
 
151
  template<class T1, class D1, class T2, class D2>
152
  bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 
 
 
 
 
 
153
 
154
  template<class T, class D>
155
  bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
156
- template <class T, class D>
157
- bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
158
- template <class T, class D>
159
- bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
160
- template <class T, class D>
161
- bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
162
  template<class T, class D>
163
  bool operator<(const unique_ptr<T, D>& x, nullptr_t);
164
  template<class T, class D>
165
  bool operator<(nullptr_t, const unique_ptr<T, D>& y);
166
- template <class T, class D>
167
- bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
168
- template <class T, class D>
169
- bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
170
  template<class T, class D>
171
  bool operator>(const unique_ptr<T, D>& x, nullptr_t);
172
  template<class T, class D>
173
  bool operator>(nullptr_t, const unique_ptr<T, D>& y);
 
 
 
 
174
  template<class T, class D>
175
  bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
176
  template<class T, class D>
177
  bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
 
 
 
 
 
 
 
178
 
179
  // [util.smartptr.weak.bad], class bad_weak_ptr
180
  class bad_weak_ptr;
181
 
182
  // [util.smartptr.shared], class template shared_ptr
183
  template<class T> class shared_ptr;
184
 
185
  // [util.smartptr.shared.create], shared_ptr creation
186
  template<class T, class... Args>
187
- shared_ptr<T> make_shared(Args&&... args);
188
  template<class T, class A, class... Args>
189
- shared_ptr<T> allocate_shared(const A& a, Args&&... args);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
 
191
  // [util.smartptr.shared.cmp], shared_ptr comparisons
192
  template<class T, class U>
193
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
194
  template<class T, class U>
195
- bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
196
- template<class T, class U>
197
- bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
198
- template<class T, class U>
199
- bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
200
- template<class T, class U>
201
- bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
202
- template<class T, class U>
203
- bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
204
 
205
  template<class T>
206
  bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
207
  template<class T>
208
- bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
209
- template <class T>
210
- bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
211
- template <class T>
212
- bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
213
- template <class T>
214
- bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
215
- template <class T>
216
- bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
217
- template <class T>
218
- bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
219
- template <class T>
220
- bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
221
- template <class T>
222
- bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
223
- template <class T>
224
- bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
225
- template <class T>
226
- bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
227
- template <class T>
228
- bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
229
 
230
  // [util.smartptr.shared.spec], shared_ptr specialized algorithms
231
  template<class T>
232
  void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
233
 
234
  // [util.smartptr.shared.cast], shared_ptr casts
235
  template<class T, class U>
236
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
 
 
237
  template<class T, class U>
238
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
 
 
239
  template<class T, class U>
240
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
 
 
 
 
 
 
241
 
242
  // [util.smartptr.getdeleter], shared_ptr get_deleter
243
  template<class D, class T>
244
  D* get_deleter(const shared_ptr<T>& p) noexcept;
245
 
@@ -257,52 +465,19 @@ namespace std {
257
  template<class T = void> struct owner_less;
258
 
259
  // [util.smartptr.enab], class template enable_shared_from_this
260
  template<class T> class enable_shared_from_this;
261
 
262
- // [util.smartptr.shared.atomic], shared_ptr atomic access
263
- template<class T>
264
- bool atomic_is_lock_free(const shared_ptr<T>* p);
265
-
266
- template<class T>
267
- shared_ptr<T> atomic_load(const shared_ptr<T>* p);
268
- template<class T>
269
- shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
270
-
271
- template<class T>
272
- void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
273
- template<class T>
274
- void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
275
-
276
- template<class T>
277
- shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
278
- template<class T>
279
- shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
280
-
281
- template<class T>
282
- bool atomic_compare_exchange_weak(
283
- shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
284
- template<class T>
285
- bool atomic_compare_exchange_strong(
286
- shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
287
- template<class T>
288
- bool atomic_compare_exchange_weak_explicit(
289
- shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
290
- memory_order success, memory_order failure);
291
- template<class T>
292
- bool atomic_compare_exchange_strong_explicit(
293
- shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
294
- memory_order success, memory_order failure);
295
-
296
  // [util.smartptr.hash], hash support
297
  template<class T> struct hash;
298
  template<class T, class D> struct hash<unique_ptr<T, D>>;
299
  template<class T> struct hash<shared_ptr<T>>;
300
 
301
- // [allocator.uses.trait], uses_allocator
302
- template <class T, class Alloc>
303
- inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
 
304
  }
305
  ```
306
 
307
  ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
308
 
@@ -326,61 +501,97 @@ namespace std {
326
  using element_type = T;
327
  using difference_type = ptrdiff_t;
328
 
329
  template<class U> using rebind = U*;
330
 
331
- static pointer pointer_to(see below r) noexcept;
332
  };
333
  }
334
  ```
335
 
336
- #### Pointer traits member types <a id="pointer.traits.types">[[pointer.traits.types]]</a>
337
 
338
  ``` cpp
339
  using element_type = see below;
340
  ```
341
 
342
  *Type:* `Ptr::element_type` if the *qualified-id* `Ptr::element_type` is
343
- valid and denotes a type ([[temp.deduct]]); otherwise, `T` if `Ptr` is
344
- a class template instantiation of the form `SomePointer<T, Args>`, where
345
  `Args` is zero or more type arguments; otherwise, the specialization is
346
  ill-formed.
347
 
348
  ``` cpp
349
  using difference_type = see below;
350
  ```
351
 
352
  *Type:* `Ptr::difference_type` if the *qualified-id*
353
- `Ptr::difference_type` is valid and denotes a type ([[temp.deduct]]);
354
  otherwise, `ptrdiff_t`.
355
 
356
  ``` cpp
357
  template<class U> using rebind = see below;
358
  ```
359
 
360
  *Alias template:* `Ptr::rebind<U>` if the *qualified-id*
361
- `Ptr::rebind<U>` is valid and denotes a type ([[temp.deduct]]);
362
- otherwise, `SomePointer<U, Args>` if `Ptr` is a class template
363
- instantiation of the form `SomePointer<T, Args>`, where `Args` is zero
364
- or more type arguments; otherwise, the instantiation of `rebind` is
365
- ill-formed.
366
 
367
- #### Pointer traits member functions <a id="pointer.traits.functions">[[pointer.traits.functions]]</a>
368
 
369
  ``` cpp
370
  static pointer pointer_traits::pointer_to(see below r);
371
- static pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
372
  ```
373
 
 
 
 
 
 
 
 
 
 
374
  *Remarks:* If `element_type` is cv `void`, the type of `r` is
375
  unspecified; otherwise, it is `element_type&`.
376
 
377
- *Returns:* The first member function returns a pointer to `r` obtained
378
- by calling `Ptr::pointer_to(r)` through which indirection is valid; an
379
- instantiation of this function is ill-formed if `Ptr` does not have a
380
- matching `pointer_to` static member function. The second member function
381
- returns `addressof(r)`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
 
383
  ### Pointer safety <a id="util.dynamic.safety">[[util.dynamic.safety]]</a>
384
 
385
  A complete object is *declared reachable* while the number of calls to
386
  `declare_reachable` with an argument referencing the object exceeds the
@@ -389,30 +600,29 @@ the object.
389
 
390
  ``` cpp
391
  void declare_reachable(void* p);
392
  ```
393
 
394
- *Requires:* `p` shall be a safely-derived
395
- pointer ([[basic.stc.dynamic.safety]]) or a null pointer value.
396
 
397
  *Effects:* If `p` is not null, the complete object referenced by `p` is
398
- subsequently declared reachable ([[basic.stc.dynamic.safety]]).
399
 
400
  *Throws:* May throw `bad_alloc` if the system cannot allocate additional
401
  memory that may be required to track objects declared reachable.
402
 
403
  ``` cpp
404
  template<class T> T* undeclare_reachable(T* p);
405
  ```
406
 
407
- *Requires:* If `p` is not null, the complete object referenced by `p`
408
- shall have been previously declared reachable, and shall be
409
- live ([[basic.life]]) from the time of the call until the last
410
- `undeclare_reachable(p)` call on the object.
411
 
412
- *Returns:* A safely derived copy of `p` which shall compare equal to
413
- `p`.
414
 
415
  *Throws:* Nothing.
416
 
417
  [*Note 1*: It is expected that calls to `declare_reachable(p)` will
418
  consume a small amount of memory in addition to that occupied by the
@@ -422,14 +632,14 @@ matched. — *end note*]
422
 
423
  ``` cpp
424
  void declare_no_pointers(char* p, size_t n);
425
  ```
426
 
427
- *Requires:* No bytes in the specified range are currently registered
428
- with `declare_no_pointers()`. If the specified range is in an allocated
429
- object, then it must be entirely within a single allocated object. The
430
- object must be live until the corresponding `undeclare_no_pointers()`
431
  call.
432
 
433
  [*Note 2*: In a garbage-collecting implementation, the fact that a
434
  region in an object is registered with `declare_no_pointers()` should
435
  not prevent the object from being collected. — *end note*]
@@ -450,69 +660,92 @@ fails. — *end note*]
450
 
451
  ``` cpp
452
  void undeclare_no_pointers(char* p, size_t n);
453
  ```
454
 
455
- *Requires:* The same range must previously have been passed to
456
  `declare_no_pointers()`.
457
 
458
  *Effects:* Unregisters a range registered with `declare_no_pointers()`
459
- for destruction. It must be called before the lifetime of the object
460
  ends.
461
 
462
  *Throws:* Nothing.
463
 
464
  ``` cpp
465
  pointer_safety get_pointer_safety() noexcept;
466
  ```
467
 
468
  *Returns:* `pointer_safety::strict` if the implementation has strict
469
- pointer safety ([[basic.stc.dynamic.safety]]). It is
470
  *implementation-defined* whether `get_pointer_safety` returns
471
  `pointer_safety::relaxed` or `pointer_safety::preferred` if the
472
  implementation has relaxed pointer safety.[^1]
473
 
474
- ### Align <a id="ptr.align">[[ptr.align]]</a>
475
 
476
  ``` cpp
477
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
478
  ```
479
 
 
 
 
 
 
 
480
  *Effects:* If it is possible to fit `size` bytes of storage aligned by
481
  `alignment` into the buffer pointed to by `ptr` with length `space`, the
482
  function updates `ptr` to represent the first possible address of such
483
  storage and decreases `space` by the number of bytes used for alignment.
484
  Otherwise, the function does nothing.
485
 
486
- *Requires:*
487
-
488
- - `alignment` shall be a power of two
489
- - `ptr` shall represent the address of contiguous storage of at least
490
- `space` bytes
491
-
492
  *Returns:* A null pointer if the requested aligned buffer would not fit
493
  into the available space, otherwise the adjusted value of `ptr`.
494
 
495
  [*Note 1*: The function updates its `ptr` and `space` arguments so that
496
  it can be called repeatedly with possibly different `alignment` and
497
  `size` arguments for the same buffer. — *end note*]
498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
500
 
501
  ``` cpp
502
  namespace std {
503
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
504
  inline constexpr allocator_arg_t allocator_arg{};
505
  }
506
  ```
507
 
508
- The `allocator_arg_t` struct is an empty structure type used as a unique
509
  type to disambiguate constructor and function overloading. Specifically,
510
  several types (see `tuple`  [[tuple]]) have constructors with
511
  `allocator_arg_t` as the first argument, immediately followed by an
512
- argument of a type that satisfies the `Allocator` requirements (
513
- [[allocator.requirements]]).
514
 
515
  ### `uses_allocator` <a id="allocator.uses">[[allocator.uses]]</a>
516
 
517
  #### `uses_allocator` trait <a id="allocator.uses.trait">[[allocator.uses.trait]]</a>
518
 
@@ -520,46 +753,199 @@ argument of a type that satisfies the `Allocator` requirements (
520
  template<class T, class Alloc> struct uses_allocator;
521
  ```
522
 
523
  *Remarks:* Automatically detects whether `T` has a nested
524
  `allocator_type` that is convertible from `Alloc`. Meets the
525
- `BinaryTypeTrait` requirements ([[meta.rqmts]]). The implementation
526
  shall provide a definition that is derived from `true_type` if the
527
  *qualified-id* `T::allocator_type` is valid and denotes a
528
- type ([[temp.deduct]]) and
529
  `is_convertible_v<Alloc, T::allocator_type> != false`, otherwise it
530
  shall be derived from `false_type`. A program may specialize this
531
- template to derive from `true_type` for a user-defined type `T` that
532
  does not have a nested `allocator_type` but nonetheless can be
533
  constructed with an allocator where either:
534
 
535
  - the first argument of a constructor has type `allocator_arg_t` and the
536
  second argument has type `Alloc` or
537
  - the last argument of a constructor has type `Alloc`.
538
 
539
  #### Uses-allocator construction <a id="allocator.uses.construction">[[allocator.uses.construction]]</a>
540
 
541
- *Uses-allocator construction* with allocator `Alloc` refers to the
542
- construction of an object `obj` of type `T`, using constructor arguments
543
- `v1, v2, ..., vN` of types `V1, V2, ..., VN`, respectively, and an
544
- allocator `alloc` of type `Alloc`, according to the following rules:
545
-
546
- - if `uses_allocator_v<T, Alloc>` is `false` and
547
- `is_constructible_v<T, V1, V2, ..., VN>` is `true`, then `obj` is
548
- initialized as `obj(v1, v2, ..., vN)`;
549
- - otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
550
- `is_constructible_v<T, allocator_arg_t, Alloc,` `V1, V2, ..., VN>` is
551
- `true`, then `obj` is initialized as `obj(allocator_arg, alloc, v1,
552
- v2, ..., vN)`;
553
- - otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
554
- `is_constructible_v<T, V1, V2, ..., VN, Alloc>` is `true`, then `obj`
555
- is initialized as `obj(v1, v2, ..., vN, alloc)`;
556
- - otherwise, the request for uses-allocator construction is ill-formed.
557
- \[*Note 1*: An error will result if `uses_allocator_v<T, Alloc>` is
558
- `true` but the specific constructor does not take an allocator. This
559
- definition prevents a silent failure to pass the allocator to an
560
- element. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
 
562
  ### Allocator traits <a id="allocator.traits">[[allocator.traits]]</a>
563
 
564
  The class template `allocator_traits` supplies a uniform interface to
565
  all allocator types. An allocator cannot be a non-class type, however,
@@ -589,484 +975,266 @@ namespace std {
589
  using is_always_equal = see below;
590
 
591
  template<class T> using rebind_alloc = see below;
592
  template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
593
 
594
- static pointer allocate(Alloc& a, size_type n);
595
- static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
 
596
 
597
- static void deallocate(Alloc& a, pointer p, size_type n);
598
 
599
  template<class T, class... Args>
600
- static void construct(Alloc& a, T* p, Args&&... args);
601
 
602
  template<class T>
603
- static void destroy(Alloc& a, T* p);
604
 
605
- static size_type max_size(const Alloc& a) noexcept;
606
 
607
- static Alloc select_on_container_copy_construction(const Alloc& rhs);
608
  };
609
  }
610
  ```
611
 
612
- #### Allocator traits member types <a id="allocator.traits.types">[[allocator.traits.types]]</a>
613
 
614
  ``` cpp
615
  using pointer = see below;
616
  ```
617
 
618
  *Type:* `Alloc::pointer` if the *qualified-id* `Alloc::pointer` is valid
619
- and denotes a type ([[temp.deduct]]); otherwise, `value_type*`.
620
 
621
  ``` cpp
622
  using const_pointer = see below;
623
  ```
624
 
625
  *Type:* `Alloc::const_pointer` if the *qualified-id*
626
- `Alloc::const_pointer` is valid and denotes a type ([[temp.deduct]]);
627
  otherwise, `pointer_traits<pointer>::rebind<const value_type>`.
628
 
629
  ``` cpp
630
  using void_pointer = see below;
631
  ```
632
 
633
  *Type:* `Alloc::void_pointer` if the *qualified-id*
634
- `Alloc::void_pointer` is valid and denotes a type ([[temp.deduct]]);
635
  otherwise, `pointer_traits<pointer>::rebind<void>`.
636
 
637
  ``` cpp
638
  using const_void_pointer = see below;
639
  ```
640
 
641
  *Type:* `Alloc::const_void_pointer` if the *qualified-id*
642
- `Alloc::const_void_pointer` is valid and denotes a
643
- type ([[temp.deduct]]); otherwise,
644
- `pointer_traits<pointer>::rebind<const void>`.
645
 
646
  ``` cpp
647
  using difference_type = see below;
648
  ```
649
 
650
  *Type:* `Alloc::difference_type` if the *qualified-id*
651
- `Alloc::difference_type` is valid and denotes a type ([[temp.deduct]]);
652
  otherwise, `pointer_traits<pointer>::difference_type`.
653
 
654
  ``` cpp
655
  using size_type = see below;
656
  ```
657
 
658
  *Type:* `Alloc::size_type` if the *qualified-id* `Alloc::size_type` is
659
- valid and denotes a type ([[temp.deduct]]); otherwise,
660
  `make_unsigned_t<difference_type>`.
661
 
662
  ``` cpp
663
  using propagate_on_container_copy_assignment = see below;
664
  ```
665
 
666
  *Type:* `Alloc::propagate_on_container_copy_assignment` if the
667
  *qualified-id* `Alloc::propagate_on_container_copy_assignment` is valid
668
- and denotes a type ([[temp.deduct]]); otherwise `false_type`.
669
 
670
  ``` cpp
671
  using propagate_on_container_move_assignment = see below;
672
  ```
673
 
674
  *Type:* `Alloc::propagate_on_container_move_assignment` if the
675
  *qualified-id* `Alloc::propagate_on_container_move_assignment` is valid
676
- and denotes a type ([[temp.deduct]]); otherwise `false_type`.
677
 
678
  ``` cpp
679
  using propagate_on_container_swap = see below;
680
  ```
681
 
682
  *Type:* `Alloc::propagate_on_container_swap` if the *qualified-id*
683
  `Alloc::propagate_on_container_swap` is valid and denotes a
684
- type ([[temp.deduct]]); otherwise `false_type`.
685
 
686
  ``` cpp
687
  using is_always_equal = see below;
688
  ```
689
 
690
  *Type:* `Alloc::is_always_equal` if the *qualified-id*
691
- `Alloc::is_always_equal` is valid and denotes a type ([[temp.deduct]]);
692
  otherwise `is_empty<Alloc>::type`.
693
 
694
  ``` cpp
695
  template<class T> using rebind_alloc = see below;
696
  ```
697
 
698
  *Alias template:* `Alloc::rebind<T>::other` if the *qualified-id*
699
- `Alloc::rebind<T>::other` is valid and denotes a
700
- type ([[temp.deduct]]); otherwise, `Alloc<T, Args>` if `Alloc` is a
701
- class template instantiation of the form `Alloc<U, Args>`, where `Args`
702
- is zero or more type arguments; otherwise, the instantiation of
703
- `rebind_alloc` is ill-formed.
704
 
705
- #### Allocator traits static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
706
 
707
  ``` cpp
708
- static pointer allocate(Alloc& a, size_type n);
709
  ```
710
 
711
  *Returns:* `a.allocate(n)`.
712
 
713
  ``` cpp
714
- static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
715
  ```
716
 
717
  *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
718
  otherwise, `a.allocate(n)`.
719
 
720
  ``` cpp
721
- static void deallocate(Alloc& a, pointer p, size_type n);
722
  ```
723
 
724
  *Effects:* Calls `a.deallocate(p, n)`.
725
 
726
  *Throws:* Nothing.
727
 
728
  ``` cpp
729
  template<class T, class... Args>
730
- static void construct(Alloc& a, T* p, Args&&... args);
731
  ```
732
 
733
  *Effects:* Calls `a.construct(p, std::forward<Args>(args)...)` if that
734
  call is well-formed; otherwise, invokes
735
- `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`.
736
 
737
  ``` cpp
738
  template<class T>
739
- static void destroy(Alloc& a, T* p);
740
  ```
741
 
742
  *Effects:* Calls `a.destroy(p)` if that call is well-formed; otherwise,
743
- invokes `p->~T()`.
744
 
745
  ``` cpp
746
- static size_type max_size(const Alloc& a) noexcept;
747
  ```
748
 
749
  *Returns:* `a.max_size()` if that expression is well-formed; otherwise,
750
  `numeric_limits<size_type>::max()/sizeof(value_type)`.
751
 
752
  ``` cpp
753
- static Alloc select_on_container_copy_construction(const Alloc& rhs);
754
  ```
755
 
756
  *Returns:* `rhs.select_on_container_copy_construction()` if that
757
  expression is well-formed; otherwise, `rhs`.
758
 
759
  ### The default allocator <a id="default.allocator">[[default.allocator]]</a>
760
 
761
- All specializations of the default allocator satisfy the allocator
762
- completeness requirements ([[allocator.requirements.completeness]]).
763
 
764
  ``` cpp
765
  namespace std {
766
  template<class T> class allocator {
767
  public:
768
  using value_type = T;
 
 
769
  using propagate_on_container_move_assignment = true_type;
770
  using is_always_equal = true_type;
771
 
772
- allocator() noexcept;
773
- allocator(const allocator&) noexcept;
774
- template <class U> allocator(const allocator<U>&) noexcept;
775
- ~allocator();
 
776
 
777
- T* allocate(size_t n);
778
- void deallocate(T* p, size_t n);
779
  };
780
  }
781
  ```
782
 
783
- #### `allocator` members <a id="allocator.members">[[allocator.members]]</a>
784
 
785
  Except for the destructor, member functions of the default allocator
786
- shall not introduce data races ([[intro.multithread]]) as a result of
787
  concurrent calls to those member functions from different threads. Calls
788
  to these functions that allocate or deallocate a particular unit of
789
  storage shall occur in a single total order, and each such deallocation
790
  call shall happen before the next allocation (if any) in this order.
791
 
792
  ``` cpp
793
- T* allocate(size_t n);
794
  ```
795
 
796
- *Returns:* A pointer to the initial element of an array of storage of
797
- size `n` `* sizeof(T)`, aligned appropriately for objects of type `T`.
798
 
799
- *Remarks:* the storage is obtained by calling
800
- `::operator new` ([[new.delete]]), but it is unspecified when or how
801
- often this function is called.
802
 
803
- *Throws:* `bad_alloc` if the storage cannot be obtained.
 
 
 
 
 
 
 
804
 
805
  ``` cpp
806
- void deallocate(T* p, size_t n);
807
  ```
808
 
809
- *Requires:* `p` shall be a pointer value obtained from `allocate()`. `n`
810
- shall equal the value passed as the first argument to the invocation of
811
  allocate which returned `p`.
812
 
813
  *Effects:* Deallocates the storage referenced by `p` .
814
 
815
- *Remarks:* Uses `::operator delete` ([[new.delete]]), but it is
816
  unspecified when this function is called.
817
 
818
- #### `allocator` globals <a id="allocator.globals">[[allocator.globals]]</a>
819
 
820
  ``` cpp
821
  template<class T, class U>
822
- bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
823
  ```
824
 
825
  *Returns:* `true`.
826
 
827
- ``` cpp
828
- template <class T, class U>
829
- bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
830
- ```
831
-
832
- *Returns:* `false`.
833
-
834
- ### Specialized algorithms <a id="specialized.algorithms">[[specialized.algorithms]]</a>
835
-
836
- Throughout this subclause, the names of template parameters are used to
837
- express type requirements.
838
-
839
- - If an algorithm’s template parameter is named `InputIterator`, the
840
- template argument shall satisfy the requirements of an input
841
- iterator ([[input.iterators]]).
842
- - If an algorithm’s template parameter is named `ForwardIterator`, the
843
- template argument shall satisfy the requirements of a forward
844
- iterator ([[forward.iterators]]), and is required to have the
845
- property that no exceptions are thrown from increment, assignment,
846
- comparison, or indirection through valid iterators.
847
-
848
- Unless otherwise specified, if an exception is thrown in the following
849
- algorithms there are no effects.
850
-
851
- #### `addressof` <a id="specialized.addressof">[[specialized.addressof]]</a>
852
 
853
  ``` cpp
854
  template<class T> constexpr T* addressof(T& r) noexcept;
855
  ```
856
 
857
  *Returns:* The actual address of the object or function referenced by
858
  `r`, even in the presence of an overloaded `operator&`.
859
 
860
  *Remarks:* An expression `addressof(E)` is a constant
861
- subexpression ([[defns.const.subexpr]]) if `E` is an lvalue constant
862
  subexpression.
863
 
864
- #### `uninitialized_default_construct` <a id="uninitialized.construct.default">[[uninitialized.construct.default]]</a>
865
-
866
- ``` cpp
867
- template <class ForwardIterator>
868
- void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
869
- ```
870
-
871
- *Effects:* Equivalent to:
872
-
873
- ``` cpp
874
- for (; first != last; ++first)
875
- ::new (static_cast<void*>(addressof(*first)))
876
- typename iterator_traits<ForwardIterator>::value_type;
877
- ```
878
-
879
- ``` cpp
880
- template <class ForwardIterator, class Size>
881
- ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
882
- ```
883
-
884
- *Effects:* Equivalent to:
885
-
886
- ``` cpp
887
- for (; n>0; (void)++first, --n)
888
- ::new (static_cast<void*>(addressof(*first)))
889
- typename iterator_traits<ForwardIterator>::value_type;
890
- return first;
891
- ```
892
-
893
- #### `uninitialized_value_construct` <a id="uninitialized.construct.value">[[uninitialized.construct.value]]</a>
894
-
895
- ``` cpp
896
- template <class ForwardIterator>
897
- void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
898
- ```
899
-
900
- *Effects:* Equivalent to:
901
-
902
- ``` cpp
903
- for (; first != last; ++first)
904
- ::new (static_cast<void*>(addressof(*first)))
905
- typename iterator_traits<ForwardIterator>::value_type();
906
- ```
907
-
908
- ``` cpp
909
- template <class ForwardIterator, class Size>
910
- ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
911
- ```
912
-
913
- *Effects:* Equivalent to:
914
-
915
- ``` cpp
916
- for (; n>0; (void)++first, --n)
917
- ::new (static_cast<void*>(addressof(*first)))
918
- typename iterator_traits<ForwardIterator>::value_type();
919
- return first;
920
- ```
921
-
922
- #### `uninitialized_copy` <a id="uninitialized.copy">[[uninitialized.copy]]</a>
923
-
924
- ``` cpp
925
- template <class InputIterator, class ForwardIterator>
926
- ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
927
- ForwardIterator result);
928
- ```
929
-
930
- *Effects:* As if by:
931
-
932
- ``` cpp
933
- for (; first != last; ++result, (void) ++first)
934
- ::new (static_cast<void*>(addressof(*result)))
935
- typename iterator_traits<ForwardIterator>::value_type(*first);
936
- ```
937
-
938
- *Returns:* `result`.
939
-
940
- ``` cpp
941
- template <class InputIterator, class Size, class ForwardIterator>
942
- ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
943
- ForwardIterator result);
944
- ```
945
-
946
- *Effects:* As if by:
947
-
948
- ``` cpp
949
- for ( ; n > 0; ++result, (void) ++first, --n) {
950
- ::new (static_cast<void*>(addressof(*result)))
951
- typename iterator_traits<ForwardIterator>::value_type(*first);
952
- }
953
- ```
954
-
955
- *Returns:* `result`.
956
-
957
- #### `uninitialized_move` <a id="uninitialized.move">[[uninitialized.move]]</a>
958
-
959
- ``` cpp
960
- template <class InputIterator, class ForwardIterator>
961
- ForwardIterator uninitialized_move(InputIterator first, InputIterator last,
962
- ForwardIterator result);
963
- ```
964
-
965
- *Effects:* Equivalent to:
966
-
967
- ``` cpp
968
- for (; first != last; (void)++result, ++first)
969
- ::new (static_cast<void*>(addressof(*result)))
970
- typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
971
- return result;
972
- ```
973
-
974
- *Remarks:* If an exception is thrown, some objects in the range
975
- \[`first`, `last`) are left in a valid but unspecified state.
976
-
977
- ``` cpp
978
- template <class InputIterator, class Size, class ForwardIterator>
979
- pair<InputIterator, ForwardIterator>
980
- uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
981
- ```
982
-
983
- *Effects:* Equivalent to:
984
-
985
- ``` cpp
986
- for (; n > 0; ++result, (void) ++first, --n)
987
- ::new (static_cast<void*>(addressof(*result)))
988
- typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
989
- return {first,result};
990
- ```
991
-
992
- *Remarks:* If an exception is thrown, some objects in the range
993
- \[`first`, `std::next(first,n)`) are left in a valid but unspecified
994
- state.
995
-
996
- #### `uninitialized_fill` <a id="uninitialized.fill">[[uninitialized.fill]]</a>
997
-
998
- ``` cpp
999
- template <class ForwardIterator, class T>
1000
- void uninitialized_fill(ForwardIterator first, ForwardIterator last,
1001
- const T& x);
1002
- ```
1003
-
1004
- *Effects:* As if by:
1005
-
1006
- ``` cpp
1007
- for (; first != last; ++first)
1008
- ::new (static_cast<void*>(addressof(*first)))
1009
- typename iterator_traits<ForwardIterator>::value_type(x);
1010
- ```
1011
-
1012
- ``` cpp
1013
- template <class ForwardIterator, class Size, class T>
1014
- ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
1015
- ```
1016
-
1017
- *Effects:* As if by:
1018
-
1019
- ``` cpp
1020
- for (; n--; ++first)
1021
- ::new (static_cast<void*>(addressof(*first)))
1022
- typename iterator_traits<ForwardIterator>::value_type(x);
1023
- return first;
1024
- ```
1025
-
1026
- #### `destroy` <a id="specialized.destroy">[[specialized.destroy]]</a>
1027
-
1028
- ``` cpp
1029
- template <class T>
1030
- void destroy_at(T* location);
1031
- ```
1032
-
1033
- *Effects:* Equivalent to:
1034
-
1035
- ``` cpp
1036
- location->~T();
1037
- ```
1038
-
1039
- ``` cpp
1040
- template <class ForwardIterator>
1041
- void destroy(ForwardIterator first, ForwardIterator last);
1042
- ```
1043
-
1044
- *Effects:* Equivalent to:
1045
-
1046
- ``` cpp
1047
- for (; first!=last; ++first)
1048
- destroy_at(addressof(*first));
1049
- ```
1050
-
1051
- ``` cpp
1052
- template <class ForwardIterator, class Size>
1053
- ForwardIterator destroy_n(ForwardIterator first, Size n);
1054
- ```
1055
-
1056
- *Effects:* Equivalent to:
1057
-
1058
- ``` cpp
1059
- for (; n > 0; (void)++first, --n)
1060
- destroy_at(addressof(*first));
1061
- return first;
1062
- ```
1063
-
1064
  ### C library memory allocation <a id="c.malloc">[[c.malloc]]</a>
1065
 
1066
- [*Note 1*: The header `<cstdlib>` ([[cstdlib.syn]]) declares the
1067
- functions described in this subclause. — *end note*]
1068
 
1069
  ``` cpp
1070
  void* aligned_alloc(size_t alignment, size_t size);
1071
  void* calloc(size_t nmemb, size_t size);
1072
  void* malloc(size_t size);
@@ -1075,11 +1243,11 @@ void* realloc(void* ptr, size_t size);
1075
 
1076
  *Effects:* These functions have the semantics specified in the C
1077
  standard library.
1078
 
1079
  *Remarks:* These functions do not attempt to allocate storage by calling
1080
- `::operator new()` ([[support.dynamic]]).
1081
 
1082
  Storage allocated directly with these functions is implicitly declared
1083
  reachable (see  [[basic.stc.dynamic.safety]]) on allocation, ceases to
1084
  be declared reachable on deallocation, and need not cease to be declared
1085
  reachable as the result of an `undeclare_reachable()` call.
@@ -1093,17 +1261,22 @@ implemented with a separate allocation arena, bypassing the normal
1093
  intentionally be used as a replacement for `declare_reachable()`, and
1094
  newly written code is strongly encouraged to treat memory allocated with
1095
  these functions as though it were allocated with
1096
  `operator new`. — *end note*]
1097
 
 
 
 
 
 
1098
  ``` cpp
1099
  void free(void* ptr);
1100
  ```
1101
 
1102
  *Effects:* This function has the semantics specified in the C standard
1103
  library.
1104
 
1105
  *Remarks:* This function does not attempt to deallocate storage by
1106
  calling `::operator delete()`.
1107
 
1108
- ISO C 7.22.3.
1109
 
 
1
  ## Memory <a id="memory">[[memory]]</a>
2
 
3
  ### In general <a id="memory.general">[[memory.general]]</a>
4
 
5
+ Subclause  [[memory]] describes the contents of the header `<memory>`
6
+ and some of the contents of the header `<cstdlib>`.
 
7
 
8
  ### Header `<memory>` synopsis <a id="memory.syn">[[memory.syn]]</a>
9
 
10
  The header `<memory>` defines several types and function templates that
11
  describe properties of pointers and pointer-like types, manage memory
12
  for containers and other template types, destroy objects, and construct
13
+ objects in uninitialized memory buffers ([[pointer.traits]]–
14
+ [[specialized.addressof]] and [[specialized.algorithms]]). The header
15
+ also defines the templates `unique_ptr`, `shared_ptr`, `weak_ptr`, and
16
+ various function templates that operate on objects of these types
17
+ [[smartptr]].
18
 
19
  ``` cpp
20
+ #include <compare> // see [compare.syn]
21
+
22
  namespace std {
23
  // [pointer.traits], pointer traits
24
  template<class Ptr> struct pointer_traits;
25
  template<class T> struct pointer_traits<T*>;
26
 
27
+ // [pointer.conversion], pointer conversion
28
+ template<class T>
29
+ constexpr T* to_address(T* p) noexcept;
30
+ template<class Ptr>
31
+ constexpr auto to_address(const Ptr& p) noexcept;
32
+
33
+ // [util.dynamic.safety], pointer safety%
34
+ %
35
+ {pointer_safety{pointer_safety{pointer_safety}
36
  enum class pointer_safety { relaxed, preferred, strict };
37
  void declare_reachable(void* p);
38
+ template<class T>
39
+ T* undeclare_reachable(T* p);
40
  void declare_no_pointers(char* p, size_t n);
41
  void undeclare_no_pointers(char* p, size_t n);
42
  pointer_safety get_pointer_safety() noexcept;
43
 
44
+ // [ptr.align], pointer alignment
45
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
46
+ template<size_t N, class T>
47
+ [[nodiscard]] constexpr T* assume_aligned(T* ptr);
48
 
49
  // [allocator.tag], allocator argument tag
50
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
51
  inline constexpr allocator_arg_t allocator_arg{};
52
 
53
  // [allocator.uses], uses_allocator
54
  template<class T, class Alloc> struct uses_allocator;
55
 
56
+ // [allocator.uses.trait], uses_allocator
57
+ template<class T, class Alloc>
58
+ inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
59
+
60
+ // [allocator.uses.construction], uses-allocator construction
61
+ template<class T, class Alloc, class... Args>
62
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
63
+ Args&&... args) noexcept -> see below;
64
+ template<class T, class Alloc, class Tuple1, class Tuple2>
65
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
66
+ Tuple1&& x, Tuple2&& y)
67
+ noexcept -> see below;
68
+ template<class T, class Alloc>
69
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
70
+ template<class T, class Alloc, class U, class V>
71
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
72
+ U&& u, V&& v) noexcept -> see below;
73
+ template<class T, class Alloc, class U, class V>
74
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
75
+ const pair<U,V>& pr) noexcept -> see below;
76
+ template<class T, class Alloc, class U, class V>
77
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
78
+ pair<U,V>&& pr) noexcept -> see below;
79
+ template<class T, class Alloc, class... Args>
80
+ constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
81
+ template<class T, class Alloc, class... Args>
82
+ constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc,
83
+ Args&&... args);
84
+
85
  // [allocator.traits], allocator traits
86
  template<class Alloc> struct allocator_traits;
87
 
88
  // [default.allocator], the default allocator
89
  template<class T> class allocator;
90
  template<class T, class U>
91
+ constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
92
+
93
+ // [specialized.addressof], addressof
94
+ template<class T>
95
+ constexpr T* addressof(T& r) noexcept;
96
+ template<class T>
97
+ const T* addressof(const T&&) = delete;
98
 
99
  // [specialized.algorithms], specialized algorithms
100
+ // [special.mem.concepts], special memory concepts
101
+ template<class I>
102
+ concept no-throw-input-iterator = see below; // exposition only
103
+ template<class I>
104
+ concept no-throw-forward-iterator = see below; // exposition only
105
+ template<class S, class I>
106
+ concept no-throw-sentinel = see below; // exposition only
107
+ template<class R>
108
+ concept no-throw-input-range = see below; // exposition only
109
+ template<class R>
110
+ concept no-throw-forward-range = see below; // exposition only
111
+
112
+ template<class NoThrowForwardIterator>
113
+ void uninitialized_default_construct(NoThrowForwardIterator first,
114
+ NoThrowForwardIterator last);
115
+ template<class ExecutionPolicy, class NoThrowForwardIterator>
116
  void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
117
+ NoThrowForwardIterator first,
118
+ NoThrowForwardIterator last);
119
+ template<class NoThrowForwardIterator, class Size>
120
+ NoThrowForwardIterator
121
+ uninitialized_default_construct_n(NoThrowForwardIterator first, Size n);
122
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
123
+ NoThrowForwardIterator
124
+ uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
125
+ NoThrowForwardIterator first, Size n);
126
+
127
+ namespace ranges {
128
+ template<no-throw-forward-iterator I, no-throw-sentinel<I> S>
129
+ requires default_initializable<iter_value_t<I>>
130
+ I uninitialized_default_construct(I first, S last);
131
+ template<no-throw-forward-range R>
132
+ requires default_initializable<range_value_t<R>>
133
+ borrowed_iterator_t<R> uninitialized_default_construct(R&& r);
134
+
135
+ template<no-throw-forward-iterator I>
136
+ requires default_initializable<iter_value_t<I>>
137
+ I uninitialized_default_construct_n(I first, iter_difference_t<I> n);
138
+ }
139
+
140
+ template<class NoThrowForwardIterator>
141
+ void uninitialized_value_construct(NoThrowForwardIterator first,
142
+ NoThrowForwardIterator last);
143
+ template<class ExecutionPolicy, class NoThrowForwardIterator>
144
  void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
145
+ NoThrowForwardIterator first,
146
+ NoThrowForwardIterator last);
147
+ template<class NoThrowForwardIterator, class Size>
148
+ NoThrowForwardIterator
149
+ uninitialized_value_construct_n(NoThrowForwardIterator first, Size n);
150
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
151
+ NoThrowForwardIterator
152
+ uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
153
+ NoThrowForwardIterator first, Size n);
154
+
155
+ namespace ranges {
156
+ template<no-throw-forward-iterator I, no-throw-sentinel<I> S>
157
+ requires default_initializable<iter_value_t<I>>
158
+ I uninitialized_value_construct(I first, S last);
159
+ template<no-throw-forward-range R>
160
+ requires default_initializable<range_value_t<R>>
161
+ borrowed_iterator_t<R> uninitialized_value_construct(R&& r);
162
+
163
+ template<no-throw-forward-iterator I>
164
+ requires default_initializable<iter_value_t<I>>
165
+ I uninitialized_value_construct_n(I first, iter_difference_t<I> n);
166
+ }
167
+
168
+ template<class InputIterator, class NoThrowForwardIterator>
169
+ NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
170
+ NoThrowForwardIterator result);
171
+ template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator>
172
+ NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
173
  InputIterator first, InputIterator last,
174
+ NoThrowForwardIterator result);
175
+ template<class InputIterator, class Size, class NoThrowForwardIterator>
176
+ NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n,
177
+ NoThrowForwardIterator result);
178
+ template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator>
179
+ NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
180
  InputIterator first, Size n,
181
+ NoThrowForwardIterator result);
182
+
183
+ namespace ranges {
184
+ template<class I, class O>
185
+ using uninitialized_copy_result = in_out_result<I, O>;
186
+ template<input_iterator I, sentinel_for<I> S1,
187
+ no-throw-forward-iterator O, no-throw-sentinel<O> S2>
188
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
189
+ uninitialized_copy_result<I, O>
190
+ uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast);
191
+ template<input_range IR, no-throw-forward-range OR>
192
+ requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
193
+ uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
194
+ uninitialized_copy(IR&& in_range, OR&& out_range);
195
+
196
+ template<class I, class O>
197
+ using uninitialized_copy_n_result = in_out_result<I, O>;
198
+ template<input_iterator I, no-throw-forward-iterator O, no-throw-sentinel<O> S>
199
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
200
+ uninitialized_copy_n_result<I, O>
201
+ uninitialized_copy_n(I ifirst, iter_difference_t<I> n, O ofirst, S olast);
202
+ }
203
+
204
+ template<class InputIterator, class NoThrowForwardIterator>
205
+ NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,
206
+ NoThrowForwardIterator result);
207
+ template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator>
208
+ NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
209
  InputIterator first, InputIterator last,
210
+ NoThrowForwardIterator result);
211
+ template<class InputIterator, class Size, class NoThrowForwardIterator>
212
+ pair<InputIterator, NoThrowForwardIterator>
213
+ uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result);
214
+ template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator>
215
+ pair<InputIterator, NoThrowForwardIterator>
216
  uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
217
+ InputIterator first, Size n, NoThrowForwardIterator result);
218
+
219
+ namespace ranges {
220
+ template<class I, class O>
221
+ using uninitialized_move_result = in_out_result<I, O>;
222
+ template<input_iterator I, sentinel_for<I> S1,
223
+ no-throw-forward-iterator O, no-throw-sentinel<O> S2>
224
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
225
+ uninitialized_move_result<I, O>
226
+ uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast);
227
+ template<input_range IR, no-throw-forward-range OR>
228
+ requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
229
+ uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
230
+ uninitialized_move(IR&& in_range, OR&& out_range);
231
+
232
+ template<class I, class O>
233
+ using uninitialized_move_n_result = in_out_result<I, O>;
234
+ template<input_iterator I,
235
+ no-throw-forward-iterator O, no-throw-sentinel<O> S>
236
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
237
+ uninitialized_move_n_result<I, O>
238
+ uninitialized_move_n(I ifirst, iter_difference_t<I> n, O ofirst, S olast);
239
+ }
240
+
241
+ template<class NoThrowForwardIterator, class T>
242
+ void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last,
243
  const T& x);
244
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
245
  void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
246
+ NoThrowForwardIterator first, NoThrowForwardIterator last,
247
  const T& x);
248
+ template<class NoThrowForwardIterator, class Size, class T>
249
+ NoThrowForwardIterator
250
+ uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x);
251
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
252
+ NoThrowForwardIterator
253
+ uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
254
+ NoThrowForwardIterator first, Size n, const T& x);
255
+
256
+ namespace ranges {
257
+ template<no-throw-forward-iterator I, no-throw-sentinel<I> S, class T>
258
+ requires constructible_from<iter_value_t<I>, const T&>
259
+ I uninitialized_fill(I first, S last, const T& x);
260
+ template<no-throw-forward-range R, class T>
261
+ requires constructible_from<range_value_t<R>, const T&>
262
+ borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x);
263
+
264
+ template<no-throw-forward-iterator I, class T>
265
+ requires constructible_from<iter_value_t<I>, const T&>
266
+ I uninitialized_fill_n(I first, iter_difference_t<I> n, const T& x);
267
+ }
268
+
269
+ // [specialized.construct], construct_at
270
+ template<class T, class... Args>
271
+ constexpr T* construct_at(T* location, Args&&... args);
272
+
273
+ namespace ranges {
274
+ template<class T, class... Args>
275
+ constexpr T* construct_at(T* location, Args&&... args);
276
+ }
277
+
278
+ // [specialized.destroy], destroy
279
  template<class T>
280
+ constexpr void destroy_at(T* location);
281
+ template<class NoThrowForwardIterator>
282
+ constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last);
283
+ template<class ExecutionPolicy, class NoThrowForwardIterator>
284
  void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
285
+ NoThrowForwardIterator first, NoThrowForwardIterator last);
286
+ template<class NoThrowForwardIterator, class Size>
287
+ constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n);
288
+ template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
289
+ NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
290
+ NoThrowForwardIterator first, Size n);
291
+
292
+ namespace ranges {
293
+ template<destructible T>
294
+ constexpr void destroy_at(T* location) noexcept;
295
+
296
+ template<no-throw-input-iterator I, no-throw-sentinel<I> S>
297
+ requires destructible<iter_value_t<I>>
298
+ constexpr I destroy(I first, S last) noexcept;
299
+ template<no-throw-input-range R>
300
+ requires destructible<range_value_t<R>>
301
+ constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept;
302
+
303
+ template<no-throw-input-iterator I>
304
+ requires destructible<iter_value_t<I>>
305
+ constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept;
306
+ }
307
 
308
  // [unique.ptr], class template unique_ptr
309
  template<class T> struct default_delete;
310
  template<class T> struct default_delete<T[]>;
311
  template<class T, class D = default_delete<T>> class unique_ptr;
312
  template<class T, class D> class unique_ptr<T[], D>;
313
 
314
+ template<class T, class... Args>
315
+ unique_ptr<T> make_unique(Args&&... args); // T is not array
316
+ template<class T>
317
+ unique_ptr<T> make_unique(size_t n); // T is U[]
318
+ template<class T, class... Args>
319
+ unspecified make_unique(Args&&...) = delete; // T is U[N]
320
 
321
+ template<class T>
322
+ unique_ptr<T> make_unique_for_overwrite(); // T is not array
323
+ template<class T>
324
+ unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]
325
+ template<class T, class... Args>
326
+ unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N]
327
+
328
+ template<class T, class D>
329
+ void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
330
 
331
  template<class T1, class D1, class T2, class D2>
332
  bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 
 
333
  template<class T1, class D1, class T2, class D2>
334
  bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 
 
335
  template<class T1, class D1, class T2, class D2>
336
  bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
337
+ template<class T1, class D1, class T2, class D2>
338
+ bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
339
  template<class T1, class D1, class T2, class D2>
340
  bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
341
+ template<class T1, class D1, class T2, class D2>
342
+ requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
343
+ typename unique_ptr<T2, D2>::pointer>
344
+ compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
345
+ typename unique_ptr<T2, D2>::pointer>
346
+ operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
347
 
348
  template<class T, class D>
349
  bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
 
 
 
 
 
 
350
  template<class T, class D>
351
  bool operator<(const unique_ptr<T, D>& x, nullptr_t);
352
  template<class T, class D>
353
  bool operator<(nullptr_t, const unique_ptr<T, D>& y);
 
 
 
 
354
  template<class T, class D>
355
  bool operator>(const unique_ptr<T, D>& x, nullptr_t);
356
  template<class T, class D>
357
  bool operator>(nullptr_t, const unique_ptr<T, D>& y);
358
+ template<class T, class D>
359
+ bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
360
+ template<class T, class D>
361
+ bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
362
  template<class T, class D>
363
  bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
364
  template<class T, class D>
365
  bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
366
+ template<class T, class D>
367
+ requires three_way_comparable_with<typename unique_ptr<T, D>::pointer, nullptr_t>
368
+ compare_three_way_result_t<typename unique_ptr<T, D>::pointer, nullptr_t>
369
+ operator<=>(const unique_ptr<T, D>& x, nullptr_t);
370
+
371
+ template<class E, class T, class Y, class D>
372
+ basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p);
373
 
374
  // [util.smartptr.weak.bad], class bad_weak_ptr
375
  class bad_weak_ptr;
376
 
377
  // [util.smartptr.shared], class template shared_ptr
378
  template<class T> class shared_ptr;
379
 
380
  // [util.smartptr.shared.create], shared_ptr creation
381
  template<class T, class... Args>
382
+ shared_ptr<T> make_shared(Args&&... args); // T is not array
383
  template<class T, class A, class... Args>
384
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
385
+
386
+ template<class T>
387
+ shared_ptr<T> make_shared(size_t N); // T is U[]
388
+ template<class T, class A>
389
+ shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
390
+
391
+ template<class T>
392
+ shared_ptr<T> make_shared(); // T is U[N]
393
+ template<class T, class A>
394
+ shared_ptr<T> allocate_shared(const A& a); // T is U[N]
395
+
396
+ template<class T>
397
+ shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
398
+ template<class T, class A>
399
+ shared_ptr<T> allocate_shared(const A& a, size_t N,
400
+ const remove_extent_t<T>& u); // T is U[]
401
+
402
+ template<class T>
403
+ shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
404
+ template<class T, class A>
405
+ shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N]
406
+
407
+ template<class T>
408
+ shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
409
+ template<class T, class A>
410
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]
411
+
412
+ template<class T>
413
+ shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
414
+ template<class T, class A>
415
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]
416
 
417
  // [util.smartptr.shared.cmp], shared_ptr comparisons
418
  template<class T, class U>
419
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
420
  template<class T, class U>
421
+ strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
 
 
 
 
 
 
 
422
 
423
  template<class T>
424
  bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
425
  template<class T>
426
+ strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
 
428
  // [util.smartptr.shared.spec], shared_ptr specialized algorithms
429
  template<class T>
430
  void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
431
 
432
  // [util.smartptr.shared.cast], shared_ptr casts
433
  template<class T, class U>
434
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
435
+ template<class T, class U>
436
+ shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
437
  template<class T, class U>
438
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
439
+ template<class T, class U>
440
+ shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
441
  template<class T, class U>
442
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
443
+ template<class T, class U>
444
+ shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
445
+ template<class T, class U>
446
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
447
+ template<class T, class U>
448
+ shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
449
 
450
  // [util.smartptr.getdeleter], shared_ptr get_deleter
451
  template<class D, class T>
452
  D* get_deleter(const shared_ptr<T>& p) noexcept;
453
 
 
465
  template<class T = void> struct owner_less;
466
 
467
  // [util.smartptr.enab], class template enable_shared_from_this
468
  template<class T> class enable_shared_from_this;
469
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  // [util.smartptr.hash], hash support
471
  template<class T> struct hash;
472
  template<class T, class D> struct hash<unique_ptr<T, D>>;
473
  template<class T> struct hash<shared_ptr<T>>;
474
 
475
+ // [util.smartptr.atomic], atomic smart pointers
476
+ template<class T> struct atomic;
477
+ template<class T> struct atomic<shared_ptr<T>>;
478
+ template<class T> struct atomic<weak_ptr<T>>;
479
  }
480
  ```
481
 
482
  ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
483
 
 
501
  using element_type = T;
502
  using difference_type = ptrdiff_t;
503
 
504
  template<class U> using rebind = U*;
505
 
506
+ static constexpr pointer pointer_to(see below r) noexcept;
507
  };
508
  }
509
  ```
510
 
511
+ #### Member types <a id="pointer.traits.types">[[pointer.traits.types]]</a>
512
 
513
  ``` cpp
514
  using element_type = see below;
515
  ```
516
 
517
  *Type:* `Ptr::element_type` if the *qualified-id* `Ptr::element_type` is
518
+ valid and denotes a type [[temp.deduct]]; otherwise, `T` if `Ptr` is a
519
+ class template instantiation of the form `SomePointer<T, Args>`, where
520
  `Args` is zero or more type arguments; otherwise, the specialization is
521
  ill-formed.
522
 
523
  ``` cpp
524
  using difference_type = see below;
525
  ```
526
 
527
  *Type:* `Ptr::difference_type` if the *qualified-id*
528
+ `Ptr::difference_type` is valid and denotes a type [[temp.deduct]];
529
  otherwise, `ptrdiff_t`.
530
 
531
  ``` cpp
532
  template<class U> using rebind = see below;
533
  ```
534
 
535
  *Alias template:* `Ptr::rebind<U>` if the *qualified-id*
536
+ `Ptr::rebind<U>` is valid and denotes a type [[temp.deduct]]; otherwise,
537
+ `SomePointer<U, Args>` if `Ptr` is a class template instantiation of the
538
+ form `SomePointer<T, Args>`, where `Args` is zero or more type
539
+ arguments; otherwise, the instantiation of `rebind` is ill-formed.
 
540
 
541
+ #### Member functions <a id="pointer.traits.functions">[[pointer.traits.functions]]</a>
542
 
543
  ``` cpp
544
  static pointer pointer_traits::pointer_to(see below r);
545
+ static constexpr pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
546
  ```
547
 
548
+ *Mandates:* For the first member function, `Ptr::pointer_to(r)` is
549
+ well-formed.
550
+
551
+ *Preconditions:* For the first member function, `Ptr::pointer_to(r)`
552
+ returns a pointer to `r` through which indirection is valid.
553
+
554
+ *Returns:* The first member function returns `Ptr::pointer_to(r)`. The
555
+ second member function returns `addressof(r)`.
556
+
557
  *Remarks:* If `element_type` is cv `void`, the type of `r` is
558
  unspecified; otherwise, it is `element_type&`.
559
 
560
+ #### Optional members <a id="pointer.traits.optmem">[[pointer.traits.optmem]]</a>
561
+
562
+ Specializations of `pointer_traits` may define the member declared in
563
+ this subclause to customize the behavior of the standard library.
564
+
565
+ ``` cpp
566
+ static element_type* to_address(pointer p) noexcept;
567
+ ```
568
+
569
+ *Returns:* A pointer of type `element_type*` that references the same
570
+ location as the argument `p`.
571
+
572
+ [*Note 1*: This function should be the inverse of `pointer_to`. If
573
+ defined, it customizes the behavior of the non-member function
574
+ `to_address` [[pointer.conversion]]. — *end note*]
575
+
576
+ ### Pointer conversion <a id="pointer.conversion">[[pointer.conversion]]</a>
577
+
578
+ ``` cpp
579
+ template<class T> constexpr T* to_address(T* p) noexcept;
580
+ ```
581
+
582
+ *Mandates:* `T` is not a function type.
583
+
584
+ *Returns:* `p`.
585
+
586
+ ``` cpp
587
+ template<class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
588
+ ```
589
+
590
+ *Returns:* `pointer_traits<Ptr>::to_address(p)` if that expression is
591
+ well-formed (see [[pointer.traits.optmem]]), otherwise
592
+ `to_address(p.operator->())`.
593
 
594
  ### Pointer safety <a id="util.dynamic.safety">[[util.dynamic.safety]]</a>
595
 
596
  A complete object is *declared reachable* while the number of calls to
597
  `declare_reachable` with an argument referencing the object exceeds the
 
600
 
601
  ``` cpp
602
  void declare_reachable(void* p);
603
  ```
604
 
605
+ *Preconditions:* `p` is a safely-derived
606
+ pointer [[basic.stc.dynamic.safety]] or a null pointer value.
607
 
608
  *Effects:* If `p` is not null, the complete object referenced by `p` is
609
+ subsequently declared reachable [[basic.stc.dynamic.safety]].
610
 
611
  *Throws:* May throw `bad_alloc` if the system cannot allocate additional
612
  memory that may be required to track objects declared reachable.
613
 
614
  ``` cpp
615
  template<class T> T* undeclare_reachable(T* p);
616
  ```
617
 
618
+ *Preconditions:* If `p` is not null, the complete object referenced by
619
+ `p` has been previously declared reachable, and is live [[basic.life]]
620
+ from the time of the call until the last `undeclare_reachable(p)` call
621
+ on the object.
622
 
623
+ *Returns:* A safely derived copy of `p` which compares equal to `p`.
 
624
 
625
  *Throws:* Nothing.
626
 
627
  [*Note 1*: It is expected that calls to `declare_reachable(p)` will
628
  consume a small amount of memory in addition to that occupied by the
 
632
 
633
  ``` cpp
634
  void declare_no_pointers(char* p, size_t n);
635
  ```
636
 
637
+ *Preconditions:* No bytes in the specified range are currently
638
+ registered with `declare_no_pointers()`. If the specified range is in an
639
+ allocated object, then it is entirely within a single allocated object.
640
+ The object is live until the corresponding `undeclare_no_pointers()`
641
  call.
642
 
643
  [*Note 2*: In a garbage-collecting implementation, the fact that a
644
  region in an object is registered with `declare_no_pointers()` should
645
  not prevent the object from being collected. — *end note*]
 
660
 
661
  ``` cpp
662
  void undeclare_no_pointers(char* p, size_t n);
663
  ```
664
 
665
+ *Preconditions:* The same range has previously been passed to
666
  `declare_no_pointers()`.
667
 
668
  *Effects:* Unregisters a range registered with `declare_no_pointers()`
669
+ for destruction. It shall be called before the lifetime of the object
670
  ends.
671
 
672
  *Throws:* Nothing.
673
 
674
  ``` cpp
675
  pointer_safety get_pointer_safety() noexcept;
676
  ```
677
 
678
  *Returns:* `pointer_safety::strict` if the implementation has strict
679
+ pointer safety [[basic.stc.dynamic.safety]]. It is
680
  *implementation-defined* whether `get_pointer_safety` returns
681
  `pointer_safety::relaxed` or `pointer_safety::preferred` if the
682
  implementation has relaxed pointer safety.[^1]
683
 
684
+ ### Pointer alignment <a id="ptr.align">[[ptr.align]]</a>
685
 
686
  ``` cpp
687
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
688
  ```
689
 
690
+ *Preconditions:*
691
+
692
+ - `alignment` is a power of two
693
+ - `ptr` represents the address of contiguous storage of at least `space`
694
+ bytes
695
+
696
  *Effects:* If it is possible to fit `size` bytes of storage aligned by
697
  `alignment` into the buffer pointed to by `ptr` with length `space`, the
698
  function updates `ptr` to represent the first possible address of such
699
  storage and decreases `space` by the number of bytes used for alignment.
700
  Otherwise, the function does nothing.
701
 
 
 
 
 
 
 
702
  *Returns:* A null pointer if the requested aligned buffer would not fit
703
  into the available space, otherwise the adjusted value of `ptr`.
704
 
705
  [*Note 1*: The function updates its `ptr` and `space` arguments so that
706
  it can be called repeatedly with possibly different `alignment` and
707
  `size` arguments for the same buffer. — *end note*]
708
 
709
+ ``` cpp
710
+ template<size_t N, class T>
711
+ [[nodiscard]] constexpr T* assume_aligned(T* ptr);
712
+ ```
713
+
714
+ *Mandates:* `N` is a power of two.
715
+
716
+ *Preconditions:* `ptr` points to an object `X` of a type
717
+ similar [[conv.qual]] to `T`, where `X` has alignment `N`
718
+ [[basic.align]].
719
+
720
+ *Returns:* `ptr`.
721
+
722
+ *Throws:* Nothing.
723
+
724
+ [*Note 2*: The alignment assumption on an object `X` expressed by a
725
+ call to `assume_aligned` may result in generation of more efficient
726
+ code. It is up to the program to ensure that the assumption actually
727
+ holds. The call does not cause the compiler to verify or enforce this.
728
+ An implementation might only make the assumption for those operations on
729
+ `X` that access `X` through the pointer returned by
730
+ `assume_aligned`. — *end note*]
731
+
732
  ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
733
 
734
  ``` cpp
735
  namespace std {
736
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
737
  inline constexpr allocator_arg_t allocator_arg{};
738
  }
739
  ```
740
 
741
+ The `allocator_arg_t` struct is an empty class type used as a unique
742
  type to disambiguate constructor and function overloading. Specifically,
743
  several types (see `tuple`  [[tuple]]) have constructors with
744
  `allocator_arg_t` as the first argument, immediately followed by an
745
+ argument of a type that meets the *Cpp17Allocator* requirements (
746
+ [[cpp17.allocator]]).
747
 
748
  ### `uses_allocator` <a id="allocator.uses">[[allocator.uses]]</a>
749
 
750
  #### `uses_allocator` trait <a id="allocator.uses.trait">[[allocator.uses.trait]]</a>
751
 
 
753
  template<class T, class Alloc> struct uses_allocator;
754
  ```
755
 
756
  *Remarks:* Automatically detects whether `T` has a nested
757
  `allocator_type` that is convertible from `Alloc`. Meets the
758
+ *Cpp17BinaryTypeTrait* requirements [[meta.rqmts]]. The implementation
759
  shall provide a definition that is derived from `true_type` if the
760
  *qualified-id* `T::allocator_type` is valid and denotes a
761
+ type [[temp.deduct]] and
762
  `is_convertible_v<Alloc, T::allocator_type> != false`, otherwise it
763
  shall be derived from `false_type`. A program may specialize this
764
+ template to derive from `true_type` for a program-defined type `T` that
765
  does not have a nested `allocator_type` but nonetheless can be
766
  constructed with an allocator where either:
767
 
768
  - the first argument of a constructor has type `allocator_arg_t` and the
769
  second argument has type `Alloc` or
770
  - the last argument of a constructor has type `Alloc`.
771
 
772
  #### Uses-allocator construction <a id="allocator.uses.construction">[[allocator.uses.construction]]</a>
773
 
774
+ *Uses-allocator construction* with allocator `alloc` and constructor
775
+ arguments `args...` refers to the construction of an object of type `T`
776
+ such that `alloc` is passed to the constructor of `T` if `T` uses an
777
+ allocator type compatible with `alloc`. When applied to the construction
778
+ of an object of type `T`, it is equivalent to initializing it with the
779
+ value of the expression `make_obj_using_allocator<T>(alloc, args...)`,
780
+ described below.
781
+
782
+ The following utility functions support three conventions for passing
783
+ `alloc` to a constructor:
784
+
785
+ - If `T` does not use an allocator compatible with `alloc`, then `alloc`
786
+ is ignored.
787
+ - Otherwise, if `T` has a constructor invocable as
788
+ `T(allocator_arg, alloc, args...)` (leading-allocator convention),
789
+ then uses-allocator construction chooses this constructor form.
790
+ - Otherwise, if `T` has a constructor invocable as `T(args..., alloc)`
791
+ (trailing-allocator convention), then uses-allocator construction
792
+ chooses this constructor form.
793
+
794
+ The `uses_allocator_construction_args` function template takes an
795
+ allocator and argument list and produces (as a tuple) a new argument
796
+ list matching one of the above conventions. Additionally, overloads are
797
+ provided that treat specializations of `pair` such that uses-allocator
798
+ construction is applied individually to the `first` and `second` data
799
+ members. The `make_obj_using_allocator` and
800
+ `uninitialized_construct_using_allocator` function templates apply the
801
+ modified constructor arguments to construct an object of type `T` as a
802
+ return value or in-place, respectively.
803
+
804
+ [*Note 1*: For `uses_allocator_construction_args` and
805
+ `make_obj_using_allocator`, type `T` is not deduced and must therefore
806
+ be specified explicitly by the caller. — *end note*]
807
+
808
+ ``` cpp
809
+ template<class T, class Alloc, class... Args>
810
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
811
+ Args&&... args) noexcept -> see below;
812
+ ```
813
+
814
+ *Constraints:* `T` is not a specialization of `pair`.
815
+
816
+ *Returns:* A `tuple` value determined as follows:
817
+
818
+ - If `uses_allocator_v<T, Alloc>` is `false` and
819
+ `is_constructible_v<T, Args...>` is `true`, return
820
+ `forward_as_tuple(std::forward<Args>(args)...)`.
821
+ - Otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
822
+ `is_constructible_v<T, allocator_arg_t, const Alloc&, Args...>` is
823
+ `true`, return
824
+ ``` cpp
825
+ tuple<allocator_arg_t, const Alloc&, Args&&...>(
826
+ allocator_arg, alloc, std::forward<Args>(args)...)
827
+ ```
828
+ - Otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
829
+ `is_constructible_v<T, Args..., const Alloc&>` is `true`, return
830
+ `forward_as_tuple(std::forward<Args>(args)..., alloc)`.
831
+ - Otherwise, the program is ill-formed.
832
+
833
+ [*Note 1*: This definition prevents a silent failure to pass the
834
+ allocator to a constructor of a type for which
835
+ `uses_allocator_v<T, Alloc>` is `true`. — *end note*]
836
+
837
+ ``` cpp
838
+ template<class T, class Alloc, class Tuple1, class Tuple2>
839
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
840
+ Tuple1&& x, Tuple2&& y)
841
+ noexcept -> see below;
842
+ ```
843
+
844
+ *Constraints:* `T` is a specialization of `pair`.
845
+
846
+ *Effects:* For `T` specified as `pair<T1, T2>`, equivalent to:
847
+
848
+ ``` cpp
849
+ return make_tuple(
850
+ piecewise_construct,
851
+ apply([&alloc](auto&&... args1) {
852
+ return uses_allocator_construction_args<T1>(
853
+ alloc, std::forward<decltype(args1)>(args1)...);
854
+ }, std::forward<Tuple1>(x)),
855
+ apply([&alloc](auto&&... args2) {
856
+ return uses_allocator_construction_args<T2>(
857
+ alloc, std::forward<decltype(args2)>(args2)...);
858
+ }, std::forward<Tuple2>(y)));
859
+ ```
860
+
861
+ ``` cpp
862
+ template<class T, class Alloc>
863
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
864
+ ```
865
+
866
+ *Constraints:* `T` is a specialization of `pair`.
867
+
868
+ *Effects:* Equivalent to:
869
+
870
+ ``` cpp
871
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
872
+ tuple<>{}, tuple<>{});
873
+ ```
874
+
875
+ ``` cpp
876
+ template<class T, class Alloc, class U, class V>
877
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
878
+ U&& u, V&& v) noexcept -> see below;
879
+ ```
880
+
881
+ *Constraints:* `T` is a specialization of `pair`.
882
+
883
+ *Effects:* Equivalent to:
884
+
885
+ ``` cpp
886
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
887
+ forward_as_tuple(std::forward<U>(u)),
888
+ forward_as_tuple(std::forward<V>(v)));
889
+ ```
890
+
891
+ ``` cpp
892
+ template<class T, class Alloc, class U, class V>
893
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
894
+ const pair<U,V>& pr) noexcept -> see below;
895
+ ```
896
+
897
+ *Constraints:* `T` is a specialization of `pair`.
898
+
899
+ *Effects:* Equivalent to:
900
+
901
+ ``` cpp
902
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
903
+ forward_as_tuple(pr.first),
904
+ forward_as_tuple(pr.second));
905
+ ```
906
+
907
+ ``` cpp
908
+ template<class T, class Alloc, class U, class V>
909
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
910
+ pair<U,V>&& pr) noexcept -> see below;
911
+ ```
912
+
913
+ *Constraints:* `T` is a specialization of `pair`.
914
+
915
+ *Effects:* Equivalent to:
916
+
917
+ ``` cpp
918
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
919
+ forward_as_tuple(std::move(pr).first),
920
+ forward_as_tuple(std::move(pr).second));
921
+ ```
922
+
923
+ ``` cpp
924
+ template<class T, class Alloc, class... Args>
925
+ constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
926
+ ```
927
+
928
+ *Effects:* Equivalent to:
929
+
930
+ ``` cpp
931
+ return make_from_tuple<T>(uses_allocator_construction_args<T>(
932
+ alloc, std::forward<Args>(args)...));
933
+ ```
934
+
935
+ ``` cpp
936
+ template<class T, class Alloc, class... Args>
937
+ constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
938
+ ```
939
+
940
+ *Effects:* Equivalent to:
941
+
942
+ ``` cpp
943
+ return apply([&]<class... U>(U&&... xs) {
944
+ return construct_at(p, std::forward<U>(xs)...);
945
+ }, uses_allocator_construction_args<T>(alloc, std::forward<Args>(args)...));
946
+ ```
947
 
948
  ### Allocator traits <a id="allocator.traits">[[allocator.traits]]</a>
949
 
950
  The class template `allocator_traits` supplies a uniform interface to
951
  all allocator types. An allocator cannot be a non-class type, however,
 
975
  using is_always_equal = see below;
976
 
977
  template<class T> using rebind_alloc = see below;
978
  template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
979
 
980
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
981
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
982
+ const_void_pointer hint);
983
 
984
+ static constexpr void deallocate(Alloc& a, pointer p, size_type n);
985
 
986
  template<class T, class... Args>
987
+ static constexpr void construct(Alloc& a, T* p, Args&&... args);
988
 
989
  template<class T>
990
+ static constexpr void destroy(Alloc& a, T* p);
991
 
992
+ static constexpr size_type max_size(const Alloc& a) noexcept;
993
 
994
+ static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
995
  };
996
  }
997
  ```
998
 
999
+ #### Member types <a id="allocator.traits.types">[[allocator.traits.types]]</a>
1000
 
1001
  ``` cpp
1002
  using pointer = see below;
1003
  ```
1004
 
1005
  *Type:* `Alloc::pointer` if the *qualified-id* `Alloc::pointer` is valid
1006
+ and denotes a type [[temp.deduct]]; otherwise, `value_type*`.
1007
 
1008
  ``` cpp
1009
  using const_pointer = see below;
1010
  ```
1011
 
1012
  *Type:* `Alloc::const_pointer` if the *qualified-id*
1013
+ `Alloc::const_pointer` is valid and denotes a type [[temp.deduct]];
1014
  otherwise, `pointer_traits<pointer>::rebind<const value_type>`.
1015
 
1016
  ``` cpp
1017
  using void_pointer = see below;
1018
  ```
1019
 
1020
  *Type:* `Alloc::void_pointer` if the *qualified-id*
1021
+ `Alloc::void_pointer` is valid and denotes a type [[temp.deduct]];
1022
  otherwise, `pointer_traits<pointer>::rebind<void>`.
1023
 
1024
  ``` cpp
1025
  using const_void_pointer = see below;
1026
  ```
1027
 
1028
  *Type:* `Alloc::const_void_pointer` if the *qualified-id*
1029
+ `Alloc::const_void_pointer` is valid and denotes a type [[temp.deduct]];
1030
+ otherwise, `pointer_traits<pointer>::rebind<const void>`.
 
1031
 
1032
  ``` cpp
1033
  using difference_type = see below;
1034
  ```
1035
 
1036
  *Type:* `Alloc::difference_type` if the *qualified-id*
1037
+ `Alloc::difference_type` is valid and denotes a type [[temp.deduct]];
1038
  otherwise, `pointer_traits<pointer>::difference_type`.
1039
 
1040
  ``` cpp
1041
  using size_type = see below;
1042
  ```
1043
 
1044
  *Type:* `Alloc::size_type` if the *qualified-id* `Alloc::size_type` is
1045
+ valid and denotes a type [[temp.deduct]]; otherwise,
1046
  `make_unsigned_t<difference_type>`.
1047
 
1048
  ``` cpp
1049
  using propagate_on_container_copy_assignment = see below;
1050
  ```
1051
 
1052
  *Type:* `Alloc::propagate_on_container_copy_assignment` if the
1053
  *qualified-id* `Alloc::propagate_on_container_copy_assignment` is valid
1054
+ and denotes a type [[temp.deduct]]; otherwise `false_type`.
1055
 
1056
  ``` cpp
1057
  using propagate_on_container_move_assignment = see below;
1058
  ```
1059
 
1060
  *Type:* `Alloc::propagate_on_container_move_assignment` if the
1061
  *qualified-id* `Alloc::propagate_on_container_move_assignment` is valid
1062
+ and denotes a type [[temp.deduct]]; otherwise `false_type`.
1063
 
1064
  ``` cpp
1065
  using propagate_on_container_swap = see below;
1066
  ```
1067
 
1068
  *Type:* `Alloc::propagate_on_container_swap` if the *qualified-id*
1069
  `Alloc::propagate_on_container_swap` is valid and denotes a
1070
+ type [[temp.deduct]]; otherwise `false_type`.
1071
 
1072
  ``` cpp
1073
  using is_always_equal = see below;
1074
  ```
1075
 
1076
  *Type:* `Alloc::is_always_equal` if the *qualified-id*
1077
+ `Alloc::is_always_equal` is valid and denotes a type [[temp.deduct]];
1078
  otherwise `is_empty<Alloc>::type`.
1079
 
1080
  ``` cpp
1081
  template<class T> using rebind_alloc = see below;
1082
  ```
1083
 
1084
  *Alias template:* `Alloc::rebind<T>::other` if the *qualified-id*
1085
+ `Alloc::rebind<T>::other` is valid and denotes a type [[temp.deduct]];
1086
+ otherwise, `Alloc<T, Args>` if `Alloc` is a class template instantiation
1087
+ of the form `Alloc<U, Args>`, where `Args` is zero or more type
1088
+ arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
 
1089
 
1090
+ #### Static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
1091
 
1092
  ``` cpp
1093
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1094
  ```
1095
 
1096
  *Returns:* `a.allocate(n)`.
1097
 
1098
  ``` cpp
1099
+ [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1100
  ```
1101
 
1102
  *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
1103
  otherwise, `a.allocate(n)`.
1104
 
1105
  ``` cpp
1106
+ static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1107
  ```
1108
 
1109
  *Effects:* Calls `a.deallocate(p, n)`.
1110
 
1111
  *Throws:* Nothing.
1112
 
1113
  ``` cpp
1114
  template<class T, class... Args>
1115
+ static constexpr void construct(Alloc& a, T* p, Args&&... args);
1116
  ```
1117
 
1118
  *Effects:* Calls `a.construct(p, std::forward<Args>(args)...)` if that
1119
  call is well-formed; otherwise, invokes
1120
+ `construct_at(p, std::forward<Args>(args)...)`.
1121
 
1122
  ``` cpp
1123
  template<class T>
1124
+ static constexpr void destroy(Alloc& a, T* p);
1125
  ```
1126
 
1127
  *Effects:* Calls `a.destroy(p)` if that call is well-formed; otherwise,
1128
+ invokes `destroy_at(p)`.
1129
 
1130
  ``` cpp
1131
+ static constexpr size_type max_size(const Alloc& a) noexcept;
1132
  ```
1133
 
1134
  *Returns:* `a.max_size()` if that expression is well-formed; otherwise,
1135
  `numeric_limits<size_type>::max()/sizeof(value_type)`.
1136
 
1137
  ``` cpp
1138
+ static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
1139
  ```
1140
 
1141
  *Returns:* `rhs.select_on_container_copy_construction()` if that
1142
  expression is well-formed; otherwise, `rhs`.
1143
 
1144
  ### The default allocator <a id="default.allocator">[[default.allocator]]</a>
1145
 
1146
+ All specializations of the default allocator meet the allocator
1147
+ completeness requirements [[allocator.requirements.completeness]].
1148
 
1149
  ``` cpp
1150
  namespace std {
1151
  template<class T> class allocator {
1152
  public:
1153
  using value_type = T;
1154
+ using size_type = size_t;
1155
+ using difference_type = ptrdiff_t;
1156
  using propagate_on_container_move_assignment = true_type;
1157
  using is_always_equal = true_type;
1158
 
1159
+ constexpr allocator() noexcept;
1160
+ constexpr allocator(const allocator&) noexcept;
1161
+ template<class U> constexpr allocator(const allocator<U>&) noexcept;
1162
+ constexpr ~allocator();
1163
+ constexpr allocator& operator=(const allocator&) = default;
1164
 
1165
+ [[nodiscard]] constexpr T* allocate(size_t n);
1166
+ constexpr void deallocate(T* p, size_t n);
1167
  };
1168
  }
1169
  ```
1170
 
1171
+ #### Members <a id="allocator.members">[[allocator.members]]</a>
1172
 
1173
  Except for the destructor, member functions of the default allocator
1174
+ shall not introduce data races [[intro.multithread]] as a result of
1175
  concurrent calls to those member functions from different threads. Calls
1176
  to these functions that allocate or deallocate a particular unit of
1177
  storage shall occur in a single total order, and each such deallocation
1178
  call shall happen before the next allocation (if any) in this order.
1179
 
1180
  ``` cpp
1181
+ [[nodiscard]] constexpr T* allocate(size_t n);
1182
  ```
1183
 
1184
+ *Mandates:* `T` is not an incomplete type [[basic.types]].
 
1185
 
1186
+ *Returns:* A pointer to the initial element of an array of `n` `T`.
 
 
1187
 
1188
+ *Remarks:* The storage for the array is obtained by calling
1189
+ `::operator new` [[new.delete]], but it is unspecified when or how often
1190
+ this function is called. This function starts the lifetime of the array
1191
+ object, but not that of any of the array elements.
1192
+
1193
+ *Throws:* `bad_array_new_length` if
1194
+ `numeric_limits<size_t>::max() / sizeof(T) < n`, or `bad_alloc` if the
1195
+ storage cannot be obtained.
1196
 
1197
  ``` cpp
1198
+ constexpr void deallocate(T* p, size_t n);
1199
  ```
1200
 
1201
+ *Preconditions:* `p` is a pointer value obtained from `allocate()`. `n`
1202
+ equals the value passed as the first argument to the invocation of
1203
  allocate which returned `p`.
1204
 
1205
  *Effects:* Deallocates the storage referenced by `p` .
1206
 
1207
+ *Remarks:* Uses `::operator delete` [[new.delete]], but it is
1208
  unspecified when this function is called.
1209
 
1210
+ #### Operators <a id="allocator.globals">[[allocator.globals]]</a>
1211
 
1212
  ``` cpp
1213
  template<class T, class U>
1214
+ constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
1215
  ```
1216
 
1217
  *Returns:* `true`.
1218
 
1219
+ ### `addressof` <a id="specialized.addressof">[[specialized.addressof]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220
 
1221
  ``` cpp
1222
  template<class T> constexpr T* addressof(T& r) noexcept;
1223
  ```
1224
 
1225
  *Returns:* The actual address of the object or function referenced by
1226
  `r`, even in the presence of an overloaded `operator&`.
1227
 
1228
  *Remarks:* An expression `addressof(E)` is a constant
1229
+ subexpression [[defns.const.subexpr]] if `E` is an lvalue constant
1230
  subexpression.
1231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1232
  ### C library memory allocation <a id="c.malloc">[[c.malloc]]</a>
1233
 
1234
+ [*Note 1*: The header `<cstdlib>` declares the functions described in
1235
+ this subclause. — *end note*]
1236
 
1237
  ``` cpp
1238
  void* aligned_alloc(size_t alignment, size_t size);
1239
  void* calloc(size_t nmemb, size_t size);
1240
  void* malloc(size_t size);
 
1243
 
1244
  *Effects:* These functions have the semantics specified in the C
1245
  standard library.
1246
 
1247
  *Remarks:* These functions do not attempt to allocate storage by calling
1248
+ `::operator new()` [[new.delete]].
1249
 
1250
  Storage allocated directly with these functions is implicitly declared
1251
  reachable (see  [[basic.stc.dynamic.safety]]) on allocation, ceases to
1252
  be declared reachable on deallocation, and need not cease to be declared
1253
  reachable as the result of an `undeclare_reachable()` call.
 
1261
  intentionally be used as a replacement for `declare_reachable()`, and
1262
  newly written code is strongly encouraged to treat memory allocated with
1263
  these functions as though it were allocated with
1264
  `operator new`. — *end note*]
1265
 
1266
+ These functions implicitly create objects [[intro.object]] in the
1267
+ returned region of storage and return a pointer to a suitable created
1268
+ object. In the case of `calloc` and `realloc`, the objects are created
1269
+ before the storage is zeroed or copied, respectively.
1270
+
1271
  ``` cpp
1272
  void free(void* ptr);
1273
  ```
1274
 
1275
  *Effects:* This function has the semantics specified in the C standard
1276
  library.
1277
 
1278
  *Remarks:* This function does not attempt to deallocate storage by
1279
  calling `::operator delete()`.
1280
 
1281
+ See also: ISO C 7.22.3
1282