From Jason Turner

[util.smartptr.shared]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp_pcucx3u/{from.md → to.md} +160 -139
tmp/tmp_pcucx3u/{from.md → to.md} RENAMED
@@ -17,68 +17,73 @@ namespace std {
17
 
18
  // [util.smartptr.shared.const], constructors
19
  constexpr shared_ptr() noexcept;
20
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
21
  template<class Y>
22
- explicit shared_ptr(Y* p);
23
  template<class Y, class D>
24
- shared_ptr(Y* p, D d);
25
  template<class Y, class D, class A>
26
- shared_ptr(Y* p, D d, A a);
27
  template<class D>
28
- shared_ptr(nullptr_t p, D d);
29
  template<class D, class A>
30
- shared_ptr(nullptr_t p, D d, A a);
31
  template<class Y>
32
- shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
33
  template<class Y>
34
- shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
35
- shared_ptr(const shared_ptr& r) noexcept;
36
  template<class Y>
37
- shared_ptr(const shared_ptr<Y>& r) noexcept;
38
- shared_ptr(shared_ptr&& r) noexcept;
39
  template<class Y>
40
- shared_ptr(shared_ptr<Y>&& r) noexcept;
41
  template<class Y>
42
- explicit shared_ptr(const weak_ptr<Y>& r);
43
  template<class Y, class D>
44
- shared_ptr(unique_ptr<Y, D>&& r);
45
 
46
  // [util.smartptr.shared.dest], destructor
47
- ~shared_ptr();
48
 
49
  // [util.smartptr.shared.assign], assignment
50
- shared_ptr& operator=(const shared_ptr& r) noexcept;
51
  template<class Y>
52
- shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
53
- shared_ptr& operator=(shared_ptr&& r) noexcept;
54
  template<class Y>
55
- shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
56
  template<class Y, class D>
57
- shared_ptr& operator=(unique_ptr<Y, D>&& r);
58
 
59
  // [util.smartptr.shared.mod], modifiers
60
- void swap(shared_ptr& r) noexcept;
61
- void reset() noexcept;
62
  template<class Y>
63
- void reset(Y* p);
64
  template<class Y, class D>
65
- void reset(Y* p, D d);
66
  template<class Y, class D, class A>
67
- void reset(Y* p, D d, A a);
68
 
69
  // [util.smartptr.shared.obs], observers
70
- element_type* get() const noexcept;
71
- T& operator*() const noexcept;
72
- T* operator->() const noexcept;
73
- element_type& operator[](ptrdiff_t i) const;
74
- long use_count() const noexcept;
75
- explicit operator bool() const noexcept;
76
  template<class U>
77
- bool owner_before(const shared_ptr<U>& b) const noexcept;
78
  template<class U>
79
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
80
  };
81
 
82
  template<class T>
83
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
84
  template<class T, class D>
@@ -110,13 +115,13 @@ For purposes of determining the presence of a data race, member
110
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
111
  objects themselves and not objects they refer to. Changes in
112
  `use_count()` do not reflect modifications that can introduce data
113
  races.
114
 
115
- For the purposes of subclause [[smartptr]], a pointer type `Y*` is said
116
- to be *compatible with* a pointer type `T*` when either `Y*` is
117
- convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
118
 
119
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
120
 
121
  In the constructor definitions below, enables `shared_from_this` with
122
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
@@ -124,26 +129,26 @@ unambiguous and accessible base class that is a specialization of
124
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
125
  shall be implicitly convertible to `T*` and the constructor evaluates
126
  the statement:
127
 
128
  ``` cpp
129
- if (p != nullptr && p->weak_this.expired())
130
- p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
131
  ```
132
 
133
- The assignment to the `weak_this` member is not atomic and conflicts
134
  with any potentially concurrent access to the same object
135
  [[intro.multithread]].
136
 
137
  ``` cpp
138
  constexpr shared_ptr() noexcept;
139
  ```
140
 
141
  *Ensures:* `use_count() == 0 && get() == nullptr`.
142
 
143
  ``` cpp
144
- template<class Y> explicit shared_ptr(Y* p);
145
  ```
146
 
147
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
148
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
149
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
@@ -167,14 +172,14 @@ not an array type, `delete[] p` otherwise.
167
 
168
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
169
  resource other than memory cannot be obtained.
170
 
171
  ``` cpp
172
- template<class Y, class D> shared_ptr(Y* p, D d);
173
- template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
174
- template<class D> shared_ptr(nullptr_t p, D d);
175
- template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
176
  ```
177
 
178
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
179
  well-formed expression. For the first two overloads:
180
 
@@ -199,12 +204,12 @@ use. If an exception is thrown, `d(p)` is called.
199
 
200
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
201
  resource other than memory cannot be obtained.
202
 
203
  ``` cpp
204
- template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
205
- template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
206
  ```
207
 
