From Jason Turner

[memory]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp53_igoit/{from.md → to.md} +464 -295
tmp/tmp53_igoit/{from.md → to.md} RENAMED
@@ -10,365 +10,416 @@ and some of the contents of the header `<cstdlib>`.
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
@@ -466,36 +517,48 @@ namespace std {
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
 
 
 
484
  The class template `pointer_traits` supplies a uniform interface to
485
  certain attributes of pointer-like types.
486
 
487
  ``` cpp
488
  namespace std {
489
  template<class Ptr> struct pointer_traits {
490
- using pointer = Ptr;
491
- using element_type = see below;
492
- using difference_type = see below;
493
-
494
- template<class U> using rebind = see below;
495
-
496
- static pointer pointer_to(see below r);
497
  };
498
 
499
  template<class T> struct pointer_traits<T*> {
500
  using pointer = T*;
501
  using element_type = T;
@@ -508,19 +571,49 @@ namespace std {
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
 
@@ -558,21 +651,23 @@ second member function returns `addressof(r)`.
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
@@ -589,100 +684,10 @@ template<class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
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
598
- number of calls to `undeclare_reachable` with an argument referencing
599
- the object.
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
629
- referenced object until the matching call to `undeclare_reachable(p)` is
630
- encountered. Long running programs should arrange that calls are
631
- matched. — *end note*]
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*]
646
-
647
- *Effects:* The `n` bytes starting at `p` no longer contain traceable
648
- pointer locations, independent of their type. Hence indirection through
649
- a pointer located there is undefined if the object it points to was
650
- created by global `operator new` and not previously declared reachable.
651
-
652
- [*Note 3*: This may be used to inform a garbage collector or leak
653
- detector that this region of memory need not be traced. — *end note*]
654
-
655
- *Throws:* Nothing.
656
-
657
- [*Note 4*: Under some conditions implementations may need to allocate
658
- memory. However, the request can be ignored if memory allocation
659
- fails. — *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
  ```
@@ -720,17 +725,77 @@ similar [[conv.qual]] to `T`, where `X` has alignment `N`
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; };
@@ -740,12 +805,12 @@ namespace std {
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
 
@@ -806,28 +871,28 @@ return value or in-place, respectively.
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
@@ -835,17 +900,18 @@ 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) {
@@ -858,14 +924,14 @@ return make_tuple(
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,
@@ -873,14 +939,14 @@ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
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,
@@ -889,14 +955,17 @@ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
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,
@@ -905,23 +974,88 @@ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
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
 
@@ -945,17 +1079,22 @@ return apply([&]<class... U>(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,
952
  even if `allocator_traits` supplies the entire required interface.
953
 
954
  [*Note 1*: Thus, it is always possible to create a derived class from
955
  an allocator. — *end note*]
956
 
 
 
 
957
  ``` cpp
958
  namespace std {
959
  template<class Alloc> struct allocator_traits {
960
  using allocator_type = Alloc;
961
 
@@ -978,10 +1117,12 @@ namespace std {
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);
@@ -1100,10 +1241,18 @@ arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
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)`.
@@ -1139,12 +1288,20 @@ 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 {
@@ -1152,24 +1309,28 @@ namespace std {
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
@@ -1179,30 +1340,54 @@ 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.
@@ -1245,26 +1430,10 @@ void* realloc(void* ptr, size_t size);
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.
1254
-
1255
- [*Note 1*: This allows existing C libraries to remain unaffected by
1256
- restrictions on pointers that are not safely derived, at the expense of
1257
- providing far fewer garbage collection and leak detection options for
1258
- `malloc()`-allocated objects. It also allows `malloc()` to be
1259
- implemented with a separate allocation arena, bypassing the normal
1260
- `declare_reachable()` implementation. The above functions should never
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
 
 
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`,
16
+ `out_ptr_t`, `inout_ptr_t`, and various function templates that operate
17
+ on objects of these types [[smartptr]].
18
+
19
+ Let `POINTER_OF(T)` denote a type that is
20
+
21
+ - `T::pointer` if the *qualified-id* `T::pointer` is valid and denotes a
22
+ type,
23
+ - otherwise, `T::element_type*` if the *qualified-id* `T::element_type`
24
+ is valid and denotes a type,
25
+ - otherwise, `pointer_traits<T>::element_type*`.
26
+
27
+ Let `POINTER_OF_OR(T, U)` denote a type that is:
28
+
29
+ - `POINTER_OF(T)` if `POINTER_OF(T)` is valid and denotes a type,
30
+ - otherwise, `U`.
31
 
32
  ``` cpp
33
  #include <compare> // see [compare.syn]
34
 
35
  namespace std {
36
  // [pointer.traits], pointer traits
37
+ template<class Ptr> struct pointer_traits; // freestanding
38
+ template<class T> struct pointer_traits<T*>; // freestanding
39
 
40
  // [pointer.conversion], pointer conversion
41
  template<class T>
42
+ constexpr T* to_address(T* p) noexcept; // freestanding
43
  template<class Ptr>
44
+ constexpr auto to_address(const Ptr& p) noexcept; // freestanding
 
 
 
 
 
 
 
 
 
 
 
45
 
46
  // [ptr.align], pointer alignment
47
+ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestanding
48
  template<size_t N, class T>
49
+ [[nodiscard]] constexpr T* assume_aligned(T* ptr); // freestanding
50
+
51
+ // [obj.lifetime], explicit lifetime management
52
+ template<class T>
53
+ T* start_lifetime_as(void* p) noexcept; // freestanding
54
+ template<class T>
55
+ const T* start_lifetime_as(const void* p) noexcept; // freestanding
56
+ template<class T>
57
+ volatile T* start_lifetime_as(volatile void* p) noexcept; // freestanding
58
+ template<class T>
59
+ const volatile T* start_lifetime_as(const volatile void* p) noexcept; // freestanding
60
+ template<class T>
61
+ T* start_lifetime_as_array(void* p, size_t n) noexcept; // freestanding
62
+ template<class T>
63
+ const T* start_lifetime_as_array(const void* p, size_t n) noexcept; // freestanding
64
+ template<class T>
65
+ volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; // freestanding
66
+ template<class T>
67
+ const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding
68
+ size_t n) noexcept;
69
 
70
  // [allocator.tag], allocator argument tag
71
+ struct allocator_arg_t { // freestanding
72
+ explicit allocator_arg_t() = default; // freestanding
73
+ };
74
+ inline constexpr allocator_arg_t allocator_arg{}; // freestanding
75
 
76
  // [allocator.uses], uses_allocator
77
+ template<class T, class Alloc> struct uses_allocator; // freestanding
78
 
79
  // [allocator.uses.trait], uses_allocator
80
  template<class T, class Alloc>
81
+ constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; // freestanding
82
 
83
  // [allocator.uses.construction], uses-allocator construction
84
  template<class T, class Alloc, class... Args>
85
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
86
+ Args&&... args) noexcept;
87
  template<class T, class Alloc, class Tuple1, class Tuple2>
88
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
89
+ piecewise_construct_t,
90
+ Tuple1&& x, Tuple2&& y) noexcept;
91
  template<class T, class Alloc>
92
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept; // freestanding
93
  template<class T, class Alloc, class U, class V>
94
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
95
+ U&& u, V&& v) noexcept;
96
  template<class T, class Alloc, class U, class V>
97
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
98
+ pair<U, V>& pr) noexcept;
99
  template<class T, class Alloc, class U, class V>
100
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
101
+ const pair<U, V>& pr) noexcept;
102
+ template<class T, class Alloc, class U, class V>
103
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
104
+ pair<U, V>&& pr) noexcept;
105
+ template<class T, class Alloc, class U, class V>
106
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
107
+ const pair<U, V>&& pr) noexcept;
108
+ template<class T, class Alloc, pair-like P>
109
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
110
+ P&& p) noexcept;
111
+ template<class T, class Alloc, class U>
112
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding
113
+ U&& u) noexcept;
114
  template<class T, class Alloc, class... Args>
