From Jason Turner

[mem]

Large diff (158.4 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5x_6zp6f/{from.md → to.md} +1771 -403
tmp/tmp5x_6zp6f/{from.md → to.md} RENAMED
@@ -9,20 +9,21 @@ smart pointers, memory resources, and scoped allocators, as summarized
9
  in [[mem.summary]].
10
 
11
  **Table: Memory management library summary** <a id="mem.summary">[mem.summary]</a>
12
 
13
  | Subclause | | Header |
14
- | --------------------- | ----------------- | ----------------------- |
15
  | [[memory]] | Memory | `<cstdlib>`, `<memory>` |
16
  | [[smartptr]] | Smart pointers | `<memory>` |
 
17
  | [[mem.res]] | Memory resources | `<memory_resource>` |
18
  | [[allocator.adaptor]] | Scoped allocators | `<scoped_allocator>` |
19
 
20
 
21
  ## Memory <a id="memory">[[memory]]</a>
22
 
23
- ### In general <a id="memory.general">[[memory.general]]</a>
24
 
25
  Subclause  [[memory]] describes the contents of the header `<memory>`
26
  and some of the contents of the header `<cstdlib>`.
27
 
28
  ### Header `<memory>` synopsis <a id="memory.syn">[[memory.syn]]</a>
@@ -64,11 +65,13 @@ namespace std {
64
  constexpr auto to_address(const Ptr& p) noexcept; // freestanding
65
 
66
  // [ptr.align], pointer alignment
67
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestanding
68
  template<size_t N, class T>
69
- [[nodiscard]] constexpr T* assume_aligned(T* ptr); // freestanding
 
 
70
 
71
  // [obj.lifetime], explicit lifetime management
72
  template<class T>
73
  T* start_lifetime_as(void* p) noexcept; // freestanding
74
  template<class T>
@@ -84,15 +87,17 @@ namespace std {
84
  template<class T>
85
  volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; // freestanding
86
  template<class T>
87
  const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding
88
  size_t n) noexcept;
 
 
 
 
89
 
90
  // [allocator.tag], allocator argument tag
91
- struct allocator_arg_t { // freestanding
92
- explicit allocator_arg_t() = default; // freestanding
93
- };
94
  inline constexpr allocator_arg_t allocator_arg{}; // freestanding
95
 
96
  // [allocator.uses], uses_allocator
97
  template<class T, class Alloc> struct uses_allocator; // freestanding
98
 
@@ -161,179 +166,287 @@ namespace std {
161
  // [special.mem.concepts], special memory concepts
162
  template<class I>
163
  concept nothrow-input-iterator = see below; // exposition only
164
  template<class I>
165
  concept nothrow-forward-iterator = see below; // exposition only
 
 
 
 
166
  template<class S, class I>
167
  concept nothrow-sentinel-for = see below; // exposition only
 
 
168
  template<class R>
169
  concept nothrow-input-range = see below; // exposition only
170
  template<class R>
171
  concept nothrow-forward-range = see below; // exposition only
 
 
 
 
 
 
172
 
173
  template<class NoThrowForwardIterator>
174
- void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding
175
  NoThrowForwardIterator last);
176
  template<class ExecutionPolicy, class NoThrowForwardIterator>
177
- void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
178
- NoThrowForwardIterator first,
179
  NoThrowForwardIterator last);
180
  template<class NoThrowForwardIterator, class Size>
181
- NoThrowForwardIterator
182
  uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding
183
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
184
  NoThrowForwardIterator
185
- uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
186
- NoThrowForwardIterator first, Size n);
 
187
 
188
  namespace ranges {
189
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
190
  requires default_initializable<iter_value_t<I>>
191
- I uninitialized_default_construct(I first, S last); // freestanding
192
  template<nothrow-forward-range R>
193
  requires default_initializable<range_value_t<R>>
194
- borrowed_iterator_t<R> uninitialized_default_construct(R&& r); // freestanding
195
 
196
  template<nothrow-forward-iterator I>
197
  requires default_initializable<iter_value_t<I>>
198
- I uninitialized_default_construct_n(I first, iter_difference_t<I> n); // freestanding
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
200
 
201
  template<class NoThrowForwardIterator>
202
- void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding
203
  NoThrowForwardIterator last);
204
  template<class ExecutionPolicy, class NoThrowForwardIterator>
205
- void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
206
- NoThrowForwardIterator first,
207
  NoThrowForwardIterator last);
208
  template<class NoThrowForwardIterator, class Size>
209
- NoThrowForwardIterator
210
  uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding
211
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
212
  NoThrowForwardIterator
213
- uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
214
- NoThrowForwardIterator first, Size n);
 
215
 
216
  namespace ranges {
217
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
218
  requires default_initializable<iter_value_t<I>>
219
- I uninitialized_value_construct(I first, S last); // freestanding
220
  template<nothrow-forward-range R>
221
  requires default_initializable<range_value_t<R>>
222
- borrowed_iterator_t<R> uninitialized_value_construct(R&& r); // freestanding
223
 
224
  template<nothrow-forward-iterator I>
225
  requires default_initializable<iter_value_t<I>>
226
- I uninitialized_value_construct_n(I first, iter_difference_t<I> n); // freestanding
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  }
228
 
229
  template<class InputIterator, class NoThrowForwardIterator>
230
- NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding
231
  InputIterator last,
232
  NoThrowForwardIterator result);
233
  template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
234
- NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
235
- ForwardIterator first, ForwardIterator last,
 
236
  NoThrowForwardIterator result);
237
  template<class InputIterator, class Size, class NoThrowForwardIterator>
238
- NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, // freestanding
 
239
  NoThrowForwardIterator result);
240
  template<class ExecutionPolicy, class ForwardIterator, class Size,
241
  class NoThrowForwardIterator>
242
- NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
243
- ForwardIterator first, Size n,
 
244
  NoThrowForwardIterator result);
245
 
246
  namespace ranges {
247
  template<class I, class O>
248
  using uninitialized_copy_result = in_out_result<I, O>; // freestanding
249
  template<input_iterator I, sentinel_for<I> S1,
250
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
251
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
252
- uninitialized_copy_result<I, O>
253
  uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
254
  template<input_range IR, nothrow-forward-range OR>
255
  requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
256
- uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
257
  uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding
258
 
259
  template<class I, class O>
260
  using uninitialized_copy_n_result = in_out_result<I, O>; // freestanding
261
  template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
262
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
263
- uninitialized_copy_n_result<I, O>
264
  uninitialized_copy_n(I ifirst, iter_difference_t<I> n, // freestanding
265
  O ofirst, S olast);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  }
267
 
268
  template<class InputIterator, class NoThrowForwardIterator>
269
- NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding
270
  InputIterator last,
271
  NoThrowForwardIterator result);
272
  template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
273
- NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
274
- ForwardIterator first, ForwardIterator last,
 
275
  NoThrowForwardIterator result);
276
  template<class InputIterator, class Size, class NoThrowForwardIterator>
277
- pair<InputIterator, NoThrowForwardIterator>
278
  uninitialized_move_n(InputIterator first, Size n, // freestanding
279
  NoThrowForwardIterator result);
280
  template<class ExecutionPolicy, class ForwardIterator, class Size,
281
  class NoThrowForwardIterator>
282
  pair<ForwardIterator, NoThrowForwardIterator>
283
- uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
284
- ForwardIterator first, Size n, NoThrowForwardIterator result);
 
285
 
286
  namespace ranges {
287
  template<class I, class O>
288
  using uninitialized_move_result = in_out_result<I, O>; // freestanding
289
  template<input_iterator I, sentinel_for<I> S1,
290
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
291
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
292
- uninitialized_move_result<I, O>
293
  uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
294
  template<input_range IR, nothrow-forward-range OR>
295
  requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
296
- uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
297
  uninitialized_move(IR&& in_range, OR&& out_range); // freestanding
298
 
299
  template<class I, class O>
300
  using uninitialized_move_n_result = in_out_result<I, O>; // freestanding
301
  template<input_iterator I,
302
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
303
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
304
- uninitialized_move_n_result<I, O>
305
  uninitialized_move_n(I ifirst, iter_difference_t<I> n, // freestanding
306
  O ofirst, S olast);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
308
 
309
  template<class NoThrowForwardIterator, class T>
310
- void uninitialized_fill(NoThrowForwardIterator first, // freestanding
311
  NoThrowForwardIterator last, const T& x);
312
  template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
313
- void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
314
- NoThrowForwardIterator first, NoThrowForwardIterator last,
 
315
  const T& x);
316
  template<class NoThrowForwardIterator, class Size, class T>
317
- NoThrowForwardIterator
318
  uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding
319
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
320
  NoThrowForwardIterator
321
- uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
322
- NoThrowForwardIterator first, Size n, const T& x);
 
323
 
324
  namespace ranges {
325
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S, class T>
326
  requires constructible_from<iter_value_t<I>, const T&>
327
- I uninitialized_fill(I first, S last, const T& x); // freestanding
328
  template<nothrow-forward-range R, class T>
329
  requires constructible_from<range_value_t<R>, const T&>
330
- borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); // freestanding
331
 
332
  template<nothrow-forward-iterator I, class T>
333
  requires constructible_from<iter_value_t<I>, const T&>
334
- I uninitialized_fill_n(I first, iter_difference_t<I> n, const T& x); // freestanding
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
336
 
337
  // [specialized.construct], construct_at
338
  template<class T, class... Args>
339
  constexpr T* construct_at(T* location, Args&&... args); // freestanding
@@ -348,18 +461,19 @@ namespace std {
348
  constexpr void destroy_at(T* location); // freestanding
349
  template<class NoThrowForwardIterator>
350
  constexpr void destroy(NoThrowForwardIterator first, // freestanding
351
  NoThrowForwardIterator last);
352
  template<class ExecutionPolicy, class NoThrowForwardIterator>
353
- void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
354
- NoThrowForwardIterator first, NoThrowForwardIterator last);
 
355
  template<class NoThrowForwardIterator, class Size>
356
  constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding
357
  Size n);
358
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
359
- NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
360
- NoThrowForwardIterator first, Size n);
361
 
362
  namespace ranges {
363
  template<destructible T>
364
  constexpr void destroy_at(T* location) noexcept; // freestanding
365
 
@@ -371,10 +485,24 @@ namespace std {
371
  constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; // freestanding
372
 
373
  template<nothrow-input-iterator I>
374
  requires destructible<iter_value_t<I>>
375
  constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; // freestanding
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  }
377
 
378
  // [unique.ptr], class template unique_ptr
379
  template<class T> struct default_delete; // freestanding
380
  template<class T> struct default_delete<T[]>; // freestanding
@@ -400,21 +528,25 @@ namespace std {
400
 
401
  template<class T1, class D1, class T2, class D2>
402
  constexpr bool operator==(const unique_ptr<T1, D1>& x, // freestanding
403
  const unique_ptr<T2, D2>& y);
404
  template<class T1, class D1, class T2, class D2>
405
- bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
 
406
  template<class T1, class D1, class T2, class D2>
407
- bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
 
408
  template<class T1, class D1, class T2, class D2>
409
- bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
 
410
  template<class T1, class D1, class T2, class D2>
411
- bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
 
412
  template<class T1, class D1, class T2, class D2>
413
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
414
  typename unique_ptr<T2, D2>::pointer>
415
- compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
416
  typename unique_ptr<T2, D2>::pointer>
417
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
418
 
419
  template<class T, class D>
420
  constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // freestanding
@@ -448,95 +580,103 @@ namespace std {
448
  // [util.smartptr.shared], class template shared_ptr
449
  template<class T> class shared_ptr;
450
 
451
  // [util.smartptr.shared.create], shared_ptr creation
452
  template<class T, class... Args>
453
- shared_ptr<T> make_shared(Args&&... args); // T is not array
454
  template<class T, class A, class... Args>
455
- shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
456
 
457
  template<class T>
458
- shared_ptr<T> make_shared(size_t N); // T is U[]
459
  template<class T, class A>
460
- shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
461
 
462
  template<class T>
463
- shared_ptr<T> make_shared(); // T is U[N]
464
  template<class T, class A>
465
- shared_ptr<T> allocate_shared(const A& a); // T is U[N]
466
 
467
  template<class T>
468
- shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
469
  template<class T, class A>
470
- shared_ptr<T> allocate_shared(const A& a, size_t N,
471
  const remove_extent_t<T>& u); // T is U[]
472
 
473
  template<class T>
474
- shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
475
  template<class T, class A>
476
- shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N]
 
477
 
478
  template<class T>
479
- shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
480
  template<class T, class A>
481
- shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]
482
 
483
  template<class T>
484
- shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
485
  template<class T, class A>
486
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]
487
 
488
  // [util.smartptr.shared.cmp], shared_ptr comparisons
489
  template<class T, class U>
490
- bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
491
  template<class T, class U>
492
- strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
493
 
494
  template<class T>
495
- bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
496
  template<class T>
497
- strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept;
498
 
499
  // [util.smartptr.shared.spec], shared_ptr specialized algorithms
500
  template<class T>
501
- void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
502
 
503
  // [util.smartptr.shared.cast], shared_ptr casts
504
  template<class T, class U>
505
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
506
  template<class T, class U>
507
- shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
508
  template<class T, class U>
509
- shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
510
  template<class T, class U>
511
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
512
  template<class T, class U>
513
- shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
514
  template<class T, class U>
515
- shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
516
  template<class T, class U>
517
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
518
  template<class T, class U>
519
  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
520
 
521
  // [util.smartptr.getdeleter], shared_ptr get_deleter
522
  template<class D, class T>
523
- D* get_deleter(const shared_ptr<T>& p) noexcept;
524
 
525
  // [util.smartptr.shared.io], shared_ptr I/O
526
  template<class E, class T, class Y>
527
  basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
528
 
529
  // [util.smartptr.weak], class template weak_ptr
530
  template<class T> class weak_ptr;
531
 
532
  // [util.smartptr.weak.spec], weak_ptr specialized algorithms
533
- template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
534
 
535
  // [util.smartptr.ownerless], class template owner_less
536
  template<class T = void> struct owner_less;
537
 
 
 
 
 
 
 
538
  // [util.smartptr.enab], class template enable_shared_from_this
539
  template<class T> class enable_shared_from_this;
540
 
541
  // [util.smartptr.hash], hash support
542
  template<class T> struct hash; // freestanding
@@ -548,23 +688,39 @@ namespace std {
548
  template<class T> struct atomic<shared_ptr<T>>;
549
  template<class T> struct atomic<weak_ptr<T>>;
550
 
551
  // [out.ptr.t], class template out_ptr_t
552
  template<class Smart, class Pointer, class... Args>
553
- class out_ptr_t;
554
 
555
  // [out.ptr], function template out_ptr
556
  template<class Pointer = void, class Smart, class... Args>
557
- auto out_ptr(Smart& s, Args&&... args);
558
 
559
  // [inout.ptr.t], class template inout_ptr_t
560
  template<class Smart, class Pointer, class... Args>
561
- class inout_ptr_t;
562
 
563
  // [inout.ptr], function template inout_ptr
564
  template<class Pointer = void, class Smart, class... Args>
565
- auto inout_ptr(Smart& s, Args&&... args);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  }
567
  ```
568
 
569
  ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
570
 
@@ -601,11 +757,11 @@ template<class T>
601
  struct ptr-traits-elem // exposition only
602
  { };
603
 
604
  template<class T> requires requires { typename T::element_type; }
605
  struct ptr-traits-elem<T>
606
- { using type = typename T::element_type; };
607
 
608
  template<template<class...> class SomePointer, class T, class... Args>
609
  requires (!requires { typename SomePointer<T, Args...>::element_type; })
610
  struct ptr-traits-elem<SomePointer<T, Args...>>
611
  { using type = T; };
@@ -731,31 +887,43 @@ into the available space, otherwise the adjusted value of `ptr`.
731
  it can be called repeatedly with possibly different `alignment` and
732
  `size` arguments for the same buffer. — *end note*]
733
 
734
  ``` cpp
735
  template<size_t N, class T>
736
- [[nodiscard]] constexpr T* assume_aligned(T* ptr);
737
  ```
738
 
739
  *Mandates:* `N` is a power of two.
740
 
741
- *Preconditions:* `ptr` points to an object `X` of a type
742
- similar [[conv.qual]] to `T`, where `X` has alignment `N`
743
- [[basic.align]].
744
 
745
  *Returns:* `ptr`.
746
 
747
  *Throws:* Nothing.
748
 
749
- [*Note 2*: The alignment assumption on an object `X` expressed by a
750
- call to `assume_aligned` might result in generation of more efficient
751
- code. It is up to the program to ensure that the assumption actually
752
- holds. The call does not cause the implementation to verify or enforce
753
- this. An implementation might only make the assumption for those
754
- operations on `X` that access `X` through the pointer returned by
755
  `assume_aligned`. — *end note*]
756
 
 
 
 
 
 
 
 
 
 
 
 
 
 
757
  ### Explicit lifetime management <a id="obj.lifetime">[[obj.lifetime]]</a>
758
 
759
  ``` cpp
760
  template<class T>
761
  T* start_lifetime_as(void* p) noexcept;
@@ -765,26 +933,28 @@ template<class T>
765
  volatile T* start_lifetime_as(volatile void* p) noexcept;
766
  template<class T>
767
  const volatile T* start_lifetime_as(const volatile void* p) noexcept;
768
  ```
769
 
770
- *Mandates:* `T` is an implicit-lifetime type [[basic.types.general]] and
771
- not an incomplete type [[term.incomplete.type]].
 
772
 
773
  *Preconditions:* \[`p`, `(char*)p + sizeof(T)`) denotes a region of
774
  allocated storage that is a subset of the region of storage reachable
775
  through [[basic.compound]] `p` and suitably aligned for the type `T`.
776
 
777
  *Effects:* Implicitly creates objects [[intro.object]] within the
778
  denoted region consisting of an object *a* of type `T` whose address is
779
  `p`, and objects nested within *a*, as follows: The object
780
  representation of *a* is the contents of the storage prior to the call
781
  to `start_lifetime_as`. The value of each created object *o* of
782
- trivially-copyable type `U` is determined in the same manner as for a
783
- call to `bit_cast<U>(E)` [[bit.cast]], where `E` is an lvalue of type
784
- `U` denoting *o*, except that the storage is not accessed. The value of
785
- any other created object is unspecified.
 
786
 
787
  [*Note 1*: The unspecified value can be indeterminate. — *end note*]
788
 
789
  *Returns:* A pointer to the *a* defined in the *Effects* paragraph.
790
 
@@ -812,10 +982,86 @@ where `U` is the type “array of `n` `T`”. Otherwise, there are no
812
  effects.
813
 
814
  *Returns:* A pointer to the first element of the created array, if any;
815
  otherwise, a pointer that compares equal to `p` [[expr.eq]].
816
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
817
  ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
818
 
819
  ``` cpp
820
  namespace std {
821
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
@@ -1116,11 +1362,11 @@ If a program declares an explicit or partial specialization of
1116
  ``` cpp
1117
  namespace std {
1118
  template<class Alloc> struct allocator_traits {
1119
  using allocator_type = Alloc;
1120
 
1121
- using value_type = typename Alloc::value_type;
1122
 
1123
  using pointer = see below;
1124
  using const_pointer = see below;
1125
  using void_pointer = see below;
1126
  using const_void_pointer = see below;
@@ -1134,14 +1380,13 @@ namespace std {
1134
  using is_always_equal = see below;
1135
 
1136
  template<class T> using rebind_alloc = see below;
1137
  template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
1138
 
1139
- [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1140
- [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
1141
- const_void_pointer hint);
1142
- [[nodiscard]] static constexpr allocation_result<pointer, size_type>
1143
  allocate_at_least(Alloc& a, size_type n);
1144
 
1145
  static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1146
 
1147
  template<class T, class... Args>
@@ -1249,25 +1494,24 @@ of the form `Alloc<U, Args>`, where `Args` is zero or more type
1249
  arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
1250
 
1251
  #### Static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
1252
 
1253
  ``` cpp
1254
- [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
1255
  ```
1256
 
1257
  *Returns:* `a.allocate(n)`.
1258
 
1259
  ``` cpp
1260
- [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1261
  ```
1262
 
1263
  *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
1264
  otherwise, `a.allocate(n)`.
1265
 
1266
  ``` cpp
1267
- [[nodiscard]] static constexpr allocation_result<pointer, size_type>
1268
- allocate_at_least(Alloc& a, size_type n);
1269
  ```
1270
 
1271
  *Returns:* `a.allocate_at_least(n)` if that expression is well-formed;
1272
  otherwise, `{a.allocate(n), n}`.
1273
 
@@ -1336,12 +1580,12 @@ namespace std {
1336
  constexpr allocator(const allocator&) noexcept;
1337
  template<class U> constexpr allocator(const allocator<U>&) noexcept;
1338
  constexpr ~allocator();
1339
  constexpr allocator& operator=(const allocator&) = default;
1340
 
1341
- [[nodiscard]] constexpr T* allocate(size_t n);
1342
- [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);
1343
  constexpr void deallocate(T* p, size_t n);
1344
  };
1345
  }
1346
  ```
1347
 
@@ -1357,11 +1601,11 @@ concurrent calls to those member functions from different threads. Calls
1357
  to these functions that allocate or deallocate a particular unit of
1358
  storage shall occur in a single total order, and each such deallocation
1359
  call shall happen before the next allocation (if any) in this order.
1360
 
1361
  ``` cpp
1362
- [[nodiscard]] constexpr T* allocate(size_t n);
1363
  ```
1364
 
1365
  *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1366
 
1367
  *Returns:* A pointer to the initial element of an array of `n` `T`.
@@ -1374,11 +1618,11 @@ storage cannot be obtained.
1374
  `::operator new` [[new.delete]], but it is unspecified when or how often
1375
  this function is called. This function starts the lifetime of the array
1376
  object, but not that of any of the array elements.
1377
 
1378
  ``` cpp
1379
- [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);
1380
  ```
1381
 
1382
  *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1383
 
1384
  *Returns:* `allocation_result<T*>{ptr, count}`, where `ptr` is a pointer
@@ -1441,23 +1685,38 @@ this subclause. — *end note*]
1441
 
1442
  ``` cpp
1443
  void* aligned_alloc(size_t alignment, size_t size);
1444
  void* calloc(size_t nmemb, size_t size);
1445
  void* malloc(size_t size);
1446
- void* realloc(void* ptr, size_t size);
1447
  ```
1448
 
1449
  *Effects:* These functions have the semantics specified in the C
1450
  standard library.
1451
 
1452
  *Remarks:* These functions do not attempt to allocate storage by calling
1453
  `::operator new()` [[new.delete]].
1454
 
1455
  These functions implicitly create objects [[intro.object]] in the
1456
  returned region of storage and return a pointer to a suitable created
1457
- object. In the case of `calloc` and `realloc`, the objects are created
1458
- before the storage is zeroed or copied, respectively.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1459
 
1460
  ``` cpp
1461
  void free(void* ptr);
1462
  ```
1463
 
@@ -1465,11 +1724,11 @@ void free(void* ptr);
1465
  library.
1466
 
1467
  *Remarks:* This function does not attempt to deallocate storage by
1468
  calling `::operator delete()`.
1469
 
1470
- See also: ISO C 7.22.3
1471
 
1472
  ## Smart pointers <a id="smartptr">[[smartptr]]</a>
1473
 
1474
  ### Unique-ownership pointers <a id="unique.ptr">[[unique.ptr]]</a>
1475
 
@@ -1504,11 +1763,11 @@ for dynamically allocated memory, passing ownership of dynamically
1504
  allocated memory to a function, and returning dynamically allocated
1505
  memory from a function. — *end note*]
1506
 
1507
  #### Default deleters <a id="unique.ptr.dltr">[[unique.ptr.dltr]]</a>
1508
 
1509
- ##### In general <a id="unique.ptr.dltr.general">[[unique.ptr.dltr.general]]</a>
1510
 
1511
  The class template `default_delete` serves as the default deleter
1512
  (destruction policy) for the class template `unique_ptr`.
1513
 
1514
  The template parameter `T` of `default_delete` may be an incomplete
@@ -1623,10 +1882,16 @@ namespace std {
1623
  unique_ptr& operator=(const unique_ptr&) = delete;
1624
  };
1625
  }
1626
  ```
1627
 
 
 
 
 
 
 
1628
  The default type for the template parameter `D` is `default_delete`. A
1629
  client-supplied template argument `D` shall be a function object type
1630
  [[function.objects]], lvalue reference to function, or lvalue reference
1631
  to function object type for which, given a value `d` of type `D` and a
1632
  value `ptr` of type `unique_ptr<T, D>::pointer`, the expression `d(ptr)`
@@ -1851,11 +2116,15 @@ constexpr unique_ptr& operator=(nullptr_t) noexcept;
1851
 
1852
  ``` cpp
1853
  constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
1854
  ```
1855
 
1856
- *Preconditions:* `get() != nullptr`.
 
 
 
 
1857
 
1858
  *Returns:* `*get()`.
1859
 
1860
  ``` cpp
1861
  constexpr pointer operator->() const noexcept;
@@ -2081,11 +2350,11 @@ constexpr void reset(nullptr_t p = nullptr) noexcept;
2081
  ```
2082
 
2083
  *Effects:* Equivalent to `reset(pointer())`.
2084
 
2085
  ``` cpp
2086
- constexpr template<class U> void reset(U p) noexcept;
2087
  ```
2088
 
2089
  This function behaves the same as the `reset` member of the primary
2090
  template.
2091
 
@@ -2158,11 +2427,11 @@ template<class T1, class D1, class T2, class D2>
2158
 
2159
  *Returns:* `x.get() == y.get()`.
2160
 
2161
  ``` cpp
2162
  template<class T1, class D1, class T2, class D2>
2163
- bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2164
  ```
2165
 
2166
  Let `CT` denote
2167
 
2168
  ``` cpp
@@ -2181,34 +2450,34 @@ ordering [[alg.sorting]] on the pointer values.
2181
 
2182
  *Returns:* `less<CT>()(x.get(), y.get())`.
2183
 
2184
  ``` cpp
2185
  template<class T1, class D1, class T2, class D2>
2186
- bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2187
  ```
2188
 
2189
  *Returns:* `y < x`.
2190
 
2191
  ``` cpp
2192
  template<class T1, class D1, class T2, class D2>
2193
- bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2194
  ```
2195
 
2196
  *Returns:* `!(y < x)`.
2197
 
2198
  ``` cpp
2199
  template<class T1, class D1, class T2, class D2>
2200
- bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2201
  ```
2202
 
2203
  *Returns:* `!(x < y)`.