208
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
209
  ownership with the initial value of `r`.
210
 
@@ -217,12 +222,12 @@ destroyed. — *end note*]
217
 
218
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
219
  instance with a non-null stored pointer. — *end note*]
220
 
221
  ``` cpp
222
- shared_ptr(const shared_ptr& r) noexcept;
223
- template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
224
  ```
225
 
226
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
227
 
228
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
@@ -230,23 +235,23 @@ otherwise, constructs a `shared_ptr` object that shares ownership with
230
  `r`.
231
 
232
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
233
 
234
  ``` cpp
235
- shared_ptr(shared_ptr&& r) noexcept;
236
- template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
237
  ```
238
 
239
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
240
 
241
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
242
 
243
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
244
  `r.get() == nullptr`.
245
 
246
  ``` cpp
247
- template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
248
  ```
249
 
250
  *Constraints:* `Y*` is compatible with `T*`.
251
 
252
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
@@ -256,11 +261,11 @@ thrown, the constructor has no effect.
256
  *Ensures:* `use_count() == r.use_count()`.
257
 
258
  *Throws:* `bad_weak_ptr` when `r.expired()`.
259
 
260
  ``` cpp
261
- template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
262
  ```
263
 
264
  *Constraints:* `Y*` is compatible with `T*` and
265
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
266
 
@@ -271,11 +276,11 @@ equivalent to `shared_ptr(r.release(), ref(r.get_deleter()))`. If an
271
  exception is thrown, the constructor has no effect.
272
 
273
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
274
 
275
  ``` cpp
276
- ~shared_ptr();
277
  ```
278
 
279
  *Effects:*
280
 
281
  - If `*this` is empty or shares ownership with another `shared_ptr`
@@ -291,12 +296,12 @@ been destroyed all `shared_ptr` instances that shared ownership with
291
  value. — *end note*]
292
 
293
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
294
 
295
  ``` cpp
296
- shared_ptr& operator=(const shared_ptr& r) noexcept;
297
- template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
298
  ```
299
 
300
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
301
 
302
  *Returns:* `*this`.
@@ -318,68 +323,68 @@ q = p;
318
  both assignments can be no-ops.
319
 
320
  — *end note*]
321
 
322
  ``` cpp
323
- shared_ptr& operator=(shared_ptr&& r) noexcept;
324
- template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
325
  ```
326
 
327
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
328
 
329
  *Returns:* `*this`.
330
 
331
  ``` cpp
332
- template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
333
  ```
334
 
335
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
336
 
337
  *Returns:* `*this`.
338
 
339
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
340
 
341
  ``` cpp
342
- void swap(shared_ptr& r) noexcept;
343
  ```
344
 
345
  *Effects:* Exchanges the contents of `*this` and `r`.
346
 
347
  ``` cpp
348
- void reset() noexcept;
349
  ```
350
 
351
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
352
 
353
  ``` cpp
354
- template<class Y> void reset(Y* p);
355
  ```
356
 
357
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
358
 
359
  ``` cpp
360
- template<class Y, class D> void reset(Y* p, D d);
361
  ```
362
 
363
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
364
 
365
  ``` cpp
366
- template<class Y, class D, class A> void reset(Y* p, D d, A a);
367
  ```
368
 
369
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
370
 
371
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
372
 
373
  ``` cpp
374
- element_type* get() const noexcept;
375
  ```
376
 
377
  *Returns:* The stored pointer.
378
 
379
  ``` cpp
380
- T& operator*() const noexcept;
381
  ```
382
 
383
  *Preconditions:* `get() != nullptr`.
384
 
385
  *Returns:* `*get()`.
@@ -389,11 +394,11 @@ whether this member function is declared. If it is declared, it is
389
  unspecified what its return type is, except that the declaration
390
  (although not necessarily the definition) of the function shall be
391
  well-formed.
392
 
393
  ``` cpp
394
- T* operator->() const noexcept;
395
  ```
396
 
397
  *Preconditions:* `get() != nullptr`.
398
 
399
  *Returns:* `get()`.
@@ -402,15 +407,16 @@ T* operator->() const noexcept;
402
  member function is declared. If it is declared, it is unspecified what
403
  its return type is, except that the declaration (although not
404
  necessarily the definition) of the function shall be well-formed.
405
 
406
  ``` cpp
407
- element_type& operator[](ptrdiff_t i) const;
408
  ```
409
 
410
- *Preconditions:* `get() != nullptr && i >= 0`. If `T` is `U[N]`,
411
- `i < N`.
 
412
 
413
  *Returns:* `get()[i]`.
414
 
415
  *Throws:* Nothing.
416
 
@@ -418,11 +424,11 @@ element_type& operator[](ptrdiff_t i) const;
418
  member function is declared. If it is declared, it is unspecified what
419
  its return type is, except that the declaration (although not
420
  necessarily the definition) of the function shall be well-formed.