115
+ constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); // freestanding
116
  template<class T, class Alloc, class... Args>
117
+ constexpr T* uninitialized_construct_using_allocator(T* p, // freestanding
118
+ const Alloc& alloc, Args&&... args);
119
 
120
  // [allocator.traits], allocator traits
121
+ template<class Alloc> struct allocator_traits; // freestanding
122
+
123
+ template<class Pointer, class SizeType = size_t>
124
+ struct allocation_result { // freestanding
125
+ Pointer ptr;
126
+ SizeType count;
127
+ };
128
 
129
  // [default.allocator], the default allocator
130
  template<class T> class allocator;
131
  template<class T, class U>
132
  constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
133
 
134
  // [specialized.addressof], addressof
135
  template<class T>
136
+ constexpr T* addressof(T& r) noexcept; // freestanding
137
  template<class T>
138
+ const T* addressof(const T&&) = delete; // freestanding
139
 
140
  // [specialized.algorithms], specialized algorithms
141
  // [special.mem.concepts], special memory concepts
142
  template<class I>
143
+ concept nothrow-input-iterator = see below; // exposition only
144
  template<class I>
145
+ concept nothrow-forward-iterator = see below; // exposition only
146
  template<class S, class I>
147
+ concept nothrow-sentinel-for = see below; // exposition only
148
  template<class R>
149
+ concept nothrow-input-range = see below; // exposition only
150
  template<class R>
151
+ concept nothrow-forward-range = see below; // exposition only
152
 
153
  template<class NoThrowForwardIterator>
154
+ void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding
155
  NoThrowForwardIterator last);
156
  template<class ExecutionPolicy, class NoThrowForwardIterator>
157
  void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
158
  NoThrowForwardIterator first,
159
  NoThrowForwardIterator last);
160
  template<class NoThrowForwardIterator, class Size>
161
  NoThrowForwardIterator
162
+ uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding
163
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
164
  NoThrowForwardIterator
165
  uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
166
  NoThrowForwardIterator first, Size n);
167
 
168
  namespace ranges {
169
+ template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
170
  requires default_initializable<iter_value_t<I>>
171
+ I uninitialized_default_construct(I first, S last); // freestanding
172
+ template<nothrow-forward-range R>
173
  requires default_initializable<range_value_t<R>>
174
+ borrowed_iterator_t<R> uninitialized_default_construct(R&& r); // freestanding
175
 
176
+ template<nothrow-forward-iterator I>
177
  requires default_initializable<iter_value_t<I>>
178
+ I uninitialized_default_construct_n(I first, iter_difference_t<I> n); // freestanding
179
  }
180
 
181
  template<class NoThrowForwardIterator>
182
+ void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding
183
  NoThrowForwardIterator last);
184
  template<class ExecutionPolicy, class NoThrowForwardIterator>