2204
 
2205
  ``` cpp
2206
  template<class T1, class D1, class T2, class D2>
2207
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
2208
  typename unique_ptr<T2, D2>::pointer>
2209
- compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
2210
  typename unique_ptr<T2, D2>::pointer>
2211
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2212
  ```
2213
 
2214
  *Returns:* `compare_three_way()(x.get(), y.get())`.
@@ -2306,20 +2575,20 @@ template<class E, class T, class Y, class D>
2306
  ``` cpp
2307
  namespace std {
2308
  class bad_weak_ptr : public exception {
2309
  public:
2310
  // see [exception] for the specification of the special member functions
2311
- const char* what() const noexcept override;
2312
  };
2313
  }
2314
  ```
2315
 
2316
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
2317
  constructor taking a `weak_ptr`.
2318
 
2319
  ``` cpp
2320
- const char* what() const noexcept override;
2321
  ```
2322
 
2323
  *Returns:* An *implementation-defined* NTBS.
2324
 
2325
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
@@ -2341,68 +2610,73 @@ namespace std {
2341
 
2342
  // [util.smartptr.shared.const], constructors
2343
  constexpr shared_ptr() noexcept;
2344
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
2345
  template<class Y>
2346
- explicit shared_ptr(Y* p);
2347
  template<class Y, class D>
2348
- shared_ptr(Y* p, D d);
2349
  template<class Y, class D, class A>
2350
- shared_ptr(Y* p, D d, A a);
2351
  template<class D>
2352
- shared_ptr(nullptr_t p, D d);
2353
  template<class D, class A>
2354
- shared_ptr(nullptr_t p, D d, A a);
2355
  template<class Y>
2356
- shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
2357
  template<class Y>
2358
- shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
2359
- shared_ptr(const shared_ptr& r) noexcept;
2360
  template<class Y>
2361
- shared_ptr(const shared_ptr<Y>& r) noexcept;
2362
- shared_ptr(shared_ptr&& r) noexcept;
2363
  template<class Y>
2364
- shared_ptr(shared_ptr<Y>&& r) noexcept;
2365
  template<class Y>
2366
- explicit shared_ptr(const weak_ptr<Y>& r);
2367
  template<class Y, class D>
2368
- shared_ptr(unique_ptr<Y, D>&& r);
2369
 
2370
  // [util.smartptr.shared.dest], destructor
2371
- ~shared_ptr();
2372
 
2373
  // [util.smartptr.shared.assign], assignment
2374
- shared_ptr& operator=(const shared_ptr& r) noexcept;
2375
  template<class Y>
2376
- shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
2377
- shared_ptr& operator=(shared_ptr&& r) noexcept;
2378
  template<class Y>
2379
- shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
2380
  template<class Y, class D>
2381
- shared_ptr& operator=(unique_ptr<Y, D>&& r);
2382
 
2383
  // [util.smartptr.shared.mod], modifiers
2384
- void swap(shared_ptr& r) noexcept;
2385
- void reset() noexcept;
2386
  template<class Y>
2387
- void reset(Y* p);
2388
  template<class Y, class D>
2389
- void reset(Y* p, D d);
2390
  template<class Y, class D, class A>
2391
- void reset(Y* p, D d, A a);
2392
 
2393
  // [util.smartptr.shared.obs], observers
2394
- element_type* get() const noexcept;
2395
- T& operator*() const noexcept;
2396
- T* operator->() const noexcept;
2397
- element_type& operator[](ptrdiff_t i) const;
2398
- long use_count() const noexcept;
2399
- explicit operator bool() const noexcept;
2400
  template<class U>
2401
- bool owner_before(const shared_ptr<U>& b) const noexcept;
2402
  template<class U>
2403
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
2404
  };
2405
 
2406
  template<class T>
2407
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
2408
  template<class T, class D>
@@ -2434,13 +2708,13 @@ For purposes of determining the presence of a data race, member
2434
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
2435
  objects themselves and not objects they refer to. Changes in
2436
  `use_count()` do not reflect modifications that can introduce data
2437
  races.
2438
 
2439
- For the purposes of subclause [[smartptr]], a pointer type `Y*` is said
2440
- to be *compatible with* a pointer type `T*` when either `Y*` is
2441
- convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
2442
 
2443
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
2444
 
2445
  In the constructor definitions below, enables `shared_from_this` with
2446
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
@@ -2448,26 +2722,26 @@ unambiguous and accessible base class that is a specialization of
2448
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
2449
  shall be implicitly convertible to `T*` and the constructor evaluates
2450
  the statement:
2451
 
2452
  ``` cpp
2453
- if (p != nullptr && p->weak_this.expired())
2454
- p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
2455
  ```
2456
 
2457
- The assignment to the `weak_this` member is not atomic and conflicts
2458
  with any potentially concurrent access to the same object
2459
  [[intro.multithread]].
2460
 
2461
  ``` cpp
2462
  constexpr shared_ptr() noexcept;
2463
  ```
2464
 
2465
  *Ensures:* `use_count() == 0 && get() == nullptr`.
2466
 
2467
  ``` cpp
2468
- template<class Y> explicit shared_ptr(Y* p);
2469
  ```
2470
 
2471
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
2472
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
2473
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
@@ -2491,14 +2765,14 @@ not an array type, `delete[] p` otherwise.
2491
 
2492
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
2493
  resource other than memory cannot be obtained.
2494
 
2495
  ``` cpp
2496
- template<class Y, class D> shared_ptr(Y* p, D d);
2497
- template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
2498
- template<class D> shared_ptr(nullptr_t p, D d);
2499
- template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
2500
  ```
2501
 
2502
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
2503
  well-formed expression. For the first two overloads:
2504
 
@@ -2523,12 +2797,12 @@ use. If an exception is thrown, `d(p)` is called.
2523
 
2524
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
2525
  resource other than memory cannot be obtained.
2526
 
2527
  ``` cpp
2528
- template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
2529
- template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
2530
  ```
2531
 
2532
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
2533
  ownership with the initial value of `r`.
2534
 
@@ -2541,12 +2815,12 @@ destroyed. — *end note*]
2541
 
2542
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
2543
  instance with a non-null stored pointer. — *end note*]
2544
 
2545
  ``` cpp
2546
- shared_ptr(const shared_ptr& r) noexcept;
2547
- template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
2548
  ```
2549
 
2550
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
2551
 
2552
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
@@ -2554,23 +2828,23 @@ otherwise, constructs a `shared_ptr` object that shares ownership with
2554
  `r`.
2555
 
2556
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
2557
 
2558
  ``` cpp
2559
- shared_ptr(shared_ptr&& r) noexcept;
2560
- template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
2561
  ```
2562
 
2563
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
2564
 
2565
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
2566
 
2567
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
2568
  `r.get() == nullptr`.
2569
 
2570
  ``` cpp
2571
- template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
2572
  ```
2573
 
2574
  *Constraints:* `Y*` is compatible with `T*`.
2575
 
2576
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
@@ -2580,11 +2854,11 @@ thrown, the constructor has no effect.
2580
  *Ensures:* `use_count() == r.use_count()`.
2581
 
2582
  *Throws:* `bad_weak_ptr` when `r.expired()`.
2583
 
2584
  ``` cpp
2585
- template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
2586
  ```
2587
 
2588
  *Constraints:* `Y*` is compatible with `T*` and
2589
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
2590
 
@@ -2595,11 +2869,11 @@ equivalent to `shared_ptr(r.release(), ref(r.get_deleter()))`. If an
2595
  exception is thrown, the constructor has no effect.
2596
 
2597
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
2598
 
2599
  ``` cpp
2600
- ~shared_ptr();
2601
  ```
2602
 
2603
  *Effects:*
2604
 
2605
  - If `*this` is empty or shares ownership with another `shared_ptr`
@@ -2615,12 +2889,12 @@ been destroyed all `shared_ptr` instances that shared ownership with
2615
  value. — *end note*]
2616
 
2617
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
2618
 
2619
  ``` cpp
2620
- shared_ptr& operator=(const shared_ptr& r) noexcept;
2621
- template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
2622
  ```
2623
 
2624
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
2625
 
2626
  *Returns:* `*this`.
@@ -2642,68 +2916,68 @@ q = p;
2642
  both assignments can be no-ops.
2643
 
2644
  — *end note*]
2645
 
2646
  ``` cpp
2647
- shared_ptr& operator=(shared_ptr&& r) noexcept;
2648
- template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
2649
  ```
2650
 
2651
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
2652
 
2653
  *Returns:* `*this`.
2654
 
2655
  ``` cpp
2656
- template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
2657
  ```
2658
 
2659
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
2660
 
2661
  *Returns:* `*this`.
2662
 
2663
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
2664
 
2665
  ``` cpp
2666
- void swap(shared_ptr& r) noexcept;
2667
  ```
2668
 
2669
  *Effects:* Exchanges the contents of `*this` and `r`.
2670
 
2671
  ``` cpp
2672
- void reset() noexcept;
2673
  ```
2674
 
2675
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
2676
 
2677
  ``` cpp
2678
- template<class Y> void reset(Y* p);
2679
  ```
2680
 
2681
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
2682
 
2683
  ``` cpp
2684
- template<class Y, class D> void reset(Y* p, D d);
2685
  ```
2686
 
2687
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
2688
 
2689
  ``` cpp
2690
- template<class Y, class D, class A> void reset(Y* p, D d, A a);
2691
  ```
2692
 
2693
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
2694
 
2695
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
2696
 
2697
  ``` cpp
2698
- element_type* get() const noexcept;
2699
  ```
2700
 
2701
  *Returns:* The stored pointer.
2702
 
2703
  ``` cpp
2704
- T& operator*() const noexcept;
2705
  ```
2706
 
2707
  *Preconditions:* `get() != nullptr`.
2708
 
2709
  *Returns:* `*get()`.
@@ -2713,11 +2987,11 @@ whether this member function is declared. If it is declared, it is
2713
  unspecified what its return type is, except that the declaration
2714
  (although not necessarily the definition) of the function shall be
2715
  well-formed.
2716
 
2717
  ``` cpp
2718
- T* operator->() const noexcept;
2719
  ```
2720
 
2721
  *Preconditions:* `get() != nullptr`.
2722
 
2723
  *Returns:* `get()`.
@@ -2726,15 +3000,16 @@ T* operator->() const noexcept;
2726
  member function is declared. If it is declared, it is unspecified what
2727
  its return type is, except that the declaration (although not
2728
  necessarily the definition) of the function shall be well-formed.
2729
 
2730
  ``` cpp
2731
- element_type& operator[](ptrdiff_t i) const;
2732
  ```
2733
 
2734
- *Preconditions:* `get() != nullptr && i >= 0`. If `T` is `U[N]`,
2735
- `i < N`.
 
2736
 
2737
  *Returns:* `get()[i]`.
2738
 
2739
  *Throws:* Nothing.
2740
 
@@ -2742,11 +3017,11 @@ element_type& operator[](ptrdiff_t i) const;
2742
  member function is declared. If it is declared, it is unspecified what
2743
  its return type is, except that the declaration (although not
2744
  necessarily the definition) of the function shall be well-formed.
2745
 
2746
  ``` cpp
2747
- long use_count() const noexcept;
2748
  ```
2749
 
2750
  *Synchronization:* None.
2751
 
2752
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
@@ -2762,45 +3037,62 @@ share ownership with `*this`, or `0` when `*this` is empty.
2762
  `use_count()`, the result is approximate. In particular,
2763
  `use_count() == 1` does not imply that accesses through a previously
2764
  destroyed `shared_ptr` have in any sense completed. — *end note*]
2765
 
2766
  ``` cpp
2767
- explicit operator bool() const noexcept;
2768
  ```
2769
 
2770
  *Returns:* `get() != nullptr`.
2771
 
2772
  ``` cpp
2773
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
2774
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
2775
  ```
2776
 
2777
  *Returns:* An unspecified value such that
2778
 
2779
- - `x.owner_before(y)` defines a strict weak ordering as defined
2780
  in  [[alg.sorting]];
2781
- - under the equivalence relation defined by `owner_before`,
2782
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
2783
- `weak_ptr` instances are equivalent if and only if they share
2784
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2785
 
2786
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
2787
 
2788
  The common requirements that apply to all `make_shared`,
2789
  `allocate_shared`, `make_shared_for_overwrite`, and
2790
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
2791
  are described below.
2792
 
2793
  ``` cpp
2794
  template<class T, ...>
2795
- shared_ptr<T> make_shared(args);
2796
  template<class T, class A, ...>
2797
- shared_ptr<T> allocate_shared(const A& a, args);
2798
  template<class T, ...>
2799
- shared_ptr<T> make_shared_for_overwrite(args);
2800
  template<class T, class A, ...>
2801
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
2802
  ```
2803
 
2804
  *Preconditions:* `A` meets the *Cpp17Allocator*
2805
  requirements [[allocator.requirements.general]].
2806
 
@@ -2841,56 +3133,58 @@ the initialization of the object.
2841
  suitable to hold an object of type `U`.
2842
  - When a (sub)object of a non-array type `U` is specified to have an
2843
  initial value of `v`, or `U(l...)`, where `l...` is a list of
2844
  constructor arguments, `allocate_shared` shall initialize this
2845
  (sub)object via the expression
2846
- - `allocator_traits<A2>::construct(a2, pv, v)` or
2847
- - `allocator_traits<A2>::construct(a2, pv, l...)`
2848
 
2849
- respectively, where `pv` points to storage suitable to hold an object
2850
- of type `U` and `a2` of type `A2` is a rebound copy of the allocator
2851
- `a` passed to `allocate_shared` such that its `value_type` is
2852
- `remove_cv_t<U>`.
2853
  - When a (sub)object of non-array type `U` is specified to have a
2854
  default initial value, `make_shared` shall initialize this (sub)object
2855
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
2856
  points to storage suitable to hold an object of type `U`.
2857
  - When a (sub)object of non-array type `U` is specified to have a
2858
- default initial value, `allocate_shared` shall initialize this
2859
- (sub)object via the expression
2860
- `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
2861
- storage suitable to hold an object of type `U` and `a2` of type `A2`
2862
- is a rebound copy of the allocator `a` passed to `allocate_shared`
2863
- such that its `value_type` is `remove_cv_t<U>`.
2864
  - When a (sub)object of non-array type `U` is initialized by
2865
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
2866
  initialized via the expression `::new(pv) U`, where `pv` has type
2867
  `void*` and points to storage suitable to hold an object of type `U`.
2868
  - Array elements are initialized in ascending order of their addresses.
2869
  - When the lifetime of the object managed by the return value ends, or
2870
  when the initialization of an array element throws an exception, the
2871
  initialized elements are destroyed in the reverse order of their
2872
  original construction.
2873
  - When a (sub)object of non-array type `U` that was initialized by
2874
- `make_shared` is to be destroyed, it is destroyed via the expression
2875
- `pv->~U()` where `pv` points to that object of type `U`.
 
 
2876
  - When a (sub)object of non-array type `U` that was initialized by
2877
  `allocate_shared` is to be destroyed, it is destroyed via the
2878
- expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
2879
- to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
2880
- rebound copy of the allocator `a` passed to `allocate_shared` such
2881
- that its `value_type` is `remove_cv_t<U>`.
2882
 
2883
  [*Note 7*: These functions will typically allocate more memory than
2884
  `sizeof(T)` to allow for internal bookkeeping structures such as
2885
  reference counts. — *end note*]
2886
 
2887
  ``` cpp
2888
  template<class T, class... Args>
2889
- shared_ptr<T> make_shared(Args&&... args); // T is not array
2890
  template<class T, class A, class... Args>
2891
- shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
2892
  ```
2893
 
2894
  *Constraints:* `T` is not an array type.
2895
 
2896
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
@@ -2909,14 +3203,14 @@ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
2909
  ```
2910
 
2911
  — *end example*]
2912
 
2913
  ``` cpp
2914
- template<class T> shared_ptr<T>
2915
- make_shared(size_t N); // T is U[]
2916
  template<class T, class A>
2917
- shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
2918
  ```
2919
 
2920
  *Constraints:* `T` is of the form `U[]`.
2921
 
2922
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
@@ -2933,13 +3227,13 @@ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
2933
 
2934
  — *end example*]
2935
 
2936
  ``` cpp
2937
  template<class T>
2938
- shared_ptr<T> make_shared(); // T is U[N]
2939
  template<class T, class A>
2940
- shared_ptr<T> allocate_shared(const A& a); // T is U[N]
2941
  ```
2942
 
2943
  *Constraints:* `T` is of the form `U[N]`.
2944
 
2945
  *Returns:* A `shared_ptr` to an object of type `T` with a default
@@ -2956,14 +3250,14 @@ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
2956
 
2957
  — *end example*]
2958
 
2959
  ``` cpp
2960
  template<class T>
2961
- shared_ptr<T> make_shared(size_t N,
2962
  const remove_extent_t<T>& u); // T is U[]
2963
  template<class T, class A>
2964
- shared_ptr<T> allocate_shared(const A& a, size_t N,
2965
  const remove_extent_t<T>& u); // T is U[]
2966
  ```
2967
 
2968
  *Constraints:* `T` is of the form `U[]`.
2969
 
@@ -2983,13 +3277,13 @@ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
2983
 
2984
  — *end example*]
2985
 
2986
  ``` cpp
2987
  template<class T>
2988
- shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
2989
  template<class T, class A>
2990
- shared_ptr<T> allocate_shared(const A& a,
2991
  const remove_extent_t<T>& u); // T is U[N]
2992
  ```
2993
 
2994
  *Constraints:* `T` is of the form `U[N]`.
2995
 
@@ -3009,13 +3303,13 @@ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
3009
 
3010
  — *end example*]
3011
 
3012
  ``` cpp
3013
  template<class T>
3014
- shared_ptr<T> make_shared_for_overwrite();
3015
  template<class T, class A>
3016
- shared_ptr<T> allocate_shared_for_overwrite(const A& a);
3017
  ```
3018
 
3019
  *Constraints:* `T` is not an array of unknown bound.
3020
 
3021
  *Returns:* A `shared_ptr` to an object of type `T`.
@@ -3033,13 +3327,13 @@ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
3033
 
3034
  — *end example*]
3035
 
3036
  ``` cpp
3037
  template<class T>
3038
- shared_ptr<T> make_shared_for_overwrite(size_t N);
3039
  template<class T, class A>
3040
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
3041
  ```
3042
 
3043
  *Constraints:* `T` is an array of unknown bound.
3044
 
3045
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
@@ -3056,59 +3350,59 @@ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
3056
 
3057
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
3058
 
3059
  ``` cpp
3060
  template<class T, class U>
3061
- bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
3062
  ```
3063
 
3064
  *Returns:* `a.get() == b.get()`.
3065
 
3066
  ``` cpp
3067
  template<class T>
3068
- bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
3069
  ```
3070
 
3071
  *Returns:* `!a`.
3072
 
3073
  ``` cpp
3074
  template<class T, class U>
3075
- strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
3076
  ```
3077
 
3078
  *Returns:* `compare_three_way()(a.get(), b.get())`.
3079
 
3080
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
3081
  objects to be used as keys in associative containers. — *end note*]
3082
 
3083
  ``` cpp
3084
  template<class T>
3085
- strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
3086
  ```
3087
 
3088
  *Returns:*
3089
 
3090
  ``` cpp
3091
- compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr).
3092
  ```
3093
 
3094
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
3095
 
3096
  ``` cpp
3097
  template<class T>
3098
- void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
3099
  ```
3100
 
3101
  *Effects:* Equivalent to `a.swap(b)`.
3102
 
3103
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
3104
 
3105
  ``` cpp
3106
  template<class T, class U>
3107
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
3108
  template<class T, class U>
3109
- shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
3110
  ```
3111
 
3112
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
3113
  well-formed.
3114
 