421
 
422
  ``` cpp
423
- long use_count() const noexcept;
424
  ```
425
 
426
  *Synchronization:* None.
427
 
428
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
@@ -438,45 +444,62 @@ share ownership with `*this`, or `0` when `*this` is empty.
438
  `use_count()`, the result is approximate. In particular,
439
  `use_count() == 1` does not imply that accesses through a previously
440
  destroyed `shared_ptr` have in any sense completed. — *end note*]
441
 
442
  ``` cpp
443
- explicit operator bool() const noexcept;
444
  ```
445
 
446
  *Returns:* `get() != nullptr`.
447
 
448
  ``` cpp
449
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
450
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
451
  ```
452
 
453
  *Returns:* An unspecified value such that
454
 
455
- - `x.owner_before(y)` defines a strict weak ordering as defined
456
  in  [[alg.sorting]];
457
- - under the equivalence relation defined by `owner_before`,
458
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
459
- `weak_ptr` instances are equivalent if and only if they share
460
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
 
462
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
463
 
464
  The common requirements that apply to all `make_shared`,
465
  `allocate_shared`, `make_shared_for_overwrite`, and
466
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
467
  are described below.
468
 
469
  ``` cpp
470
  template<class T, ...>
471
- shared_ptr<T> make_shared(args);
472
  template<class T, class A, ...>
473
- shared_ptr<T> allocate_shared(const A& a, args);
474
  template<class T, ...>
475
- shared_ptr<T> make_shared_for_overwrite(args);
476
  template<class T, class A, ...>
477
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
478
  ```
479
 
480
  *Preconditions:* `A` meets the *Cpp17Allocator*
481
  requirements [[allocator.requirements.general]].
482
 
@@ -517,56 +540,58 @@ the initialization of the object.
517
  suitable to hold an object of type `U`.
518
  - When a (sub)object of a non-array type `U` is specified to have an
519
  initial value of `v`, or `U(l...)`, where `l...` is a list of
520
  constructor arguments, `allocate_shared` shall initialize this
521
  (sub)object via the expression
522
- - `allocator_traits<A2>::construct(a2, pv, v)` or
523
- - `allocator_traits<A2>::construct(a2, pv, l...)`
524
 
525
- respectively, where `pv` points to storage suitable to hold an object
526
- of type `U` and `a2` of type `A2` is a rebound copy of the allocator
527
- `a` passed to `allocate_shared` such that its `value_type` is
528
- `remove_cv_t<U>`.
529
  - When a (sub)object of non-array type `U` is specified to have a
530
  default initial value, `make_shared` shall initialize this (sub)object
531
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
532
  points to storage suitable to hold an object of type `U`.
533
  - When a (sub)object of non-array type `U` is specified to have a
534
- default initial value, `allocate_shared` shall initialize this
535
- (sub)object via the expression
536
- `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
537
- storage suitable to hold an object of type `U` and `a2` of type `A2`
538
- is a rebound copy of the allocator `a` passed to `allocate_shared`
539
- such that its `value_type` is `remove_cv_t<U>`.
540
  - When a (sub)object of non-array type `U` is initialized by
541
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
542
  initialized via the expression `::new(pv) U`, where `pv` has type
543
  `void*` and points to storage suitable to hold an object of type `U`.
544
  - Array elements are initialized in ascending order of their addresses.
545
  - When the lifetime of the object managed by the return value ends, or
546
  when the initialization of an array element throws an exception, the
547
  initialized elements are destroyed in the reverse order of their
548
  original construction.
549
  - When a (sub)object of non-array type `U` that was initialized by
550
- `make_shared` is to be destroyed, it is destroyed via the expression
551
- `pv->~U()` where `pv` points to that object of type `U`.
 
 
552
  - When a (sub)object of non-array type `U` that was initialized by
553
  `allocate_shared` is to be destroyed, it is destroyed via the
554
- expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
555
- to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
556
- rebound copy of the allocator `a` passed to `allocate_shared` such
557
- that its `value_type` is `remove_cv_t<U>`.
558
 
559
  [*Note 7*: These functions will typically allocate more memory than
560
  `sizeof(T)` to allow for internal bookkeeping structures such as
561
  reference counts. — *end note*]
562
 
563
  ``` cpp
564
  template<class T, class... Args>
565
- shared_ptr<T> make_shared(Args&&... args); // T is not array
566
  template<class T, class A, class... Args>
567
- shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
568
  ```
569
 
570
  *Constraints:* `T` is not an array type.
571
 
572
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
@@ -585,14 +610,14 @@ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
585
  ```
586
 
587
  — *end example*]
588
 
589
  ``` cpp
590
- template<class T> shared_ptr<T>
591
- make_shared(size_t N); // T is U[]
592
  template<class T, class A>
593
- shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
594
  ```
595
 