185
  void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
186
  NoThrowForwardIterator first,
187
  NoThrowForwardIterator last);
188
  template<class NoThrowForwardIterator, class Size>
189
  NoThrowForwardIterator
190
+ uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding
191
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
192
  NoThrowForwardIterator
193
  uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
194
  NoThrowForwardIterator first, Size n);
195
 
196
  namespace ranges {
197
+ template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
198
  requires default_initializable<iter_value_t<I>>
199
+ I uninitialized_value_construct(I first, S last); // freestanding
200
+ template<nothrow-forward-range R>
201
  requires default_initializable<range_value_t<R>>
202
+ borrowed_iterator_t<R> uninitialized_value_construct(R&& r); // freestanding
203
 
204
+ template<nothrow-forward-iterator I>
205
  requires default_initializable<iter_value_t<I>>
206
+ I uninitialized_value_construct_n(I first, iter_difference_t<I> n); // freestanding
207
  }
208
 
209
  template<class InputIterator, class NoThrowForwardIterator>
210
+ NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding
211
+ InputIterator last,
212
  NoThrowForwardIterator result);
213
+ template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
214
  NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
215
+ ForwardIterator first, ForwardIterator last,
216
  NoThrowForwardIterator result);
217
  template<class InputIterator, class Size, class NoThrowForwardIterator>
218
+ NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, // freestanding
219
  NoThrowForwardIterator result);
220
+ template<class ExecutionPolicy, class ForwardIterator, class Size,
221
+ class NoThrowForwardIterator>
222
  NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
223
+ ForwardIterator first, Size n,
224
  NoThrowForwardIterator result);
225
 
226
  namespace ranges {
227
  template<class I, class O>
228
+ using uninitialized_copy_result = in_out_result<I, O>; // freestanding
229
  template<input_iterator I, sentinel_for<I> S1,
230
+ nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
231
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
232
  uninitialized_copy_result<I, O>
233
+ uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
234
+ template<input_range IR, nothrow-forward-range OR>
235
  requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
236
  uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
237
+ uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding
238
 
239
  template<class I, class O>
240
+ using uninitialized_copy_n_result = in_out_result<I, O>; // freestanding
241
+ template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
242
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
243
  uninitialized_copy_n_result<I, O>
244
+ uninitialized_copy_n(I ifirst, iter_difference_t<I> n, // freestanding
245
+ O ofirst, S olast);
246
  }
247
 
248
  template<class InputIterator, class NoThrowForwardIterator>
249
+ NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding
250
+ InputIterator last,
251
  NoThrowForwardIterator result);
252
+ template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
253
  NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
254
+ ForwardIterator first, ForwardIterator last,
255
  NoThrowForwardIterator result);
256
  template<class InputIterator, class Size, class NoThrowForwardIterator>
257
  pair<InputIterator, NoThrowForwardIterator>
258
+ uninitialized_move_n(InputIterator first, Size n, // freestanding
259
+ NoThrowForwardIterator result);
260
+ template<class ExecutionPolicy, class ForwardIterator, class Size,
261
+ class NoThrowForwardIterator>
262
+ pair<ForwardIterator, NoThrowForwardIterator>
263
  uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
264
+ ForwardIterator first, Size n, NoThrowForwardIterator result);
265
 
266
  namespace ranges {
267
  template<class I, class O>
268
+ using uninitialized_move_result = in_out_result<I, O>; // freestanding
269
  template<input_iterator I, sentinel_for<I> S1,
270
+ nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
271
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
272
  uninitialized_move_result<I, O>
273
+ uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
274
+ template<input_range IR, nothrow-forward-range OR>
275
  requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
276
  uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
277
+ uninitialized_move(IR&& in_range, OR&& out_range); // freestanding
278
 
279
  template<class I, class O>
280
+ using uninitialized_move_n_result = in_out_result<I, O>; // freestanding
281
  template<input_iterator I,
282
+ nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
283
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
284
  uninitialized_move_n_result<I, O>
285
+ uninitialized_move_n(I ifirst, iter_difference_t<I> n, // freestanding
286
+ O ofirst, S olast);
287
  }
288
 
289
  template<class NoThrowForwardIterator, class T>
290
+ void uninitialized_fill(NoThrowForwardIterator first, // freestanding
291
+ NoThrowForwardIterator last, const T& x);
292
  template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
293
  void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
294
  NoThrowForwardIterator first, NoThrowForwardIterator last,
295
  const T& x);
296
  template<class NoThrowForwardIterator, class Size, class T>
297
  NoThrowForwardIterator
298
+ uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding
299
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
300
  NoThrowForwardIterator
301
  uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
302
  NoThrowForwardIterator first, Size n, const T& x);
303
 
304
  namespace ranges {
305
+ template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S, class T>
306
  requires constructible_from<iter_value_t<I>, const T&>
307
+ I uninitialized_fill(I first, S last, const T& x); // freestanding
308
+ template<nothrow-forward-range R, class T>
309
  requires constructible_from<range_value_t<R>, const T&>
310
+ borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); // freestanding
311
 
312
+ template<nothrow-forward-iterator I, class T>
313
  requires constructible_from<iter_value_t<I>, const T&>
314
+ I uninitialized_fill_n(I first, iter_difference_t<I> n, const T& x); // freestanding
315
  }
316
 
317
  // [specialized.construct], construct_at
318
  template<class T, class... Args>