@@ -3120,19 +3414,18 @@ shared_ptr<T>(R, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
3120
 
3121
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
3122
  second.
3123
 
3124
  [*Note 9*: The seemingly equivalent expression
3125
- `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
3126
- undefined behavior, attempting to delete the same object
3127
- twice. — *end note*]
3128
 
3129
  ``` cpp
3130
  template<class T, class U>
3131
- shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
3132
  template<class T, class U>
3133
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
3134
  ```
3135
 
3136
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
3137
  well-formed. The expression
3138
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
@@ -3148,19 +3441,18 @@ well-defined behavior.
3148
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
3149
  is `r` for the first overload, and `std::move(r)` for the second.
3150
  - Otherwise, `shared_ptr<T>()`.
3151
 
3152
  [*Note 10*: The seemingly equivalent expression
3153
- `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
3154
- undefined behavior, attempting to delete the same object
3155
- twice. — *end note*]
3156
 
3157
  ``` cpp
3158
  template<class T, class U>
3159
- shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
3160
  template<class T, class U>
3161
- shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
3162
  ```
3163
 
3164
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
3165
 
3166
  *Returns:*
@@ -3171,13 +3463,12 @@ shared_ptr<T>(R, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
3171
 
3172
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
3173
  second.
3174
 
3175
  [*Note 11*: The seemingly equivalent expression
3176
- `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
3177
- undefined behavior, attempting to delete the same object
3178
- twice. — *end note*]
3179
 
3180
  ``` cpp
3181
  template<class T, class U>
3182
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
3183
  template<class T, class U>
@@ -3195,19 +3486,18 @@ shared_ptr<T>(R, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()
3195
 
3196
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
3197
  second.
3198
 
3199
  [*Note 12*: The seemingly equivalent expression
3200
- `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
3201
- undefined behavior, attempting to delete the same object
3202
- twice. — *end note*]
3203
 
3204
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
3205
 
3206
  ``` cpp
3207
  template<class D, class T>
3208
- D* get_deleter(const shared_ptr<T>& p) noexcept;
3209
  ```
3210
 
3211
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
3212
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
3213
  remains valid as long as there exists a `shared_ptr` instance that owns
@@ -3244,43 +3534,48 @@ namespace std {
3244
  using element_type = remove_extent_t<T>;
3245
 
3246
  // [util.smartptr.weak.const], constructors
3247
  constexpr weak_ptr() noexcept;
3248
  template<class Y>
3249
- weak_ptr(const shared_ptr<Y>& r) noexcept;
3250
- weak_ptr(const weak_ptr& r) noexcept;
3251
  template<class Y>
3252
- weak_ptr(const weak_ptr<Y>& r) noexcept;
3253
- weak_ptr(weak_ptr&& r) noexcept;
3254
  template<class Y>
3255
- weak_ptr(weak_ptr<Y>&& r) noexcept;
3256
 
3257
  // [util.smartptr.weak.dest], destructor
3258
- ~weak_ptr();
3259
 
3260
  // [util.smartptr.weak.assign], assignment
3261
- weak_ptr& operator=(const weak_ptr& r) noexcept;
3262
  template<class Y>
3263
- weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
3264
  template<class Y>
3265
- weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
3266
- weak_ptr& operator=(weak_ptr&& r) noexcept;
3267
  template<class Y>
3268
- weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
3269
 
3270
  // [util.smartptr.weak.mod], modifiers
3271
- void swap(weak_ptr& r) noexcept;
3272
- void reset() noexcept;
3273
 
3274
  // [util.smartptr.weak.obs], observers
3275
- long use_count() const noexcept;
3276
- bool expired() const noexcept;
3277
- shared_ptr<T> lock() const noexcept;
3278
  template<class U>
3279
- bool owner_before(const shared_ptr<U>& b) const noexcept;
3280
  template<class U>
3281
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
3282
  };
3283
 
3284
  template<class T>
3285
  weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
3286
  }
@@ -3300,13 +3595,13 @@ constexpr weak_ptr() noexcept;
3300
  pointer value.
3301
 
3302
  *Ensures:* `use_count() == 0`.
3303
 
3304
  ``` cpp
3305
- weak_ptr(const weak_ptr& r) noexcept;
3306
- template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
3307
- template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
3308
  ```
3309
 
3310
  *Constraints:* For the second and third constructors, `Y*` is compatible
3311
  with `T*`.
3312
 
@@ -3316,12 +3611,12 @@ that shares ownership with `r` and stores a copy of the pointer stored
3316
  in `r`.
3317
 
3318
  *Ensures:* `use_count() == r.use_count()`.
3319
 
3320
  ``` cpp
3321
- weak_ptr(weak_ptr&& r) noexcept;
3322
- template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
3323
  ```
3324
 
3325
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
3326
 
3327
  *Effects:* Move constructs a `weak_ptr` instance from `r`.
@@ -3330,95 +3625,112 @@ template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
3330
  null pointer value, and `r.use_count() == 0`.
3331
 
3332
  ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
3333
 
3334
  ``` cpp
3335
- ~weak_ptr();
3336
  ```
3337
 
3338
  *Effects:* Destroys this `weak_ptr` object but has no effect on the
3339
  object its stored pointer points to.
3340
 
3341
  ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
3342
 
3343
  ``` cpp
3344
- weak_ptr& operator=(const weak_ptr& r) noexcept;
3345
- template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
3346
- template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
3347
  ```
3348
 
3349
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
3350
 
3351
  *Returns:* `*this`.
3352
 
3353
  *Remarks:* The implementation may meet the effects (and the implied
3354
  guarantees) via different means, without creating a temporary object.
3355
 
3356
  ``` cpp
3357
- weak_ptr& operator=(weak_ptr&& r) noexcept;
3358
- template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
3359
  ```
3360
 
3361
  *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
3362
 
3363
  *Returns:* `*this`.
3364
 
3365
  ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
3366
 
3367
  ``` cpp
3368
- void swap(weak_ptr& r) noexcept;
3369
  ```
3370
 
3371
  *Effects:* Exchanges the contents of `*this` and `r`.
3372
 
3373
  ``` cpp
3374
- void reset() noexcept;
3375
  ```
3376
 
3377
  *Effects:* Equivalent to `weak_ptr().swap(*this)`.
3378
 
3379
  ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
3380
 
3381
  ``` cpp
3382
- long use_count() const noexcept;
3383
  ```
3384
 
3385
  *Returns:* `0` if `*this` is empty; otherwise, the number of
3386
  `shared_ptr` instances that share ownership with `*this`.
3387
 
3388
  ``` cpp
3389
- bool expired() const noexcept;
3390
  ```
3391
 
3392
  *Returns:* `use_count() == 0`.
3393
 
3394
  ``` cpp
3395
- shared_ptr<T> lock() const noexcept;
3396
  ```
3397
 
3398
  *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
3399
  executed atomically.
3400
 
3401
  ``` cpp
3402
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
3403
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
3404
  ```
3405
 
3406
  *Returns:* An unspecified value such that
3407
 
3408
- - `x.owner_before(y)` defines a strict weak ordering as defined
3409
  in  [[alg.sorting]];
3410
- - under the equivalence relation defined by `owner_before`,
3411
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
3412
- `weak_ptr` instances are equivalent if and only if they share
3413
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3414
 
3415
  ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
3416
 
3417
  ``` cpp
3418
  template<class T>
3419
- void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
3420
  ```
3421
 
3422
  *Effects:* Equivalent to `a.swap(b)`.
3423
 
3424
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
@@ -3429,30 +3741,30 @@ of shared and weak pointers.
3429
  ``` cpp
3430
  namespace std {
3431
  template<class T = void> struct owner_less;
3432
 
3433
  template<class T> struct owner_less<shared_ptr<T>> {
3434
- bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
3435
- bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
3436
- bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
3437
  };
3438
 
3439
  template<class T> struct owner_less<weak_ptr<T>> {
3440
- bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
3441
- bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
3442
- bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
3443
  };
3444
 
3445
  template<> struct owner_less<void> {
3446
  template<class T, class U>
3447
- bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
3448
  template<class T, class U>
3449
- bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
3450
  template<class T, class U>
3451
- bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
3452
  template<class T, class U>
3453
- bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
3454
 
3455
  using is_transparent = unspecified;
3456
  };
3457
  }
3458
  ```
@@ -3463,17 +3775,83 @@ namespace std {
3463
 
3464
  Note that
3465
 
3466
  - `operator()` defines a strict weak ordering as defined in 
3467
  [[alg.sorting]];
3468
- - two `shared_ptr` or `weak_ptr` instances are equivalent under the
3469
- equivalence relation defined by `operator()`,
3470
- `!operator()(a, b) && !operator()(b, a)`, if and only if they share
3471
- ownership or are both empty.
3472
 
3473
  — *end note*]
3474
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3475
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
3476
 
3477
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
3478
  `shared_from_this` member functions that obtain a `shared_ptr` instance
3479
  pointing to `*this`.
@@ -3485,68 +3863,68 @@ struct X: public enable_shared_from_this<X> { };
3485
 
3486
  int main() {
3487
  shared_ptr<X> p(new X);
3488
  shared_ptr<X> q = p->shared_from_this();
3489
  assert(p == q);
3490
- assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
3491
  }
3492
  ```
3493
 
3494
  — *end example*]
3495
 
3496
  ``` cpp
3497
  namespace std {
3498
  template<class T> class enable_shared_from_this {
3499
  protected:
3500
  constexpr enable_shared_from_this() noexcept;
3501
- enable_shared_from_this(const enable_shared_from_this&) noexcept;
3502
- enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
3503
- ~enable_shared_from_this();
3504
 
3505
  public:
3506
- shared_ptr<T> shared_from_this();
3507
- shared_ptr<T const> shared_from_this() const;
3508
- weak_ptr<T> weak_from_this() noexcept;
3509
- weak_ptr<T const> weak_from_this() const noexcept;
3510
 
3511
  private:
3512
- mutable weak_ptr<T> weak_this; // exposition only
3513
  };
3514
  }
3515
  ```
3516
 
3517
  The template parameter `T` of `enable_shared_from_this` may be an
3518
  incomplete type.
3519
 
3520
  ``` cpp
3521
  constexpr enable_shared_from_this() noexcept;
3522
- enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
3523
  ```
3524
 
3525
- *Effects:* Value-initializes `weak_this`.
3526
 
3527
  ``` cpp
3528
- enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
3529
  ```
3530
 
3531
  *Returns:* `*this`.
3532
 
3533
- [*Note 1*: `weak_this` is not changed. — *end note*]
3534
 
3535
  ``` cpp
3536
- shared_ptr<T> shared_from_this();
3537
- shared_ptr<T const> shared_from_this() const;
3538
  ```
3539
 
3540
- *Returns:* `shared_ptr<T>(weak_this)`.
3541
 
3542
  ``` cpp
3543
- weak_ptr<T> weak_from_this() noexcept;
3544
- weak_ptr<T const> weak_from_this() const noexcept;
3545
  ```
3546
 
3547
- *Returns:* `weak_this`.
3548
 
3549
  ### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
3550
 
3551
  ``` cpp
3552
  template<class T, class D> struct hash<unique_ptr<T, D>>;
@@ -3607,16 +3985,16 @@ pointer value and manually delete it on error or failure.
3607
  ``` cpp
3608
  namespace std {
3609
  template<class Smart, class Pointer, class... Args>
3610
  class out_ptr_t {
3611
  public:
3612
- explicit out_ptr_t(Smart&, Args...);
3613
  out_ptr_t(const out_ptr_t&) = delete;
3614
 
3615
- ~out_ptr_t();
3616
 
3617
- operator Pointer*() const noexcept;
3618
  operator void**() const noexcept;
3619
 
3620
  private:
3621
  Smart& s; // exposition only
3622
  tuple<Args...> a; // exposition only
@@ -3640,41 +4018,40 @@ template.
3640
 
3641
  Evaluations of the conversion functions on the same object may conflict
3642
  [[intro.races]].
3643
 
3644
  ``` cpp
3645
- explicit out_ptr_t(Smart& smart, Args... args);
3646
  ```
3647
 
3648
  *Effects:* Initializes `s` with `smart`, `a` with
3649
  `std::forward<Args>(args)...`, and value-initializes `p`. Then,
3650
  equivalent to:
3651
 
3652
- - ``` cpp
 
3653
  s.reset();
3654
  ```
3655
 
3656
  if the expression `s.reset()` is well-formed;
3657
-
3658
  - otherwise,
3659
  ``` cpp
3660
  s = Smart();
3661
  ```
3662
 
3663
  if `is_constructible_v<Smart>` is `true`;
3664
-
3665
  - otherwise, the program is ill-formed.
3666
 
3667
  [*Note 1*: The constructor is not `noexcept` to allow for a variety of
3668
  non-terminating and safe implementation strategies. For example, an
3669
  implementation can allocate a `shared_ptr`’s internal node in the
3670
  constructor and let implementation-defined exceptions escape safely. The
3671
  destructor can then move the allocated control block in directly and
3672
  avoid any other exceptions. — *end note*]
3673
 
3674
  ``` cpp
3675
- ~out_ptr_t();
3676
  ```
3677
 
3678
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
3679
 
3680
  *Effects:* Equivalent to:
@@ -3700,11 +4077,11 @@ Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
3700
 
3701
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
3702
  - otherwise, the program is ill-formed.
3703
 
3704
  ``` cpp
3705
- operator Pointer*() const noexcept;
3706
  ```
3707
 
3708
  *Preconditions:* `operator void**()` has not been called on `*this`.
3709
 
3710
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
@@ -3735,18 +4112,18 @@ implementations. — *end note*]
3735
 
3736
  #### Function template `out_ptr` <a id="out.ptr">[[out.ptr]]</a>
3737
 
3738
  ``` cpp
3739
  template<class Pointer = void, class Smart, class... Args>
3740
- auto out_ptr(Smart& s, Args&&... args);
3741
  ```
3742
 
3743
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
3744
  *`POINTER_OF`*`(Smart)`.
3745
 
3746
  *Returns:*
3747
- `out_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`
3748
 
3749
  #### Class template `inout_ptr_t` <a id="inout.ptr.t">[[inout.ptr.t]]</a>
3750
 
3751
  `inout_ptr_t` is a class template used to adapt types such as smart
3752
  pointers [[smartptr]] for functions that use output pointer parameters
@@ -3786,16 +4163,16 @@ place.
3786
  ``` cpp
3787
  namespace std {
3788
  template<class Smart, class Pointer, class... Args>
3789
  class inout_ptr_t {
3790
  public:
3791
- explicit inout_ptr_t(Smart&, Args...);
3792
  inout_ptr_t(const inout_ptr_t&) = delete;
3793
 
3794
- ~inout_ptr_t();
3795
 
3796
- operator Pointer*() const noexcept;
3797
  operator void**() const noexcept;
3798
 
3799
  private:
3800
  Smart& s; // exposition only
3801
  tuple<Args...> a; // exposition only
@@ -3817,11 +4194,11 @@ template.
3817
 
3818
  Evaluations of the conversion functions on the same object may conflict
3819
  [[intro.races]].
3820
 
3821
  ``` cpp
3822
- explicit inout_ptr_t(Smart& smart, Args... args);
3823
  ```
3824
 
3825
  *Effects:* Initializes `s` with `smart`, `a` with
3826
  `std::forward<Args>(args)...`, and `p` to either
3827
 
@@ -3834,11 +4211,11 @@ explicit inout_ptr_t(Smart& smart, Args... args);
3834
  non-terminating and safe implementation strategies. For example, an
3835
  intrusive pointer implementation with a control block can allocate in
3836
  the constructor and safely fail with an exception. — *end note*]
3837
 
3838
  ``` cpp
3839
- ~inout_ptr_t();
3840
  ```
3841
 
3842
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
3843
 
3844
  Let *release-statement* be `s.release();` if an implementation does not
@@ -3846,14 +4223,12 @@ call `s.release()` in the constructor. Otherwise, it is empty.
3846
 
3847
  *Effects:* Equivalent to:
3848
 
3849
  -
3850
  ``` cpp
3851
- if (p) {
3852
  apply([&](auto&&... args) {
3853
  s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
3854
- }
3855
  ```
3856
 
3857
  if `is_pointer_v<Smart>` is `true`;
3858
  - otherwise,
3859
  ``` cpp
@@ -3878,11 +4253,11 @@ call `s.release()` in the constructor. Otherwise, it is empty.
3878
 
3879
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
3880
  - otherwise, the program is ill-formed.
3881
 
3882
  ``` cpp
3883
- operator Pointer*() const noexcept;
3884
  ```
3885
 
3886
  *Preconditions:* `operator void**()` has not been called on `*this`.
3887
 
3888
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
@@ -3913,19 +4288,977 @@ implementations. — *end note*]
3913
 
3914
  #### Function template `inout_ptr` <a id="inout.ptr">[[inout.ptr]]</a>
3915
 
3916
  ``` cpp
3917
  template<class Pointer = void, class Smart, class... Args>
3918
- auto inout_ptr(Smart& s, Args&&... args);
3919
  ```
3920
 
3921
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
3922
  *`POINTER_OF`*`(Smart)`.
3923
 
3924
  *Returns:*
3925
  `inout_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`.
3926
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3927
  ## Memory resources <a id="mem.res">[[mem.res]]</a>
3928
 
3929
  ### Header `<memory_resource>` synopsis <a id="mem.res.syn">[[mem.res.syn]]</a>
3930
 
3931
  ``` cpp
@@ -3973,11 +5306,11 @@ namespace std::pmr {
3973
  memory_resource(const memory_resource&) = default;
3974
  virtual ~memory_resource();
3975
 
3976
  memory_resource& operator=(const memory_resource&) = default;
3977
 
3978
- [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
3979
  void deallocate(void* p, size_t bytes, size_t alignment = max_align);
3980
 
3981
  bool is_equal(const memory_resource& other) const noexcept;
3982
 
3983
  private:
@@ -3996,11 +5329,11 @@ namespace std::pmr {
3996
  ```
3997
 
3998
  *Effects:* Destroys this `memory_resource`.
3999
 
4000
  ``` cpp
4001
- [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align);
4002
  ```
4003
 
4004
  *Effects:* Allocates storage by calling `do_allocate(bytes, alignment)`
4005
  and implicitly creates objects within the allocated region of storage.
4006
 
@@ -4053,16 +5386,16 @@ allocated storage.
4053
  ``` cpp
4054
  virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
4055
  ```
4056
 
4057
  *Returns:* A derived class shall implement this function to return
4058
- `true` if memory allocated from `this` can be deallocated from `other`
4059
  and vice-versa, otherwise `false`.
4060
 
4061
  [*Note 1*: It is possible that the most-derived type of `other` does
4062
- not match the type of `this`. For a derived class `D`, an implementation
4063
- of this function can immediately return `false` if
4064
  `dynamic_cast<const D*>(&other) == nullptr`. — *end note*]
4065
 
4066
  #### Equality <a id="mem.res.eq">[[mem.res.eq]]</a>
4067
 
4068
  ``` cpp
@@ -4108,23 +5441,26 @@ namespace std::pmr {
4108
  polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
4109
 
4110
  polymorphic_allocator& operator=(const polymorphic_allocator&) = delete;
4111
 
4112
  // [mem.poly.allocator.mem], member functions
4113
- [[nodiscard]] Tp* allocate(size_t n);
4114
  void deallocate(Tp* p, size_t n);
4115
 
4116
- [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
4117
  void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
4118
- template<class T> [[nodiscard]] T* allocate_object(size_t n = 1);
4119
  template<class T> void deallocate_object(T* p, size_t n = 1);
4120
- template<class T, class... CtorArgs> [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
4121
  template<class T> void delete_object(T* p);
4122
 
4123
  template<class T, class... Args>
4124
  void construct(T* p, Args&&... args);
4125
 
 
 
 
4126
  polymorphic_allocator select_on_container_copy_construction() const;
4127
 
4128
  memory_resource* resource() const;
4129
 
4130
  // friends
@@ -4164,11 +5500,11 @@ template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) n
4164
  *Effects:* Sets `memory_rsrc` to `other.resource()`.
4165
 
4166
  #### Member functions <a id="mem.poly.allocator.mem">[[mem.poly.allocator.mem]]</a>
4167
 
4168
  ``` cpp
4169
- [[nodiscard]] Tp* allocate(size_t n);
4170
  ```
4171
 
4172
  *Effects:* If `numeric_limits<size_t>::max() / sizeof(Tp) < n`, throws
4173
  `bad_array_new_length`. Otherwise equivalent to:
4174
 
@@ -4187,11 +5523,11 @@ void deallocate(Tp* p, size_t n);
4187
  `memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp))`.
4188
 
4189
  *Throws:* Nothing.
4190
 
4191
  ``` cpp
4192
- [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
4193
  ```
4194
 
4195
  *Effects:* Equivalent to:
4196
  `return memory_rsrc->allocate(nbytes, alignment);`
4197
 
@@ -4207,11 +5543,11 @@ void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_ali
4207
  *Effects:* Equivalent to
4208
  `memory_rsrc->deallocate(p, nbytes, alignment)`.
4209
 
4210
  ``` cpp
4211
  template<class T>
4212
- [[nodiscard]] T* allocate_object(size_t n = 1);
4213
  ```
4214
 
4215
  *Effects:* Allocates memory suitable for holding an array of `n` objects
4216
  of type `T`, as follows:
4217
 
@@ -4232,11 +5568,11 @@ template<class T>
4232
 
4233
  *Effects:* Equivalent to `deallocate_bytes(p, n*sizeof(T), alignof(T))`.
4234
 
4235
  ``` cpp
4236
  template<class T, class... CtorArgs>
4237
- [[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
4238
  ```
4239
 
4240
  *Effects:* Allocates and constructs an object of type `T`, as follows.
4241
  Equivalent to:
4242
 
@@ -4260,11 +5596,11 @@ template<class T>
4260
  ```
4261
 
4262
  *Effects:* Equivalent to:
4263
 
4264
  ``` cpp
4265
- allocator_traits<polymorphic_allocator>::destroy(*this, p);
4266
  deallocate_object(p);
4267
  ```
4268
 
4269
  ``` cpp
4270
  template<class T, class... Args>
@@ -4273,16 +5609,23 @@ template<class T, class... Args>
4273
 
4274
  *Mandates:* Uses-allocator construction of `T` with allocator `*this`
4275
  (see  [[allocator.uses.construction]]) and constructor arguments
4276
  `std::forward<Args>(args)...` is well-formed.
4277
 
4278
- *Effects:* Construct a `T` object in the storage whose address is
4279
  represented by `p` by uses-allocator construction with allocator `*this`
4280
  and constructor arguments `std::forward<Args>(args)...`.
4281
 
4282
  *Throws:* Nothing unless the constructor for `T` throws.
4283
 
 
 
 
 
 
 
 
4284
  ``` cpp
4285
  polymorphic_allocator select_on_container_copy_construction() const;
4286
  ```
4287
 
4288
  *Returns:* `polymorphic_allocator()`.
@@ -4341,13 +5684,13 @@ resource pointer to `r`, otherwise sets the default memory resource
4341
  pointer to `new_delete_resource()`.
4342
 
4343
  *Returns:* The previous value of the default memory resource pointer.
4344
 
4345
  *Remarks:* Calling the `set_default_resource` and `get_default_resource`
4346
- functions shall not incur a data race. A call to the
4347
- `set_default_resource` function shall synchronize with subsequent calls
4348
- to the `set_default_resource` and `get_default_resource` functions.
4349
 
4350
  ``` cpp
4351
  memory_resource* get_default_resource() noexcept;
4352
  ```
4353
 
@@ -4464,11 +5807,11 @@ size_t max_blocks_per_chunk;
4464
  The maximum number of blocks that will be allocated at once from the
4465
  upstream memory resource [[mem.res.monotonic.buffer]] to replenish a
4466
  pool. If the value of `max_blocks_per_chunk` is zero or is greater than
4467
  an *implementation-defined* limit, that limit is used instead. The
4468
  implementation may choose to use a smaller value than is specified in
4469
- this field and may use different values for different pools.
4470
 
4471
  ``` cpp
4472
  size_t largest_required_pool_block;
4473
  ```
4474
 
@@ -4476,11 +5819,11 @@ The largest allocation size that is required to be fulfilled using the
4476
  pooling mechanism. Attempts to allocate a single block larger than this
4477
  threshold will be allocated directly from the upstream memory resource.
4478
  If `largest_required_pool_block` is zero or is greater than an
4479
  *implementation-defined* limit, that limit is used instead. The
4480
  implementation may choose a pass-through threshold larger than specified
4481
- in this field.
4482
 
4483
  #### Constructors and destructors <a id="mem.res.pool.ctor">[[mem.res.pool.ctor]]</a>
4484
 
4485
  ``` cpp
4486
  synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
@@ -4665,12 +6008,12 @@ void release();
4665
  *Effects:* Calls `upstream_rsrc->deallocate()` as necessary to release
4666
  all allocated memory. Resets `current_buffer` and `next_buffer_size` to
4667
  their initial values at construction.
4668
 
4669
  [*Note 1*: The memory is released back to `upstream_rsrc` even if some
4670
- blocks that were allocated from `this` have not been deallocated from
4671
- `this`. — *end note*]
4672
 
4673
  ``` cpp
4674
  memory_resource* upstream_resource() const;
4675
  ```
4676
 
@@ -4764,17 +6107,17 @@ namespace std {
4764
 
4765
  public:
4766
  using outer_allocator_type = OuterAlloc;
4767
  using inner_allocator_type = see below;
4768
 
4769
- using value_type = typename OuterTraits::value_type;
4770
- using size_type = typename OuterTraits::size_type;
4771
- using difference_type = typename OuterTraits::difference_type;
4772
- using pointer = typename OuterTraits::pointer;
4773
- using const_pointer = typename OuterTraits::const_pointer;
4774
- using void_pointer = typename OuterTraits::void_pointer;
4775
- using const_void_pointer = typename OuterTraits::const_void_pointer;
4776
 
4777
  using propagate_on_container_copy_assignment = see below;
4778
  using propagate_on_container_move_assignment = see below;
4779
  using propagate_on_container_swap = see below;
4780
  using is_always_equal = see below;
@@ -4807,12 +6150,12 @@ namespace std {
4807
  inner_allocator_type& inner_allocator() noexcept;
4808
  const inner_allocator_type& inner_allocator() const noexcept;
4809
  outer_allocator_type& outer_allocator() noexcept;
4810
  const outer_allocator_type& outer_allocator() const noexcept;
4811
 
4812
- [[nodiscard]] pointer allocate(size_type n);
4813
- [[nodiscard]] pointer allocate(size_type n, const_void_pointer hint);
4814
  void deallocate(pointer p, size_type n);
4815
  size_type max_size() const;
4816
 
4817
  template<class T, class... Args>
4818
  void construct(T* p, Args&&... args);
@@ -4962,18 +6305,18 @@ const outer_allocator_type& outer_allocator() const noexcept;
4962
  ```
4963
 
4964
  *Returns:* `static_cast<const OuterAlloc&>(*this)`.
4965
 
4966
  ``` cpp
4967
- [[nodiscard]] pointer allocate(size_type n);
4968
  ```
4969
 
4970
  *Returns:*
4971
  `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)`.
4972
 
4973
  ``` cpp
4974
- [[nodiscard]] pointer allocate(size_type n, const_void_pointer hint);
4975
  ```
4976
 
4977
  *Returns:*
4978
  `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)`.
4979
 
@@ -5065,14 +6408,15 @@ a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_all
5065
  [allocator.uses]: #allocator.uses
5066
  [allocator.uses.construction]: #allocator.uses.construction
5067
  [allocator.uses.trait]: #allocator.uses.trait
5068
  [basic.align]: basic.md#basic.align
5069
  [basic.compound]: basic.md#basic.compound
 
5070
  [basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
5071
- [basic.types.general]: basic.md#basic.types.general
5072
  [bit.cast]: utilities.md#bit.cast
5073
  [c.malloc]: #c.malloc
 
5074
  [conv.qual]: expr.md#conv.qual
5075
  [cpp17.defaultconstructible]: #cpp17.defaultconstructible
5076
  [cpp17.destructible]: #cpp17.destructible
5077
  [cpp17.moveassignable]: #cpp17.moveassignable
5078
  [cpp17.moveconstructible]: #cpp17.moveconstructible
@@ -5080,16 +6424,28 @@ a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_all
5080
  [default.allocator]: #default.allocator
5081
  [default.allocator.general]: #default.allocator.general
5082
  [defns.const.subexpr]: intro.md#defns.const.subexpr
5083
  [expr.eq]: expr.md#expr.eq
5084
  [function.objects]: utilities.md#function.objects
 
 
 
 
 
 
 
 
 
 
 
5085
  [inout.ptr]: #inout.ptr
5086
  [inout.ptr.t]: #inout.ptr.t
5087
  [intro.multithread]: basic.md#intro.multithread
5088
  [intro.object]: basic.md#intro.object
5089
  [intro.races]: basic.md#intro.races
5090
  [mem]: #mem
 
5091
  [mem.general]: #mem.general
5092
  [mem.poly.allocator.class]: #mem.poly.allocator.class
5093
  [mem.poly.allocator.class.general]: #mem.poly.allocator.class.general
5094
  [mem.poly.allocator.ctor]: #mem.poly.allocator.ctor
5095
  [mem.poly.allocator.eq]: #mem.poly.allocator.eq
@@ -5124,20 +6480,30 @@ a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_all
5124
  [pointer.traits]: #pointer.traits
5125
  [pointer.traits.functions]: #pointer.traits.functions
5126
  [pointer.traits.general]: #pointer.traits.general
5127
  [pointer.traits.optmem]: #pointer.traits.optmem
5128
  [pointer.traits.types]: #pointer.traits.types
 
 
 
 
 
 
 
 
5129
  [ptr.align]: #ptr.align
5130
  [scoped.adaptor.operators]: #scoped.adaptor.operators
5131
  [smartptr]: #smartptr
5132
  [smartptr.adapt]: #smartptr.adapt
5133
  [specialized.addressof]: #specialized.addressof
5134
  [specialized.algorithms]: algorithms.md#specialized.algorithms
5135
  [stmt.dcl]: stmt.md#stmt.dcl
5136
  [swappable.requirements]: library.md#swappable.requirements
5137
  [temp.deduct]: temp.md#temp.deduct
 
5138
  [term.incomplete.type]: basic.md#term.incomplete.type
 
5139
  [tuple]: utilities.md#tuple
5140
  [unique.ptr]: #unique.ptr
5141
  [unique.ptr.create]: #unique.ptr.create
5142
  [unique.ptr.dltr]: #unique.ptr.dltr
5143
  [unique.ptr.dltr.dflt]: #unique.ptr.dltr.dflt
@@ -5162,10 +6528,12 @@ a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_all
5162
  [unord.hash]: utilities.md#unord.hash
5163
  [util.sharedptr]: #util.sharedptr
5164
  [util.smartptr.enab]: #util.smartptr.enab
5165
  [util.smartptr.getdeleter]: #util.smartptr.getdeleter
5166
  [util.smartptr.hash]: #util.smartptr.hash
 
 
5167
  [util.smartptr.ownerless]: #util.smartptr.ownerless
5168
  [util.smartptr.shared]: #util.smartptr.shared
5169
  [util.smartptr.shared.assign]: #util.smartptr.shared.assign
5170
  [util.smartptr.shared.cast]: #util.smartptr.shared.cast
5171
  [util.smartptr.shared.cmp]: #util.smartptr.shared.cmp
 
9
  in [[mem.summary]].
10
 
11
  **Table: Memory management library summary** <a id="mem.summary">[mem.summary]</a>
12
 
13
  | Subclause | | Header |
14
+ | ----------------------- | -------------------------------- | ----------------------- |
15
  | [[memory]] | Memory | `<cstdlib>`, `<memory>` |
16
  | [[smartptr]] | Smart pointers | `<memory>` |
17
+ | [[mem.composite.types]] | Types for composite class design | `<memory>` |
18
  | [[mem.res]] | Memory resources | `<memory_resource>` |
19
  | [[allocator.adaptor]] | Scoped allocators | `<scoped_allocator>` |
20
 
21
 
22
  ## Memory <a id="memory">[[memory]]</a>
23
 
24
+ ### General <a id="memory.general">[[memory.general]]</a>
25
 
26
  Subclause  [[memory]] describes the contents of the header `<memory>`
27
  and some of the contents of the header `<cstdlib>`.
28
 
29
  ### Header `<memory>` synopsis <a id="memory.syn">[[memory.syn]]</a>
 
65
  constexpr auto to_address(const Ptr& p) noexcept; // freestanding
66
 
67
  // [ptr.align], pointer alignment
68
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestanding
69
  template<size_t N, class T>
70
+ constexpr T* assume_aligned(T* ptr); // freestanding
71
+ template<size_t Alignment, class T>
72
+ bool is_sufficiently_aligned(T* ptr);
73
 
74
  // [obj.lifetime], explicit lifetime management
75
  template<class T>
76
  T* start_lifetime_as(void* p) noexcept; // freestanding
77
  template<class T>
 
87
  template<class T>
88
  volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; // freestanding
89
  template<class T>
90
  const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding
91
  size_t n) noexcept;
92
+ template<class T>
93
+ T* trivially_relocate(T* first, T* last, T* result); // freestanding
94
+ template<class T>
95
+ constexpr T* relocate(T* first, T* last, T* result); // freestanding
96
 
97
  // [allocator.tag], allocator argument tag
98
+ struct allocator_arg_t { explicit allocator_arg_t() = default; }; // freestanding
 
 
99
  inline constexpr allocator_arg_t allocator_arg{}; // freestanding
100
 
101
  // [allocator.uses], uses_allocator
102
  template<class T, class Alloc> struct uses_allocator; // freestanding
103
 
 
166
  // [special.mem.concepts], special memory concepts
167
  template<class I>
168
  concept nothrow-input-iterator = see below; // exposition only
169
  template<class I>
170
  concept nothrow-forward-iterator = see below; // exposition only
171
+ template<class I>
172
+ concept nothrow-bidirectional-iterator = see below; // exposition only
173
+ template<class I>
174
+ concept nothrow-random-access-iterator = see below; // exposition only
175
  template<class S, class I>
176
  concept nothrow-sentinel-for = see below; // exposition only
177
+ template<class S, class I>
178
+ concept nothrow-sized-sentinel-for = see below; // exposition only
179
  template<class R>
180
  concept nothrow-input-range = see below; // exposition only
181
  template<class R>
182
  concept nothrow-forward-range = see below; // exposition only
183
+ template<class R>
184
+ concept nothrow-bidirectional-range = see below; // exposition only
185
+ template<class R>
186
+ concept nothrow-random-access-range = see below; // exposition only
187
+ template<class R>
188
+ concept nothrow-sized-random-access-range = see below; // exposition only
189
 
190
  template<class NoThrowForwardIterator>
191
+ constexpr void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding
192
  NoThrowForwardIterator last);
193
  template<class ExecutionPolicy, class NoThrowForwardIterator>
194
+ void uninitialized_default_construct(ExecutionPolicy&& exec, // freestanding-deleted,
195
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
196
  NoThrowForwardIterator last);
197
  template<class NoThrowForwardIterator, class Size>
198
+ constexpr NoThrowForwardIterator
199
  uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestanding
200
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
201
  NoThrowForwardIterator
202
+ uninitialized_default_construct_n(ExecutionPolicy&& exec, // freestanding-deleted,
203
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
204
+ Size n);
205
 
206
  namespace ranges {
207
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
208
  requires default_initializable<iter_value_t<I>>
209
+ constexpr I uninitialized_default_construct(I first, S last); // freestanding
210
  template<nothrow-forward-range R>
211
  requires default_initializable<range_value_t<R>>
212
+ constexpr borrowed_iterator_t<R> uninitialized_default_construct(R&& r); // freestanding
213
 
214
  template<nothrow-forward-iterator I>
215
  requires default_initializable<iter_value_t<I>>
216
+ constexpr I uninitialized_default_construct_n(I first, // freestanding
217
+ iter_difference_t<I> n);
218
+
219
+ template<execution-policy Ep, nothrow-random-access-iterator I,
220
+ nothrow-sized-sentinel-for<I> S>
221
+ requires default_initializable<iter_value_t<I>>
222
+ I uninitialized_default_construct(Ep&& exec, I first, S last); // freestanding-deleted,
223
+ // see [algorithms.parallel.overloads]
224
+ template<execution-policy Ep, nothrow-sized-random-access-range R>
225
+ requires default_initializable<range_value_t<R>>
226
+ borrowed_iterator_t<R> uninitialized_default_construct(Ep&& exec, // freestanding-deleted,
227
+ R&& r); // see [algorithms.parallel.overloads]
228
+
229
+ template<execution-policy Ep, nothrow-random-access-iterator I>
230
+ requires default_initializable<iter_value_t<I>>
231
+ I uninitialized_default_construct_n(Ep&& exec, I first, // freestanding-deleted,
232
+ iter_difference_t<I> n); // see [algorithms.parallel.overloads]
233
  }
234
 
235
  template<class NoThrowForwardIterator>
236
+ constexpr void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding
237
  NoThrowForwardIterator last);
238
  template<class ExecutionPolicy, class NoThrowForwardIterator>
239
+ void uninitialized_value_construct(ExecutionPolicy&& exec, // freestanding-deleted,
240
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
241
  NoThrowForwardIterator last);
242
  template<class NoThrowForwardIterator, class Size>
243
+ constexpr NoThrowForwardIterator
244
  uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestanding
245
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
246
  NoThrowForwardIterator
247
+ uninitialized_value_construct_n(ExecutionPolicy&& exec, // freestanding-deleted,
248
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
249
+ Size n);
250
 
251
  namespace ranges {
252
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S>
253
  requires default_initializable<iter_value_t<I>>
254
+ constexpr I uninitialized_value_construct(I first, S last); // freestanding
255
  template<nothrow-forward-range R>
256
  requires default_initializable<range_value_t<R>>
257
+ constexpr borrowed_iterator_t<R> uninitialized_value_construct(R&& r); // freestanding
258
 
259
  template<nothrow-forward-iterator I>
260
  requires default_initializable<iter_value_t<I>>
261
+ constexpr I uninitialized_value_construct_n(I first, // freestanding
262
+ iter_difference_t<I> n);
263
+
264
+ template<execution-policy Ep, nothrow-random-access-iterator I,
265
+ nothrow-sized-sentinel-for<I> S>
266
+ requires default_initializable<iter_value_t<I>>
267
+ I uninitialized_value_construct(Ep&& exec, I first, S last); // freestanding-deleted,
268
+ // see [algorithms.parallel.overloads]
269
+ template<execution-policy Ep, nothrow-sized-random-access-range R>
270
+ requires default_initializable<range_value_t<R>>
271
+ borrowed_iterator_t<R> uninitialized_value_construct(Ep&& exec, // freestanding-deleted,
272
+ R&& r); // see [algorithms.parallel.overloads]
273
+
274
+ template<execution-policy Ep, nothrow-random-access-iterator I>
275
+ requires default_initializable<iter_value_t<I>>
276
+ I uninitialized_value_construct_n(Ep&& exec, I first, // freestanding-deleted,
277
+ iter_difference_t<I> n); // see [algorithms.parallel.overloads]
278
  }
279
 
280
  template<class InputIterator, class NoThrowForwardIterator>
281
+ constexpr NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding
282
  InputIterator last,
283
  NoThrowForwardIterator result);
284
  template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
285
+ NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // freestanding-deleted,
286
+ ForwardIterator first, // see [algorithms.parallel.overloads]
287
+ ForwardIterator last,
288
  NoThrowForwardIterator result);
289
  template<class InputIterator, class Size, class NoThrowForwardIterator>
290
+ constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, // freestanding
291
+ Size n,
292
  NoThrowForwardIterator result);
293
  template<class ExecutionPolicy, class ForwardIterator, class Size,
294
  class NoThrowForwardIterator>
295
+ NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // freestanding-deleted,
296
+ ForwardIterator first, // see [algorithms.parallel.overloads]
297
+ Size n,
298
  NoThrowForwardIterator result);
299
 
300
  namespace ranges {
301
  template<class I, class O>
302
  using uninitialized_copy_result = in_out_result<I, O>; // freestanding
303
  template<input_iterator I, sentinel_for<I> S1,
304
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
305
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
306
+ constexpr uninitialized_copy_result<I, O>
307
  uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
308
  template<input_range IR, nothrow-forward-range OR>
309
  requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
310
+ constexpr uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
311
  uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding
312
 
313
  template<class I, class O>
314
  using uninitialized_copy_n_result = in_out_result<I, O>; // freestanding
315
  template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
316
  requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
317
+ constexpr uninitialized_copy_n_result<I, O>
318
  uninitialized_copy_n(I ifirst, iter_difference_t<I> n, // freestanding
319
  O ofirst, S olast);
320
+
321
+ template<execution-policy Ep, random_access_iterator I, sized_sentinel_for<I> S1,
322
+ nothrow-random-access-iterator O, nothrow-sized-sentinel-for<O> S2>
323
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
324
+ uninitialized_copy_result<I, O>
325
+ uninitialized_copy(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted,
326
+ O ofirst, S2 olast); // see [algorithms.parallel.overloads]
327
+ template<execution-policy Ep, sized-random-access-range IR,
328
+ nothrow-sized-random-access-range OR>
329
+ requires constructible_from<range_value_t<OR>, range_reference_t<IR>>
330
+ uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
331
+ uninitialized_copy(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted,
332
+ // see [algorithms.parallel.overloads]
333
+ template<execution-policy Ep, random_access_iterator I, nothrow-random-access-iterator O,
334
+ nothrow-sized-sentinel-for<O> S>
335
+ requires constructible_from<iter_value_t<O>, iter_reference_t<I>>
336
+ uninitialized_copy_n_result<I, O>
337
+ uninitialized_copy_n(Ep&& exec, I ifirst, iter_difference_t<I> n, // freestanding-deleted,
338
+ O ofirst, S olast); // see [algorithms.parallel.overloads]
339
  }
340
 
341
  template<class InputIterator, class NoThrowForwardIterator>
342
+ constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding
343
  InputIterator last,
344
  NoThrowForwardIterator result);
345
  template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator>
346
+ NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // freestanding-deleted,
347
+ ForwardIterator first, // see [algorithms.parallel.overloads]
348
+ ForwardIterator last,
349
  NoThrowForwardIterator result);
350
  template<class InputIterator, class Size, class NoThrowForwardIterator>
351
+ constexpr pair<InputIterator, NoThrowForwardIterator>
352
  uninitialized_move_n(InputIterator first, Size n, // freestanding
353
  NoThrowForwardIterator result);
354
  template<class ExecutionPolicy, class ForwardIterator, class Size,
355
  class NoThrowForwardIterator>
356
  pair<ForwardIterator, NoThrowForwardIterator>
357
+ uninitialized_move_n(ExecutionPolicy&& exec, // freestanding-deleted,
358
+ ForwardIterator first, Size n, // see [algorithms.parallel.overloads]
359
+ NoThrowForwardIterator result);
360
 
361
  namespace ranges {
362
  template<class I, class O>
363
  using uninitialized_move_result = in_out_result<I, O>; // freestanding
364
  template<input_iterator I, sentinel_for<I> S1,
365
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S2>
366
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
367
+ constexpr uninitialized_move_result<I, O>
368
  uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestanding
369
  template<input_range IR, nothrow-forward-range OR>
370
  requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
371
+ constexpr uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
372
  uninitialized_move(IR&& in_range, OR&& out_range); // freestanding
373
 
374
  template<class I, class O>
375
  using uninitialized_move_n_result = in_out_result<I, O>; // freestanding
376
  template<input_iterator I,
377
  nothrow-forward-iterator O, nothrow-sentinel-for<O> S>
378
  requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
379
+ constexpr uninitialized_move_n_result<I, O>
380
  uninitialized_move_n(I ifirst, iter_difference_t<I> n, // freestanding
381
  O ofirst, S olast);
382
+
383
+ template<execution-policy Ep, random_access_iterator I, sized_sentinel_for<I> S1,
384
+ nothrow-random-access-iterator O, nothrow-sized-sentinel-for<O> S2>
385
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
386
+ uninitialized_move_result<I, O>
387
+ uninitialized_move(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted,
388
+ O ofirst, S2 olast); // see [algorithms.parallel.overloads]
389
+ template<execution-policy Ep, sized-random-access-range IR,
390
+ nothrow-sized-random-access-range OR>
391
+ requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>>
392
+ uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>>
393
+ uninitialized_move(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted,
394
+ // see [algorithms.parallel.overloads]
395
+
396
+ template<execution-policy Ep, random_access_iterator I,
397
+ nothrow-random-access-iterator O, nothrow-sized-sentinel-for<O> S>
398
+ requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>
399
+ uninitialized_move_n_result<I, O>
400
+ uninitialized_move_n(Ep&& exec, I ifirst, iter_difference_t<I> n, // freestanding-deleted,
401
+ O ofirst, S olast); // see [algorithms.parallel.overloads]
402
  }
403
 
404
  template<class NoThrowForwardIterator, class T>
405
+ constexpr void uninitialized_fill(NoThrowForwardIterator first, // freestanding
406
  NoThrowForwardIterator last, const T& x);
407
  template<class ExecutionPolicy, class NoThrowForwardIterator, class T>
408
+ void uninitialized_fill(ExecutionPolicy&& exec, // freestanding-deleted,
409
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
410
+ NoThrowForwardIterator last,
411
  const T& x);
412
  template<class NoThrowForwardIterator, class Size, class T>
413
+ constexpr NoThrowForwardIterator
414
  uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding
415
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T>
416
  NoThrowForwardIterator
417
+ uninitialized_fill_n(ExecutionPolicy&& exec, // freestanding-deleted,
418
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
419
+ Size n, const T& x);
420
 
421
  namespace ranges {
422
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S, class T>
423
  requires constructible_from<iter_value_t<I>, const T&>
424
+ constexpr I uninitialized_fill(I first, S last, const T& x); // freestanding
425
  template<nothrow-forward-range R, class T>
426
  requires constructible_from<range_value_t<R>, const T&>
427
+ constexpr borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); // freestanding
428
 
429
  template<nothrow-forward-iterator I, class T>
430
  requires constructible_from<iter_value_t<I>, const T&>
431
+ constexpr I uninitialized_fill_n(I first, // freestanding
432
+ iter_difference_t<I> n, const T& x);
433
+
434
+ template<execution-policy Ep, nothrow-random-access-iterator I,
435
+ nothrow-sized-sentinel-for<I> S, class T>
436
+ requires constructible_from<iter_value_t<I>, const T&>
437
+ I uninitialized_fill(Ep&& exec, I first, S last, const T& x); // freestanding-deleted,
438
+ // see [algorithms.parallel.overloads]
439
+ template<execution-policy Ep, nothrow-sized-random-access-range R, class T>
440
+ requires constructible_from<range_value_t<R>, const T&>
441
+ borrowed_iterator_t<R> uninitialized_fill(Ep&& exec, R&& r, // freestanding-deleted,
442
+ const T& x); // see [algorithms.parallel.overloads]
443
+
444
+ template<execution-policy Ep, nothrow-random-access-iterator I, class T>
445
+ requires constructible_from<iter_value_t<I>, const T&>
446
+ I uninitialized_fill_n(Ep&& exec, I first, // freestanding-deleted,
447
+ iter_difference_t<I> n, const T& x); // see [algorithms.parallel.overloads]
448
  }
449
 
450
  // [specialized.construct], construct_at
451
  template<class T, class... Args>
452
  constexpr T* construct_at(T* location, Args&&... args); // freestanding
 
461
  constexpr void destroy_at(T* location); // freestanding
462
  template<class NoThrowForwardIterator>
463
  constexpr void destroy(NoThrowForwardIterator first, // freestanding
464
  NoThrowForwardIterator last);
465
  template<class ExecutionPolicy, class NoThrowForwardIterator>
466
+ void destroy(ExecutionPolicy&& exec, // freestanding-deleted,
467
+ NoThrowForwardIterator first, // see [algorithms.parallel.overloads]
468
+ NoThrowForwardIterator last);
469
  template<class NoThrowForwardIterator, class Size>
470
  constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding
471
  Size n);
472
  template<class ExecutionPolicy, class NoThrowForwardIterator, class Size>
473
+ NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // freestanding-deleted,
474
+ NoThrowForwardIterator first, Size n); // see [algorithms.parallel.overloads]
475
 
476
  namespace ranges {
477
  template<destructible T>
478
  constexpr void destroy_at(T* location) noexcept; // freestanding
479
 
 
485
  constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; // freestanding
486
 
487
  template<nothrow-input-iterator I>
488
  requires destructible<iter_value_t<I>>
489
  constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; // freestanding
490
+
491
+ template<execution-policy Ep, nothrow-random-access-iterator I,
492
+ nothrow-sized-sentinel-for<I> S>
493
+ requires destructible<iter_value_t<I>>
494
+ I destroy(Ep&& exec, I first, S last) noexcept; // freestanding-deleted,
495
+ // see [algorithms.parallel.overloads]
496
+ template<execution-policy Ep, nothrow-sized-random-access-range R>
497
+ requires destructible<range_value_t<R>>
498
+ borrowed_iterator_t<R> destroy(Ep&& exec, R&& r) noexcept; // freestanding-deleted,
499
+ // see [algorithms.parallel.overloads]
500
+ template<execution-policy Ep, nothrow-random-access-iterator I>
501
+ requires destructible<iter_value_t<I>>
502
+ I destroy_n(Ep&& exec, I first, iter_difference_t<I> n) noexcept; // freestanding-deleted,
503
+ // see [algorithms.parallel.overloads]
504
  }
505
 
506
  // [unique.ptr], class template unique_ptr
507
  template<class T> struct default_delete; // freestanding
508
  template<class T> struct default_delete<T[]>; // freestanding
 
528
 
529
  template<class T1, class D1, class T2, class D2>
530
  constexpr bool operator==(const unique_ptr<T1, D1>& x, // freestanding
531
  const unique_ptr<T2, D2>& y);
532
  template<class T1, class D1, class T2, class D2>
533
+ constexpr bool operator<(const unique_ptr<T1, D1>& x, // freestanding
534
+ const unique_ptr<T2, D2>& y);
535
  template<class T1, class D1, class T2, class D2>
536
+ constexpr bool operator>(const unique_ptr<T1, D1>& x, // freestanding
537
+ const unique_ptr<T2, D2>& y);
538
  template<class T1, class D1, class T2, class D2>
539
+ constexpr bool operator<=(const unique_ptr<T1, D1>& x, // freestanding
540
+ const unique_ptr<T2, D2>& y);
541
  template<class T1, class D1, class T2, class D2>
542
+ constexpr bool operator>=(const unique_ptr<T1, D1>& x, // freestanding
543
+ const unique_ptr<T2, D2>& y);
544
  template<class T1, class D1, class T2, class D2>
545
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
546
  typename unique_ptr<T2, D2>::pointer>
547
+ constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
548
  typename unique_ptr<T2, D2>::pointer>
549
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestanding
550
 
551
  template<class T, class D>
552
  constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // freestanding
 
580
  // [util.smartptr.shared], class template shared_ptr
581
  template<class T> class shared_ptr;
582
 
583
  // [util.smartptr.shared.create], shared_ptr creation
584
  template<class T, class... Args>
585
+ constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
586
  template<class T, class A, class... Args>
587
+ constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
588
 
589
  template<class T>
590
+ constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
591
  template<class T, class A>
592
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
593
 
594
  template<class T>
595
+ constexpr shared_ptr<T> make_shared(); // T is U[N]
596
  template<class T, class A>
597
+ constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
598
 
599
  template<class T>
600
+ constexpr shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
601
  template<class T, class A>
602
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
603
  const remove_extent_t<T>& u); // T is U[]
604
 
605
  template<class T>
606
+ constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
607
  template<class T, class A>
608
+ constexpr shared_ptr<T> allocate_shared(const A& a, // T is U[N]
609
+ const remove_extent_t<T>& u);
610
 
611
  template<class T>
612
+ constexpr shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
613
  template<class T, class A>
614
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]
615
 
616
  template<class T>
617
+ constexpr shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
618
  template<class T, class A>
619
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]
620
 
621
  // [util.smartptr.shared.cmp], shared_ptr comparisons
622
  template<class T, class U>
623
+ constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
624
  template<class T, class U>
625
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a,
626
+ const shared_ptr<U>& b) noexcept;
627
 
628
  template<class T>
629
+ constexpr bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
630
  template<class T>
631
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept;
632
 
633
  // [util.smartptr.shared.spec], shared_ptr specialized algorithms
634
  template<class T>
635
+ constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
636
 
637
  // [util.smartptr.shared.cast], shared_ptr casts
638
  template<class T, class U>
639
+ constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
640
  template<class T, class U>
641
+ constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
642
  template<class T, class U>
643
+ constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
644
  template<class T, class U>
645
+ constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
646
  template<class T, class U>
647
+ constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
648
  template<class T, class U>
649
+ constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
650
  template<class T, class U>
651
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
652
  template<class T, class U>
653
  shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
654
 
655
  // [util.smartptr.getdeleter], shared_ptr get_deleter
656
  template<class D, class T>
657
+ constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
658
 
659
  // [util.smartptr.shared.io], shared_ptr I/O
660
  template<class E, class T, class Y>
661
  basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
662
 
663
  // [util.smartptr.weak], class template weak_ptr
664
  template<class T> class weak_ptr;
665
 
666
  // [util.smartptr.weak.spec], weak_ptr specialized algorithms
667
+ template<class T> constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
668
 
669
  // [util.smartptr.ownerless], class template owner_less
670
  template<class T = void> struct owner_less;
671
 
672
+ // [util.smartptr.owner.hash], struct owner_hash
673
+ struct owner_hash;
674
+
675
+ // [util.smartptr.owner.equal], struct owner_equal
676
+ struct owner_equal;
677
+
678
  // [util.smartptr.enab], class template enable_shared_from_this
679
  template<class T> class enable_shared_from_this;
680
 
681
  // [util.smartptr.hash], hash support
682
  template<class T> struct hash; // freestanding
 
688
  template<class T> struct atomic<shared_ptr<T>>;
689
  template<class T> struct atomic<weak_ptr<T>>;
690
 
691
  // [out.ptr.t], class template out_ptr_t
692
  template<class Smart, class Pointer, class... Args>
693
+ class out_ptr_t; // freestanding
694
 
695
  // [out.ptr], function template out_ptr
696
  template<class Pointer = void, class Smart, class... Args>
697
+ constexpr auto out_ptr(Smart& s, Args&&... args); // freestanding
698
 
699
  // [inout.ptr.t], class template inout_ptr_t
700
  template<class Smart, class Pointer, class... Args>
701
+ class inout_ptr_t; // freestanding
702
 
703
  // [inout.ptr], function template inout_ptr
704
  template<class Pointer = void, class Smart, class... Args>
705
+ constexpr auto inout_ptr(Smart& s, Args&&... args); // freestanding
706
+
707
+ // [indirect], class template indirect
708
+ template<class T, class Allocator = allocator<T>>
709
+ class indirect;
710
+
711
+ // [indirect.hash], hash support
712
+ template<class T, class Alloc> struct hash<indirect<T, Alloc>>;
713
+
714
+ // [polymorphic], class template polymorphic
715
+ template<class T, class Allocator = allocator<T>>
716
+ class polymorphic;
717
+
718
+ namespace pmr {
719
+ template<class T> using indirect = indirect<T, polymorphic_allocator<T>>;
720
+ template<class T> using polymorphic = polymorphic<T, polymorphic_allocator<T>>;
721
+ }
722
  }
723
  ```
724
 
725
  ### Pointer traits <a id="pointer.traits">[[pointer.traits]]</a>
726
 
 
757
  struct ptr-traits-elem // exposition only
758
  { };
759
 
760
  template<class T> requires requires { typename T::element_type; }
761
  struct ptr-traits-elem<T>
762
+ { using type = T::element_type; };
763
 
764
  template<template<class...> class SomePointer, class T, class... Args>
765
  requires (!requires { typename SomePointer<T, Args...>::element_type; })
766
  struct ptr-traits-elem<SomePointer<T, Args...>>
767
  { using type = T; };
 
887
  it can be called repeatedly with possibly different `alignment` and
888
  `size` arguments for the same buffer. — *end note*]
889
 
890
  ``` cpp
891
  template<size_t N, class T>
892
+ constexpr T* assume_aligned(T* ptr);
893
  ```
894
 
895
  *Mandates:* `N` is a power of two.
896
 
897
+ *Preconditions:* `ptr` points to an object X of a type
898
+ similar [[conv.qual]] to `T`, where X has alignment `N` [[basic.align]].
 
899
 
900
  *Returns:* `ptr`.
901
 
902
  *Throws:* Nothing.
903
 
904
+ [*Note 2*: The alignment assumption on an object X expressed by a call
905
+ to `assume_aligned` might result in generation of more efficient code.
906
+ It is up to the program to ensure that the assumption actually holds.
907
+ The call does not cause the implementation to verify or enforce this. An
908
+ implementation might only make the assumption for those operations on X
909
+ that access X through the pointer returned by
910
  `assume_aligned`. — *end note*]
911
 
912
+ ``` cpp
913
+ template<size_t Alignment, class T>
914
+ bool is_sufficiently_aligned(T* ptr);
915
+ ```
916
+
917
+ *Preconditions:* `p` points to an object `X` of a type
918
+ similar [[conv.qual]] to `T`.
919
+
920
+ *Returns:* `true` if `X` has alignment at least `Alignment`, otherwise
921
+ `false`.
922
+
923
+ *Throws:* Nothing.
924
+
925
  ### Explicit lifetime management <a id="obj.lifetime">[[obj.lifetime]]</a>
926
 
927
  ``` cpp
928
  template<class T>
929
  T* start_lifetime_as(void* p) noexcept;
 
933
  volatile T* start_lifetime_as(volatile void* p) noexcept;
934
  template<class T>
935
  const volatile T* start_lifetime_as(const volatile void* p) noexcept;
936
  ```
937
 
938
+ *Mandates:* `T` is an implicit-lifetime
939
+ type [[term.implicit.lifetime.type]] and not an incomplete
940
+ type [[term.incomplete.type]].
941
 
942
  *Preconditions:* \[`p`, `(char*)p + sizeof(T)`) denotes a region of
943
  allocated storage that is a subset of the region of storage reachable
944
  through [[basic.compound]] `p` and suitably aligned for the type `T`.
945
 
946
  *Effects:* Implicitly creates objects [[intro.object]] within the
947
  denoted region consisting of an object *a* of type `T` whose address is
948
  `p`, and objects nested within *a*, as follows: The object
949
  representation of *a* is the contents of the storage prior to the call
950
  to `start_lifetime_as`. The value of each created object *o* of
951
+ trivially copyable type [[term.trivially.copyable.type]] `U` is
952
+ determined in the same manner as for a call to `bit_cast<U>(E)`
953
+ [[bit.cast]], where `E` is an lvalue of type `U` denoting *o*, except
954
+ that the storage is not accessed. The value of any other created object
955
+ is unspecified.
956
 
957
  [*Note 1*: The unspecified value can be indeterminate. — *end note*]
958
 
959
  *Returns:* A pointer to the *a* defined in the *Effects* paragraph.
960
 
 
982
  effects.
983
 
984
  *Returns:* A pointer to the first element of the created array, if any;
985
  otherwise, a pointer that compares equal to `p` [[expr.eq]].
986
 
987
+ ``` cpp
988
+ template<class T>
989
+ T* trivially_relocate(T* first, T* last, T* result);
990
+ ```
991
+
992
+ *Mandates:* `is_trivially_relocatable_v<T> && !is_const_v<T>` is `true`.
993
+ `T` is not an array of unknown bound.
994
+
995
+ *Preconditions:*
996
+
997
+ - \[`first`, `last`) is a valid range.
998
+ - \[`result`, `result + (last - first)`) denotes a region of storage
999
+ that is a subset of the region reachable through `result`
1000
+ [[basic.compound]] and suitably aligned for the type `T`.
1001
+ - No element in the range \[`first`, `last`) is a
1002
+ potentially-overlapping subobject.
1003
+
1004
+ *Ensures:* No effect if `result == first` is `true`. Otherwise, the
1005
+ range denoted by \[`result`, `result + (last - first)`) contains objects
1006
+ (including subobjects) whose lifetime has begun and whose object
1007
+ representations are the original object representations of the
1008
+ corresponding objects in the source range \[`first`, `last`) except for
1009
+ any parts of the object representations used by the implementation to
1010
+ represent type information [[intro.object]]. If any of the objects has
1011
+ union type, its active member is the same as that of the corresponding
1012
+ object in the source range. If any of the aforementioned objects has a
1013
+ non-static data member of reference type, that reference refers to the
1014
+ same entity as does the corresponding reference in the source range. The
1015
+ lifetimes of the original objects in the source range have ended.
1016
+
1017
+ *Returns:* `result + (last - first)`.
1018
+
1019
+ *Throws:* Nothing.
1020
+
1021
+ *Complexity:* Linear in the length of the source range.
1022
+
1023
+ *Remarks:* The destination region of storage is considered
1024
+ reused [[basic.life]]. No constructors or destructors are invoked.
1025
+
1026
+ [*Note 2*: Overlapping ranges are supported. — *end note*]
1027
+
1028
+ ``` cpp
1029
+ template<class T>
1030
+ constexpr T* relocate(T* first, T* last, T* result);
1031
+ ```
1032
+
1033
+ *Mandates:* `is_nothrow_relocatable_v<T> && !is_const_v<T>` is `true`.
1034
+ `T` is not an array of unknown bound.
1035
+
1036
+ *Preconditions:*
1037
+
1038
+ - \[`first`, `last`) is a valid range.
1039
+ - \[`result`, `result + (last - first)`) denotes a region of storage
1040
+ that is a subset of the region reachable through `result`
1041
+ [[basic.compound]] and suitably aligned for the type `T`.
1042
+ - No element in the range \[`first`, `last`) is a
1043
+ potentially-overlapping subobject.
1044
+
1045
+ *Effects:*
1046
+
1047
+ - If `result == first` is `true`, no effect;
1048
+ - otherwise, if not called during constant evaluation and
1049
+ `is_trivially_relocatable_v<T>` is `true`, then has effects equivalent
1050
+ to: `trivially_relocate(first, last, result);`
1051
+ - otherwise, for each integer `i` in \[`0`, `last - first`),
1052
+ - if `T` is an array type, equivalent to:
1053
+ `relocate(begin(first[i]), end(first[i]), *start_lifetime_as<T>(result + i));`
1054
+ - otherwise, equivalent to:
1055
+ `construct_at(result + i, std::move(first[i])); destroy_at(first + i);`
1056
+
1057
+ *Returns:* `result + (last - first)`.
1058
+
1059
+ *Throws:* Nothing.
1060
+
1061
+ [*Note 3*: Overlapping ranges are supported. — *end note*]
1062
+
1063
  ### Allocator argument tag <a id="allocator.tag">[[allocator.tag]]</a>
1064
 
1065
  ``` cpp
1066
  namespace std {
1067
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
 
1362
  ``` cpp
1363
  namespace std {
1364
  template<class Alloc> struct allocator_traits {
1365
  using allocator_type = Alloc;
1366
 
1367
+ using value_type = Alloc::value_type;
1368
 
1369
  using pointer = see below;
1370
  using const_pointer = see below;
1371
  using void_pointer = see below;
1372
  using const_void_pointer = see below;
 
1380
  using is_always_equal = see below;
1381
 
1382
  template<class T> using rebind_alloc = see below;
1383
  template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
1384
 
1385
+ static constexpr pointer allocate(Alloc& a, size_type n);
1386
+ static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1387
+ static constexpr allocation_result<pointer, size_type>
 
1388
  allocate_at_least(Alloc& a, size_type n);
1389
 
1390
  static constexpr void deallocate(Alloc& a, pointer p, size_type n);
1391
 
1392
  template<class T, class... Args>
 
1494
  arguments; otherwise, the instantiation of `rebind_alloc` is ill-formed.
1495
 
1496
  #### Static member functions <a id="allocator.traits.members">[[allocator.traits.members]]</a>
1497
 
1498
  ``` cpp
1499
+ static constexpr pointer allocate(Alloc& a, size_type n);
1500
  ```
1501
 
1502
  *Returns:* `a.allocate(n)`.
1503
 
1504
  ``` cpp
1505
+ static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
1506
  ```
1507
 
1508
  *Returns:* `a.allocate(n, hint)` if that expression is well-formed;
1509
  otherwise, `a.allocate(n)`.
1510
 
1511
  ``` cpp
1512
+ static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n);
 
1513
  ```
1514
 
1515
  *Returns:* `a.allocate_at_least(n)` if that expression is well-formed;
1516
  otherwise, `{a.allocate(n), n}`.
1517
 
 
1580
  constexpr allocator(const allocator&) noexcept;
1581
  template<class U> constexpr allocator(const allocator<U>&) noexcept;
1582
  constexpr ~allocator();
1583
  constexpr allocator& operator=(const allocator&) = default;
1584
 
1585
+ constexpr T* allocate(size_t n);
1586
+ constexpr allocation_result<T*> allocate_at_least(size_t n);
1587
  constexpr void deallocate(T* p, size_t n);
1588
  };
1589
  }
1590
  ```
1591
 
 
1601
  to these functions that allocate or deallocate a particular unit of
1602
  storage shall occur in a single total order, and each such deallocation
1603
  call shall happen before the next allocation (if any) in this order.
1604
 
1605
  ``` cpp
1606
+ constexpr T* allocate(size_t n);
1607
  ```
1608
 
1609
  *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1610
 
1611
  *Returns:* A pointer to the initial element of an array of `n` `T`.
 
1618
  `::operator new` [[new.delete]], but it is unspecified when or how often
1619
  this function is called. This function starts the lifetime of the array
1620
  object, but not that of any of the array elements.
1621
 
1622
  ``` cpp
1623
+ constexpr allocation_result<T*> allocate_at_least(size_t n);
1624
  ```
1625
 
1626
  *Mandates:* `T` is not an incomplete type [[term.incomplete.type]].
1627
 
1628
  *Returns:* `allocation_result<T*>{ptr, count}`, where `ptr` is a pointer
 
1685
 
1686
  ``` cpp
1687
  void* aligned_alloc(size_t alignment, size_t size);
1688
  void* calloc(size_t nmemb, size_t size);
1689
  void* malloc(size_t size);
 
1690
  ```
1691
 
1692
  *Effects:* These functions have the semantics specified in the C
1693
  standard library.
1694
 
1695
  *Remarks:* These functions do not attempt to allocate storage by calling
1696
  `::operator new()` [[new.delete]].
1697
 
1698
  These functions implicitly create objects [[intro.object]] in the
1699
  returned region of storage and return a pointer to a suitable created
1700
+ object. In the case of `calloc`, the objects are created before the
1701
+ storage is zeroed.
1702
+
1703
+ ``` cpp
1704
+ void* realloc(void* ptr, size_t size);
1705
+ ```
1706
+
1707
+ *Preconditions:* `free(ptr)` has well-defined behavior.
1708
+
1709
+ *Effects:* If `ptr` is not null and `size` is zero, the behavior is
1710
+ erroneous and the effects are implementation-defined. Otherwise, this
1711
+ function has the semantics specified in the C standard library.
1712
+
1713
+ *Remarks:* This function does not attempt to allocate storage by calling
1714
+ `::operator new()` [[new.delete]]. When a non-null pointer is returned,
1715
+ this function implicitly creates objects [[intro.object]] in the
1716
+ returned region of storage and returns a pointer to a suitable created
1717
+ object. The objects are created before the storage is copied.
1718
 
1719
  ``` cpp
1720
  void free(void* ptr);
1721
  ```
1722
 
 
1724
  library.
1725
 
1726
  *Remarks:* This function does not attempt to deallocate storage by
1727
  calling `::operator delete()`.
1728
 
1729
+ See also: ISO C 7.24.4
1730
 
1731
  ## Smart pointers <a id="smartptr">[[smartptr]]</a>
1732
 
1733
  ### Unique-ownership pointers <a id="unique.ptr">[[unique.ptr]]</a>
1734
 
 
1763
  allocated memory to a function, and returning dynamically allocated
1764
  memory from a function. — *end note*]
1765
 
1766
  #### Default deleters <a id="unique.ptr.dltr">[[unique.ptr.dltr]]</a>
1767
 
1768
+ ##### General <a id="unique.ptr.dltr.general">[[unique.ptr.dltr.general]]</a>
1769
 
1770
  The class template `default_delete` serves as the default deleter
1771
  (destruction policy) for the class template `unique_ptr`.
1772
 
1773
  The template parameter `T` of `default_delete` may be an incomplete
 
1882
  unique_ptr& operator=(const unique_ptr&) = delete;
1883
  };
1884
  }
1885
  ```
1886
 
1887
+ A program that instantiates the definition of `unique_ptr<T, D>` is
1888
+ ill-formed if `T*` is an invalid type.
1889
+
1890
+ [*Note 1*: This prevents the instantiation of specializations such as
1891
+ `unique_ptr<T&, D>` and `unique_ptr<int() const, D>`. — *end note*]
1892
+
1893
  The default type for the template parameter `D` is `default_delete`. A
1894
  client-supplied template argument `D` shall be a function object type
1895
  [[function.objects]], lvalue reference to function, or lvalue reference
1896
  to function object type for which, given a value `d` of type `D` and a
1897
  value `ptr` of type `unique_ptr<T, D>::pointer`, the expression `d(ptr)`
 
2116
 
2117
  ``` cpp
2118
  constexpr add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));
2119
  ```
2120
 
2121
+ *Mandates:*
2122
+ `reference_converts_from_temporary_v<add_lvalue_reference_t<T>, decltype(*declval<pointer>())>`
2123
+ is `false`.
2124
+
2125
+ *Preconditions:* `get() != nullptr` is `true`.
2126
 
2127
  *Returns:* `*get()`.
2128
 
2129
  ``` cpp
2130
  constexpr pointer operator->() const noexcept;
 
2350
  ```
2351
 
2352
  *Effects:* Equivalent to `reset(pointer())`.
2353
 
2354
  ``` cpp
2355
+ template<class U> constexpr void reset(U p) noexcept;
2356
  ```
2357
 
2358
  This function behaves the same as the `reset` member of the primary
2359
  template.
2360
 
 
2427
 
2428
  *Returns:* `x.get() == y.get()`.
2429
 
2430
  ``` cpp
2431
  template<class T1, class D1, class T2, class D2>
2432
+ constexpr bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2433
  ```
2434
 
2435
  Let `CT` denote
2436
 
2437
  ``` cpp
 
2450
 
2451
  *Returns:* `less<CT>()(x.get(), y.get())`.
2452
 
2453
  ``` cpp
2454
  template<class T1, class D1, class T2, class D2>
2455
+ constexpr bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2456
  ```
2457
 
2458
  *Returns:* `y < x`.
2459
 
2460
  ``` cpp
2461
  template<class T1, class D1, class T2, class D2>
2462
+ constexpr bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2463
  ```
2464
 
2465
  *Returns:* `!(y < x)`.
2466
 
2467
  ``` cpp
2468
  template<class T1, class D1, class T2, class D2>
2469
+ constexpr bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2470
  ```
2471
 
2472
  *Returns:* `!(x < y)`.
2473
 
2474
  ``` cpp
2475
  template<class T1, class D1, class T2, class D2>
2476
  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
2477
  typename unique_ptr<T2, D2>::pointer>
2478
+ constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
2479
  typename unique_ptr<T2, D2>::pointer>
2480
  operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
2481
  ```
2482
 
2483
  *Returns:* `compare_three_way()(x.get(), y.get())`.
 
2575
  ``` cpp
2576
  namespace std {
2577
  class bad_weak_ptr : public exception {
2578
  public:
2579
  // see [exception] for the specification of the special member functions
2580
+ constexpr const char* what() const noexcept override;
2581
  };
2582
  }
2583
  ```
2584
 
2585
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
2586
  constructor taking a `weak_ptr`.
2587
 
2588
  ``` cpp
2589
+ constexpr const char* what() const noexcept override;
2590
  ```
2591
 
2592
  *Returns:* An *implementation-defined* NTBS.
2593
 
2594
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
 
2610
 
2611
  // [util.smartptr.shared.const], constructors
2612
  constexpr shared_ptr() noexcept;
2613
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
2614
  template<class Y>
2615
+ constexpr explicit shared_ptr(Y* p);
2616
  template<class Y, class D>
2617
+ constexpr shared_ptr(Y* p, D d);
2618
  template<class Y, class D, class A>
2619
+ constexpr shared_ptr(Y* p, D d, A a);
2620
  template<class D>
2621
+ constexpr shared_ptr(nullptr_t p, D d);
2622
  template<class D, class A>
2623
+ constexpr shared_ptr(nullptr_t p, D d, A a);
2624
  template<class Y>
2625
+ constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
2626
  template<class Y>
2627
+ constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
2628
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
2629
  template<class Y>
2630
+ constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
2631
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
2632
  template<class Y>
2633
+ constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
2634
  template<class Y>
2635
+ constexpr explicit shared_ptr(const weak_ptr<Y>& r);
2636
  template<class Y, class D>
2637
+ constexpr shared_ptr(unique_ptr<Y, D>&& r);
2638
 
2639
  // [util.smartptr.shared.dest], destructor
2640
+ constexpr ~shared_ptr();
2641
 
2642
  // [util.smartptr.shared.assign], assignment
2643
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
2644
  template<class Y>
2645
+ constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
2646
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
2647
  template<class Y>
2648
+ constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
2649
  template<class Y, class D>
2650
+ constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
2651
 
2652
  // [util.smartptr.shared.mod], modifiers
2653
+ constexpr void swap(shared_ptr& r) noexcept;
2654
+ constexpr void reset() noexcept;
2655
  template<class Y>
2656
+ constexpr void reset(Y* p);
2657
  template<class Y, class D>
2658
+ constexpr void reset(Y* p, D d);
2659
  template<class Y, class D, class A>
2660
+ constexpr void reset(Y* p, D d, A a);
2661
 
2662
  // [util.smartptr.shared.obs], observers
2663
+ constexpr element_type* get() const noexcept;
2664
+ constexpr T& operator*() const noexcept;
2665
+ constexpr T* operator->() const noexcept;
2666
+ constexpr element_type& operator[](ptrdiff_t i) const;
2667
+ constexpr long use_count() const noexcept;
2668
+ constexpr explicit operator bool() const noexcept;
2669
  template<class U>
2670
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
2671
  template<class U>
2672
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
2673
+ size_t owner_hash() const noexcept;
2674
+ template<class U>
2675
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
2676
+ template<class U>
2677
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
2678
  };
2679
 
2680
  template<class T>
2681
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
2682
  template<class T, class D>
 
2708
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
2709
  objects themselves and not objects they refer to. Changes in
2710
  `use_count()` do not reflect modifications that can introduce data
2711
  races.
2712
 
2713
+ For the purposes of [[smartptr]], a pointer type `Y*` is said to be
2714
+ *compatible with* a pointer type `T*` when either `Y*` is convertible to
2715
+ `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
2716
 
2717
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
2718
 
2719
  In the constructor definitions below, enables `shared_from_this` with
2720
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
 
2722
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
2723
  shall be implicitly convertible to `T*` and the constructor evaluates
2724
  the statement:
2725
 
2726
  ``` cpp
2727
+ if (p != nullptr && p->weak-this.expired())
2728
+ p->weak-this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
2729
  ```
2730
 
2731
+ The assignment to the *`weak-this`* member is not atomic and conflicts
2732
  with any potentially concurrent access to the same object
2733
  [[intro.multithread]].
2734
 
2735
  ``` cpp
2736
  constexpr shared_ptr() noexcept;
2737
  ```
2738
 
2739
  *Ensures:* `use_count() == 0 && get() == nullptr`.
2740
 
2741
  ``` cpp
2742
+ template<class Y> constexpr explicit shared_ptr(Y* p);
2743
  ```
2744
 
2745
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
2746
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
2747
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
 
2765
 
2766
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
2767
  resource other than memory cannot be obtained.
2768
 
2769
  ``` cpp
2770
+ template<class Y, class D> constexpr shared_ptr(Y* p, D d);
2771
+ template<class Y, class D, class A> constexpr shared_ptr(Y* p, D d, A a);
2772
+ template<class D> constexpr shared_ptr(nullptr_t p, D d);
2773
+ template<class D, class A> constexpr shared_ptr(nullptr_t p, D d, A a);
2774
  ```
2775
 
2776
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
2777
  well-formed expression. For the first two overloads:
2778
 
 
2797
 
2798
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
2799
  resource other than memory cannot be obtained.
2800
 
2801
  ``` cpp
2802
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
2803
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
2804
  ```
2805
 
2806
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
2807
  ownership with the initial value of `r`.
2808
 
 
2815
 
2816
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
2817
  instance with a non-null stored pointer. — *end note*]
2818
 
2819
  ``` cpp
2820
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
2821
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
2822
  ```
2823
 
2824
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
2825
 
2826
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
 
2828
  `r`.
2829
 
2830
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
2831
 
2832
  ``` cpp
2833
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
2834
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
2835
  ```
2836
 
2837
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
2838
 
2839
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
2840
 
2841
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
2842
  `r.get() == nullptr`.
2843
 
2844
  ``` cpp
2845
+ template<class Y> constexpr explicit shared_ptr(const weak_ptr<Y>& r);
2846
  ```
2847
 
2848
  *Constraints:* `Y*` is compatible with `T*`.
2849
 
2850
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
 
2854
  *Ensures:* `use_count() == r.use_count()`.
2855
 
2856
  *Throws:* `bad_weak_ptr` when `r.expired()`.
2857
 
2858
  ``` cpp
2859
+ template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
2860
  ```
2861
 
2862
  *Constraints:* `Y*` is compatible with `T*` and
2863
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
2864
 
 
2869
  exception is thrown, the constructor has no effect.
2870
 
2871
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
2872
 
2873
  ``` cpp
2874
+ constexpr ~shared_ptr();
2875
  ```
2876
 
2877
  *Effects:*
2878
 
2879
  - If `*this` is empty or shares ownership with another `shared_ptr`
 
2889
  value. — *end note*]
2890
 
2891
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
2892
 
2893
  ``` cpp
2894
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
2895
+ template<class Y> constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
2896
  ```
2897
 
2898
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
2899
 
2900
  *Returns:* `*this`.
 
2916
  both assignments can be no-ops.
2917
 
2918
  — *end note*]
2919
 
2920
  ``` cpp
2921
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
2922
+ template<class Y> constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
2923
  ```
2924
 
2925
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
2926
 
2927
  *Returns:* `*this`.
2928
 
2929
  ``` cpp
2930
+ template<class Y, class D> constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
2931
  ```
2932
 
2933
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
2934
 
2935
  *Returns:* `*this`.
2936
 
2937
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
2938
 
2939
  ``` cpp
2940
+ constexpr void swap(shared_ptr& r) noexcept;
2941
  ```
2942
 
2943
  *Effects:* Exchanges the contents of `*this` and `r`.
2944
 
2945
  ``` cpp
2946
+ constexpr void reset() noexcept;
2947
  ```
2948
 
2949
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
2950
 
2951
  ``` cpp
2952
+ template<class Y> constexpr void reset(Y* p);
2953
  ```
2954
 
2955
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
2956
 
2957
  ``` cpp
2958
+ template<class Y, class D> constexpr void reset(Y* p, D d);
2959
  ```
2960
 
2961
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
2962
 
2963
  ``` cpp
2964
+ template<class Y, class D, class A> constexpr void reset(Y* p, D d, A a);
2965
  ```
2966
 
2967
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
2968
 
2969
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
2970
 
2971
  ``` cpp
2972
+ constexpr element_type* get() const noexcept;
2973
  ```
2974
 
2975
  *Returns:* The stored pointer.
2976
 
2977
  ``` cpp
2978
+ constexpr T& operator*() const noexcept;
2979
  ```
2980
 
2981
  *Preconditions:* `get() != nullptr`.
2982
 
2983
  *Returns:* `*get()`.
 
2987
  unspecified what its return type is, except that the declaration
2988
  (although not necessarily the definition) of the function shall be
2989
  well-formed.
2990
 
2991
  ``` cpp
2992
+ constexpr T* operator->() const noexcept;
2993
  ```
2994
 
2995
  *Preconditions:* `get() != nullptr`.
2996
 
2997
  *Returns:* `get()`.
 
3000
  member function is declared. If it is declared, it is unspecified what
3001
  its return type is, except that the declaration (although not
3002
  necessarily the definition) of the function shall be well-formed.
3003
 
3004
  ``` cpp
3005
+ constexpr element_type& operator[](ptrdiff_t i) const;
3006
  ```
3007
 
3008
+ *Preconditions:* `get() != nullptr` is `true`.
3009
+
3010
+ `i` ≥ 0. If `T` is `U[N]`, `i` < `N`.
3011
 
3012
  *Returns:* `get()[i]`.
3013
 
3014
  *Throws:* Nothing.
3015
 
 
3017
  member function is declared. If it is declared, it is unspecified what
3018
  its return type is, except that the declaration (although not
3019
  necessarily the definition) of the function shall be well-formed.
3020
 
3021
  ``` cpp
3022
+ constexpr long use_count() const noexcept;
3023
  ```
3024
 
3025
  *Synchronization:* None.
3026
 
3027
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
 
3037
  `use_count()`, the result is approximate. In particular,
3038
  `use_count() == 1` does not imply that accesses through a previously
3039
  destroyed `shared_ptr` have in any sense completed. — *end note*]
3040
 
3041
  ``` cpp
3042
+ constexpr explicit operator bool() const noexcept;
3043
  ```
3044
 
3045
  *Returns:* `get() != nullptr`.
3046
 
3047
  ``` cpp
3048
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
3049
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
3050
  ```
3051
 
3052
  *Returns:* An unspecified value such that
3053
 
3054
+ - `owner_before(b)` defines a strict weak ordering as defined
3055
  in  [[alg.sorting]];
3056
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
3057
+ `owner_equal(b)` is `true`.
3058
+
3059
+ ``` cpp
3060
+ size_t owner_hash() const noexcept;
3061
+ ```
3062
+
3063
+ *Returns:* An unspecified value such that, for any object `x` where
3064
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
3065
+
3066
+ ``` cpp
3067
+ template<class U>
3068
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
3069
+ template<class U>
3070
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
3071
+ ```
3072
+
3073
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
3074
+ both empty. Otherwise returns `false`.
3075
+
3076
+ *Remarks:* `owner_equal` is an equivalence relation.
3077
 
3078
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
3079
 
3080
  The common requirements that apply to all `make_shared`,
3081
  `allocate_shared`, `make_shared_for_overwrite`, and
3082
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
3083
  are described below.
3084
 
3085
  ``` cpp
3086
  template<class T, ...>
3087
+ constexpr shared_ptr<T> make_shared(args);
3088
  template<class T, class A, ...>
3089
+ constexpr shared_ptr<T> allocate_shared(const A& a, args);
3090
  template<class T, ...>
3091
+ constexpr shared_ptr<T> make_shared_for_overwrite(args);
3092
  template<class T, class A, ...>
3093
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
3094
  ```
3095
 
3096
  *Preconditions:* `A` meets the *Cpp17Allocator*
3097
  requirements [[allocator.requirements.general]].
3098
 
 
3133
  suitable to hold an object of type `U`.
3134
  - When a (sub)object of a non-array type `U` is specified to have an
3135
  initial value of `v`, or `U(l...)`, where `l...` is a list of
3136
  constructor arguments, `allocate_shared` shall initialize this
3137
  (sub)object via the expression
3138
+ - `allocator_traits<A2>::construct(a2, pu, v)` or
3139
+ - `allocator_traits<A2>::construct(a2, pu, l...)`
3140
 
3141
+ respectively, where `pu` is a pointer of type `remove_cv_t<U>*`
3142
+ pointing to storage suitable to hold an object of type
3143
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
3144
+ of the allocator `a` passed to `allocate_shared`.
3145
  - When a (sub)object of non-array type `U` is specified to have a
3146
  default initial value, `make_shared` shall initialize this (sub)object
3147
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
3148
  points to storage suitable to hold an object of type `U`.
3149
  - When a (sub)object of non-array type `U` is specified to have a
3150
+ default initial value, `allocate_shared` initializes this (sub)object
3151
+ via the expression `allocator_traits<A2>::construct(a2, pu)`, where
3152
+ `pu` is a pointer of type `remove_cv_t<U>*` pointing to storage
3153
+ suitable to hold an object of type `remove_cv_t<U>` and `a2` of type
3154
+ `A2` is a potentially rebound copy of the allocator `a` passed to
3155
+ `allocate_shared`.
3156
  - When a (sub)object of non-array type `U` is initialized by
3157
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
3158
  initialized via the expression `::new(pv) U`, where `pv` has type
3159
  `void*` and points to storage suitable to hold an object of type `U`.
3160
  - Array elements are initialized in ascending order of their addresses.
3161
  - When the lifetime of the object managed by the return value ends, or
3162
  when the initialization of an array element throws an exception, the
3163
  initialized elements are destroyed in the reverse order of their
3164
  original construction.
3165
  - When a (sub)object of non-array type `U` that was initialized by
3166
+ `make_shared`, `make_shared_for_overwrite`, or
3167
+ `allocate_shared_for_overwrite` is to be destroyed, it is destroyed
3168
+ via the expression `pu->~U()` where `pu` points to that object of type
3169
+ `U`.
3170
  - When a (sub)object of non-array type `U` that was initialized by
3171
  `allocate_shared` is to be destroyed, it is destroyed via the
3172
+ expression `allocator_traits<A2>::destroy(a2, pu)` where `pu` is a
3173
+ pointer of type `remove_cv_t<U>*` pointing to that object of type
3174
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
3175
+ of the allocator `a` passed to `allocate_shared`.
3176
 
3177
  [*Note 7*: These functions will typically allocate more memory than
3178
  `sizeof(T)` to allow for internal bookkeeping structures such as
3179
  reference counts. — *end note*]
3180
 
3181
  ``` cpp
3182
  template<class T, class... Args>
3183
+ constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
3184
  template<class T, class A, class... Args>
3185
+ constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
3186
  ```
3187
 
3188
  *Constraints:* `T` is not an array type.
3189
 
3190
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
 
3203
  ```
3204
 
3205
  — *end example*]
3206
 
3207
  ``` cpp
3208
+ template<class T>
3209
+ constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
3210
  template<class T, class A>
3211
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
3212
  ```
3213
 
3214
  *Constraints:* `T` is of the form `U[]`.
3215
 
3216
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
 
3227
 
3228
  — *end example*]
3229
 
3230
  ``` cpp
3231
  template<class T>
3232
+ constexpr shared_ptr<T> make_shared(); // T is U[N]
3233
  template<class T, class A>
3234
+ constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
3235
  ```
3236
 
3237
  *Constraints:* `T` is of the form `U[N]`.
3238
 
3239
  *Returns:* A `shared_ptr` to an object of type `T` with a default
 
3250
 
3251
  — *end example*]
3252
 
3253
  ``` cpp
3254
  template<class T>
3255
+ constexpr shared_ptr<T> make_shared(size_t N,
3256
  const remove_extent_t<T>& u); // T is U[]
3257
  template<class T, class A>
3258
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
3259
  const remove_extent_t<T>& u); // T is U[]
3260
  ```
3261
 
3262
  *Constraints:* `T` is of the form `U[]`.
3263
 
 
3277
 
3278
  — *end example*]
3279
 
3280
  ``` cpp
3281
  template<class T>
3282
+ constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
3283
  template<class T, class A>
3284
+ constexpr shared_ptr<T> allocate_shared(const A& a,
3285
  const remove_extent_t<T>& u); // T is U[N]
3286
  ```
3287
 
3288
  *Constraints:* `T` is of the form `U[N]`.
3289
 
 
3303
 
3304
  — *end example*]
3305
 
3306
  ``` cpp
3307
  template<class T>
3308
+ constexpr shared_ptr<T> make_shared_for_overwrite();
3309
  template<class T, class A>
3310
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
3311
  ```
3312
 
3313
  *Constraints:* `T` is not an array of unknown bound.
3314
 
3315
  *Returns:* A `shared_ptr` to an object of type `T`.
 
3327
 
3328
  — *end example*]
3329
 
3330
  ``` cpp
3331
  template<class T>
3332
+ constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
3333
  template<class T, class A>
3334
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
3335
  ```
3336
 
3337
  *Constraints:* `T` is an array of unknown bound.
3338
 
3339
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
 
3350
 
3351
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
3352
 
3353
  ``` cpp
3354
  template<class T, class U>
3355
+ constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
3356
  ```
3357
 
3358
  *Returns:* `a.get() == b.get()`.
3359
 
3360
  ``` cpp
3361
  template<class T>
3362
+ constexpr bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
3363
  ```
3364
 
3365
  *Returns:* `!a`.
3366
 
3367
  ``` cpp
3368
  template<class T, class U>
3369
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
3370
  ```
3371
 
3372
  *Returns:* `compare_three_way()(a.get(), b.get())`.
3373
 
3374
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
3375
  objects to be used as keys in associative containers. — *end note*]
3376
 
3377
  ``` cpp
3378
  template<class T>
3379
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
3380
  ```
3381
 
3382
  *Returns:*
3383
 
3384
  ``` cpp
3385
+ compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))
3386
  ```
3387
 
3388
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
3389
 
3390
  ``` cpp