596
  *Constraints:* `T` is of the form `U[]`.
597
 
598
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
@@ -609,13 +634,13 @@ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
609
 
610
  — *end example*]
611
 
612
  ``` cpp
613
  template<class T>
614
- shared_ptr<T> make_shared(); // T is U[N]
615
  template<class T, class A>
616
- shared_ptr<T> allocate_shared(const A& a); // T is U[N]
617
  ```
618
 
619
  *Constraints:* `T` is of the form `U[N]`.
620
 
621
  *Returns:* A `shared_ptr` to an object of type `T` with a default
@@ -632,14 +657,14 @@ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
632
 
633
  — *end example*]
634
 
635
  ``` cpp
636
  template<class T>
637
- shared_ptr<T> make_shared(size_t N,
638
  const remove_extent_t<T>& u); // T is U[]
639
  template<class T, class A>
640
- shared_ptr<T> allocate_shared(const A& a, size_t N,
641
  const remove_extent_t<T>& u); // T is U[]
642
  ```
643
 
644
  *Constraints:* `T` is of the form `U[]`.
645
 
@@ -659,13 +684,13 @@ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
659
 
660
  — *end example*]
661
 
662
  ``` cpp
663
  template<class T>
664
- shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
665
  template<class T, class A>
666
- shared_ptr<T> allocate_shared(const A& a,
667
  const remove_extent_t<T>& u); // T is U[N]
668
  ```
669
 
670
  *Constraints:* `T` is of the form `U[N]`.
671
 
@@ -685,13 +710,13 @@ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
685
 
686
  — *end example*]
687
 
688
  ``` cpp
689
  template<class T>
690
- shared_ptr<T> make_shared_for_overwrite();
691
  template<class T, class A>
692
- shared_ptr<T> allocate_shared_for_overwrite(const A& a);
693
  ```
694
 
695
  *Constraints:* `T` is not an array of unknown bound.
696
 
697
  *Returns:* A `shared_ptr` to an object of type `T`.
@@ -709,13 +734,13 @@ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
709
 
710
  — *end example*]
711
 
712
  ``` cpp
713
  template<class T>
714
- shared_ptr<T> make_shared_for_overwrite(size_t N);
715
  template<class T, class A>
716
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
717
  ```
718
 
719
  *Constraints:* `T` is an array of unknown bound.
720
 
721
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
@@ -732,59 +757,59 @@ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
732
 
733
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
734
 
735
  ``` cpp
736
  template<class T, class U>
737
- bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
738
  ```
739
 
740
  *Returns:* `a.get() == b.get()`.
741
 
742
  ``` cpp
743
  template<class T>
744
- bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
745
  ```
746
 
747
  *Returns:* `!a`.
748
 
749
  ``` cpp
750
  template<class T, class U>
751
- strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
752
  ```
753
 
754
  *Returns:* `compare_three_way()(a.get(), b.get())`.
755
 
756
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
757
  objects to be used as keys in associative containers. — *end note*]
758
 
759
  ``` cpp
760
  template<class T>
761
- strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
762
  ```
763
 
764
  *Returns:*
765
 
766
  ``` cpp
767
- compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr).
768
  ```
769
 
770
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
771
 
772
  ``` cpp
773
  template<class T>
774
- void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
775
  ```
776
 
777
  *Effects:* Equivalent to `a.swap(b)`.
778
 
779
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
780
 
781
  ``` cpp
782
  template<class T, class U>
783
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
784
  template<class T, class U>
785
- shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
786
  ```
787
 
788
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
789
  well-formed.
790
 