319
+ constexpr T* construct_at(T* location, Args&&... args); // freestanding
320
 
321
  namespace ranges {
322
  template<class T, class... Args>
323
+ constexpr T* construct_at(T* location, Args&&... args); // freestanding
324
  }
325
 
326
  // [specialized.destroy], destroy
327
  template<class T>
328
+ constexpr void destroy_at(T* location); // freestanding
329
  template<class NoThrowForwardIterator>
330
+ constexpr void destroy(NoThrowForwardIterator first, // freestanding
331
+ NoThrowForwardIterator last);
332
  template<class ExecutionPolicy, class NoThrowForwardIterator>
333
  void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
334
  NoThrowForwardIterator first, NoThrowForwardIterator last);
335
  template<class NoThrowForwardIterator, class Size>
336
+ constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding
337
+ Size n);
338
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
339
  NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
340
  NoThrowForwardIterator first, Size n);
341
 
342
  namespace ranges {
343
  template<destructible T>
344
+ constexpr void destroy_at(T* location) noexcept; // freestanding
345
 
346
+ template<nothrow-input-iterator I, nothrow-sentinel-for<I> S>
347
  requires destructible<iter_value_t<I>>
348
+ constexpr I destroy(I first, S last) noexcept; // freestanding
349
+ template<nothrow-input-range R>
350
  requires destructible<range_value_t<R>>
351
+ constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; // freestanding
352
 
353
+ template<nothrow-input-iterator I>
354
  requires destructible<iter_value_t<I>>
355
+ constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; // freestanding
356
  }
357
 
358
  // [unique.ptr], class template unique_ptr
359
+ template<class T> struct default_delete; // freestanding
360
+ template<class T> struct default_delete<T[]>; // freestanding
361
+ template<class T, class D = default_delete<T>> class unique_ptr; // freestanding
362
+ template<class T, class D> class unique_ptr<T[], D>; // freestanding
363
 
364
  template<class T, class... Args>
365
+ constexpr unique_ptr<T> make_unique(Args&&... args); // T is not array
366
  template<class T>
367
+ constexpr unique_ptr<T> make_unique(size_t n); // T is U[]
368
  template<class T, class... Args>
369
  unspecified make_unique(Args&&...) = delete; // T is U[N]
370
 
371
  template<class T>
372
+ constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array
373
  template<class T>
374
+ constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]
375
  template<class T, class... Args>
376
  unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N]
377
 
378
  template<class T, class D>
379
+ constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; // freestanding
380
 
381
  template<class T1, class D1, class T2, class D2>
382
+ constexpr bool operator==(const unique_ptr<T1, D1>& x, // freestanding
383
+ const unique_ptr<T2, D2>& y);
384
  template<class T1, class D1, class T2, class D2>
385
+ bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
386
  template<class T1, class D1, class T2, class D2>
387
+ bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
388
  template<class T1, class D1, class T2, class D2>
389
+ bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
390
  template<class T1, class D1, class T2, class D2>
391
+ bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
392
  template<class T1, class D1, class T2, class D2>
393
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
394
  typename unique_ptr<T2, D2>::pointer>
395
  compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
396
  typename unique_ptr<T2, D2>::pointer>
397
+ operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
398
 
399
  template<class T, class D>
400
+ constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // freestanding
401
  template<class T, class D>
402
+ constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t); // freestanding
403
  template<class T, class D>
404
+ constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y); // freestanding
405
  template<class T, class D>
406
+ constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t); // freestanding
407
  template<class T, class D>
408
+ constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y); // freestanding
409
  template<class T, class D>
410
+ constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t); // freestanding
411
  template<class T, class D>
412
+ constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y); // freestanding
413
  template<class T, class D>
414
+ constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t); // freestanding
415
  template<class T, class D>
416
+ constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y); // freestanding
417
  template<class T, class D>
418
+ requires three_way_comparable<typename unique_ptr<T, D>::pointer>
419
+ constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
420
+ operator<=>(const unique_ptr<T, D>& x, nullptr_t); // freestanding
421
 
422
  template<class E, class T, class Y, class D>
423
  basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p);
424
 
425
  // [util.smartptr.weak.bad], class bad_weak_ptr
 
517
 
518
  // [util.smartptr.enab], class template enable_shared_from_this
519
  template<class T> class enable_shared_from_this;
520
 
521
  // [util.smartptr.hash], hash support
522
+ template<class T> struct hash; // freestanding
523
+ template<class T, class D> struct hash<unique_ptr<T, D>>; // freestanding
524
  template<class T> struct hash<shared_ptr<T>>;
525
 
526
  // [util.smartptr.atomic], atomic smart pointers
527
+ template<class T> struct atomic; // freestanding
528
  template<class T> struct atomic<shared_ptr<T>>;
529
  template<class T> struct atomic<weak_ptr<T>>;
530
+
531
+ // [out.ptr.t], class template out_ptr_t
532
+ template<class Smart, class Pointer, class... Args>
533
+ class out_ptr_t;
534
+
535
+ // [out.ptr], function template out_ptr
536
+ template<class Pointer = void, class Smart, class... Args>
537
+ auto out_ptr(Smart& s, Args&&... args);
538
+
539
+ // [inout.ptr.t], class template inout_ptr_t
540
+ template<class Smart, class Pointer, class... Args>
541
+ class inout_ptr_t;
542
+
543
+ // [inout.ptr], function template inout_ptr
544
+ template<class Pointer = void, class Smart, class... Args>
545
+ auto inout_ptr(Smart& s, Args&&... args);
546
  }
