From Jason Turner

[memory]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpia523s64/{from.md → to.md} +382 -124
tmp/tmpia523s64/{from.md → to.md} RENAMED
@@ -1,8 +1,8 @@
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>
@@ -44,11 +44,13 @@ namespace std {
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>
@@ -64,15 +66,17 @@ namespace std {
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
 
@@ -141,179 +145,287 @@ namespace std {
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
@@ -328,18 +440,19 @@ namespace std {
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
 
@@ -351,10 +464,24 @@ namespace std {
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
@@ -380,21 +507,25 @@ namespace std {
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
@@ -428,95 +559,103 @@ namespace std {
428
  // [util.smartptr.shared], class template shared_ptr
429
  template<class T> class shared_ptr;
430
 
431
  // [util.smartptr.shared.create], shared_ptr creation
432
  template<class T, class... Args>
433
- shared_ptr<T> make_shared(Args&&... args); // T is not array
434
  template<class T, class A, class... Args>
435
- shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
436
 
437
  template<class T>
438
- shared_ptr<T> make_shared(size_t N); // T is U[]
439
  template<class T, class A>
440
- shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
441
 
442
  template<class T>
443
- shared_ptr<T> make_shared(); // T is U[N]
444
  template<class T, class A>
445
- shared_ptr<T> allocate_shared(const A& a); // T is U[N]
446
 
447
  template<class T>
448
- shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
449
  template<class T, class A>
450
- shared_ptr<T> allocate_shared(const A& a, size_t N,
451
  const remove_extent_t<T>& u); // T is U[]
452
 
453
  template<class T>
454
- shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
455
  template<class T, class A>
456
- shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N]
 
457
 
458
  template<class T>
459
- shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
460
  template<class T, class A>
461
- shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]
462
 
463
  template<class T>
464
- shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
465
  template<class T, class A>
466
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]
467
 
468
  // [util.smartptr.shared.cmp], shared_ptr comparisons
469
  template<class T, class U>
470
- bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
471
  template<class T, class U>
472
- strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
473
 
474
  template<class T>
475
- bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
476
  template<class T>
477
- strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept;
478
 
479
  // [util.smartptr.shared.spec], shared_ptr specialized algorithms
480
  template<class T>
481
- void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
482
 
483
  // [util.smartptr.shared.cast], shared_ptr casts
484
  template<class T, class U>
485
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
486
  template<class T, class U>
487
- shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
488
  template<class T, class U>
489
- shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
490
  template<class T, class U>
491
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
492
  template<class T, class U>
493
- shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
494
  template<class T, class U>
495
- shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
496
  template<class T, class U>
497
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
498
  template<class T, class U>
499
  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
500
 
501
  // [util.smartptr.getdeleter], shared_ptr get_deleter
502
  template<class D, class T>
503
- D* get_deleter(const shared_ptr<T>& p) noexcept;
504
 
505
  // [util.smartptr.shared.io], shared_ptr I/O
506
  template<class E, class T, class Y>
507
  basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
508
 
509
  // [util.smartptr.weak], class template weak_ptr
510
  template<class T> class weak_ptr;
511
 
512
  // [util.smartptr.weak.spec], weak_ptr specialized algorithms
513
- template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
514
 
515
  // [util.smartptr.ownerless], class template owner_less
516
  template<class T = void> struct owner_less;
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
@@ -528,23 +667,39 @@ namespace std {
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
 
@@ -581,11 +736,11 @@ 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; };
@@ -711,31 +866,43 @@ into the available space, otherwise the adjusted value of `ptr`.
711
  it can be called repeatedly with possibly different `alignment` and
712
  `size` arguments for the same buffer. — *end note*]
713
 
714
  ``` cpp
715
  template<size_t N, class T>
716
- [[nodiscard]] constexpr T* assume_aligned(T* ptr);
717
  ```
718
 
719
  *Mandates:* `N` is a power of two.
720
 
721
- *Preconditions:* `ptr` points to an object `X` of a type
722
- similar [[conv.qual]] to `T`, where `X` has alignment `N`
723
- [[basic.align]].
724
 
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;
@@ -745,26 +912,28 @@ 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
 
@@ -792,10 +961,86 @@ 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; };
@@ -1096,11 +1341,11 @@ If a program declares an explicit or partial specialization of
1096
  ``` cpp
1097
  namespace std {
1098
  template<class Alloc> struct allocator_traits {
1099
  using allocator_type = Alloc;
1100
 
1101
- using value_type = typename Alloc::value_type;
1102
 
1103
  using pointer = see below;
1104
  using const_pointer = see below;
1105
  using void_pointer = see below;
1106
  using const_void_pointer = see below;
@@ -1114,14 +1359,13 @@ namespace std {
1114
  using is_always_equal = see below;
1115
 
1116
  template<class T> using rebind_alloc = see below;
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>
@@ -1229,25 +1473,24 @@ of the form `Alloc<U, Args>`, where `Args` is zero or more type
1229
  arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
1230
 
1231
  #### Static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
1232
 
1233
  ``` cpp
1234
- [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1235
  ```
1236
 
1237
  *Returns:* `a.allocate(n)`.
1238
 
1239
  ``` cpp
1240
- [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
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
 
@@ -1316,12 +1559,12 @@ namespace std {
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
 
@@ -1337,11 +1580,11 @@ concurrent calls to those member functions from different threads. Calls
1337
  to these functions that allocate or deallocate a particular unit of
1338
  storage shall occur in a single total order, and each such deallocation
1339
  call shall happen before the next allocation (if any) in this order.
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`.
@@ -1354,11 +1597,11 @@ storage cannot be obtained.
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
@@ -1421,23 +1664,38 @@ this subclause. — *end note*]
1421
 
1422
  ``` cpp
1423
  void* aligned_alloc(size_t alignment, size_t size);
1424
  void* calloc(size_t nmemb, size_t size);
1425
  void* malloc(size_t size);
1426
- void* realloc(void* ptr, size_t size);
1427
  ```
1428
 
1429
  *Effects:* These functions have the semantics specified in the C
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
 
1440
  ``` cpp
1441
  void free(void* ptr);
1442
  ```
1443
 
@@ -1445,7 +1703,7 @@ void free(void* ptr);
1445
  library.
1446
 
1447
  *Remarks:* This function does not attempt to deallocate storage by
1448
  calling `::operator delete()`.
1449
 
1450
- See also: ISO C 7.22.3
1451
 
 
1
  ## Memory <a id="memory">[[memory]]</a>
2
 
3
+ ### 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>
 
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
+ constexpr T* assume_aligned(T* ptr); // freestanding
50
+ template<size_t Alignment, class T>
51
+ bool is_sufficiently_aligned(T* ptr);
52
 
53
  // [obj.lifetime], explicit lifetime management
54
  template<class T>
55
  T* start_lifetime_as(void* p) noexcept; // freestanding
56
  template<class T>
 
66
  template<class T>
67
  volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; // freestanding
68
  template<class T>
69
  const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding
70
  size_t n) noexcept;
71
+ template<class T>
72
+ T* trivially_relocate(T* first, T* last, T* result); // freestanding
73
+ template<class T>
74
+ constexpr T* relocate(T* first, T* last, T* result); // freestanding
75
 
76
  // [allocator.tag], allocator argument tag
77
+ struct allocator_arg_t { explicit allocator_arg_t() = default; }; // freestanding
 
 
78
  inline constexpr allocator_arg_t allocator_arg{}; // freestanding
79
 
80
  // [allocator.uses], uses_allocator
81
  template<class T, class Alloc> struct uses_allocator; // freestanding
82
 
 
145
  // [special.mem.concepts], special memory concepts
146
  template<class I>
147
  concept nothrow-input-iterator = see below; // exposition only
148
  template<class I>
149
  concept nothrow-forward-iterator = see below; // exposition only
150
+ template<class I>
151
+ concept nothrow-bidirectional-iterator = see below; // exposition only
152
+ template<class I>
153
+ concept nothrow-random-access-iterator = see below; // exposition only
154
  template<class S, class I>
155
  concept nothrow-sentinel-for = see below; // exposition only
156
+ template<class S, class I>
157
+ concept nothrow-sized-sentinel-for = see below; // exposition only
158
  template<class R>
159
  concept nothrow-input-range = see below; // exposition only
160
  template<class R>
161
  concept nothrow-forward-range = see below; // exposition only
162
+ template<class R>
163
+ concept nothrow-bidirectional-range = see below; // exposition only
164
+ template<class R>
165
+ concept nothrow-random-access-range = see below; // exposition only
166
+ template<class R>
167
+ concept nothrow-sized-random-access-range = see below; // exposition only
168
 
169
  template<class NoThrowForwardIterator>
170
+ constexpr void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding
171
  NoThrowForwardIterator last);
172
  template<class ExecutionPolicy, class NoThrowForwardIterator>
173
+ void uninitialized_default_construct(ExecutionPolicy&& exec, // freestanding-deleted,
174
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
175
  NoThrowForwardIterator last);
176
  template<class NoThrowForwardIterator, class Size>
177
+ constexpr NoThrowForwardIterator
178
  uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding
179
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
180
  NoThrowForwardIterator
181
+ uninitialized_default_construct_n(ExecutionPolicy&& exec, // freestanding-deleted,
182
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
183
+ Size n);
184
 
185
  namespace ranges {
186
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
187
  requires default_initializable<iter_value_t<I>>
188
+ constexpr I uninitialized_default_construct(I first, S last); // freestanding
189
  template<nothrow-forward-range R>
190
  requires default_initializable<range_value_t<R>>
191
+ constexpr borrowed_iterator_t<R> uninitialized_default_construct(R&& r); // freestanding
192
 
193
  template<nothrow-forward-iterator I>
194
  requires default_initializable<iter_value_t<I>>
195
+ constexpr I uninitialized_default_construct_n(I first, // freestanding
196
+ iter_difference_t<I> n);
197
+
198
+ template<execution-policy Ep, nothrow-random-access-iterator I,
199
+ nothrow-sized-sentinel-for<I> S>
200
+ requires default_initializable<iter_value_t<I>>
201
+ I uninitialized_default_construct(Ep&& exec, I first, S last); // freestanding-deleted,
202
+ // see [algorithms.parallel.overloads]
203
+ template<execution-policy Ep, nothrow-sized-random-access-range R>
204
+ requires default_initializable<range_value_t<R>>
205
+ borrowed_iterator_t<R> uninitialized_default_construct(Ep&& exec, // freestanding-deleted,
206
+ R&& r); // see [algorithms.parallel.overloads]
207
+
208
+ template<execution-policy Ep, nothrow-random-access-iterator I>
209
+ requires default_initializable<iter_value_t<I>>
210
+ I uninitialized_default_construct_n(Ep&& exec, I first, // freestanding-deleted,
211
+ iter_difference_t<I> n); // see [algorithms.parallel.overloads]
212
  }
213
 
214
  template<class NoThrowForwardIterator>
215
+ constexpr void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding
216
  NoThrowForwardIterator last);
217
  template<class ExecutionPolicy, class NoThrowForwardIterator>
218
+ void uninitialized_value_construct(ExecutionPolicy&& exec, // freestanding-deleted,
219
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
220
  NoThrowForwardIterator last);
221
  template<class NoThrowForwardIterator, class Size>
222
+ constexpr NoThrowForwardIterator
223
  uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding
224
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
225
  NoThrowForwardIterator
226
+ uninitialized_value_construct_n(ExecutionPolicy&& exec, // freestanding-deleted,
227
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
228
+ Size n);
229
 
230
  namespace ranges {
231
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
232
  requires default_initializable<iter_value_t<I>>
233
+ constexpr I uninitialized_value_construct(I first, S last); // freestanding
234
  template<nothrow-forward-range R>
235
  requires default_initializable<range_value_t<R>>
236
+ constexpr borrowed_iterator_t<R> uninitialized_value_construct(R&& r); // freestanding
237
 
238
  template<nothrow-forward-iterator I>
239
  requires default_initializable<iter_value_t<I>>
240
+ constexpr I uninitialized_value_construct_n(I first, // freestanding
241
+ iter_difference_t<I> n);
242
+
243
+ template<execution-policy Ep, nothrow-random-access-iterator I,
244
+ nothrow-sized-sentinel-for<I> S>
245
+ requires default_initializable<iter_value_t<I>>
246
+ I uninitialized_value_construct(Ep&& exec, I first, S last); // freestanding-deleted,
247
+ // see [algorithms.parallel.overloads]
248
+ template<execution-policy Ep, nothrow-sized-random-access-range R>
249
+ requires default_initializable<range_value_t<R>>
250
+ borrowed_iterator_t<R> uninitialized_value_construct(Ep&& exec, // freestanding-deleted,
251
+ R&& r); // see [algorithms.parallel.overloads]
252
+
253
+ template<execution-policy Ep, nothrow-random-access-iterator I>
254
+ requires default_initializable<iter_value_t<I>>
255
+ I uninitialized_value_construct_n(Ep&& exec, I first, // freestanding-deleted,
256
+ iter_difference_t<I> n); // see [algorithms.parallel.overloads]
257
  }
258
 
259
  template<class InputIterator, class NoThrowForwardIterator>
260
+ constexpr NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding
261
  InputIterator last,
262
  NoThrowForwardIterator result);
263
  template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
264
+ NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // freestanding-deleted,
265
+ ForwardIterator first, // see [algorithms.parallel.overloads]
266
+ ForwardIterator last,
267
  NoThrowForwardIterator result);
268
  template<class InputIterator, class Size, class NoThrowForwardIterator>
269
+ constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, // freestanding
270
+ Size n,
271
  NoThrowForwardIterator result);
272
  template<class ExecutionPolicy, class ForwardIterator, class Size,
273
  class NoThrowForwardIterator>
274
+ NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // freestanding-deleted,
275
+ ForwardIterator first, // see [algorithms.parallel.overloads]
276
+ Size n,
277
  NoThrowForwardIterator result);
278
 
279
  namespace ranges {
280
  template<class I, class O>
281
  using uninitialized_copy_result = in_out_result<I, O>; // freestanding
282
  template<input_iterator I, sentinel_for<I> S1,
283
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
284
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
285
+ constexpr uninitialized_copy_result<I, O>
286
  uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
287
  template<input_range IR, nothrow-forward-range OR>
288
  requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
289
+ constexpr uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
290
  uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding
291
 
292
  template<class I, class O>
293
  using uninitialized_copy_n_result = in_out_result<I, O>; // freestanding
294
  template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
295
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
296
+ constexpr uninitialized_copy_n_result<I, O>
297
  uninitialized_copy_n(I ifirst, iter_difference_t<I> n, // freestanding
298
  O ofirst, S olast);
299
+
300
+ template<execution-policy Ep, random_access_iterator I, sized_sentinel_for<I> S1,
301
+ nothrow-random-access-iterator O, nothrow-sized-sentinel-for<O> S2>
302
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
303
+ uninitialized_copy_result<I, O>
304
+ uninitialized_copy(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted,
305
+ O ofirst, S2 olast); // see [algorithms.parallel.overloads]
306
+ template<execution-policy Ep, sized-random-access-range IR,
307
+ nothrow-sized-random-access-range OR>
308
+ requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
309
+ uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
310
+ uninitialized_copy(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted,
311
+ // see [algorithms.parallel.overloads]
312
+ template<execution-policy Ep, random_access_iterator I, nothrow-random-access-iterator O,
313
+ nothrow-sized-sentinel-for<O> S>
314
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
315
+ uninitialized_copy_n_result<I, O>
316
+ uninitialized_copy_n(Ep&& exec, I ifirst, iter_difference_t<I> n, // freestanding-deleted,
317
+ O ofirst, S olast); // see [algorithms.parallel.overloads]
318
  }
319
 
320
  template<class InputIterator, class NoThrowForwardIterator>
321
+ constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding
322
  InputIterator last,
323
  NoThrowForwardIterator result);
324
  template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
325
+ NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // freestanding-deleted,
326
+ ForwardIterator first, // see [algorithms.parallel.overloads]
327
+ ForwardIterator last,
328
  NoThrowForwardIterator result);
329
  template<class InputIterator, class Size, class NoThrowForwardIterator>
330
+ constexpr pair<InputIterator, NoThrowForwardIterator>
331
  uninitialized_move_n(InputIterator first, Size n, // freestanding
332
  NoThrowForwardIterator result);
333
  template<class ExecutionPolicy, class ForwardIterator, class Size,
334
  class NoThrowForwardIterator>
335
  pair<ForwardIterator, NoThrowForwardIterator>
336
+ uninitialized_move_n(ExecutionPolicy&& exec, // freestanding-deleted,
337
+ ForwardIterator first, Size n, // see [algorithms.parallel.overloads]
338
+ NoThrowForwardIterator result);
339
 
340
  namespace ranges {
341
  template<class I, class O>
342
  using uninitialized_move_result = in_out_result<I, O>; // freestanding
343
  template<input_iterator I, sentinel_for<I> S1,
344
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
345
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
346
+ constexpr uninitialized_move_result<I, O>
347
  uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
348
  template<input_range IR, nothrow-forward-range OR>
349
  requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
350
+ constexpr uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
351
  uninitialized_move(IR&& in_range, OR&& out_range); // freestanding
352
 
353
  template<class I, class O>
354
  using uninitialized_move_n_result = in_out_result<I, O>; // freestanding
355
  template<input_iterator I,
356
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
357
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
358
+ constexpr uninitialized_move_n_result<I, O>
359
  uninitialized_move_n(I ifirst, iter_difference_t<I> n, // freestanding
360
  O ofirst, S olast);
361
+
362
+ template<execution-policy Ep, random_access_iterator I, sized_sentinel_for<I> S1,
363
+ nothrow-random-access-iterator O, nothrow-sized-sentinel-for<O> S2>
364
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
365
+ uninitialized_move_result<I, O>
366
+ uninitialized_move(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted,
367
+ O ofirst, S2 olast); // see [algorithms.parallel.overloads]
368
+ template<execution-policy Ep, sized-random-access-range IR,
369
+ nothrow-sized-random-access-range OR>
370
+ requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
371
+ uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
372
+ uninitialized_move(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted,
373
+ // see [algorithms.parallel.overloads]
374
+
375
+ template<execution-policy Ep, random_access_iterator I,
376
+ nothrow-random-access-iterator O, nothrow-sized-sentinel-for<O> S>
377
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
378
+ uninitialized_move_n_result<I, O>
379
+ uninitialized_move_n(Ep&& exec, I ifirst, iter_difference_t<I> n, // freestanding-deleted,
380
+ O ofirst, S olast); // see [algorithms.parallel.overloads]
381
  }
382
 
383
  template<class NoThrowForwardIterator, class T>
384
+ constexpr void uninitialized_fill(NoThrowForwardIterator first, // freestanding
385
  NoThrowForwardIterator last, const T& x);
386
  template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
387
+ void uninitialized_fill(ExecutionPolicy&& exec, // freestanding-deleted,
388
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
389
+ NoThrowForwardIterator last,
390
  const T& x);
391
  template<class NoThrowForwardIterator, class Size, class T>
392
+ constexpr NoThrowForwardIterator
393
  uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding
394
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
395
  NoThrowForwardIterator
396
+ uninitialized_fill_n(ExecutionPolicy&& exec, // freestanding-deleted,
397
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
398
+ Size n, const T& x);
399
 
400
  namespace ranges {
401
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S, class T>
402
  requires constructible_from<iter_value_t<I>, const T&>
403
+ constexpr I uninitialized_fill(I first, S last, const T& x); // freestanding
404
  template<nothrow-forward-range R, class T>
405
  requires constructible_from<range_value_t<R>, const T&>
406
+ constexpr borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); // freestanding
407
 
408
  template<nothrow-forward-iterator I, class T>
409
  requires constructible_from<iter_value_t<I>, const T&>
410
+ constexpr I uninitialized_fill_n(I first, // freestanding
411
+ iter_difference_t<I> n, const T& x);
412
+
413
+ template<execution-policy Ep, nothrow-random-access-iterator I,
414
+ nothrow-sized-sentinel-for<I> S, class T>
415
+ requires constructible_from<iter_value_t<I>, const T&>
416
+ I uninitialized_fill(Ep&& exec, I first, S last, const T& x); // freestanding-deleted,
417
+ // see [algorithms.parallel.overloads]
418
+ template<execution-policy Ep, nothrow-sized-random-access-range R, class T>
419
+ requires constructible_from<range_value_t<R>, const T&>
420
+ borrowed_iterator_t<R> uninitialized_fill(Ep&& exec, R&& r, // freestanding-deleted,
421
+ const T& x); // see [algorithms.parallel.overloads]
422
+
423
+ template<execution-policy Ep, nothrow-random-access-iterator I, class T>
424
+ requires constructible_from<iter_value_t<I>, const T&>
425
+ I uninitialized_fill_n(Ep&& exec, I first, // freestanding-deleted,
426
+ iter_difference_t<I> n, const T& x); // see [algorithms.parallel.overloads]
427
  }
428
 
429
  // [specialized.construct], construct_at
430
  template<class T, class... Args>
431
  constexpr T* construct_at(T* location, Args&&... args); // freestanding
 
440
  constexpr void destroy_at(T* location); // freestanding
441
  template<class NoThrowForwardIterator>
442
  constexpr void destroy(NoThrowForwardIterator first, // freestanding
443
  NoThrowForwardIterator last);
444
  template<class ExecutionPolicy, class NoThrowForwardIterator>
445
+ void destroy(ExecutionPolicy&& exec, // freestanding-deleted,
446
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
447
+ NoThrowForwardIterator last);
448
  template<class NoThrowForwardIterator, class Size>
449
  constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding
450
  Size n);
451
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
452
+ NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // freestanding-deleted,
453
+ NoThrowForwardIterator first, Size n); // see [algorithms.parallel.overloads]
454
 
455
  namespace ranges {
456
  template<destructible T>
457
  constexpr void destroy_at(T* location) noexcept; // freestanding
458
 
 
464
  constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; // freestanding
465
 
466
  template<nothrow-input-iterator I>
467
  requires destructible<iter_value_t<I>>
468
  constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; // freestanding
469
+
470
+ template<execution-policy Ep, nothrow-random-access-iterator I,
471
+ nothrow-sized-sentinel-for<I> S>
472
+ requires destructible<iter_value_t<I>>
473
+ I destroy(Ep&& exec, I first, S last) noexcept; // freestanding-deleted,
474
+ // see [algorithms.parallel.overloads]
475
+ template<execution-policy Ep, nothrow-sized-random-access-range R>
476
+ requires destructible<range_value_t<R>>
477
+ borrowed_iterator_t<R> destroy(Ep&& exec, R&& r) noexcept; // freestanding-deleted,
478
+ // see [algorithms.parallel.overloads]
479
+ template<execution-policy Ep, nothrow-random-access-iterator I>
480
+ requires destructible<iter_value_t<I>>
481
+ I destroy_n(Ep&& exec, I first, iter_difference_t<I> n) noexcept; // freestanding-deleted,
482
+ // see [algorithms.parallel.overloads]
483
  }
484
 
485
  // [unique.ptr], class template unique_ptr
486
  template<class T> struct default_delete; // freestanding
487
  template<class T> struct default_delete<T[]>; // freestanding
 
507
 
508
  template<class T1, class D1, class T2, class D2>
509
  constexpr bool operator==(const unique_ptr<T1, D1>& x, // freestanding
510
  const unique_ptr<T2, D2>& y);
511
  template<class T1, class D1, class T2, class D2>
512
+ constexpr bool operator<(const unique_ptr<T1, D1>& x, // freestanding
513
+ const unique_ptr<T2, D2>& y);
514
  template<class T1, class D1, class T2, class D2>
515
+ constexpr bool operator>(const unique_ptr<T1, D1>& x, // freestanding
516
+ const unique_ptr<T2, D2>& y);
517
  template<class T1, class D1, class T2, class D2>
518
+ constexpr bool operator<=(const unique_ptr<T1, D1>& x, // freestanding
519
+ const unique_ptr<T2, D2>& y);
520
  template<class T1, class D1, class T2, class D2>
521
+ constexpr bool operator>=(const unique_ptr<T1, D1>& x, // freestanding
522
+ const unique_ptr<T2, D2>& y);
523
  template<class T1, class D1, class T2, class D2>
524
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
525
  typename unique_ptr<T2, D2>::pointer>
526
+ constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
527
  typename unique_ptr<T2, D2>::pointer>
528
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
529
 
530
  template<class T, class D>
531
  constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // freestanding
 
559
  // [util.smartptr.shared], class template shared_ptr
560
  template<class T> class shared_ptr;
561
 
562
  // [util.smartptr.shared.create], shared_ptr creation
563
  template<class T, class... Args>
564
+ constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
565
  template<class T, class A, class... Args>
566
+ constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
567
 
568
  template<class T>
569
+ constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
570
  template<class T, class A>
571
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
572
 
573
  template<class T>
574
+ constexpr shared_ptr<T> make_shared(); // T is U[N]
575
  template<class T, class A>
576
+ constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
577
 
578
  template<class T>
579
+ constexpr shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
580
  template<class T, class A>
581
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
582
  const remove_extent_t<T>& u); // T is U[]
583
 
584
  template<class T>
585
+ constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
586
  template<class T, class A>
587
+ constexpr shared_ptr<T> allocate_shared(const A& a, // T is U[N]
588
+ const remove_extent_t<T>& u);
589
 
590
  template<class T>
591
+ constexpr shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
592
  template<class T, class A>
593
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]
594
 
595
  template<class T>
596
+ constexpr shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
597
  template<class T, class A>
598
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]
599
 
600
  // [util.smartptr.shared.cmp], shared_ptr comparisons
601
  template<class T, class U>
602
+ constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
603
  template<class T, class U>
604
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a,
605
+ const shared_ptr<U>& b) noexcept;
606
 
607
  template<class T>
608
+ constexpr bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
609
  template<class T>
610
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept;
611
 
612
  // [util.smartptr.shared.spec], shared_ptr specialized algorithms
613
  template<class T>
614
+ constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
615
 
616
  // [util.smartptr.shared.cast], shared_ptr casts
617
  template<class T, class U>
618
+ constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
619
  template<class T, class U>
620
+ constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
621
  template<class T, class U>
622
+ constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
623
  template<class T, class U>
624
+ constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
625
  template<class T, class U>
626
+ constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
627
  template<class T, class U>
628
+ constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
629
  template<class T, class U>
630
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
631
  template<class T, class U>
632
  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
633
 
634
  // [util.smartptr.getdeleter], shared_ptr get_deleter
635
  template<class D, class T>
636
+ constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
637
 
638
  // [util.smartptr.shared.io], shared_ptr I/O
639
  template<class E, class T, class Y>
640
  basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
641
 
642
  // [util.smartptr.weak], class template weak_ptr
643
  template<class T> class weak_ptr;
644
 
645
  // [util.smartptr.weak.spec], weak_ptr specialized algorithms
646
+ template<class T> constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
647
 
648
  // [util.smartptr.ownerless], class template owner_less
649
  template<class T = void> struct owner_less;
650
 
651
+ // [util.smartptr.owner.hash], struct owner_hash
652
+ struct owner_hash;
653
+
654
+ // [util.smartptr.owner.equal], struct owner_equal
655
+ struct owner_equal;
656
+
657
  // [util.smartptr.enab], class template enable_shared_from_this
658
  template<class T> class enable_shared_from_this;
659
 
660
  // [util.smartptr.hash], hash support
661
  template<class T> struct hash; // freestanding
 
667
  template<class T> struct atomic<shared_ptr<T>>;
668
  template<class T> struct atomic<weak_ptr<T>>;
669
 
670
  // [out.ptr.t], class template out_ptr_t
671
  template<class Smart, class Pointer, class... Args>
672
+ class out_ptr_t; // freestanding
673
 
674
  // [out.ptr], function template out_ptr
675
  template<class Pointer = void, class Smart, class... Args>
676
+ constexpr auto out_ptr(Smart& s, Args&&... args); // freestanding
677
 
678
  // [inout.ptr.t], class template inout_ptr_t
679
  template<class Smart, class Pointer, class... Args>
680
+ class inout_ptr_t; // freestanding
681
 
682
  // [inout.ptr], function template inout_ptr
683
  template<class Pointer = void, class Smart, class... Args>
684
+ constexpr auto inout_ptr(Smart& s, Args&&... args); // freestanding
685
+
686
+ // [indirect], class template indirect
687
+ template<class T, class Allocator = allocator<T>>
688
+ class indirect;
689
+
690
+ // [indirect.hash], hash support
691
+ template<class T, class Alloc> struct hash<indirect<T, Alloc>>;
692
+
693
+ // [polymorphic], class template polymorphic
694
+ template<class T, class Allocator = allocator<T>>
695
+ class polymorphic;
696
+
697
+ namespace pmr {
698
+ template<class T> using indirect = indirect<T, polymorphic_allocator<T>>;
699
+ template<class T> using polymorphic = polymorphic<T, polymorphic_allocator<T>>;
700
+ }
701
  }
702
  ```
703
 
704
  ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
705
 
 
736
  struct ptr-traits-elem // exposition only
737
  { };
738
 
739
  template<class T> requires requires { typename T::element_type; }
740
  struct ptr-traits-elem<T>
741
+ { using type = T::element_type; };
742
 
743
  template<template<class...> class SomePointer, class T, class... Args>
744
  requires (!requires { typename SomePointer<T, Args...>::element_type; })
745
  struct ptr-traits-elem<SomePointer<T, Args...>>
746
  { using type = T; };
 
866
  it can be called repeatedly with possibly different `alignment` and
867
  `size` arguments for the same buffer. — *end note*]
868
 
869
  ``` cpp
870
  template<size_t N, class T>
871
+ constexpr T* assume_aligned(T* ptr);
872
  ```
873
 
874
  *Mandates:* `N` is a power of two.
875
 
876
+ *Preconditions:* `ptr` points to an object X of a type
877
+ similar [[conv.qual]] to `T`, where X has alignment `N` [[basic.align]].
 
878
 
879
  *Returns:* `ptr`.
880
 
881
  *Throws:* Nothing.
882
 
883
+ [*Note 2*: The alignment assumption on an object X expressed by a call
884
+ to `assume_aligned` might result in generation of more efficient code.
885
+ It is up to the program to ensure that the assumption actually holds.
886
+ The call does not cause the implementation to verify or enforce this. An
887
+ implementation might only make the assumption for those operations on X
888
+ that access X through the pointer returned by
889
  `assume_aligned`. — *end note*]
890
 
891
+ ``` cpp
892
+ template<size_t Alignment, class T>
893
+ bool is_sufficiently_aligned(T* ptr);
894
+ ```
895
+
896
+ *Preconditions:* `p` points to an object `X` of a type
897
+ similar [[conv.qual]] to `T`.
898
+
899
+ *Returns:* `true` if `X` has alignment at least `Alignment`, otherwise
900
+ `false`.
901
+
902
+ *Throws:* Nothing.
903
+
904
  ### Explicit lifetime management <a id="obj.lifetime">[[obj.lifetime]]</a>
905
 
906
  ``` cpp
907
  template<class T>
908
  T* start_lifetime_as(void* p) noexcept;
 
912
  volatile T* start_lifetime_as(volatile void* p) noexcept;
913
  template<class T>
914
  const volatile T* start_lifetime_as(const volatile void* p) noexcept;
915
  ```
916
 
917
+ *Mandates:* `T` is an implicit-lifetime
918
+ type [[term.implicit.lifetime.type]] and not an incomplete
919
+ type [[term.incomplete.type]].
920
 
921
  *Preconditions:* \[`p`, `(char*)p + sizeof(T)`) denotes a region of
922
  allocated storage that is a subset of the region of storage reachable
923
  through [[basic.compound]] `p` and suitably aligned for the type `T`.
924
 
925
  *Effects:* Implicitly creates objects [[intro.object]] within the
926
  denoted region consisting of an object *a* of type `T` whose address is
927
  `p`, and objects nested within *a*, as follows: The object
928
  representation of *a* is the contents of the storage prior to the call
929
  to `start_lifetime_as`. The value of each created object *o* of
930
+ trivially copyable type [[term.trivially.copyable.type]] `U` is
931
+ determined in the same manner as for a call to `bit_cast<U>(E)`
932
+ [[bit.cast]], where `E` is an lvalue of type `U` denoting *o*, except
933
+ that the storage is not accessed. The value of any other created object
934
+ is unspecified.
935
 
936
  [*Note 1*: The unspecified value can be indeterminate. — *end note*]
937
 
938
  *Returns:* A pointer to the *a* defined in the *Effects* paragraph.
939
 
 
961
  effects.
962
 
963
  *Returns:* A pointer to the first element of the created array, if any;
964
  otherwise, a pointer that compares equal to `p` [[expr.eq]].
965
 
966
+ ``` cpp
967
+ template<class T>
968
+ T* trivially_relocate(T* first, T* last, T* result);
969
+ ```
970
+
971
+ *Mandates:* `is_trivially_relocatable_v<T> && !is_const_v<T>` is `true`.
972
+ `T` is not an array of unknown bound.
973
+
974
+ *Preconditions:*
975
+
976
+ - \[`first`, `last`) is a valid range.
977
+ - \[`result`, `result + (last - first)`) denotes a region of storage
978
+ that is a subset of the region reachable through `result`
979
+ [[basic.compound]] and suitably aligned for the type `T`.
980
+ - No element in the range \[`first`, `last`) is a
981
+ potentially-overlapping subobject.
982
+
983
+ *Ensures:* No effect if `result == first` is `true`. Otherwise, the
984
+ range denoted by \[`result`, `result + (last - first)`) contains objects
985
+ (including subobjects) whose lifetime has begun and whose object
986
+ representations are the original object representations of the
987
+ corresponding objects in the source range \[`first`, `last`) except for
988
+ any parts of the object representations used by the implementation to
989
+ represent type information [[intro.object]]. If any of the objects has
990
+ union type, its active member is the same as that of the corresponding
991
+ object in the source range. If any of the aforementioned objects has a
992
+ non-static data member of reference type, that reference refers to the
993
+ same entity as does the corresponding reference in the source range. The
994
+ lifetimes of the original objects in the source range have ended.
995
+
996
+ *Returns:* `result + (last - first)`.
997
+
998
+ *Throws:* Nothing.
999
+
1000
+ *Complexity:* Linear in the length of the source range.
1001
+
1002
+ *Remarks:* The destination region of storage is considered
1003
+ reused [[basic.life]]. No constructors or destructors are invoked.
1004
+
1005
+ [*Note 2*: Overlapping ranges are supported. — *end note*]
1006
+
1007
+ ``` cpp
1008
+ template<class T>
1009
+ constexpr T* relocate(T* first, T* last, T* result);
1010
+ ```
1011
+
1012
+ *Mandates:* `is_nothrow_relocatable_v<T> && !is_const_v<T>` is `true`.
1013
+ `T` is not an array of unknown bound.
1014
+
1015
+ *Preconditions:*
1016
+
1017
+ - \[`first`, `last`) is a valid range.
1018
+ - \[`result`, `result + (last - first)`) denotes a region of storage
1019
+ that is a subset of the region reachable through `result`
1020
+ [[basic.compound]] and suitably aligned for the type `T`.
1021
+ - No element in the range \[`first`, `last`) is a
1022
+ potentially-overlapping subobject.
1023
+
1024
+ *Effects:*
1025
+
1026
+ - If `result == first` is `true`, no effect;
1027
+ - otherwise, if not called during constant evaluation and
1028
+ `is_trivially_relocatable_v<T>` is `true`, then has effects equivalent
1029
+ to: `trivially_relocate(first, last, result);`
1030
+ - otherwise, for each integer `i` in \[`0`, `last - first`),
1031
+ - if `T` is an array type, equivalent to:
1032
+ `relocate(begin(first[i]), end(first[i]), *start_lifetime_as<T>(result + i));`
1033
+ - otherwise, equivalent to:
1034
+ `construct_at(result + i, std::move(first[i])); destroy_at(first + i);`
1035
+
1036
+ *Returns:* `result + (last - first)`.
1037
+
1038
+ *Throws:* Nothing.
1039
+
1040
+ [*Note 3*: Overlapping ranges are supported. — *end note*]
1041
+
1042
  ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
1043
 
1044
  ``` cpp
1045
  namespace std {
1046
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
 
1341
  ``` cpp
1342
  namespace std {
1343
  template<class Alloc> struct allocator_traits {
1344
  using allocator_type = Alloc;
1345
 
1346
+ using value_type = Alloc::value_type;
1347
 
1348
  using pointer = see below;
1349
  using const_pointer = see below;
1350
  using void_pointer = see below;
1351
  using const_void_pointer = see below;
 
1359
  using is_always_equal = see below;
1360
 
1361
  template<class T> using rebind_alloc = see below;
1362
  template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
1363
 
1364
+ static constexpr pointer allocate(Alloc& a, size_type n);
1365
+ static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1366
+ static constexpr allocation_result<pointer, size_type>
 
1367
  allocate_at_least(Alloc& a, size_type n);
1368
 
1369
  static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1370
 
1371
  template<class T, class... Args>
 
1473
  arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
1474
 
1475
  #### Static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
1476
 
1477
  ``` cpp
1478
+ static constexpr pointer allocate(Alloc& a, size_type n);
1479
  ```
1480
 
1481
  *Returns:* `a.allocate(n)`.
1482
 
1483
  ``` cpp
1484
+ static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1485
  ```
1486
 
1487
  *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
1488
  otherwise, `a.allocate(n)`.
1489
 
1490
  ``` cpp
1491
+ static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n);
 
1492
  ```
1493
 
1494
  *Returns:* `a.allocate_at_least(n)` if that expression is well-formed;
1495
  otherwise, `{a.allocate(n), n}`.
1496
 
 
1559
  constexpr allocator(const allocator&) noexcept;
1560
  template<class U> constexpr allocator(const allocator<U>&) noexcept;
1561
  constexpr ~allocator();
1562
  constexpr allocator& operator=(const allocator&) = default;
1563
 
1564
+ constexpr T* allocate(size_t n);
1565
+ constexpr allocation_result<T*> allocate_at_least(size_t n);
1566
  constexpr void deallocate(T* p, size_t n);
1567
  };
1568
  }
1569
  ```
1570
 
 
1580
  to these functions that allocate or deallocate a particular unit of
1581
  storage shall occur in a single total order, and each such deallocation
1582
  call shall happen before the next allocation (if any) in this order.
1583
 
1584
  ``` cpp
1585
+ constexpr T* allocate(size_t n);
1586
  ```
1587
 
1588
  *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1589
 
1590
  *Returns:* A pointer to the initial element of an array of `n` `T`.
 
1597
  `::operator new` [[new.delete]], but it is unspecified when or how often
1598
  this function is called. This function starts the lifetime of the array
1599
  object, but not that of any of the array elements.
1600
 
1601
  ``` cpp
1602
+ constexpr allocation_result<T*> allocate_at_least(size_t n);
1603
  ```
1604
 
1605
  *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1606
 
1607
  *Returns:* `allocation_result<T*>{ptr, count}`, where `ptr` is a pointer
 
1664
 
1665
  ``` cpp
1666
  void* aligned_alloc(size_t alignment, size_t size);
1667
  void* calloc(size_t nmemb, size_t size);
1668
  void* malloc(size_t size);
 
1669
  ```
1670
 
1671
  *Effects:* These functions have the semantics specified in the C
1672
  standard library.
1673
 
1674
  *Remarks:* These functions do not attempt to allocate storage by calling
1675
  `::operator new()` [[new.delete]].
1676
 
1677
  These functions implicitly create objects [[intro.object]] in the
1678
  returned region of storage and return a pointer to a suitable created
1679
+ object. In the case of `calloc`, the objects are created before the
1680
+ storage is zeroed.
1681
+
1682
+ ``` cpp
1683
+ void* realloc(void* ptr, size_t size);
1684
+ ```
1685
+
1686
+ *Preconditions:* `free(ptr)` has well-defined behavior.
1687
+
1688
+ *Effects:* If `ptr` is not null and `size` is zero, the behavior is
1689
+ erroneous and the effects are implementation-defined. Otherwise, this
1690
+ function has the semantics specified in the C standard library.
1691
+
1692
+ *Remarks:* This function does not attempt to allocate storage by calling
1693
+ `::operator new()` [[new.delete]]. When a non-null pointer is returned,
1694
+ this function implicitly creates objects [[intro.object]] in the
1695
+ returned region of storage and returns a pointer to a suitable created
1696
+ object. The objects are created before the storage is copied.
1697
 
1698
  ``` cpp
1699
  void free(void* ptr);
1700
  ```
1701
 
 
1703
  library.
1704
 
1705
  *Remarks:* This function does not attempt to deallocate storage by
1706
  calling `::operator delete()`.
1707
 
1708
+ See also: ISO C 7.24.4
1709