@@ -796,19 +821,18 @@ shared_ptr<T>(R, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
796
 
797
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
798
  second.
799
 
800
  [*Note 9*: The seemingly equivalent expression
801
- `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
802
- undefined behavior, attempting to delete the same object
803
- twice. — *end note*]
804
 
805
  ``` cpp
806
  template<class T, class U>
807
- shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
808
  template<class T, class U>
809
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
810
  ```
811
 
812
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
813
  well-formed. The expression
814
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
@@ -824,19 +848,18 @@ well-defined behavior.
824
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
825
  is `r` for the first overload, and `std::move(r)` for the second.
826
  - Otherwise, `shared_ptr<T>()`.
827
 
828
  [*Note 10*: The seemingly equivalent expression
829
- `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
830
- undefined behavior, attempting to delete the same object
831
- twice. — *end note*]
832
 
833
  ``` cpp
834
  template<class T, class U>
835
- shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
836
  template<class T, class U>
837
- shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
838
  ```
839
 
840
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
841
 
842
  *Returns:*
@@ -847,13 +870,12 @@ shared_ptr<T>(R, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
847
 
848
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
849
  second.
850
 
851
  [*Note 11*: The seemingly equivalent expression
852
- `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
853
- undefined behavior, attempting to delete the same object
854
- twice. — *end note*]
855
 
856
  ``` cpp
857
  template<class T, class U>
858
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
859
  template<class T, class U>
@@ -871,19 +893,18 @@ shared_ptr<T>(R, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()
871
 
872
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
873
  second.
874
 
875
  [*Note 12*: The seemingly equivalent expression
876
- `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
877
- undefined behavior, attempting to delete the same object
878
- twice. — *end note*]
879
 
880
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
881
 
882
  ``` cpp
883
  template<class D, class T>
884
- D* get_deleter(const shared_ptr<T>& p) noexcept;
885
  ```
886
 
887
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
888
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
889
  remains valid as long as there exists a `shared_ptr` instance that owns
 
17
 
18
  // [util.smartptr.shared.const], constructors
19
  constexpr shared_ptr() noexcept;
20
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
21
  template<class Y>
22
+ constexpr explicit shared_ptr(Y* p);
23
  template<class Y, class D>
24
+ constexpr shared_ptr(Y* p, D d);
25
  template<class Y, class D, class A>
26
+ constexpr shared_ptr(Y* p, D d, A a);
27
  template<class D>
28
+ constexpr shared_ptr(nullptr_t p, D d);
29
  template<class D, class A>
30
+ constexpr shared_ptr(nullptr_t p, D d, A a);
31
  template<class Y>
32
+ constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
33
  template<class Y>
34
+ constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
35
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
36
  template<class Y>
37
+ constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
38
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
39
  template<class Y>
40
+ constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
41
  template<class Y>
42
+ constexpr explicit shared_ptr(const weak_ptr<Y>& r);
43
  template<class Y, class D>
44
+ constexpr shared_ptr(unique_ptr<Y, D>&& r);
45
 
46
  // [util.smartptr.shared.dest], destructor
47
+ constexpr ~shared_ptr();
48
 
49
  // [util.smartptr.shared.assign], assignment
50
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
51
  template<class Y>
52
+ constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
53
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
54
  template<class Y>
55
+ constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
56
  template<class Y, class D>
57
+ constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
58
 
59
  // [util.smartptr.shared.mod], modifiers
60
+ constexpr void swap(shared_ptr& r) noexcept;
61
+ constexpr void reset() noexcept;
62
  template<class Y>
63
+ constexpr void reset(Y* p);
64
  template<class Y, class D>
65
+ constexpr void reset(Y* p, D d);
66
  template<class Y, class D, class A>
67
+ constexpr void reset(Y* p, D d, A a);
68
 
69
  // [util.smartptr.shared.obs], observers
70
+ constexpr element_type* get() const noexcept;
71
+ constexpr T& operator*() const noexcept;
72
+ constexpr T* operator->() const noexcept;
73
+ constexpr element_type& operator[](ptrdiff_t i) const;
74
+ constexpr long use_count() const noexcept;
75
+ constexpr explicit operator bool() const noexcept;
76
  template<class U>
77
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
78
  template<class U>
79
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
80
+ size_t owner_hash() const noexcept;
81
+ template<class U>
82
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
83
+ template<class U>
84
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
85
  };
86
 
87
  template<class T>
88
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
89
  template<class T, class D>
 
115
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
116
  objects themselves and not objects they refer to. Changes in
117
  `use_count()` do not reflect modifications that can introduce data
118
  races.
119
 
120
+ For the purposes of [[smartptr]], a pointer type `Y*` is said to be
121
+ *compatible with* a pointer type `T*` when either `Y*` is convertible to
122
+ `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
123
 
124
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
125
 
126
  In the constructor definitions below, enables `shared_from_this` with
127
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
 
129
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
130
  shall be implicitly convertible to `T*` and the constructor evaluates
131
  the statement:
132
 
133
  ``` cpp
134
+ if (p != nullptr && p->weak-this.expired())
135
+ p->weak-this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
136
  ```
137
 
138
+ The assignment to the *`weak-this`* member is not atomic and conflicts
139
  with any potentially concurrent access to the same object
140
  [[intro.multithread]].
141
 
142
  ``` cpp
143
  constexpr shared_ptr() noexcept;
144
  ```
145
 
146
  *Ensures:* `use_count() == 0 && get() == nullptr`.
147
 
148
  ``` cpp
149
+ template<class Y> constexpr explicit shared_ptr(Y* p);
150
  ```
151
 
152
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
153
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
154
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
 
172
 
173
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
174
  resource other than memory cannot be obtained.
175
 
176
  ``` cpp
177
+ template<class Y, class D> constexpr shared_ptr(Y* p, D d);
178
+ template<class Y, class D, class A> constexpr shared_ptr(Y* p, D d, A a);
179
+ template<class D> constexpr shared_ptr(nullptr_t p, D d);
180
+ template<class D, class A> constexpr shared_ptr(nullptr_t p, D d, A a);
181
  ```
182
 
183
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
184
  well-formed expression. For the first two overloads:
185
 
 
204
 
205
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
206
  resource other than memory cannot be obtained.
207
 
208
  ``` cpp
209
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
210
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
211
  ```
212
 
213
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
214
  ownership with the initial value of `r`.
215
 
 
222
 
223
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
224
  instance with a non-null stored pointer. — *end note*]
225
 
226
  ``` cpp
227
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
228
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
229
  ```
230
 
231
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
232
 
233
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
 
235
  `r`.
236
 
237
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
238
 
239
  ``` cpp
240
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
241
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
242
  ```
243
 
244
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
245
 
246
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
247
 
248
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
249
  `r.get() == nullptr`.
250
 
251
  ``` cpp
252
+ template<class Y> constexpr explicit shared_ptr(const weak_ptr<Y>& r);
253
  ```
254
 
255
  *Constraints:* `Y*` is compatible with `T*`.
256
 
257
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
 
261
  *Ensures:* `use_count() == r.use_count()`.
262
 
263
  *Throws:* `bad_weak_ptr` when `r.expired()`.
264
 
265
  ``` cpp
266
+ template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
267
  ```
268
 
269
  *Constraints:* `Y*` is compatible with `T*` and
270
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
271
 
 
276
  exception is thrown, the constructor has no effect.
277
 
278
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
279
 
280
  ``` cpp
281
+ constexpr ~shared_ptr();
282
  ```
283
 
284
  *Effects:*
285
 
286
  - If `*this` is empty or shares ownership with another `shared_ptr`
 
296
  value. — *end note*]
297
 
298
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
299
 
300
  ``` cpp
301
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
302
+ template<class Y> constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
303
  ```
304
 
305
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
306
 
307
  *Returns:* `*this`.
 
323
  both assignments can be no-ops.
324
 
325
  — *end note*]
326
 
327
  ``` cpp
328
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
329
+ template<class Y> constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
330
  ```
331
 
332
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
333
 
334
  *Returns:* `*this`.
335
 
336
  ``` cpp
337
+ template<class Y, class D> constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
338
  ```
339
 
340
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
341
 
342
  *Returns:* `*this`.
343
 
344
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
345
 
346
  ``` cpp
347
+ constexpr void swap(shared_ptr& r) noexcept;
348
  ```
349
 
350
  *Effects:* Exchanges the contents of `*this` and `r`.
351
 
352
  ``` cpp
353
+ constexpr void reset() noexcept;
354
  ```
355
 
356
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
357
 
358
  ``` cpp
359
+ template<class Y> constexpr void reset(Y* p);
360
  ```
361
 
362
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
363
 
364
  ``` cpp
365
+ template<class Y, class D> constexpr void reset(Y* p, D d);
366
  ```
367
 
368
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
369
 
370
  ``` cpp
371
+ template<class Y, class D, class A> constexpr void reset(Y* p, D d, A a);
372
  ```
373
 
374
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
375
 
376
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
377
 
378
  ``` cpp
379
+ constexpr element_type* get() const noexcept;
380
  ```
381
 
382
  *Returns:* The stored pointer.
383
 
384
  ``` cpp
385
+ constexpr T& operator*() const noexcept;
386
  ```
387
 
388
  *Preconditions:* `get() != nullptr`.
389
 
390
  *Returns:* `*get()`.
 
394
  unspecified what its return type is, except that the declaration
395
  (although not necessarily the definition) of the function shall be
396
  well-formed.
397
 
398
  ``` cpp
399
+ constexpr T* operator->() const noexcept;
400
  ```
401
 
402
  *Preconditions:* `get() != nullptr`.
403
 
404
  *Returns:* `get()`.
 
407
  member function is declared. If it is declared, it is unspecified what
408
  its return type is, except that the declaration (although not
409
  necessarily the definition) of the function shall be well-formed.
410
 
411
  ``` cpp
412
+ constexpr element_type& operator[](ptrdiff_t i) const;
413
  ```
414
 
415
+ *Preconditions:* `get() != nullptr` is `true`.
416
+
417
+ `i` ≥ 0. If `T` is `U[N]`, `i` < `N`.
418
 
419
  *Returns:* `get()[i]`.
420
 
421
  *Throws:* Nothing.
422
 
 
424
  member function is declared. If it is declared, it is unspecified what
425
  its return type is, except that the declaration (although not
426
  necessarily the definition) of the function shall be well-formed.
427
 
428
  ``` cpp
429
+ constexpr long use_count() const noexcept;
430
  ```
431
 
432
  *Synchronization:* None.
433
 
434
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
 
444
  `use_count()`, the result is approximate. In particular,
445
  `use_count() == 1` does not imply that accesses through a previously
446
  destroyed `shared_ptr` have in any sense completed. — *end note*]
447
 
448
  ``` cpp
449
+ constexpr explicit operator bool() const noexcept;
450
  ```
451
 
452
  *Returns:* `get() != nullptr`.
453
 
454
  ``` cpp
455
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
456
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
457
  ```
458
 
459
  *Returns:* An unspecified value such that
460
 
461
+ - `owner_before(b)` defines a strict weak ordering as defined
462
  in  [[alg.sorting]];
463
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
464
+ `owner_equal(b)` is `true`.
465
+
466
+ ``` cpp
467
+ size_t owner_hash() const noexcept;
468
+ ```
469
+
470
+ *Returns:* An unspecified value such that, for any object `x` where
471
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
472
+
473
+ ``` cpp
474
+ template<class U>
475
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
476
+ template<class U>
477
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
478
+ ```
479
+
480
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
481
+ both empty. Otherwise returns `false`.
482
+
483
+ *Remarks:* `owner_equal` is an equivalence relation.
484
 
485
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
486
 
487
  The common requirements that apply to all `make_shared`,
488
  `allocate_shared`, `make_shared_for_overwrite`, and
489
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
490
  are described below.
491
 
492
  ``` cpp
493
  template<class T, ...>
494
+ constexpr shared_ptr<T> make_shared(args);
495
  template<class T, class A, ...>
496
+ constexpr shared_ptr<T> allocate_shared(const A& a, args);
497
  template<class T, ...>
498
+ constexpr shared_ptr<T> make_shared_for_overwrite(args);
499
  template<class T, class A, ...>
500
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
501
  ```
502
 
503
  *Preconditions:* `A` meets the *Cpp17Allocator*
504
  requirements [[allocator.requirements.general]].
505
 
 
540
  suitable to hold an object of type `U`.
541
  - When a (sub)object of a non-array type `U` is specified to have an
542
  initial value of `v`, or `U(l...)`, where `l...` is a list of
543
  constructor arguments, `allocate_shared` shall initialize this
544
  (sub)object via the expression
545
+ - `allocator_traits<A2>::construct(a2, pu, v)` or
546
+ - `allocator_traits<A2>::construct(a2, pu, l...)`
547
 
548
+ respectively, where `pu` is a pointer of type `remove_cv_t<U>*`
549
+ pointing to storage suitable to hold an object of type
550
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
551
+ of the allocator `a` passed to `allocate_shared`.
552
  - When a (sub)object of non-array type `U` is specified to have a
553
  default initial value, `make_shared` shall initialize this (sub)object
554
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
555
  points to storage suitable to hold an object of type `U`.
556
  - When a (sub)object of non-array type `U` is specified to have a
557
+ default initial value, `allocate_shared` initializes this (sub)object
558
+ via the expression `allocator_traits<A2>::construct(a2, pu)`, where
559
+ `pu` is a pointer of type `remove_cv_t<U>*` pointing to storage
560
+ suitable to hold an object of type `remove_cv_t<U>` and `a2` of type
561
+ `A2` is a potentially rebound copy of the allocator `a` passed to
562
+ `allocate_shared`.
563
  - When a (sub)object of non-array type `U` is initialized by
564
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
565
  initialized via the expression `::new(pv) U`, where `pv` has type
566
  `void*` and points to storage suitable to hold an object of type `U`.
567
  - Array elements are initialized in ascending order of their addresses.
568
  - When the lifetime of the object managed by the return value ends, or
569
  when the initialization of an array element throws an exception, the
570
  initialized elements are destroyed in the reverse order of their
571
  original construction.
572
  - When a (sub)object of non-array type `U` that was initialized by
573
+ `make_shared`, `make_shared_for_overwrite`, or
574
+ `allocate_shared_for_overwrite` is to be destroyed, it is destroyed
575
+ via the expression `pu->~U()` where `pu` points to that object of type
576
+ `U`.
577
  - When a (sub)object of non-array type `U` that was initialized by
578
  `allocate_shared` is to be destroyed, it is destroyed via the
579
+ expression `allocator_traits<A2>::destroy(a2, pu)` where `pu` is a
580
+ pointer of type `remove_cv_t<U>*` pointing to that object of type
581
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
582
+ of the allocator `a` passed to `allocate_shared`.
583
 
584
  [*Note 7*: These functions will typically allocate more memory than
585
  `sizeof(T)` to allow for internal bookkeeping structures such as
586
  reference counts. — *end note*]
587
 
588
  ``` cpp
589
  template<class T, class... Args>
590
+ constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
591
  template<class T, class A, class... Args>
592
+ constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
593
  ```
594
 
595
  *Constraints:* `T` is not an array type.
596
 
597
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
 
610
  ```
611
 
612
  — *end example*]
613
 
614
  ``` cpp
615
+ template<class T>
616
+ constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
617
  template<class T, class A>
618
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
619
  ```
620
 
621
  *Constraints:* `T` is of the form `U[]`.
622
 
623
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
 
634
 
635
  — *end example*]
636
 
637
  ``` cpp
638
  template<class T>
639
+ constexpr shared_ptr<T> make_shared(); // T is U[N]
640
  template<class T, class A>
641
+ constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
642
  ```
643
 
644
  *Constraints:* `T` is of the form `U[N]`.
645
 
646
  *Returns:* A `shared_ptr` to an object of type `T` with a default
 
657
 
658
  — *end example*]
659
 
660
  ``` cpp
661
  template<class T>
662
+ constexpr shared_ptr<T> make_shared(size_t N,
663
  const remove_extent_t<T>& u); // T is U[]
664
  template<class T, class A>
665
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
666
  const remove_extent_t<T>& u); // T is U[]