547
  ```
548
 
549
  ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
550
 
551
+ #### General <a id="pointer.traits.general">[[pointer.traits.general]]</a>
552
+
553
  The class template `pointer_traits` supplies a uniform interface to
554
  certain attributes of pointer-like types.
555
 
556
  ``` cpp
557
  namespace std {
558
  template<class Ptr> struct pointer_traits {
559
+ see below;
 
 
 
 
 
 
560
  };
561
 
562
  template<class T> struct pointer_traits<T*> {
563
  using pointer = T*;
564
  using element_type = T;
 
571
  }
572
  ```
573
 
574
  #### Member types <a id="pointer.traits.types">[[pointer.traits.types]]</a>
575
 
576
+ The definitions in this subclause make use of the following
577
+ exposition-only class template and concept:
578
+
579
+ ``` cpp
580
+ template<class T>
581
+ struct ptr-traits-elem // exposition only
582
+ { };
583
+
584
+ template<class T> requires requires { typename T::element_type; }
585
+ struct ptr-traits-elem<T>
586
+ { using type = typename T::element_type; };
587
+
588
+ template<template<class...> class SomePointer, class T, class... Args>
589
+ requires (!requires { typename SomePointer<T, Args...>::element_type; })
590
+ struct ptr-traits-elem<SomePointer<T, Args...>>
591
+ { using type = T; };
592
+
593
+ template<class Ptr>
594
+ concept has-elem-type = // exposition only
595
+ requires { typename ptr-traits-elem<Ptr>::type; }
596
+ ```
597
+
598
+ If `Ptr` satisfies `has-elem-type`, a specialization
599
+ `pointer_traits<Ptr>` generated from the `pointer_traits` primary
600
+ template has the following members as well as those described in 
601
+ [[pointer.traits.functions]]; otherwise, such a specialization has no
602
+ members by any of those names.
603
+
604
+ ``` cpp
605
+ using pointer = see below;
606
+ ```
607
+
608
+ *Type:* `Ptr`.
609
+
610
  ``` cpp
611
  using element_type = see below;
612
  ```
613
 
614
+ *Type:* `typename `*`ptr-traits-elem`*`<Ptr>::type`.
 
 
 
 
615
 
616
  ``` cpp
617
  using difference_type = see below;
618
  ```
619
 
 
651
  unspecified; otherwise, it is `element_type&`.
652
 
653
  #### Optional members <a id="pointer.traits.optmem">[[pointer.traits.optmem]]</a>
654
 
655
  Specializations of `pointer_traits` may define the member declared in
656
+ this subclause to customize the behavior of the standard library. A
657
+ specialization generated from the `pointer_traits` primary template has
658
+ no member by this name.
659
 
660
  ``` cpp
661
  static element_type* to_address(pointer p) noexcept;
662
  ```
663
 
664
  *Returns:* A pointer of type `element_type*` that references the same
665
  location as the argument `p`.
666
 
667
+ [*Note 1*: This function is intended to be the inverse of `pointer_to`.
668
+ If defined, it customizes the behavior of the non-member function
669
  `to_address` [[pointer.conversion]]. — *end note*]
670
 
671
  ### Pointer conversion <a id="pointer.conversion">[[pointer.conversion]]</a>
672
 
673
  ``` cpp
 
684
 
685
  *Returns:* `pointer_traits<Ptr>::to_address(p)` if that expression is
686
  well-formed (see [[pointer.traits.optmem]]), otherwise
687
  `to_address(p.operator->())`.
688
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
  ### Pointer alignment <a id="ptr.align">[[ptr.align]]</a>
690
 
691
  ``` cpp
692
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
693
  ```
 
725
  *Returns:* `ptr`.
726
 
727
  *Throws:* Nothing.
728
 
729
  [*Note 2*: The alignment assumption on an object `X` expressed by a
730
+ call to `assume_aligned` might result in generation of more efficient
731
  code. It is up to the program to ensure that the assumption actually
732
+ holds. The call does not cause the implementation to verify or enforce
733
+ this. An implementation might only make the assumption for those
734
+ operations on `X` that access `X` through the pointer returned by
735
  `assume_aligned`. — *end note*]
736
 
737
+ ### Explicit lifetime management <a id="obj.lifetime">[[obj.lifetime]]</a>
738
+
739
+ ``` cpp
740
+ template<class T>
741
+ T* start_lifetime_as(void* p) noexcept;
742
+ template<class T>
743
+ const T* start_lifetime_as(const void* p) noexcept;
744
+ template<class T>
745
+ volatile T* start_lifetime_as(volatile void* p) noexcept;
746
+ template<class T>
747
+ const volatile T* start_lifetime_as(const volatile void* p) noexcept;
748
+ ```
749
+
750
+ *Mandates:* `T` is an implicit-lifetime type [[basic.types.general]] and
751
+ not an incomplete type [[term.incomplete.type]].
752
+
753
+ *Preconditions:* \[`p`, `(char*)p + sizeof(T)`) denotes a region of
754
+ allocated storage that is a subset of the region of storage reachable
755
+ through [[basic.compound]] `p` and suitably aligned for the type `T`.
756
+
757
+ *Effects:* Implicitly creates objects [[intro.object]] within the
758
+ denoted region consisting of an object *a* of type `T` whose address is
759
+ `p`, and objects nested within *a*, as follows: The object
760
+ representation of *a* is the contents of the storage prior to the call
761
+ to `start_lifetime_as`. The value of each created object *o* of
762
+ trivially-copyable type `U` is determined in the same manner as for a
763
+ call to `bit_cast<U>(E)` [[bit.cast]], where `E` is an lvalue of type
764
+ `U` denoting *o*, except that the storage is not accessed. The value of
765
+ any other created object is unspecified.
766
+
767
+ [*Note 1*: The unspecified value can be indeterminate. — *end note*]
768
+
769
+ *Returns:* A pointer to the *a* defined in the *Effects* paragraph.
770
+
771
+ ``` cpp
772
+ template<class T>
773
+ T* start_lifetime_as_array(void* p, size_t n) noexcept;
774
+ template<class T>
775
+ const T* start_lifetime_as_array(const void* p, size_t n) noexcept;
776
+ template<class T>
777
+ volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept;
778
+ template<class T>
779
+ const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept;
780
+ ```
781
+
782
+ *Mandates:* `T` is a complete type.
783
+
784
+ *Preconditions:* `p` is suitably aligned for an array of `T` or is null.
785
+ `n <= size_t(-1) / sizeof(T)` is `true`. If `n > 0` is `true`,
786
+ \[`(char*)p`, `(char*)p + (n * sizeof(T))`) denotes a region of
787
+ allocated storage that is a subset of the region of storage reachable
788
+ through [[basic.compound]] `p`.
789
+
790
+ *Effects:* If `n > 0` is `true`, equivalent to `start_lifetime_as<U>(p)`
791
+ where `U` is the type “array of `n` `T`”. Otherwise, there are no
792
+ effects.
793
+
794
+ *Returns:* A pointer to the first element of the created array, if any;
795
+ otherwise, a pointer that compares equal to `p` [[expr.eq]].
796
+
797
  ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
798
 
799
  ``` cpp
800
  namespace std {
801
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
 
805
 
806
  The `allocator_arg_t` struct is an empty class type used as a unique
807
  type to disambiguate constructor and function overloading. Specifically,
808
  several types (see `tuple`  [[tuple]]) have constructors with
809
  `allocator_arg_t` as the first argument, immediately followed by an
810
+ argument of a type that meets the *Cpp17Allocator* requirements
811
+ [[allocator.requirements.general]].
812
 
813
  ### `uses_allocator` <a id="allocator.uses">[[allocator.uses]]</a>
814
 
815
  #### `uses_allocator` trait <a id="allocator.uses.trait">[[allocator.uses.trait]]</a>
816
 
 
871
  be specified explicitly by the caller. — *end note*]
872
 
873
  ``` cpp
874
  template<class T, class Alloc, class... Args>
875
  constexpr auto uses_allocator_construction_args(const Alloc& alloc,
876
+ Args&&... args) noexcept;
877
  ```
878
 
879
+ *Constraints:* `remove_cv_t<T>` is not a specialization of `pair`.
880
 
881
  *Returns:* A `tuple` value determined as follows:
882
 
883
+ - If `uses_allocator_v<remove_cv_t<T>, Alloc>` is `false` and
884
  `is_constructible_v<T,Args...>` is `true`, return
885
  `forward_as_tuple(std::forward<Args>(args)...)`.
886
+ - Otherwise, if `uses_allocator_v<remove_cv_t<T>, Alloc>` is `true` and
887
  `is_constructible_v<T, allocator_arg_t, const Alloc&, Args...>` is
888
  `true`, return
889
  ``` cpp
890
  tuple<allocator_arg_t, const Alloc&, Args&&...>(
891
  allocator_arg, alloc, std::forward<Args>(args)...)
892
  ```
893
+ - Otherwise, if `uses_allocator_v<remove_cv_t<T>, Alloc>` is `true` and
894
  `is_constructible_v<T, Args..., const Alloc&>` is `true`, return
895
  `forward_as_tuple(std::forward<Args>(args)..., alloc)`.
896
  - Otherwise, the program is ill-formed.
897
 
898
  [*Note 1*: This definition prevents a silent failure to pass the
 
900
  `uses_allocator_v<T, Alloc>` is `true`. — *end note*]
901
 
902
  ``` cpp
903
  template<class T, class Alloc, class Tuple1, class Tuple2>
904
  constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
905
+ Tuple1&& x, Tuple2&& y) noexcept;
 