3391
  template<class T>
3392
+ constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
3393
  ```
3394
 
3395
  *Effects:* Equivalent to `a.swap(b)`.
3396
 
3397
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
3398
 
3399
  ``` cpp
3400
  template<class T, class U>
3401
+ constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
3402
  template<class T, class U>
3403
+ constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
3404
  ```
3405
 
3406
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
3407
  well-formed.
3408
 
 
3414
 
3415
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
3416
  second.
3417
 
3418
  [*Note 9*: The seemingly equivalent expression
3419
+ `shared_ptr<T>(static_cast<T*>(r.get()))` can result in undefined
3420
+ behavior, attempting to delete the same object twice. — *end note*]
 
3421
 
3422
  ``` cpp
3423
  template<class T, class U>
3424
+ constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
3425
  template<class T, class U>
3426
+ constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
3427
  ```
3428
 
3429
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
3430
  well-formed. The expression
3431
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
 
3441
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
3442
  is `r` for the first overload, and `std::move(r)` for the second.
3443
  - Otherwise, `shared_ptr<T>()`.
3444
 
3445
  [*Note 10*: The seemingly equivalent expression
3446
+ `shared_ptr<T>(dynamic_cast<T*>(r.get()))` can result in undefined
3447
+ behavior, attempting to delete the same object twice. — *end note*]
 
3448
 
3449
  ``` cpp