667
  ```
668
 
669
  *Constraints:* `T` is of the form `U[]`.
670
 
 
684
 
685
  — *end example*]
686
 
687
  ``` cpp
688
  template<class T>
689
+ constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
690
  template<class T, class A>
691
+ constexpr shared_ptr<T> allocate_shared(const A& a,
692
  const remove_extent_t<T>& u); // T is U[N]
693
  ```
694
 
695
  *Constraints:* `T` is of the form `U[N]`.
696
 
 
710
 
711
  — *end example*]
712
 
713
  ``` cpp
714
  template<class T>
715
+ constexpr shared_ptr<T> make_shared_for_overwrite();
716
  template<class T, class A>
717
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
718
  ```
719
 
720
  *Constraints:* `T` is not an array of unknown bound.
721
 
722
  *Returns:* A `shared_ptr` to an object of type `T`.
 
734
 
735
  — *end example*]
736
 
737
  ``` cpp
738
  template<class T>
739
+ constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
740
  template<class T, class A>
741
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
742
  ```
743
 
744
  *Constraints:* `T` is an array of unknown bound.
745
 
746
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
 
757
 
758
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
759
 
760
  ``` cpp
761
  template<class T, class U>
762
+ constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
763
  ```
764
 
765
  *Returns:* `a.get() == b.get()`.
766
 
767
  ``` cpp