906
  ```
907
 
908
+ Let `T1` be `T::first_type`. Let `T2` be `T::second_type`.
909
 
910
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
911
+
912
+ *Effects:* Equivalent to:
913
 
914
  ``` cpp
915
  return make_tuple(
916
  piecewise_construct,
917
  apply([&alloc](auto&&... args1) {
 
924
  }, std::forward<Tuple2>(y)));
925
  ```
926
 
927
  ``` cpp
928
  template<class T, class Alloc>
929
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;
930
  ```
931
 
932
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
933
 
934
  *Effects:* Equivalent to:
935
 
936
  ``` cpp
937
  return uses_allocator_construction_args<T>(alloc, piecewise_construct,
 
939
  ```
940
 
941
  ``` cpp
942
  template<class T, class Alloc, class U, class V>
943
  constexpr auto uses_allocator_construction_args(const Alloc& alloc,
944
+ U&& u, V&& v) noexcept;
945
  ```
946
 
947
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
948
 
949
  *Effects:* Equivalent to:
950
 
951
  ``` cpp
952
  return uses_allocator_construction_args<T>(alloc, piecewise_construct,
 
955
  ```
956
 
957
  ``` cpp
958
  template<class T, class Alloc, class U, class V>
959
  constexpr auto uses_allocator_construction_args(const Alloc& alloc,
960
+ pair<U, V>& pr) noexcept;
961
+ template<class T, class Alloc, class U, class V>
962
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
963
+ const pair<U, V>& pr) noexcept;
964
  ```
965
 
966
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
967
 
968
  *Effects:* Equivalent to:
969
 
970
  ``` cpp
971
  return uses_allocator_construction_args<T>(alloc, piecewise_construct,
 
974
  ```
975
 
976
  ``` cpp
977
  template<class T, class Alloc, class U, class V>
978
  constexpr auto uses_allocator_construction_args(const Alloc& alloc,
979
+ pair<U, V>&& pr) noexcept;
980
+ template<class T, class Alloc, class U, class V>
981
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
982
+ const pair<U, V>&& pr) noexcept;
983
  ```
984
 
985
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`.
986
 
987
  *Effects:* Equivalent to:
988
 
989
  ``` cpp
990
  return uses_allocator_construction_args<T>(alloc, piecewise_construct,
991
+ forward_as_tuple(get<0>(std::move(pr))),
992
+ forward_as_tuple(get<1>(std::move(pr))));
993
  ```
994
 
995
+ ``` cpp
996
+ template<class T, class Alloc, pair-like P>
997
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
998
+ ```
999
+
1000
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair` and
1001
+ `remove_cvref_t<P>` is not a specialization of `ranges::subrange`.
1002
+
1003
+ *Effects:* Equivalent to:
1004
+
1005
+ ``` cpp
1006
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
1007
+ forward_as_tuple(get<0>(std::forward<P>(p))),
1008
+ forward_as_tuple(get<1>(std::forward<P>(p))));
1009
+ ```
1010
+
1011
+ ``` cpp
1012
+ template<class T, class Alloc, class U>
1013
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
1014
+ ```
1015
+
1016
+ Let *FUN* be the function template:
1017
+
1018
+ ``` cpp
1019
+ template<class A, class B>
1020
+ void FUN(const pair<A, B>&);
1021
+ ```
1022
+
1023
+ *Constraints:* `remove_cv_t<T>` is a specialization of `pair`, and
1024
+ either:
1025
+
1026
+ - `remove_cvref_t<U>` is a specialization of `ranges::subrange`, or
1027
+ - `U` does not satisfy `pair-like` and the expression *`FUN`*`(u)` is
1028
+ not well-formed when considered as an unevaluated operand.
1029
+
1030
+ Let *pair-constructor* be an exposition-only class defined as follows:
1031
+
1032
+ ``` cpp
1033
+ class pair-constructor {
1034
+ using pair-type = remove_cv_t<T>; // exposition only
1035
+
1036
+ constexpr auto do-construct(const pair-type& p) const { // exposition only
1037
+ return make_obj_using_allocator<pair-type>(alloc_, p);
1038
+ }
1039
+ constexpr auto do-construct(pair-type&& p) const { // exposition only
1040
+ return make_obj_using_allocator<pair-type>(alloc_, std::move(p));
1041
+ }
1042
+
1043
+ const Alloc& alloc_; // exposition only
1044
+ U& u_; // exposition only
1045
+
1046
+ public:
1047
+ constexpr operator pair-type() const {
1048
+ return do-construct(std::forward<U>(u_));
1049
+ }
1050
+ };
1051
+ ```
1052
+
1053
+ *Returns:* `make_tuple(pc)`, where `pc` is a *pair-constructor* object
1054
+ whose *alloc\_* member is initialized with `alloc` and whose *u\_*
1055
+ member is initialized with `u`.
1056
+
1057
  ``` cpp