3450
  template<class T, class U>
3451
+ constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
3452
  template<class T, class U>
3453
+ constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
3454
  ```
3455
 
3456
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
3457
 
3458
  *Returns:*
 
3463
 
3464
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
3465
  second.
3466
 
3467
  [*Note 11*: The seemingly equivalent expression
3468
+ `shared_ptr<T>(const_cast<T*>(r.get()))` can result in undefined
3469
+ behavior, attempting to delete the same object twice. — *end note*]
 
3470
 
3471
  ``` cpp
3472
  template<class T, class U>
3473
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
3474
  template<class T, class U>
 
3486
 
3487
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
3488
  second.
3489
 
3490
  [*Note 12*: The seemingly equivalent expression
3491
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` can result in undefined
3492
+ behavior, attempting to delete the same object twice. — *end note*]
 
3493
 
3494
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
3495
 
3496
  ``` cpp
3497
  template<class D, class T>
3498
+ constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
3499
  ```
3500
 
3501
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
3502
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
3503
  remains valid as long as there exists a `shared_ptr` instance that owns
 
3534
  using element_type = remove_extent_t<T>;
3535
 
3536
  // [util.smartptr.weak.const], constructors
3537
  constexpr weak_ptr() noexcept;
3538
  template<class Y>
3539
+ constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
3540
+ constexpr weak_ptr(const weak_ptr& r) noexcept;
3541
  template<class Y>
3542
+ constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
3543
+ constexpr weak_ptr(weak_ptr&& r) noexcept;
3544
  template<class Y>
3545
+ constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
3546
 
3547
  // [util.smartptr.weak.dest], destructor
3548
+ constexpr ~weak_ptr();
3549
 
3550
  // [util.smartptr.weak.assign], assignment
3551
+ constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
3552
  template<class Y>
3553
+ constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
3554
  template<class Y>
3555
+ constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
3556
+ constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
3557
  template<class Y>
3558
+ constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
3559
 
3560
  // [util.smartptr.weak.mod], modifiers
3561
+ constexpr void swap(weak_ptr& r) noexcept;
3562
+ constexpr void reset() noexcept;
3563
 
3564
  // [util.smartptr.weak.obs], observers
3565
+ constexpr long use_count() const noexcept;
3566
+ constexpr bool expired() const noexcept;
3567
+ constexpr shared_ptr<T> lock() const noexcept;
3568
  template<class U>
3569
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
3570
  template<class U>
3571
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
3572
+ size_t owner_hash() const noexcept;
3573
+ template<class U>
3574
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
3575
+ template<class U>
3576
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
3577
  };
3578
 
3579
  template<class T>
3580
  weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
3581
  }
 
3595
  pointer value.
3596
 
3597
  *Ensures:* `use_count() == 0`.
3598
 
3599
  ``` cpp
3600
+ constexpr weak_ptr(const weak_ptr& r) noexcept;
3601
+ template<class Y> constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
3602
+ template<class Y> constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
3603
  ```
3604
 
3605
  *Constraints:* For the second and third constructors, `Y*` is compatible
3606
  with `T*`.
3607
 
 
3611
  in `r`.
3612
 
3613
  *Ensures:* `use_count() == r.use_count()`.
3614
 
3615
  ``` cpp
3616
+ constexpr weak_ptr(weak_ptr&& r) noexcept;
3617
+ template<class Y> constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
3618
  ```
3619
 
3620
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
3621
 
3622
  *Effects:* Move constructs a `weak_ptr` instance from `r`.
 
3625
  null pointer value, and `r.use_count() == 0`.
3626
 
3627
  ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
3628
 
3629
  ``` cpp
3630
+ constexpr ~weak_ptr();
3631
  ```
3632
 
3633
  *Effects:* Destroys this `weak_ptr` object but has no effect on the
3634
  object its stored pointer points to.
3635
 
3636
  ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
3637
 
3638
  ``` cpp
3639
+ constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
3640
+ template<class Y> constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
3641
+ template<class Y> constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
3642
  ```
3643
 
3644
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
3645
 
3646
  *Returns:* `*this`.
3647
 
3648
  *Remarks:* The implementation may meet the effects (and the implied
3649
  guarantees) via different means, without creating a temporary object.
3650
 
3651
  ``` cpp
3652
+ constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
3653
+ template<class Y> constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
3654
  ```
3655
 
3656
  *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
3657
 
3658
  *Returns:* `*this`.
3659
 
3660
  ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
3661
 
3662
  ``` cpp
3663
+ constexpr void swap(weak_ptr& r) noexcept;
3664
  ```
3665
 
3666
  *Effects:* Exchanges the contents of `*this` and `r`.
3667
 
3668
  ``` cpp
3669
+ constexpr void reset() noexcept;
3670
  ```
3671
 
3672
  *Effects:* Equivalent to `weak_ptr().swap(*this)`.
3673
 
3674
  ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
3675
 
3676
  ``` cpp
3677
+ constexpr long use_count() const noexcept;
3678
  ```
3679
 
3680
  *Returns:* `0` if `*this` is empty; otherwise, the number of
3681
  `shared_ptr` instances that share ownership with `*this`.
3682
 
3683
  ``` cpp
3684
+ constexpr bool expired() const noexcept;
3685
  ```
3686
 
3687
  *Returns:* `use_count() == 0`.
3688
 
3689
  ``` cpp
3690
+ constexpr shared_ptr<T> lock() const noexcept;
3691
  ```
3692
 
3693
  *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
3694
  executed atomically.
3695
 
3696
  ``` cpp
3697
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
3698
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
3699
  ```
3700
 
3701
  *Returns:* An unspecified value such that
3702
 
3703
+ - `owner_before(b)` defines a strict weak ordering as defined
3704
  in  [[alg.sorting]];
3705
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
3706
+ `owner_equal(b)` is `true`.
3707
+
3708
+ ``` cpp
3709
+ size_t owner_hash() const noexcept;
3710
+ ```
3711
+
3712
+ *Returns:* An unspecified value such that, for any object `x` where
3713
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
3714
+
3715
+ ``` cpp
3716
+ template<class U>
3717
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
3718
+ template<class U>
3719
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
3720
+ ```
3721
+
3722
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
3723
+ both empty. Otherwise returns `false`.
3724
+
3725
+ *Remarks:* `owner_equal` is an equivalence relation.
3726
 
3727
  ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
3728
 
3729
  ``` cpp
3730
  template<class T>
3731
+ constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
3732
  ```
3733
 
3734
  *Effects:* Equivalent to `a.swap(b)`.
3735
 
3736
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
 
3741
  ``` cpp
3742
  namespace std {
3743
  template<class T = void> struct owner_less;
3744
 
3745
  template<class T> struct owner_less<shared_ptr<T>> {
3746
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
3747
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
3748
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
3749
  };
3750
 
3751
  template<class T> struct owner_less<weak_ptr<T>> {
3752
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
3753
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
3754
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
3755
  };
3756
 
3757
  template<> struct owner_less<void> {
3758
  template<class T, class U>
3759
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
3760
  template<class T, class U>
3761
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
3762
  template<class T, class U>
3763
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
3764
  template<class T, class U>
3765
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
3766
 
3767
  using is_transparent = unspecified;
3768
  };
3769
  }
3770
  ```
 
3775
 
3776
  Note that
3777
 
3778
  - `operator()` defines a strict weak ordering as defined in 
3779
  [[alg.sorting]];
3780
+ - `!operator()(a, b) && !operator()(b, a)` is `true` if and only if
3781
+ `a.owner_equal(b)` is `true`.
 
 
3782
 
3783
  — *end note*]
3784
 
3785
+ #### Struct `owner_hash` <a id="util.smartptr.owner.hash">[[util.smartptr.owner.hash]]</a>
3786
+
3787
+ The class `owner_hash` provides ownership-based hashing.
3788
+
3789
+ ``` cpp
3790
+ namespace std {
3791
+ struct owner_hash {
3792
+ template<class T>
3793
+ size_t operator()(const shared_ptr<T>&) const noexcept;
3794
+
3795
+ template<class T>
3796
+ size_t operator()(const weak_ptr<T>&) const noexcept;
3797
+
3798
+ using is_transparent = unspecified;
3799
+ };
3800
+ }
3801
+ ```
3802
+
3803
+ ``` cpp
3804
+ template<class T>
3805
+ size_t operator()(const shared_ptr<T>& x) const noexcept;
3806
+ template<class T>
3807
+ size_t operator()(const weak_ptr<T>& x) const noexcept;
3808
+ ```
3809
+
3810
+ *Returns:* `x.owner_hash()`.
3811
+
3812
+ [*Note 1*: For any object `y` where `x.owner_equal(y)` is `true`,
3813
+ `x.owner_hash() == y.owner_hash()` is `true`. — *end note*]
3814
+
3815
+ #### Struct `owner_equal` <a id="util.smartptr.owner.equal">[[util.smartptr.owner.equal]]</a>
3816
+
3817
+ The class `owner_equal` provides ownership-based mixed equality
3818
+ comparisons of shared and weak pointers.
3819
+
3820
+ ``` cpp
3821
+ namespace std {
3822
+ struct owner_equal {
3823
+ template<class T, class U>
3824
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
3825
+ template<class T, class U>
3826
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
3827
+ template<class T, class U>
3828
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
3829
+ template<class T, class U>
3830
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
3831
+
3832
+ using is_transparent = unspecified;
3833
+ };
3834
+ }
3835
+ ```
3836
+
3837
+ ``` cpp
3838
+ template<class T, class U>
3839
+ constexpr bool operator()(const shared_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
3840
+ template<class T, class U>
3841
+ constexpr bool operator()(const shared_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
3842
+ template<class T, class U>
3843
+ constexpr bool operator()(const weak_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
3844
+ template<class T, class U>
3845
+ constexpr bool operator()(const weak_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
3846
+ ```
3847
+
3848
+ *Returns:* `x.owner_equal(y)`.
3849
+
3850
+ [*Note 1*: `x.owner_equal(y)` is `true` if and only if `x` and `y`
3851
+ share ownership or are both empty. — *end note*]
3852
+
3853
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
3854
 
3855
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
3856
  `shared_from_this` member functions that obtain a `shared_ptr` instance
3857
  pointing to `*this`.
 
3863
 
3864
  int main() {
3865
  shared_ptr<X> p(new X);
3866
  shared_ptr<X> q = p->shared_from_this();
3867
  assert(p == q);
3868
+ assert(p.owner_equal(q)); // p and q share ownership
3869
  }
3870
  ```
3871
 
3872
  — *end example*]
3873
 
3874
  ``` cpp
3875
  namespace std {
3876
  template<class T> class enable_shared_from_this {
3877
  protected:
3878
  constexpr enable_shared_from_this() noexcept;
3879
+ constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept;
3880
+ constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
3881
+ constexpr ~enable_shared_from_this();
3882
 
3883
  public:
3884
+ constexpr shared_ptr<T> shared_from_this();
3885
+ constexpr shared_ptr<T const> shared_from_this() const;
3886
+ constexpr weak_ptr<T> weak_from_this() noexcept;
3887
+ constexpr weak_ptr<T const> weak_from_this() const noexcept;
3888
 
3889
  private:
3890
+ mutable weak_ptr<T> weak-this; // exposition only
3891
  };
3892
  }
3893
  ```
3894
 
3895
  The template parameter `T` of `enable_shared_from_this` may be an
3896
  incomplete type.
3897
 
3898
  ``` cpp
3899
  constexpr enable_shared_from_this() noexcept;
3900
+ constexpr enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
3901
  ```
3902
 
3903
+ *Effects:* Value-initializes *weak-this*.
3904
 
3905
  ``` cpp
3906
+ constexpr enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
3907
  ```
3908
 
3909
  *Returns:* `*this`.
3910
 
3911
+ [*Note 1*: *weak-this* is not changed. — *end note*]
3912
 
3913
  ``` cpp
3914
+ constexpr shared_ptr<T> shared_from_this();
3915
+ constexpr shared_ptr<T const> shared_from_this() const;
3916
  ```
3917
 
3918
+ *Returns:* `shared_ptr<T>(`*`weak-this`*`)`.
3919
 
3920
  ``` cpp
3921
+ constexpr weak_ptr<T> weak_from_this() noexcept;
3922
+ constexpr weak_ptr<T const> weak_from_this() const noexcept;
3923
  ```
3924
 
3925
+ *Returns:* *weak-this*.
3926
 
3927
  ### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
3928
 
3929
  ``` cpp
3930
  template<class T, class D> struct hash<unique_ptr<T, D>>;
 
3985
  ``` cpp
3986
  namespace std {
3987
  template<class Smart, class Pointer, class... Args>
3988
  class out_ptr_t {
3989
  public:
3990
+ constexpr explicit out_ptr_t(Smart&, Args...);
3991
  out_ptr_t(const out_ptr_t&) = delete;
3992
 
3993
+ constexpr ~out_ptr_t();
3994
 
3995
+ constexpr operator Pointer*() const noexcept;
3996
  operator void**() const noexcept;
3997
 
3998
  private:
3999
  Smart& s; // exposition only
4000
  tuple<Args...> a; // exposition only
 
4018
 
4019
  Evaluations of the conversion functions on the same object may conflict
4020
  [[intro.races]].
4021
 
4022
  ``` cpp
4023
+ constexpr explicit out_ptr_t(Smart& smart, Args... args);
4024
  ```
4025
 
4026
  *Effects:* Initializes `s` with `smart`, `a` with
4027
  `std::forward<Args>(args)...`, and value-initializes `p`. Then,
4028
  equivalent to:
4029
 
4030
+ -
4031
+ ``` cpp
4032
  s.reset();
4033
  ```
4034
 
4035
  if the expression `s.reset()` is well-formed;
 
4036
  - otherwise,
4037
  ``` cpp
4038
  s = Smart();
4039
  ```
4040
 
4041
  if `is_constructible_v<Smart>` is `true`;
 
4042
  - otherwise, the program is ill-formed.
4043
 
4044
  [*Note 1*: The constructor is not `noexcept` to allow for a variety of
4045
  non-terminating and safe implementation strategies. For example, an
4046
  implementation can allocate a `shared_ptr`’s internal node in the
4047
  constructor and let implementation-defined exceptions escape safely. The
4048
  destructor can then move the allocated control block in directly and
4049
  avoid any other exceptions. — *end note*]
4050
 
4051
  ``` cpp
4052
+ constexpr ~out_ptr_t();
4053
  ```
4054
 
4055
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
4056
 
4057
  *Effects:* Equivalent to:
 
4077
 
4078
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
4079
  - otherwise, the program is ill-formed.
4080
 
4081
  ``` cpp
4082
+ constexpr operator Pointer*() const noexcept;
4083
  ```
4084
 
4085
  *Preconditions:* `operator void**()` has not been called on `*this`.
4086
 
4087
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
 
4112
 
4113
  #### Function template `out_ptr` <a id="out.ptr">[[out.ptr]]</a>
4114
 
4115
  ``` cpp
4116
  template<class Pointer = void, class Smart, class... Args>
4117
+ constexpr auto out_ptr(Smart& s, Args&&... args);
4118
  ```
4119
 
4120
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
4121
  *`POINTER_OF`*`(Smart)`.
4122
 
4123
  *Returns:*
4124
+ `out_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`.
4125
 
4126
  #### Class template `inout_ptr_t` <a id="inout.ptr.t">[[inout.ptr.t]]</a>
4127
 
4128
  `inout_ptr_t` is a class template used to adapt types such as smart
4129
  pointers [[smartptr]] for functions that use output pointer parameters
 
4163
  ``` cpp
4164
  namespace std {
4165
  template<class Smart, class Pointer, class... Args>
4166
  class inout_ptr_t {
4167
  public:
4168
+ constexpr explicit inout_ptr_t(Smart&, Args...);
4169
  inout_ptr_t(const inout_ptr_t&) = delete;
4170
 
4171
+ constexpr ~inout_ptr_t();
4172
 
4173
+ constexpr operator Pointer*() const noexcept;
4174
  operator void**() const noexcept;
4175
 
4176
  private:
4177
  Smart& s; // exposition only
4178
  tuple<Args...> a; // exposition only
 
4194
 
4195
  Evaluations of the conversion functions on the same object may conflict
4196
  [[intro.races]].
4197
 
4198
  ``` cpp
4199
+ constexpr explicit inout_ptr_t(Smart& smart, Args... args);
4200
  ```
4201
 
4202
  *Effects:* Initializes `s` with `smart`, `a` with
4203
  `std::forward<Args>(args)...`, and `p` to either
4204
 
 
4211
  non-terminating and safe implementation strategies. For example, an
4212
  intrusive pointer implementation with a control block can allocate in
4213
  the constructor and safely fail with an exception. — *end note*]
4214
 
4215
  ``` cpp
4216
+ constexpr ~inout_ptr_t();
4217
  ```
4218
 
4219
  Let `SP` be *`POINTER_OF_OR`*`(Smart, Pointer)` [[memory.general]].
4220
 
4221
  Let *release-statement* be `s.release();` if an implementation does not
 
4223
 
4224
  *Effects:* Equivalent to:
4225
 
4226
  -
4227
  ``` cpp
 
4228
  apply([&](auto&&... args) {
4229
  s = Smart(static_cast<SP>(p), std::forward<Args>(args)...); }, std::move(a));
 
4230
  ```
4231
 
4232
  if `is_pointer_v<Smart>` is `true`;
4233
  - otherwise,
4234
  ``` cpp
 
4253
 
4254
  if `is_constructible_v<Smart, SP, Args...>` is `true`;
4255
  - otherwise, the program is ill-formed.
4256
 
4257
  ``` cpp
4258
+ constexpr operator Pointer*() const noexcept;
4259
  ```
4260
 
4261
  *Preconditions:* `operator void**()` has not been called on `*this`.
4262
 
4263
  *Returns:* `addressof(const_cast<Pointer&>(p))`.
 
4288
 
4289
  #### Function template `inout_ptr` <a id="inout.ptr">[[inout.ptr]]</a>
4290
 
4291
  ``` cpp
4292
  template<class Pointer = void, class Smart, class... Args>
4293
+ constexpr auto inout_ptr(Smart& s, Args&&... args);
4294
  ```
4295
 
4296
  Let `P` be `Pointer` if `is_void_v<Pointer>` is `false`, otherwise
4297
  *`POINTER_OF`*`(Smart)`.
4298
 
4299
  *Returns:*
4300
  `inout_ptr_t<Smart, P, Args&&...>(s, std::forward<Args>(args)...)`.
4301
 
4302
+ ## Types for composite class design <a id="mem.composite.types">[[mem.composite.types]]</a>
4303
+
4304
+ ### Class template `indirect` <a id="indirect">[[indirect]]</a>
4305
+
4306
+ #### General <a id="indirect.general">[[indirect.general]]</a>
4307
+
4308
+ An indirect object manages the lifetime of an owned object. An indirect
4309
+ object is *valueless* if it has no owned object. An indirect object may
4310
+ become valueless only after it has been moved from.
4311
+
4312
+ In every specialization `indirect<T, Allocator>`, if the type
4313
+ `allocator_traits<Allocator>::value_type` is not the same type as `T`,
4314
+ the program is ill-formed. Every object of type `indirect<T, Allocator>`
4315
+ uses an object of type `Allocator` to allocate and free storage for the
4316
+ owned object as needed.
4317
+
4318
+ Constructing an owned object with `args...` using the allocator `a`
4319
+ means calling `allocator_traits<Allocator>::construct(a, p, args...)`
4320
+ where `args` is an expression pack, `a` is an allocator, and *`p`* is a
4321
+ pointer obtained by calling `allocator_traits<Allocator>::allocate`.
4322
+
4323
+ The member *`alloc`* is used for any memory allocation and element
4324
+ construction performed by member functions during the lifetime of each
4325
+ indirect object. The allocator *`alloc`* may be replaced only via
4326
+ assignment or `swap()`. `Allocator` replacement is performed by copy
4327
+ assignment, move assignment, or swapping of the allocator only if
4328
+ [[container.reqmts]]:
4329
+
4330
+ - `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value`,
4331
+ or
4332
+ - `allocator_traits<Allocator>::propagate_on_container_move_assignment::value`,
4333
+ or
4334
+ - `allocator_traits<Allocator>::propagate_on_container_swap::value`
4335
+
4336
+ is `true` within the implementation of the corresponding `indirect`
4337
+ operation.
4338
+
4339
+ A program that instantiates the definition of the template
4340
+ `indirect<T, Allocator>` with a type for the `T` parameter that is a
4341
+ non-object type, an array type, `in_place_t`, a specialization of
4342
+ `in_place_type_t`, or a cv-qualified type is ill-formed.
4343
+
4344
+ The template parameter `T` of `indirect` may be an incomplete type.
4345
+
4346
+ The template parameter `Allocator` of `indirect` shall meet the
4347
+ *Cpp17Allocator* requirements.
4348
+
4349
+ If a program declares an explicit or partial specialization of
4350
+ `indirect`, the behavior is undefined.
4351
+
4352
+ #### Synopsis <a id="indirect.syn">[[indirect.syn]]</a>
4353
+
4354
+ ``` cpp
4355
+ namespace std {
4356
+ template<class T, class Allocator = allocator<T>>
4357
+ class indirect {
4358
+ public:
4359
+ using value_type = T;
4360
+ using allocator_type = Allocator;
4361
+ using pointer = allocator_traits<Allocator>::pointer;
4362
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
4363
+
4364
+ // [indirect.ctor], constructors
4365
+ constexpr explicit indirect();
4366
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a);
4367
+ constexpr indirect(const indirect& other);
4368
+ constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other);
4369
+ constexpr indirect(indirect&& other) noexcept;
4370
+ constexpr indirect(allocator_arg_t, const Allocator& a, indirect&& other)
4371
+ noexcept(see below);
4372
+ template<class U = T>
4373
+ constexpr explicit indirect(U&& u);
4374
+ template<class U = T>
4375
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u);
4376
+ template<class... Us>
4377
+ constexpr explicit indirect(in_place_t, Us&&... us);
4378
+ template<class... Us>
4379
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a,
4380
+ in_place_t, Us&&... us);
4381
+ template<class I, class... Us>
4382
+ constexpr explicit indirect(in_place_t, initializer_list<I> ilist, Us&&... us);
4383
+ template<class I, class... Us>
4384
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a,
4385
+ in_place_t, initializer_list<I> ilist, Us&&... us);
4386
+
4387
+ // [indirect.dtor], destructor
4388
+ constexpr ~indirect();
4389
+
4390
+ // [indirect.assign], assignment
4391
+ constexpr indirect& operator=(const indirect& other);
4392
+ constexpr indirect& operator=(indirect&& other) noexcept(see below);
4393
+ template<class U = T>
4394
+ constexpr indirect& operator=(U&& u);
4395
+
4396
+ // [indirect.obs], observers
4397
+ constexpr const T& operator*() const & noexcept;
4398
+ constexpr T& operator*() & noexcept;
4399
+ constexpr const T&& operator*() const && noexcept;
4400
+ constexpr T&& operator*() && noexcept;
4401
+ constexpr const_pointer operator->() const noexcept;
4402
+ constexpr pointer operator->() noexcept;
4403
+ constexpr bool valueless_after_move() const noexcept;
4404
+ constexpr allocator_type get_allocator() const noexcept;
4405
+
4406
+ // [indirect.swap], swap
4407
+ constexpr void swap(indirect& other) noexcept(see below);
4408
+ friend constexpr void swap(indirect& lhs, indirect& rhs) noexcept(see below);
4409
+
4410
+ // [indirect.relops], relational operators
4411
+ template<class U, class AA>
4412
+ friend constexpr bool operator==(const indirect& lhs, const indirect<U, AA>& rhs)
4413
+ noexcept(see below);
4414
+ template<class U, class AA>
4415
+ friend constexpr auto operator<=>(const indirect& lhs, const indirect<U, AA>& rhs)
4416
+ -> synth-three-way-result<T, U>;
4417
+
4418
+ // [indirect.comp.with.t], comparison with T
4419
+ template<class U>
4420
+ friend constexpr bool operator==(const indirect& lhs, const U& rhs) noexcept(see below);
4421
+ template<class U>
4422
+ friend constexpr auto operator<=>(const indirect& lhs, const U& rhs)
4423
+ -> synth-three-way-result<T, U>;
4424
+
4425
+ private:
4426
+ pointer p; // exposition only
4427
+ Allocator alloc = Allocator(); // exposition only
4428
+ };
4429
+ template<class Value>
4430
+ indirect(Value) -> indirect<Value>;
4431
+ template<class Allocator, class Value>
4432
+ indirect(allocator_arg_t, Allocator, Value)
4433
+ -> indirect<Value, typename allocator_traits<Allocator>::template rebind_alloc<Value>>;
4434
+ }
4435
+ ```
4436
+
4437
+ #### Constructors <a id="indirect.ctor">[[indirect.ctor]]</a>
4438
+
4439
+ The following element applies to all functions in  [[indirect.ctor]]:
4440
+
4441
+ *Throws:* Nothing unless `allocator_traits<Allocator>::allocate` or
4442
+ `allocator_traits<Allocator>::construct` throws.
4443
+
4444
+ ``` cpp
4445
+ constexpr explicit indirect();
4446
+ ```
4447
+
4448
+ *Constraints:* `is_default_constructible_v<Allocator>` is `true`.
4449
+
4450
+ *Mandates:* `is_default_constructible_v<T>` is `true`.
4451
+
4452
+ *Effects:* Constructs an owned object of type `T` with an empty argument
4453
+ list, using the allocator *alloc*.
4454
+
4455
+ ``` cpp
4456
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a);
4457
+ ```
4458
+
4459
+ *Mandates:* `is_default_constructible_v<T>` is `true`.
4460
+
4461
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
4462
+ an owned object of type `T` with an empty argument list, using the
4463
+ allocator *alloc*.
4464
+
4465
+ ``` cpp
4466
+ constexpr indirect(const indirect& other);
4467
+ ```
4468
+
4469
+ *Mandates:* `is_copy_constructible_v<T>` is `true`.
4470
+
4471
+ *Effects:* *alloc* is direct-non-list-initialized with
4472
+ `allocator_traits<Allocator>::select_on_container_copy_construction(other.`*`alloc`*`)`.
4473
+ If `other` is valueless, `*this` is valueless. Otherwise, constructs an
4474
+ owned object of type `T` with `*other`, using the allocator *alloc*.
4475
+
4476
+ ``` cpp
4477
+ constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other);
4478
+ ```
4479
+
4480
+ *Mandates:* `is_copy_constructible_v<T>` is `true`.
4481
+
4482
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. If `other`
4483
+ is valueless, `*this` is valueless. Otherwise, constructs an owned
4484
+ object of type `T` with `*other`, using the allocator *alloc*.
4485
+
4486
+ ``` cpp
4487
+ constexpr indirect(indirect&& other) noexcept;
4488
+ ```
4489
+
4490
+ *Effects:* *alloc* is direct-non-list-initialized from
4491
+ `std::move(other.`*`alloc`*`)`. If `other` is valueless, `*this` is
4492
+ valueless. Otherwise `*this` takes ownership of the owned object of
4493
+ `other`.
4494
+
4495
+ *Ensures:* `other` is valueless.
4496
+
4497
+ ``` cpp
4498
+ constexpr indirect(allocator_arg_t, const Allocator& a, indirect&& other)
4499
+ noexcept(allocator_traits<Allocator>::is_always_equal::value);
4500
+ ```
4501
+
4502
+ *Mandates:* If `allocator_traits<Allocator>::is_always_equal::value` is
4503
+ `false` then `T` is a complete type.
4504
+
4505
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. If `other`
4506
+ is valueless, `*this` is valueless. Otherwise, if
4507
+ *`alloc`*` == other.`*`alloc`* is `true`, constructs an object of type
4508
+ `indirect` that takes ownership of the owned object of `other`.
4509
+ Otherwise, constructs an owned object of type `T` with
4510
+ `*std::move(other)`, using the allocator *alloc*.
4511
+
4512
+ *Ensures:* `other` is valueless.
4513
+
4514
+ ``` cpp
4515
+ template<class U = T>
4516
+ constexpr explicit indirect(U&& u);
4517
+ ```
4518
+
4519
+ *Constraints:*
4520
+
4521
+ - `is_same_v<remove_cvref_t<U>, indirect>` is `false`,
4522
+ - `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`,
4523
+ - `is_constructible_v<T, U>` is `true`, and
4524
+ - `is_default_constructible_v<Allocator>` is `true`.
4525
+
4526
+ *Effects:* Constructs an owned object of type `T` with
4527
+ `std::forward<U>(u)`, using the allocator *alloc*.
4528
+
4529
+ ``` cpp
4530
+ template<class U = T>
4531
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u);
4532
+ ```
4533
+
4534
+ *Constraints:*
4535
+
4536
+ - `is_same_v<remove_cvref_t<U>, indirect>` is `false`,
4537
+ - `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`, and
4538
+ - `is_constructible_v<T, U>` is `true`.
4539
+
4540
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
4541
+ an owned object of type `T` with `std::forward<U>(u)`, using the
4542
+ allocator *alloc*.
4543
+
4544
+ ``` cpp
4545
+ template<class... Us>
4546
+ constexpr explicit indirect(in_place_t, Us&&... us);
4547
+ ```
4548
+
4549
+ *Constraints:*
4550
+
4551
+ - `is_constructible_v<T, Us...>` is `true`, and
4552
+ - `is_default_constructible_v<Allocator>` is `true`.
4553
+
4554
+ *Effects:* Constructs an owned object of type `T` with
4555
+ `std::forward<Us>(us)...`, using the allocator *alloc*.
4556
+
4557
+ ``` cpp
4558
+ template<class... Us>
4559
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a,
4560
+ in_place_t, Us&& ...us);
4561
+ ```
4562
+
4563
+ *Constraints:* `is_constructible_v<T, Us...>` is `true`.
4564
+
4565
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
4566
+ an owned object of type `T` with `std::forward<Us>(us)...`, using the
4567
+ allocator *alloc*.
4568
+
4569
+ ``` cpp
4570
+ template<class I, class... Us>
4571
+ constexpr explicit indirect(in_place_t, initializer_list<I> ilist, Us&&... us);
4572
+ ```
4573
+
4574
+ *Constraints:*
4575
+
4576
+ - `is_constructible_v<T, initializer_list<I>&, Us...>` is `true`, and
4577
+ - `is_default_constructible_v<Allocator>` is `true`.
4578
+
4579
+ *Effects:* Constructs an owned object of type `T` with the arguments
4580
+ `ilist, std::forward<Us>(us)...`, using the allocator *alloc*.
4581
+
4582
+ ``` cpp
4583
+ template<class I, class... Us>
4584
+ constexpr explicit indirect(allocator_arg_t, const Allocator& a,
4585
+ in_place_t, initializer_list<I> ilist, Us&&... us);
4586
+ ```
4587
+
4588
+ *Constraints:* `is_constructible_v<T, initializer_list<I>&, Us...>` is
4589
+ `true`.
4590
+
4591
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
4592
+ an owned object of type `T` with the arguments
4593
+ `ilist, std::forward<Us>(us)...`, using the allocator *alloc*.
4594
+
4595
+ #### Destructor <a id="indirect.dtor">[[indirect.dtor]]</a>
4596
+
4597
+ ``` cpp
4598
+ constexpr ~indirect();
4599
+ ```
4600
+
4601
+ *Mandates:* `T` is a complete type.
4602
+
4603
+ *Effects:* If `*this` is not valueless, destroys the owned object using
4604
+ `allocator_traits<Allocator>::destroy` and then the storage is
4605
+ deallocated.
4606
+
4607
+ #### Assignment <a id="indirect.assign">[[indirect.assign]]</a>
4608
+
4609
+ ``` cpp
4610
+ constexpr indirect& operator=(const indirect& other);
4611
+ ```
4612
+
4613
+ *Mandates:*
4614
+
4615
+ - `is_copy_assignable_v<T>` is `true`, and
4616
+ - `is_copy_constructible_v<T>` is `true`.
4617
+
4618
+ *Effects:* If `addressof(other) == this` is `true`, there are no
4619
+ effects. Otherwise:
4620
+
4621
+ - The allocator needs updating if
4622
+ `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value`
4623
+ is `true`.
4624
+ - If `other` is valueless, `*this` becomes valueless and the owned
4625
+ object in `*this`, if any, is destroyed using
4626
+ `allocator_traits<Allocator>::destroy` and then the storage is
4627
+ deallocated.
4628
+ - Otherwise, if *`alloc`*` == other.`*`alloc`* is `true` and `*this` is
4629
+ not valueless, equivalent to `**this = *other`.
4630
+ - Otherwise a new owned object is constructed in `*this` using
4631
+ `allocator_traits<Allocator>::construct` with the owned object from
4632
+ `other` as the argument, using either the allocator in `*this` or the
4633
+ allocator in `other` if the allocator needs updating.
4634
+ - The previously owned object in `*this`, if any, is destroyed using
4635
+ `allocator_traits<Allocator>::destroy` and then the storage is
4636
+ deallocated.
4637
+ - If the allocator needs updating, the allocator in `*this` is replaced
4638
+ with a copy of the allocator in `other`.
4639
+
4640
+ *Returns:* A reference to `*this`.
4641
+
4642
+ *Remarks:* If any exception is thrown, the result of the expression
4643
+ `this->valueless_after_move()` remains unchanged. If an exception is
4644
+ thrown during the call to `T`’s selected copy constructor, no effect. If
4645
+ an exception is thrown during the call to `T`’s copy assignment, the
4646
+ state of its owned object is as defined by the exception safety
4647
+ guarantee of `T`’s copy assignment.
4648
+
4649
+ ``` cpp
4650
+ constexpr indirect& operator=(indirect&& other)
4651
+ noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
4652
+ allocator_traits<Allocator>::is_always_equal::value);
4653
+ ```
4654
+
4655
+ *Mandates:* `is_copy_constructible_v<T>` is `true`.
4656
+
4657
+ *Effects:* If `addressof(other) == this` is `true`, there are no
4658
+ effects. Otherwise:
4659
+
4660
+ - The allocator needs updating if
4661
+ `allocator_traits<Allocator>::propagate_on_container_move_assignment::value`
4662
+ is `true`.
4663
+ - If `other` is valueless, `*this` becomes valueless and the owned
4664
+ object in `*this`, if any, is destroyed using
4665
+ `allocator_traits<Allocator>::destroy` and then the storage is
4666
+ deallocated.
4667
+ - Otherwise, if *`alloc`*` == other.`*`alloc`* is `true`, swaps the
4668
+ owned objects in `*this` and `other`; the owned object in `other`, if
4669
+ any, is then destroyed using `allocator_traits<Allocator>::destroy`
4670
+ and then the storage is deallocated.
4671
+ - Otherwise, constructs a new owned object with the owned object of
4672
+ `other` as the argument as an rvalue, using either the allocator in
4673
+ `*this` or the allocator in `other` if the allocator needs updating.
4674
+ - The previously owned object in `*this`, if any, is destroyed using
4675
+ `allocator_traits<Allocator>::destroy` and then the storage is
4676
+ deallocated.
4677
+ - If the allocator needs updating, the allocator in `*this` is replaced
4678
+ with a copy of the allocator in `other`.
4679
+
4680
+ *Ensures:* `other` is valueless.
4681
+
4682
+ *Returns:* A reference to `*this`.
4683
+
4684
+ *Remarks:* If any exception is thrown, there are no effects on `*this`
4685
+ or `other`.
4686
+
4687
+ ``` cpp
4688
+ template<class U = T>
4689
+ constexpr indirect& operator=(U&& u);
4690
+ ```
4691
+
4692
+ *Constraints:*
4693
+
4694
+ - `is_same_v<remove_cvref_t<U>, indirect>` is `false`,
4695
+ - `is_constructible_v<T, U>` is `true`, and
4696
+ - `is_assignable_v<T&, U>` is `true`.
4697
+
4698
+ *Effects:* If `*this` is valueless then constructs an owned object of
4699
+ type `T` with `std::forward<U>(u)` using the allocator *alloc*.
4700
+ Otherwise, equivalent to `**this = std::forward<U>(u)`.
4701
+
4702
+ *Returns:* A reference to `*this`.
4703
+
4704
+ #### Observers <a id="indirect.obs">[[indirect.obs]]</a>
4705
+
4706
+ ``` cpp
4707
+ constexpr const T& operator*() const & noexcept;
4708
+ constexpr T& operator*() & noexcept;
4709
+ ```
4710
+
4711
+ *Preconditions:* `*this` is not valueless.
4712
+
4713
+ *Returns:* `*`*`p`*.
4714
+
4715
+ ``` cpp
4716
+ constexpr const T&& operator*() const && noexcept;
4717
+ constexpr T&& operator*() && noexcept;
4718
+ ```
4719
+
4720
+ *Preconditions:* `*this` is not valueless.
4721
+
4722
+ *Returns:* `std::move(*`*`p`*`)`.
4723
+
4724
+ ``` cpp
4725
+ constexpr const_pointer operator->() const noexcept;
4726
+ constexpr pointer operator->() noexcept;
4727
+ ```
4728
+
4729
+ *Preconditions:* `*this` is not valueless.
4730
+
4731
+ *Returns:* *p*.
4732
+
4733
+ ``` cpp
4734
+ constexpr bool valueless_after_move() const noexcept;
4735
+ ```
4736
+
4737
+ *Returns:* `true` if `*this` is valueless, otherwise `false`.
4738
+
4739
+ ``` cpp
4740
+ constexpr allocator_type get_allocator() const noexcept;
4741
+ ```
4742
+
4743
+ *Returns:* *alloc*.
4744
+
4745
+ #### Swap <a id="indirect.swap">[[indirect.swap]]</a>
4746
+
4747
+ ``` cpp
4748
+ constexpr void swap(indirect& other)
4749
+ noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
4750
+ allocator_traits<Allocator>::is_always_equal::value);
4751
+ ```
4752
+
4753
+ *Preconditions:* If
4754
+ `allocator_traits<Allocator>::propagate_on_container_swap::value` is
4755
+ `true`, then `Allocator` meets the *Cpp17Swappable* requirements.
4756
+ Otherwise `get_allocator() == other.get_allocator()` is `true`.
4757
+
4758
+ *Effects:* Swaps the states of `*this` and `other`, exchanging owned
4759
+ objects or valueless states. If
4760
+ `allocator_traits<Allocator>::propagate_on_container_swap::value` is
4761
+ `true`, then the allocators of `*this` and `other` are exchanged by
4762
+ calling `swap` as described in  [[swappable.requirements]]. Otherwise,
4763
+ the allocators are not swapped.
4764
+
4765
+ [*Note 1*: Does not call `swap` on the owned objects
4766
+ directly. — *end note*]
4767
+
4768
+ ``` cpp
4769
+ constexpr void swap(indirect& lhs, indirect& rhs) noexcept(noexcept(lhs.swap(rhs)));
4770
+ ```
4771
+
4772
+ *Effects:* Equivalent to `lhs.swap(rhs)`.
4773
+
4774
+ #### Relational operators <a id="indirect.relops">[[indirect.relops]]</a>
4775
+
4776
+ ``` cpp
4777
+ template<class U, class AA>
4778
+ constexpr bool operator==(const indirect& lhs, const indirect<U, AA>& rhs)
4779
+ noexcept(noexcept(*lhs == *rhs));
4780
+ ```
4781
+
4782
+ *Mandates:* The expression `*lhs == *rhs` is well-formed and its result
4783
+ is convertible to `bool`.
4784
+
4785
+ *Returns:* If `lhs` is valueless or `rhs` is valueless,
4786
+ `lhs.valueless_after_move() == rhs.valueless_after_move()`; otherwise
4787
+ `*lhs == *rhs`.
4788
+
4789
+ ``` cpp
4790
+ template<class U, class AA>
4791
+ constexpr synth-three-way-result<T, U>
4792
+ operator<=>(const indirect& lhs, const indirect<U, AA>& rhs);
4793
+ ```
4794
+
4795
+ *Returns:* If `lhs` is valueless or `rhs` is valueless,
4796
+ `!lhs.valueless_after_move() <=> !rhs.valueless_after_move()`; otherwise
4797
+ *`synth-three-way`*`(*lhs, *rhs)`.
4798
+
4799
+ #### Comparison with `T` <a id="indirect.comp.with.t">[[indirect.comp.with.t]]</a>
4800
+
4801
+ ``` cpp
4802
+ template<class U>
4803
+ constexpr bool operator==(const indirect& lhs, const U& rhs) noexcept(noexcept(*lhs == rhs));
4804
+ ```
4805
+
4806
+ *Mandates:* The expression `*lhs == rhs` is well-formed and its result
4807
+ is convertible to `bool`.
4808
+
4809
+ *Returns:* If `lhs` is valueless, `false`; otherwise `*lhs == rhs`.
4810
+
4811
+ ``` cpp
4812
+ template<class U>
4813
+ constexpr synth-three-way-result<T, U>
4814
+ operator<=>(const indirect& lhs, const U& rhs);
4815
+ ```
4816
+
4817
+ *Returns:* If `lhs` is valueless, `strong_ordering::less`; otherwise
4818
+ *`synth-three-way`*`(*lhs, rhs)`.
4819
+
4820
+ #### Hash support <a id="indirect.hash">[[indirect.hash]]</a>
4821
+
4822
+ ``` cpp
4823
+ template<class T, class Allocator>
4824
+ struct hash<indirect<T, Allocator>>;
4825
+ ```
4826
+
4827
+ The specialization `hash<indirect<T, Allocator>>` is
4828
+ enabled [[unord.hash]] if and only if `hash<T>` is enabled. When enabled
4829
+ for an object `i` of type `indirect<T, Allocator>`,
4830
+ `hash<indirect<T, Allocator>>()(i)` evaluates to either the same value
4831
+ as `hash<T>()(*i)`, if `i` is not valueless; otherwise to an
4832
+ *implementation-defined* value. The member functions are not guaranteed
4833
+ to be `noexcept`.
4834
+
4835
+ ### Class template `polymorphic` <a id="polymorphic">[[polymorphic]]</a>
4836
+
4837
+ #### General <a id="polymorphic.general">[[polymorphic.general]]</a>
4838
+
4839
+ A polymorphic object manages the lifetime of an owned object. A
4840
+ polymorphic object may own objects of different types at different
4841
+ points in its lifetime. A polymorphic object is *valueless* if it has no
4842
+ owned object. A polymorphic object may become valueless only after it
4843
+ has been moved from.
4844
+
4845
+ In every specialization `polymorphic<T, Allocator>`, if the type
4846
+ `allocator_traits<Allocator>::value_type` is not the same type as `T`,
4847
+ the program is ill-formed. Every object of type
4848
+ `polymorphic<T, Allocator>` uses an object of type `Allocator` to
4849
+ allocate and free storage for the owned object as needed.
4850
+
4851
+ Constructing an owned object of type `U` with `args...` using the
4852
+ allocator `a` means calling
4853
+ `allocator_traits<Allocator>::construct(a, p, args...)` where `args` is
4854
+ an expression pack, `a` is an allocator, and *`p`* points to storage
4855
+ suitable for an owned object of type `U`.
4856
+
4857
+ The member *`alloc`* is used for any memory allocation and element
4858
+ construction performed by member functions during the lifetime of each
4859
+ polymorphic value object, or until the allocator is replaced. The
4860
+ allocator may be replaced only via assignment or `swap()`. `Allocator`
4861
+ replacement is performed by copy assignment, move assignment, or
4862
+ swapping of the allocator only if [[container.reqmts]]:
4863
+
4864
+ - `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value`,
4865
+ or
4866
+ - `allocator_traits<Allocator>::propagate_on_container_move_assignment::value`,
4867
+ or
4868
+ - `allocator_traits<Allocator>::propagate_on_container_swap::value`
4869
+
4870
+ is `true` within the implementation of the corresponding `polymorphic`
4871
+ operation.
4872
+
4873
+ A program that instantiates the definition of `polymorphic` for a
4874
+ non-object type, an array type, `in_place_t`, a specialization of
4875
+ `in_place_type_t`, or a cv-qualified type is ill-formed.
4876
+
4877
+ The template parameter `T` of `polymorphic` may be an incomplete type.
4878
+
4879
+ The template parameter `Allocator` of `polymorphic` shall meet the
4880
+ requirements of *Cpp17Allocator*.
4881
+
4882
+ If a program declares an explicit or partial specialization of
4883
+ `polymorphic`, the behavior is undefined.
4884
+
4885
+ #### Synopsis <a id="polymorphic.syn">[[polymorphic.syn]]</a>
4886
+
4887
+ ``` cpp
4888
+ namespace std {
4889
+ template<class T, class Allocator = allocator<T>>
4890
+ class polymorphic {
4891
+ public:
4892
+ using value_type = T;
4893
+ using allocator_type = Allocator;
4894
+ using pointer = allocator_traits<Allocator>::pointer;
4895
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
4896
+
4897
+ // [polymorphic.ctor], constructors
4898
+ constexpr explicit polymorphic();
4899
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a);
4900
+ constexpr polymorphic(const polymorphic& other);
4901
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, const polymorphic& other);
4902
+ constexpr polymorphic(polymorphic&& other) noexcept;
4903
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, polymorphic&& other)
4904
+ noexcept(see below);
4905
+ template<class U = T>
4906
+ constexpr explicit polymorphic(U&& u);
4907
+ template<class U = T>
4908
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u);
4909
+ template<class U, class... Ts>
4910
+ constexpr explicit polymorphic(in_place_type_t<U>, Ts&&... ts);
4911
+ template<class U, class... Ts>
4912
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
4913
+ in_place_type_t<U>, Ts&&... ts);
4914
+ template<class U, class I, class... Us>
4915
+ constexpr explicit polymorphic(in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
4916
+ template<class U, class I, class... Us>
4917
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
4918
+ in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
4919
+
4920
+ // [polymorphic.dtor], destructor
4921
+ constexpr ~polymorphic();
4922
+
4923
+ // [polymorphic.assign], assignment
4924
+ constexpr polymorphic& operator=(const polymorphic& other);
4925
+ constexpr polymorphic& operator=(polymorphic&& other) noexcept(see below);
4926
+
4927
+ // [polymorphic.obs], observers
4928
+ constexpr const T& operator*() const noexcept;
4929
+ constexpr T& operator*() noexcept;
4930
+ constexpr const_pointer operator->() const noexcept;
4931
+ constexpr pointer operator->() noexcept;
4932
+ constexpr bool valueless_after_move() const noexcept;
4933
+ constexpr allocator_type get_allocator() const noexcept;
4934
+
4935
+ // [polymorphic.swap], swap
4936
+ constexpr void swap(polymorphic& other) noexcept(see below);
4937
+ friend constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(see below);
4938
+
4939
+ private:
4940
+ Allocator alloc = Allocator(); // exposition only
4941
+ };
4942
+ }
4943
+ ```
4944
+
4945
+ #### Constructors <a id="polymorphic.ctor">[[polymorphic.ctor]]</a>
4946
+
4947
+ The following element applies to all functions in  [[polymorphic.ctor]]:
4948
+
4949
+ *Throws:* Nothing unless `allocator_traits<Allocator>::allocate` or
4950
+ `allocator_traits<Allocator>::construct` throws.
4951
+
4952
+ ``` cpp
4953
+ constexpr explicit polymorphic();
4954
+ ```
4955
+
4956
+ *Constraints:* `is_default_constructible_v<Allocator>` is `true`.
4957
+
4958
+ *Mandates:*
4959
+
4960
+ - `is_default_constructible_v<T>` is `true`, and
4961
+ - `is_copy_constructible_v<T>` is `true`.
4962
+
4963
+ *Effects:* Constructs an owned object of type `T` with an empty argument
4964
+ list using the allocator *alloc*.
4965
+
4966
+ ``` cpp
4967
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a);
4968
+ ```
4969
+
4970
+ *Mandates:*
4971
+
4972
+ - `is_default_constructible_v<T>` is `true`, and
4973
+ - `is_copy_constructible_v<T>` is `true`.
4974
+
4975
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
4976
+ an owned object of type `T` with an empty argument list using the
4977
+ allocator *alloc*.
4978
+
4979
+ ``` cpp
4980
+ constexpr polymorphic(const polymorphic& other);
4981
+ ```
4982
+
4983
+ *Effects:* *alloc* is direct-non-list-initialized with
4984
+ `allocator_traits<Allocator>::select_on_container_copy_construction(other.`*`alloc`*`)`.
4985
+ If `other` is valueless, `*this` is valueless. Otherwise, constructs an
4986
+ owned object of type `U`, where `U` is the type of the owned object in
4987
+ `other`, with the owned object in `other` using the allocator *alloc*.
4988
+
4989
+ ``` cpp
4990
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, const polymorphic& other);
4991
+ ```
4992
+
4993
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. If `other`
4994
+ is valueless, `*this` is valueless. Otherwise, constructs an owned
4995
+ object of type `U`, where `U` is the type of the owned object in
4996
+ `other`, with the owned object in `other` using the allocator *alloc*.
4997
+
4998
+ ``` cpp
4999
+ constexpr polymorphic(polymorphic&& other) noexcept;
5000
+ ```
5001
+
5002
+ *Effects:* *alloc* is direct-non-list-initialized with
5003
+ `std::move(other.`*`alloc`*`)`. If `other` is valueless, `*this` is
5004
+ valueless. Otherwise, either `*this` takes ownership of the owned object
5005
+ of `other` or, owns an object of the same type constructed from the
5006
+ owned object of `other` considering that owned object as an rvalue,
5007
+ using the allocator *alloc*.
5008
+
5009
+ ``` cpp
5010
+ constexpr polymorphic(allocator_arg_t, const Allocator& a, polymorphic&& other)
5011
+ noexcept(allocator_traits<Allocator>::is_always_equal::value);
5012
+ ```
5013
+
5014
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. If `other`
5015
+ is valueless, `*this` is valueless. Otherwise, if
5016
+ *`alloc`*` == other.`*`alloc`* is `true`, either constructs an object of
5017
+ type `polymorphic` that owns the owned object of `other`, making `other`
5018
+ valueless; or, owns an object of the same type constructed from the
5019
+ owned object of `other` considering that owned object as an rvalue.
5020
+ Otherwise, if *`alloc`*` != other.`*`alloc`* is `true`, constructs an
5021
+ object of type `polymorphic`, considering the owned object in `other` as
5022
+ an rvalue, using the allocator *alloc*.
5023
+
5024
+ ``` cpp
5025
+ template<class U = T>
5026
+ constexpr explicit polymorphic(U&& u);
5027
+ ```
5028
+
5029
+ *Constraints:* Where `UU` is `remove_cvref_t<U>`,
5030
+
5031
+ - `is_same_v<UU, polymorphic>` is `false`,
5032
+ - `derived_from<UU, T>` is `true`,
5033
+ - `is_constructible_v<UU, U>` is `true`,
5034
+ - `is_copy_constructible_v<UU>` is `true`,
5035
+ - `UU` is not a specialization of `in_place_type_t`, and
5036
+ - `is_default_constructible_v<Allocator>` is `true`.
5037
+
5038
+ *Effects:* Constructs an owned object of type `UU` with
5039
+ `std::forward<U>(u)` using the allocator *alloc*.
5040
+
5041
+ ``` cpp
5042
+ template<class U = T>
5043
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u);
5044
+ ```
5045
+
5046
+ *Constraints:* Where `UU` is `remove_cvref_t<U>`,
5047
+
5048
+ - `is_same_v<UU, polymorphic>` is `false`,
5049
+ - `derived_from<UU, T>` is `true`,
5050
+ - `is_constructible_v<UU, U>` is `true`,
5051
+ - `is_copy_constructible_v<UU>` is `true`, and
5052
+ - `UU` is not a specialization of `in_place_type_t`.
5053
+
5054
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
5055
+ an owned object of type `UU` with `std::forward<U>(u)` using the
5056
+ allocator *alloc*.
5057
+
5058
+ ``` cpp
5059
+ template<class U, class... Ts>
5060
+ constexpr explicit polymorphic(in_place_type_t<U>, Ts&&... ts);
5061
+ ```
5062
+
5063
+ *Constraints:*
5064
+
5065
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
5066
+ - `derived_from<U, T>` is `true`,
5067
+ - `is_constructible_v<U, Ts...>` is `true`,
5068
+ - `is_copy_constructible_v<U>` is `true`, and
5069
+ - `is_default_constructible_v<Allocator>` is `true`.
5070
+
5071
+ *Effects:* Constructs an owned object of type `U` with
5072
+ `std::forward<Ts>(ts)...` using the allocator *alloc*.
5073
+
5074
+ ``` cpp
5075
+ template<class U, class... Ts>
5076
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
5077
+ in_place_type_t<U>, Ts&&... ts);
5078
+ ```
5079
+
5080
+ *Constraints:*
5081
+
5082
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
5083
+ - `derived_from<U, T>` is `true`,
5084
+ - `is_constructible_v<U, Ts...>` is `true`, and
5085
+ - `is_copy_constructible_v<U>` is `true`.
5086
+
5087
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
5088
+ an owned object of type `U` with `std::forward<Ts>(ts)...` using the
5089
+ allocator *alloc*.
5090
+
5091
+ ``` cpp
5092
+ template<class U, class I, class... Us>
5093
+ constexpr explicit polymorphic(in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
5094
+ ```
5095
+
5096
+ *Constraints:*
5097
+
5098
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
5099
+ - `derived_from<U, T>` is `true`,
5100
+ - `is_constructible_v<U, initializer_list<I>&, Us...>` is `true`,
5101
+ - `is_copy_constructible_v<U>` is `true`, and
5102
+ - `is_default_constructible_v<Allocator>` is `true`.
5103
+
5104
+ *Effects:* Constructs an owned object of type `U` with the arguments
5105
+ `ilist, std::forward<Us>(us)...` using the allocator *alloc*.
5106
+
5107
+ ``` cpp
5108
+ template<class U, class I, class... Us>
5109
+ constexpr explicit polymorphic(allocator_arg_t, const Allocator& a,
5110
+ in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);
5111
+ ```
5112
+
5113
+ *Constraints:*
5114
+
5115
+ - `is_same_v<remove_cvref_t<U>, U>` is `true`,
5116
+ - `derived_from<U, T>` is `true`,
5117
+ - `is_constructible_v<U, initializer_list<I>&, Us...>` is `true`, and
5118
+ - `is_copy_constructible_v<U>` is `true`.
5119
+
5120
+ *Effects:* *alloc* is direct-non-list-initialized with `a`. Constructs
5121
+ an owned object of type `U` with the arguments
5122
+ `ilist, std::forward<Us>(us)...` using the allocator *alloc*.
5123
+
5124
+ #### Destructor <a id="polymorphic.dtor">[[polymorphic.dtor]]</a>
5125
+
5126
+ ``` cpp
5127
+ constexpr ~polymorphic();
5128
+ ```
5129
+
5130
+ *Mandates:* `T` is a complete type.
5131
+
5132
+ *Effects:* If `*this` is not valueless, destroys the owned object using
5133
+ `allocator_traits<Allocator>::destroy` and then the storage is
5134
+ deallocated.
5135
+
5136
+ #### Assignment <a id="polymorphic.assign">[[polymorphic.assign]]</a>
5137
+
5138
+ ``` cpp
5139
+ constexpr polymorphic& operator=(const polymorphic& other);
5140
+ ```
5141
+
5142
+ *Mandates:* `T` is a complete type.
5143
+
5144
+ *Effects:* If `addressof(other) == this` is `true`, there are no
5145
+ effects. Otherwise:
5146
+
5147
+ - The allocator needs updating if
5148
+ `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value`
5149
+ is `true`.
5150
+ - If `other` is not valueless, a new owned object is constructed in
5151
+ `*this` using `allocator_traits<Allocator>::construct` with the owned
5152
+ object from `other` as the argument, using either the allocator in
5153
+ `*this` or the allocator in `other` if the allocator needs updating.
5154
+ - The previously owned object in `*this`, if any, is destroyed using
5155
+ `allocator_traits<Allocator>::destroy` and then the storage is
5156
+ deallocated.
5157
+ - If the allocator needs updating, the allocator in `*this` is replaced
5158
+ with a copy of the allocator in `other`.
5159
+
5160
+ *Returns:* A reference to `*this`.
5161
+
5162
+ *Remarks:* If any exception is thrown, there are no effects on `*this`.
5163
+
5164
+ ``` cpp
5165
+ constexpr polymorphic& operator=(polymorphic&& other)
5166
+ noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5167
+ allocator_traits<Allocator>::is_always_equal::value);
5168
+ ```
5169
+
5170
+ *Mandates:* If `allocator_traits<Allocator>::is_always_equal::value` is
5171
+ `false`, `T` is a complete type.
5172
+
5173
+ *Effects:* If `addressof(other) == this` is `true`, there are no
5174
+ effects. Otherwise:
5175
+
5176
+ - The allocator needs updating if
5177
+ `allocator_traits<Allocator>::propagate_on_container_move_assignment::value`
5178
+ is `true`.
5179
+ - If *`alloc`*` == other.`*`alloc`* is `true`, swaps the owned objects
5180
+ in `*this` and `other`; the owned object in `other`, if any, is then
5181
+ destroyed using `allocator_traits<Allocator>::destroy` and then the
5182
+ storage is deallocated.
5183
+ - Otherwise, if *`alloc`*` != other.`*`alloc`* is `true`; if `other` is
5184
+ not valueless, a new owned object is constructed in `*this` using
5185
+ `allocator_traits<Allocator>::construct` with the owned object from
5186
+ `other` as the argument as an rvalue, using either the allocator in
5187
+ `*this` or the allocator in `other` if the allocator needs updating.
5188
+ - The previously owned object in `*this`, if any, is destroyed using
5189
+ `allocator_traits<Allocator>::destroy` and then the storage is
5190
+ deallocated.
5191
+ - If the allocator needs updating, the allocator in `*this` is replaced
5192
+ with a copy of the allocator in `other`.
5193
+
5194
+ *Returns:* A reference to `*this`.
5195
+
5196
+ *Remarks:* If any exception is thrown, there are no effects on `*this`
5197
+ or `other`.
5198
+
5199
+ #### Observers <a id="polymorphic.obs">[[polymorphic.obs]]</a>
5200
+
5201
+ ``` cpp
5202
+ constexpr const T& operator*() const noexcept;
5203
+ constexpr T& operator*() noexcept;
5204
+ ```
5205
+
5206
+ *Preconditions:* `*this` is not valueless.
5207
+
5208
+ *Returns:* A reference to the owned object.
5209
+
5210
+ ``` cpp
5211
+ constexpr const_pointer operator->() const noexcept;
5212
+ constexpr pointer operator->() noexcept;
5213
+ ```
5214
+
5215
+ *Preconditions:* `*this` is not valueless.
5216
+
5217
+ *Returns:* A pointer to the owned object.
5218
+
5219
+ ``` cpp
5220
+ constexpr bool valueless_after_move() const noexcept;
5221
+ ```
5222
+
5223
+ *Returns:* `true` if `*this` is valueless, otherwise `false`.
5224
+
5225
+ ``` cpp
5226
+ constexpr allocator_type get_allocator() const noexcept;
5227
+ ```
5228
+
5229
+ *Returns:* *alloc*.
5230
+
5231
+ #### Swap <a id="polymorphic.swap">[[polymorphic.swap]]</a>
5232
+
5233
+ ``` cpp
5234
+ constexpr void swap(polymorphic& other)
5235
+ noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
5236
+ allocator_traits<Allocator>::is_always_equal::value);
5237
+ ```
5238
+
5239
+ *Preconditions:* If
5240
+ `allocator_traits<Allocator>::propagate_on_container_swap::value` is
5241
+ `true`, then `Allocator` meets the *Cpp17Swappable* requirements.
5242
+ Otherwise `get_allocator() == other.get_allocator()` is `true`.
5243
+
5244
+ *Effects:* Swaps the states of `*this` and `other`, exchanging owned
5245
+ objects or valueless states. If
5246
+ `allocator_traits<Allocator>::propagate_on_container_swap::value` is
5247
+ `true`, then the allocators of `*this` and `other` are exchanged by
5248
+ calling `swap` as described in  [[swappable.requirements]]. Otherwise,
5249
+ the allocators are not swapped.
5250
+
5251
+ [*Note 1*: Does not call `swap` on the owned objects
5252
+ directly. — *end note*]
5253
+
5254
+ ``` cpp
5255
+ constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(noexcept(lhs.swap(rhs)));
5256
+ ```
5257
+
5258
+ *Effects:* Equivalent to `lhs.swap(rhs)`.
5259
+
5260
  ## Memory resources <a id="mem.res">[[mem.res]]</a>
5261
 
5262
  ### Header `<memory_resource>` synopsis <a id="mem.res.syn">[[mem.res.syn]]</a>
5263
 
5264
  ``` cpp
 
5306
  memory_resource(const memory_resource&) = default;
5307
  virtual ~memory_resource();
5308
 
5309
  memory_resource& operator=(const memory_resource&) = default;
5310
 
5311
+ void* allocate(size_t bytes, size_t alignment = max_align);
5312
  void deallocate(void* p, size_t bytes, size_t alignment = max_align);
5313
 
5314
  bool is_equal(const memory_resource& other) const noexcept;
5315
 
5316
  private:
 
5329
  ```
5330
 
5331
  *Effects:* Destroys this `memory_resource`.
5332
 
5333
  ``` cpp
5334
+ void* allocate(size_t bytes, size_t alignment = max_align);
5335
  ```
5336
 
5337
  *Effects:* Allocates storage by calling `do_allocate(bytes, alignment)`
5338
  and implicitly creates objects within the allocated region of storage.
5339
 
 
5386
  ``` cpp
5387
  virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
5388
  ```
5389
 
5390
  *Returns:* A derived class shall implement this function to return
5391
+ `true` if memory allocated from `*this` can be deallocated from `other`
5392
  and vice-versa, otherwise `false`.
5393
 
5394
  [*Note 1*: It is possible that the most-derived type of `other` does
5395
+ not match the type of `*this`. For a derived class `D`, an
5396
+ implementation of this function can immediately return `false` if
5397
  `dynamic_cast<const D*>(&other) == nullptr`. — *end note*]
5398
 
5399
  #### Equality <a id="mem.res.eq">[[mem.res.eq]]</a>
5400
 
5401
  ``` cpp
 
5441
  polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
5442
 
5443
  polymorphic_allocator& operator=(const polymorphic_allocator&) = delete;
5444
 
5445
  // [mem.poly.allocator.mem], member functions
5446
+ Tp* allocate(size_t n);
5447
  void deallocate(Tp* p, size_t n);
5448
 
5449
+ void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
5450
  void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
5451
+ template<class T> T* allocate_object(size_t n = 1);
5452
  template<class T> void deallocate_object(T* p, size_t n = 1);
5453
+ template<class T, class... CtorArgs> T* new_object(CtorArgs&&... ctor_args);
5454
  template<class T> void delete_object(T* p);
5455
 
5456
  template<class T, class... Args>
5457
  void construct(T* p, Args&&... args);
5458
 
5459
+ template<class T>
5460
+ void destroy(T* p);
5461
+
5462
  polymorphic_allocator select_on_container_copy_construction() const;
5463
 
5464
  memory_resource* resource() const;
5465
 
5466
  // friends
 
5500
  *Effects:* Sets `memory_rsrc` to `other.resource()`.
5501
 
5502
  #### Member functions <a id="mem.poly.allocator.mem">[[mem.poly.allocator.mem]]</a>
5503
 
5504
  ``` cpp
5505
+ Tp* allocate(size_t n);
5506
  ```
5507
 
5508
  *Effects:* If `numeric_limits<size_t>::max() / sizeof(Tp) < n`, throws
5509
  `bad_array_new_length`. Otherwise equivalent to:
5510
 
 
5523
  `memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp))`.
5524
 
5525
  *Throws:* Nothing.
5526
 
5527
  ``` cpp
5528
+ void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
5529
  ```
5530
 
5531
  *Effects:* Equivalent to:
5532
  `return memory_rsrc->allocate(nbytes, alignment);`
5533
 
 
5543
  *Effects:* Equivalent to
5544
  `memory_rsrc->deallocate(p, nbytes, alignment)`.
5545
 
5546
  ``` cpp
5547
  template<class T>
5548
+ T* allocate_object(size_t n = 1);
5549
  ```
5550
 
5551
  *Effects:* Allocates memory suitable for holding an array of `n` objects
5552
  of type `T`, as follows:
5553
 
 
5568
 
5569
  *Effects:* Equivalent to `deallocate_bytes(p, n*sizeof(T), alignof(T))`.
5570
 
5571
  ``` cpp
5572
  template<class T, class... CtorArgs>
5573
+ T* new_object(CtorArgs&&... ctor_args);
5574
  ```
5575
 
5576
  *Effects:* Allocates and constructs an object of type `T`, as follows.
5577
  Equivalent to:
5578
 
 
5596
  ```
5597
 
5598
  *Effects:* Equivalent to:
5599
 
5600
  ``` cpp
5601
+ destroy(p);
5602
  deallocate_object(p);
5603
  ```
5604
 
5605
  ``` cpp
5606
  template<class T, class... Args>
 
5609
 
5610
  *Mandates:* Uses-allocator construction of `T` with allocator `*this`
5611
  (see  [[allocator.uses.construction]]) and constructor arguments
5612
  `std::forward<Args>(args)...` is well-formed.
5613
 
5614
+ *Effects:* Constructs a `T` object in the storage whose address is
5615
  represented by `p` by uses-allocator construction with allocator `*this`
5616
  and constructor arguments `std::forward<Args>(args)...`.
5617
 
5618
  *Throws:* Nothing unless the constructor for `T` throws.
5619
 
5620
+ ``` cpp
5621
+ template<class T>
5622
+ void destroy(T* p);
5623
+ ```
5624
+
5625
+ *Effects:* Equivalent to `p->T̃()`.
5626
+
5627
  ``` cpp
5628
  polymorphic_allocator select_on_container_copy_construction() const;
5629
  ```
5630
 
5631
  *Returns:* `polymorphic_allocator()`.
 
5684
  pointer to `new_delete_resource()`.
5685
 
5686
  *Returns:* The previous value of the default memory resource pointer.
5687
 
5688
  *Remarks:* Calling the `set_default_resource` and `get_default_resource`
5689
+ functions shall not incur a data race [[intro.races]]. A call to the
5690
+ `set_default_resource` function synchronizes with subsequent calls to
5691
+ the `set_default_resource` and `get_default_resource` functions.
5692
 
5693
  ``` cpp
5694
  memory_resource* get_default_resource() noexcept;
5695
  ```
5696
 
 
5807
  The maximum number of blocks that will be allocated at once from the
5808
  upstream memory resource [[mem.res.monotonic.buffer]] to replenish a
5809
  pool. If the value of `max_blocks_per_chunk` is zero or is greater than
5810
  an *implementation-defined* limit, that limit is used instead. The
5811
  implementation may choose to use a smaller value than is specified in
5812
+ this member and may use different values for different pools.
5813
 
5814
  ``` cpp
5815
  size_t largest_required_pool_block;
5816
  ```
5817
 
 
5819
  pooling mechanism. Attempts to allocate a single block larger than this
5820
  threshold will be allocated directly from the upstream memory resource.
5821
  If `largest_required_pool_block` is zero or is greater than an
5822
  *implementation-defined* limit, that limit is used instead. The
5823
  implementation may choose a pass-through threshold larger than specified
5824
+ in this member.
5825
 
5826
  #### Constructors and destructors <a id="mem.res.pool.ctor">[[mem.res.pool.ctor]]</a>
5827
 
5828
  ``` cpp
5829
  synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
 
6008
  *Effects:* Calls `upstream_rsrc->deallocate()` as necessary to release
6009
  all allocated memory. Resets `current_buffer` and `next_buffer_size` to
6010
  their initial values at construction.
6011
 
6012
  [*Note 1*: The memory is released back to `upstream_rsrc` even if some
6013
+ blocks that were allocated from `*this` have not been deallocated from
6014
+ `*this`. — *end note*]
6015
 
6016
  ``` cpp
6017
  memory_resource* upstream_resource() const;
6018
  ```
6019
 
 
6107
 
6108
  public:
6109
  using outer_allocator_type = OuterAlloc;
6110
  using inner_allocator_type = see below;
6111
 
6112
+ using value_type = OuterTraits::value_type;
6113
+ using size_type = OuterTraits::size_type;
6114
+ using difference_type = OuterTraits::difference_type;
6115
+ using pointer = OuterTraits::pointer;
6116
+ using const_pointer = OuterTraits::const_pointer;
6117
+ using void_pointer = OuterTraits::void_pointer;
6118
+ using const_void_pointer = OuterTraits::const_void_pointer;
6119
 
6120
  using propagate_on_container_copy_assignment = see below;
6121
  using propagate_on_container_move_assignment = see below;
6122
  using propagate_on_container_swap = see below;
6123
  using is_always_equal = see below;
 
6150
  inner_allocator_type& inner_allocator() noexcept;
6151
  const inner_allocator_type& inner_allocator() const noexcept;
6152
  outer_allocator_type& outer_allocator() noexcept;
6153
  const outer_allocator_type& outer_allocator() const noexcept;
6154
 
6155
+ pointer allocate(size_type n);
6156
+ pointer allocate(size_type n, const_void_pointer hint);
6157
  void deallocate(pointer p, size_type n);
6158
  size_type max_size() const;
6159
 
6160
  template<class T, class... Args>
6161
  void construct(T* p, Args&&... args);
 
6305
  ```
6306
 
6307
  *Returns:* `static_cast<const OuterAlloc&>(*this)`.
6308
 
6309
  ``` cpp
6310
+ pointer allocate(size_type n);
6311
  ```
6312
 
6313
  *Returns:*
6314
  `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)`.
6315
 
6316
  ``` cpp
6317
+ pointer allocate(size_type n, const_void_pointer hint);
6318
  ```
6319
 
6320
  *Returns:*
6321
  `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)`.
6322
 
 
6408
  [allocator.uses]: #allocator.uses
6409
  [allocator.uses.construction]: #allocator.uses.construction
6410
  [allocator.uses.trait]: #allocator.uses.trait
6411
  [basic.align]: basic.md#basic.align
6412
  [basic.compound]: basic.md#basic.compound
6413
+ [basic.life]: basic.md#basic.life
6414
  [basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
 
6415
  [bit.cast]: utilities.md#bit.cast
6416
  [c.malloc]: #c.malloc
6417
+ [container.reqmts]: containers.md#container.reqmts
6418
  [conv.qual]: expr.md#conv.qual
6419
  [cpp17.defaultconstructible]: #cpp17.defaultconstructible
6420
  [cpp17.destructible]: #cpp17.destructible
6421
  [cpp17.moveassignable]: #cpp17.moveassignable
6422
  [cpp17.moveconstructible]: #cpp17.moveconstructible
 
6424
  [default.allocator]: #default.allocator
6425
  [default.allocator.general]: #default.allocator.general
6426
  [defns.const.subexpr]: intro.md#defns.const.subexpr
6427
  [expr.eq]: expr.md#expr.eq
6428
  [function.objects]: utilities.md#function.objects
6429
+ [indirect]: #indirect
6430
+ [indirect.assign]: #indirect.assign
6431
+ [indirect.comp.with.t]: #indirect.comp.with.t
6432
+ [indirect.ctor]: #indirect.ctor
6433
+ [indirect.dtor]: #indirect.dtor
6434
+ [indirect.general]: #indirect.general
6435
+ [indirect.hash]: #indirect.hash
6436
+ [indirect.obs]: #indirect.obs
6437
+ [indirect.relops]: #indirect.relops
6438
+ [indirect.swap]: #indirect.swap
6439
+ [indirect.syn]: #indirect.syn
6440
  [inout.ptr]: #inout.ptr
6441
  [inout.ptr.t]: #inout.ptr.t
6442
  [intro.multithread]: basic.md#intro.multithread
6443
  [intro.object]: basic.md#intro.object
6444
  [intro.races]: basic.md#intro.races
6445
  [mem]: #mem
6446
+ [mem.composite.types]: #mem.composite.types
6447
  [mem.general]: #mem.general
6448
  [mem.poly.allocator.class]: #mem.poly.allocator.class
6449
  [mem.poly.allocator.class.general]: #mem.poly.allocator.class.general
6450
  [mem.poly.allocator.ctor]: #mem.poly.allocator.ctor
6451
  [mem.poly.allocator.eq]: #mem.poly.allocator.eq
 
6480
  [pointer.traits]: #pointer.traits
6481
  [pointer.traits.functions]: #pointer.traits.functions
6482
  [pointer.traits.general]: #pointer.traits.general
6483
  [pointer.traits.optmem]: #pointer.traits.optmem
6484
  [pointer.traits.types]: #pointer.traits.types
6485
+ [polymorphic]: #polymorphic
6486
+ [polymorphic.assign]: #polymorphic.assign
6487
+ [polymorphic.ctor]: #polymorphic.ctor
6488
+ [polymorphic.dtor]: #polymorphic.dtor
6489
+ [polymorphic.general]: #polymorphic.general
6490
+ [polymorphic.obs]: #polymorphic.obs
6491
+ [polymorphic.swap]: #polymorphic.swap
6492
+ [polymorphic.syn]: #polymorphic.syn
6493
  [ptr.align]: #ptr.align
6494
  [scoped.adaptor.operators]: #scoped.adaptor.operators
6495
  [smartptr]: #smartptr
6496
  [smartptr.adapt]: #smartptr.adapt
6497
  [specialized.addressof]: #specialized.addressof
6498
  [specialized.algorithms]: algorithms.md#specialized.algorithms
6499
  [stmt.dcl]: stmt.md#stmt.dcl
6500
  [swappable.requirements]: library.md#swappable.requirements
6501
  [temp.deduct]: temp.md#temp.deduct
6502
+ [term.implicit.lifetime.type]: basic.md#term.implicit.lifetime.type
6503
  [term.incomplete.type]: basic.md#term.incomplete.type
6504
+ [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
6505
  [tuple]: utilities.md#tuple
6506
  [unique.ptr]: #unique.ptr
6507
  [unique.ptr.create]: #unique.ptr.create
6508
  [unique.ptr.dltr]: #unique.ptr.dltr
6509
  [unique.ptr.dltr.dflt]: #unique.ptr.dltr.dflt
 
6528
  [unord.hash]: utilities.md#unord.hash
6529
  [util.sharedptr]: #util.sharedptr
6530
  [util.smartptr.enab]: #util.smartptr.enab
6531
  [util.smartptr.getdeleter]: #util.smartptr.getdeleter
6532
  [util.smartptr.hash]: #util.smartptr.hash
6533
+ [util.smartptr.owner.equal]: #util.smartptr.owner.equal
6534
+ [util.smartptr.owner.hash]: #util.smartptr.owner.hash
6535
  [util.smartptr.ownerless]: #util.smartptr.ownerless
6536
  [util.smartptr.shared]: #util.smartptr.shared
6537
  [util.smartptr.shared.assign]: #util.smartptr.shared.assign
6538
  [util.smartptr.shared.cast]: #util.smartptr.shared.cast
6539
  [util.smartptr.shared.cmp]: #util.smartptr.shared.cmp