768
  template<class T>
769
+ constexpr bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
770
  ```
771
 
772
  *Returns:* `!a`.
773
 
774
  ``` cpp
775
  template<class T, class U>
776
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
777
  ```
778
 
779
  *Returns:* `compare_three_way()(a.get(), b.get())`.
780
 
781
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
782
  objects to be used as keys in associative containers. — *end note*]
783
 
784
  ``` cpp
785
  template<class T>
786
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
787
  ```
788
 
789
  *Returns:*
790
 
791
  ``` cpp
792
+ compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))
793
  ```
794
 
795
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
796
 
797
  ``` cpp
798
  template<class T>
799
+ constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
800
  ```
801
 
802
  *Effects:* Equivalent to `a.swap(b)`.
803
 
804
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
805
 
806
  ``` cpp
807
  template<class T, class U>
808
+ constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
809
  template<class T, class U>
810
+ constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
811
  ```
812
 
813
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
814
  well-formed.
815
 
 
821
 
822
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
823
  second.
824
 
825
  [*Note 9*: The seemingly equivalent expression
826
+ `shared_ptr<T>(static_cast<T*>(r.get()))` can result in undefined
827
+ behavior, attempting to delete the same object twice. — *end note*]
 
828
 
829
  ``` cpp
830
  template<class T, class U>