1058
  template<class T, class Alloc, class... Args>
1059
  constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
1060
  ```
1061
 
 
1079
  }, uses_allocator_construction_args<T>(alloc, std::forward<Args>(args)...));
1080
  ```
1081
 
1082
  ### Allocator traits <a id="allocator.traits">[[allocator.traits]]</a>
1083
 
1084
+ #### General <a id="allocator.traits.general">[[allocator.traits.general]]</a>
1085
+
1086
  The class template `allocator_traits` supplies a uniform interface to
1087
  all allocator types. An allocator cannot be a non-class type, however,
1088
  even if `allocator_traits` supplies the entire required interface.
1089
 
1090
  [*Note 1*: Thus, it is always possible to create a derived class from
1091
  an allocator. — *end note*]
1092
 
1093
+ If a program declares an explicit or partial specialization of
1094
+ `allocator_traits`, the program is ill-formed, no diagnostic required.
1095
+
1096
  ``` cpp
1097
  namespace std {
1098
  template<class Alloc> struct allocator_traits {
1099
  using allocator_type = Alloc;
1100
 
 
1117
  template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
1118
 
1119
  [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1120
  [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
1121
  const_void_pointer hint);
1122
+ [[nodiscard]] static constexpr allocation_result<pointer, size_type>
1123
+ allocate_at_least(Alloc& a, size_type n);
1124
 
1125
  static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1126
 
1127
  template<class T, class... Args>
1128
  static constexpr void construct(Alloc& a, T* p, Args&&... args);
 
1241
  ```
1242
 
1243
  *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
1244
  otherwise, `a.allocate(n)`.
1245
 
1246
+ ``` cpp
1247
+ [[nodiscard]] static constexpr allocation_result<pointer, size_type>
1248
+ allocate_at_least(Alloc& a, size_type n);
1249
+ ```
1250
+
1251
+ *Returns:* `a.allocate_at_least(n)` if that expression is well-formed;
1252
+ otherwise, `{a.allocate(n), n}`.
1253
+
1254
  ``` cpp
1255
  static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1256
  ```
1257
 
1258
  *Effects:* Calls `a.deallocate(p, n)`.
 
1288
  ```
1289
 
1290
  *Returns:* `rhs.select_on_container_copy_construction()` if that
1291
  expression is well-formed; otherwise, `rhs`.
1292
 
1293
+ #### Other <a id="allocator.traits.other">[[allocator.traits.other]]</a>
1294
+
1295
+ The class template `allocation_result` has the template parameters, data
1296
+ members, and special members specified above. It has no base classes or
1297
+ members other than those specified.
1298
+
1299
  ### The default allocator <a id="default.allocator">[[default.allocator]]</a>
1300
 
1301
+ #### General <a id="default.allocator.general">[[default.allocator.general]]</a>
1302
+
1303
  All specializations of the default allocator meet the allocator
1304
  completeness requirements [[allocator.requirements.completeness]].
1305
 
1306
  ``` cpp
1307
  namespace std {
 
1309
  public:
1310
  using value_type = T;
1311
  using size_type = size_t;
1312
  using difference_type = ptrdiff_t;
1313
  using propagate_on_container_move_assignment = true_type;
 
1314
 
1315
  constexpr allocator() noexcept;
1316
  constexpr allocator(const allocator&) noexcept;
1317
  template<class U> constexpr allocator(const allocator<U>&) noexcept;
1318
  constexpr ~allocator();
1319
  constexpr allocator& operator=(const allocator&) = default;
1320
 
1321
  [[nodiscard]] constexpr T* allocate(size_t n);
1322
+ [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);
1323
  constexpr void deallocate(T* p, size_t n);
1324
  };
1325
  }
1326
  ```
1327
 
1328
+ `allocator_traits<allocator<T>>::is_always_equal::value`
1329
+
1330
+ is `true` for any `T`.
1331
+
1332
  #### Members <a id="allocator.members">[[allocator.members]]</a>
1333
 
1334
  Except for the destructor, member functions of the default allocator
1335
  shall not introduce data races [[intro.multithread]] as a result of
1336
  concurrent calls to those member functions from different threads. Calls
 
1340
 
1341
  ``` cpp
1342
  [[nodiscard]] constexpr T* allocate(size_t n);
1343
  ```
1344
 
1345
+ *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1346
 
1347
  *Returns:* A pointer to the initial element of an array of `n` `T`.
1348
 
1349
+ *Throws:* `bad_array_new_length` if
1350
+ `numeric_limits<size_t>::max() / sizeof(T) < n`, or `bad_alloc` if the
1351
+ storage cannot be obtained.
1352
+
1353
  *Remarks:* The storage for the array is obtained by calling
1354
  `::operator new` [[new.delete]], but it is unspecified when or how often
1355
  this function is called. This function starts the lifetime of the array
1356
  object, but not that of any of the array elements.
1357
 
1358
+ ``` cpp
1359
+ [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);
1360
+ ```
1361
+
1362
+ *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1363
+
1364
+ *Returns:* `allocation_result<T*>{ptr, count}`, where `ptr` is a pointer
1365
+ to the initial element of an array of `count` `T` and `count` ≥ `n`.
1366
+
1367
  *Throws:* `bad_array_new_length` if
1368
+ `numeric_limits<size_t>::max() / sizeof(T)` < `n`, or `bad_alloc` if the
1369
  storage cannot be obtained.
1370
 
1371
+ *Remarks:* The storage for the array is obtained by calling
1372
+ `::operator new`, but it is unspecified when or how often this function
1373
+ is called. This function starts the lifetime of the array object, but
1374
+ not that of any of the array elements.
1375
+
1376
  ``` cpp
1377
  constexpr void deallocate(T* p, size_t n);
1378
  ```
1379
 
1380
+ *Preconditions:*
1381
+
1382
+ - If `p` is memory that was obtained by a call to `allocate_at_least`,
1383
+ let `ret` be the value returned and `req` be the value passed as the
1384
+ first argument to that call. `p` is equal to `ret.ptr` and `n` is a
1385
+ value such that `req` ≤ `n` ≤ `ret.count`.
1386
+ - Otherwise, `p` is a pointer value obtained from `allocate`. `n` equals
1387
+ the value passed as the first argument to the invocation of `allocate`
1388
+ which returned `p`.
1389
 
1390
  *Effects:* Deallocates the storage referenced by `p`.
1391
 
1392
  *Remarks:* Uses `::operator delete` [[new.delete]], but it is
1393
  unspecified when this function is called.
 
1430
  standard library.
1431
 
1432
  *Remarks:* These functions do not attempt to allocate storage by calling
1433
  `::operator new()` [[new.delete]].
1434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1435
  These functions implicitly create objects [[intro.object]] in the
1436
  returned region of storage and return a pointer to a suitable created
1437
  object. In the case of `calloc` and `realloc`, the objects are created
1438
  before the storage is zeroed or copied, respectively.
1439