831
+ constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
832
  template<class T, class U>
833
+ constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
834
  ```
835
 
836
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
837
  well-formed. The expression
838
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
 
848
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
849
  is `r` for the first overload, and `std::move(r)` for the second.
850
  - Otherwise, `shared_ptr<T>()`.
851
 
852
  [*Note 10*: The seemingly equivalent expression
853
+ `shared_ptr<T>(dynamic_cast<T*>(r.get()))` can result in undefined
854
+ behavior, attempting to delete the same object twice. — *end note*]
 
855
 
856
  ``` cpp
857
  template<class T, class U>
858
+ constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
859
  template<class T, class U>
860
+ constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
861
  ```
862
 
863
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
864
 
865
  *Returns:*
 
870
 
871
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
872
  second.
873
 
874
  [*Note 11*: The seemingly equivalent expression
875
+ `shared_ptr<T>(const_cast<T*>(r.get()))` can result in undefined
876
+ behavior, attempting to delete the same object twice. — *end note*]
 
877
 
878
  ``` cpp
879
  template<class T, class U>
880
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
881
  template<class T, class U>
 
893
 
894
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
895
  second.
896
 
897
  [*Note 12*: The seemingly equivalent expression
898
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` can result in undefined
899
+ behavior, attempting to delete the same object twice. — *end note*]
 
900
 
901
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
902
 
903
  ``` cpp
904
  template<class D, class T>
905
+ constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
906
  ```
907
 
908
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
909
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
910
  remains valid as long as there exists a `shared_ptr` instance that owns