From Jason Turner

[util.sharedptr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpa06bnfoe/{from.md → to.md} +325 -216
tmp/tmpa06bnfoe/{from.md → to.md} RENAMED
@@ -5,20 +5,20 @@
5
  ``` cpp
6
  namespace std {
7
  class bad_weak_ptr : public exception {
8
  public:
9
  // see [exception] for the specification of the special member functions
10
- const char* what() const noexcept override;
11
  };
12
  }
13
  ```
14
 
15
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
16
  constructor taking a `weak_ptr`.
17
 
18
  ``` cpp
19
- const char* what() const noexcept override;
20
  ```
21
 
22
  *Returns:* An *implementation-defined* NTBS.
23
 
24
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
@@ -40,68 +40,73 @@ namespace std {
40
 
41
  // [util.smartptr.shared.const], constructors
42
  constexpr shared_ptr() noexcept;
43
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
44
  template<class Y>
45
- explicit shared_ptr(Y* p);
46
  template<class Y, class D>
47
- shared_ptr(Y* p, D d);
48
  template<class Y, class D, class A>
49
- shared_ptr(Y* p, D d, A a);
50
  template<class D>
51
- shared_ptr(nullptr_t p, D d);
52
  template<class D, class A>
53
- shared_ptr(nullptr_t p, D d, A a);
54
  template<class Y>
55
- shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
56
  template<class Y>
57
- shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
58
- shared_ptr(const shared_ptr& r) noexcept;
59
  template<class Y>
60
- shared_ptr(const shared_ptr<Y>& r) noexcept;
61
- shared_ptr(shared_ptr&& r) noexcept;
62
  template<class Y>
63
- shared_ptr(shared_ptr<Y>&& r) noexcept;
64
  template<class Y>
65
- explicit shared_ptr(const weak_ptr<Y>& r);
66
  template<class Y, class D>
67
- shared_ptr(unique_ptr<Y, D>&& r);
68
 
69
  // [util.smartptr.shared.dest], destructor
70
- ~shared_ptr();
71
 
72
  // [util.smartptr.shared.assign], assignment
73
- shared_ptr& operator=(const shared_ptr& r) noexcept;
74
  template<class Y>
75
- shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
76
- shared_ptr& operator=(shared_ptr&& r) noexcept;
77
  template<class Y>
78
- shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
79
  template<class Y, class D>
80
- shared_ptr& operator=(unique_ptr<Y, D>&& r);
81
 
82
  // [util.smartptr.shared.mod], modifiers
83
- void swap(shared_ptr& r) noexcept;
84
- void reset() noexcept;
85
  template<class Y>
86
- void reset(Y* p);
87
  template<class Y, class D>
88
- void reset(Y* p, D d);
89
  template<class Y, class D, class A>
90
- void reset(Y* p, D d, A a);
91
 
92
  // [util.smartptr.shared.obs], observers
93
- element_type* get() const noexcept;
94
- T& operator*() const noexcept;
95
- T* operator->() const noexcept;
96
- element_type& operator[](ptrdiff_t i) const;
97
- long use_count() const noexcept;
98
- explicit operator bool() const noexcept;
99
  template<class U>
100
- bool owner_before(const shared_ptr<U>& b) const noexcept;
101
  template<class U>
102
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
103
  };
104
 
105
  template<class T>
106
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
107
  template<class T, class D>
@@ -133,13 +138,13 @@ For purposes of determining the presence of a data race, member
133
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
134
  objects themselves and not objects they refer to. Changes in
135
  `use_count()` do not reflect modifications that can introduce data
136
  races.
137
 
138
- For the purposes of subclause [[smartptr]], a pointer type `Y*` is said
139
- to be *compatible with* a pointer type `T*` when either `Y*` is
140
- convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
141
 
142
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
143
 
144
  In the constructor definitions below, enables `shared_from_this` with
145
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
@@ -147,26 +152,26 @@ unambiguous and accessible base class that is a specialization of
147
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
148
  shall be implicitly convertible to `T*` and the constructor evaluates
149
  the statement:
150
 
151
  ``` cpp
152
- if (p != nullptr && p->weak_this.expired())
153
- p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
154
  ```
155
 
156
- The assignment to the `weak_this` member is not atomic and conflicts
157
  with any potentially concurrent access to the same object
158
  [[intro.multithread]].
159
 
160
  ``` cpp
161
  constexpr shared_ptr() noexcept;
162
  ```
163
 
164
  *Ensures:* `use_count() == 0 && get() == nullptr`.
165
 
166
  ``` cpp
167
- template<class Y> explicit shared_ptr(Y* p);
168
  ```
169
 
170
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
171
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
172
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
@@ -190,14 +195,14 @@ not an array type, `delete[] p` otherwise.
190
 
191
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
192
  resource other than memory cannot be obtained.
193
 
194
  ``` cpp
195
- template<class Y, class D> shared_ptr(Y* p, D d);
196
- template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
197
- template<class D> shared_ptr(nullptr_t p, D d);
198
- template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
199
  ```
200
 
201
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
202
  well-formed expression. For the first two overloads:
203
 
@@ -222,12 +227,12 @@ use. If an exception is thrown, `d(p)` is called.
222
 
223
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
224
  resource other than memory cannot be obtained.
225
 
226
  ``` cpp
227
- template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
228
- template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
229
  ```
230
 
231
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
232
  ownership with the initial value of `r`.
233
 
@@ -240,12 +245,12 @@ destroyed. — *end note*]
240
 
241
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
242
  instance with a non-null stored pointer. — *end note*]
243
 
244
  ``` cpp
245
- shared_ptr(const shared_ptr& r) noexcept;
246
- template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
247
  ```
248
 
249
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
250
 
251
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
@@ -253,23 +258,23 @@ otherwise, constructs a `shared_ptr` object that shares ownership with
253
  `r`.
254
 
255
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
256
 
257
  ``` cpp
258
- shared_ptr(shared_ptr&& r) noexcept;
259
- template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
260
  ```
261
 
262
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
263
 
264
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
265
 
266
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
267
  `r.get() == nullptr`.
268
 
269
  ``` cpp
270
- template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
271
  ```
272
 
273
  *Constraints:* `Y*` is compatible with `T*`.
274
 
275
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
@@ -279,11 +284,11 @@ thrown, the constructor has no effect.
279
  *Ensures:* `use_count() == r.use_count()`.
280
 
281
  *Throws:* `bad_weak_ptr` when `r.expired()`.
282
 
283
  ``` cpp
284
- template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
285
  ```
286
 
287
  *Constraints:* `Y*` is compatible with `T*` and
288
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
289
 
@@ -294,11 +299,11 @@ equivalent to `shared_ptr(r.release(), ref(r.get_deleter()))`. If an
294
  exception is thrown, the constructor has no effect.
295
 
296
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
297
 
298
  ``` cpp
299
- ~shared_ptr();
300
  ```
301
 
302
  *Effects:*
303
 
304
  - If `*this` is empty or shares ownership with another `shared_ptr`
@@ -314,12 +319,12 @@ been destroyed all `shared_ptr` instances that shared ownership with
314
  value. — *end note*]
315
 
316
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
317
 
318
  ``` cpp
319
- shared_ptr& operator=(const shared_ptr& r) noexcept;
320
- template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
321
  ```
322
 
323
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
324
 
325
  *Returns:* `*this`.
@@ -341,68 +346,68 @@ q = p;
341
  both assignments can be no-ops.
342
 
343
  — *end note*]
344
 
345
  ``` cpp
346
- shared_ptr& operator=(shared_ptr&& r) noexcept;
347
- template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
348
  ```
349
 
350
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
351
 
352
  *Returns:* `*this`.
353
 
354
  ``` cpp
355
- template<class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
356
  ```
357
 
358
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
359
 
360
  *Returns:* `*this`.
361
 
362
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
363
 
364
  ``` cpp
365
- void swap(shared_ptr& r) noexcept;
366
  ```
367
 
368
  *Effects:* Exchanges the contents of `*this` and `r`.
369
 
370
  ``` cpp
371
- void reset() noexcept;
372
  ```
373
 
374
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
375
 
376
  ``` cpp
377
- template<class Y> void reset(Y* p);
378
  ```
379
 
380
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
381
 
382
  ``` cpp
383
- template<class Y, class D> void reset(Y* p, D d);
384
  ```
385
 
386
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
387
 
388
  ``` cpp
389
- template<class Y, class D, class A> void reset(Y* p, D d, A a);
390
  ```
391
 
392
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
393
 
394
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
395
 
396
  ``` cpp
397
- element_type* get() const noexcept;
398
  ```
399
 
400
  *Returns:* The stored pointer.
401
 
402
  ``` cpp
403
- T& operator*() const noexcept;
404
  ```
405
 
406
  *Preconditions:* `get() != nullptr`.
407
 
408
  *Returns:* `*get()`.
@@ -412,11 +417,11 @@ whether this member function is declared. If it is declared, it is
412
  unspecified what its return type is, except that the declaration
413
  (although not necessarily the definition) of the function shall be
414
  well-formed.
415
 
416
  ``` cpp
417
- T* operator->() const noexcept;
418
  ```
419
 
420
  *Preconditions:* `get() != nullptr`.
421
 
422
  *Returns:* `get()`.
@@ -425,15 +430,16 @@ T* operator->() const noexcept;
425
  member function is declared. If it is declared, it is unspecified what
426
  its return type is, except that the declaration (although not
427
  necessarily the definition) of the function shall be well-formed.
428
 
429
  ``` cpp
430
- element_type& operator[](ptrdiff_t i) const;
431
  ```
432
 
433
- *Preconditions:* `get() != nullptr && i >= 0`. If `T` is `U[N]`,
434
- `i < N`.
 
435
 
436
  *Returns:* `get()[i]`.
437
 
438
  *Throws:* Nothing.
439
 
@@ -441,11 +447,11 @@ element_type& operator[](ptrdiff_t i) const;
441
  member function is declared. If it is declared, it is unspecified what
442
  its return type is, except that the declaration (although not
443
  necessarily the definition) of the function shall be well-formed.
444
 
445
  ``` cpp
446
- long use_count() const noexcept;
447
  ```
448
 
449
  *Synchronization:* None.
450
 
451
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
@@ -461,45 +467,62 @@ share ownership with `*this`, or `0` when `*this` is empty.
461
  `use_count()`, the result is approximate. In particular,
462
  `use_count() == 1` does not imply that accesses through a previously
463
  destroyed `shared_ptr` have in any sense completed. — *end note*]
464
 
465
  ``` cpp
466
- explicit operator bool() const noexcept;
467
  ```
468
 
469
  *Returns:* `get() != nullptr`.
470
 
471
  ``` cpp
472
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
473
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
474
  ```
475
 
476
  *Returns:* An unspecified value such that
477
 
478
- - `x.owner_before(y)` defines a strict weak ordering as defined
479
  in  [[alg.sorting]];
480
- - under the equivalence relation defined by `owner_before`,
481
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
482
- `weak_ptr` instances are equivalent if and only if they share
483
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- shared_ptr<T> make_shared(args);
495
  template<class T, class A, ...>
496
- shared_ptr<T> allocate_shared(const A& a, args);
497
  template<class T, ...>
498
- shared_ptr<T> make_shared_for_overwrite(args);
499
  template<class T, class A, ...>
500
- 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,56 +563,58 @@ the initialization of the object.
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, pv, v)` or
546
- - `allocator_traits<A2>::construct(a2, pv, l...)`
547
 
548
- respectively, where `pv` points to storage suitable to hold an object
549
- of type `U` and `a2` of type `A2` is a rebound copy of the allocator
550
- `a` passed to `allocate_shared` such that its `value_type` is
551
- `remove_cv_t<U>`.
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` shall initialize this
558
- (sub)object via the expression
559
- `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
560
- storage suitable to hold an object of type `U` and `a2` of type `A2`
561
- is a rebound copy of the allocator `a` passed to `allocate_shared`
562
- such that its `value_type` is `remove_cv_t<U>`.
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` is to be destroyed, it is destroyed via the expression
574
- `pv->~U()` where `pv` points to that object of type `U`.
 
 
575
  - When a (sub)object of non-array type `U` that was initialized by
576
  `allocate_shared` is to be destroyed, it is destroyed via the
577
- expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
578
- to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
579
- rebound copy of the allocator `a` passed to `allocate_shared` such
580
- that its `value_type` is `remove_cv_t<U>`.
581
 
582
  [*Note 7*: These functions will typically allocate more memory than
583
  `sizeof(T)` to allow for internal bookkeeping structures such as
584
  reference counts. — *end note*]
585
 
586
  ``` cpp
587
  template<class T, class... Args>
588
- shared_ptr<T> make_shared(Args&&... args); // T is not array
589
  template<class T, class A, class... Args>
590
- shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
591
  ```
592
 
593
  *Constraints:* `T` is not an array type.
594
 
595
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
@@ -608,14 +633,14 @@ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
608
  ```
609
 
610
  — *end example*]
611
 
612
  ``` cpp
613
- template<class T> shared_ptr<T>
614
- make_shared(size_t N); // T is U[]
615
  template<class T, class A>
616
- shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
617
  ```
618
 
619
  *Constraints:* `T` is of the form `U[]`.
620
 
621
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
@@ -632,13 +657,13 @@ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
632
 
633
  — *end example*]
634
 
635
  ``` cpp
636
  template<class T>
637
- shared_ptr<T> make_shared(); // T is U[N]
638
  template<class T, class A>
639
- shared_ptr<T> allocate_shared(const A& a); // T is U[N]
640
  ```
641
 
642
  *Constraints:* `T` is of the form `U[N]`.
643
 
644
  *Returns:* A `shared_ptr` to an object of type `T` with a default
@@ -655,14 +680,14 @@ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
655
 
656
  — *end example*]
657
 
658
  ``` cpp
659
  template<class T>
660
- shared_ptr<T> make_shared(size_t N,
661
  const remove_extent_t<T>& u); // T is U[]
662
  template<class T, class A>
663
- shared_ptr<T> allocate_shared(const A& a, size_t N,
664
  const remove_extent_t<T>& u); // T is U[]
665
  ```
666
 
667
  *Constraints:* `T` is of the form `U[]`.
668
 
@@ -682,13 +707,13 @@ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
682
 
683
  — *end example*]
684
 
685
  ``` cpp
686
  template<class T>
687
- shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
688
  template<class T, class A>
689
- shared_ptr<T> allocate_shared(const A& a,
690
  const remove_extent_t<T>& u); // T is U[N]
691
  ```
692
 
693
  *Constraints:* `T` is of the form `U[N]`.
694
 
@@ -708,13 +733,13 @@ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
708
 
709
  — *end example*]
710
 
711
  ``` cpp
712
  template<class T>
713
- shared_ptr<T> make_shared_for_overwrite();
714
  template<class T, class A>
715
- shared_ptr<T> allocate_shared_for_overwrite(const A& a);
716
  ```
717
 
718
  *Constraints:* `T` is not an array of unknown bound.
719
 
720
  *Returns:* A `shared_ptr` to an object of type `T`.
@@ -732,13 +757,13 @@ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
732
 
733
  — *end example*]
734
 
735
  ``` cpp
736
  template<class T>
737
- shared_ptr<T> make_shared_for_overwrite(size_t N);
738
  template<class T, class A>
739
- shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
740
  ```
741
 
742
  *Constraints:* `T` is an array of unknown bound.
743
 
744
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
@@ -755,59 +780,59 @@ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
755
 
756
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
757
 
758
  ``` cpp
759
  template<class T, class U>
760
- bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
761
  ```
762
 
763
  *Returns:* `a.get() == b.get()`.
764
 
765
  ``` cpp
766
  template<class T>
767
- bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
768
  ```
769
 
770
  *Returns:* `!a`.
771
 
772
  ``` cpp
773
  template<class T, class U>
774
- strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
775
  ```
776
 
777
  *Returns:* `compare_three_way()(a.get(), b.get())`.
778
 
779
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
780
  objects to be used as keys in associative containers. — *end note*]
781
 
782
  ``` cpp
783
  template<class T>
784
- strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
785
  ```
786
 
787
  *Returns:*
788
 
789
  ``` cpp
790
- compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr).
791
  ```
792
 
793
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
794
 
795
  ``` cpp
796
  template<class T>
797
- void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
798
  ```
799
 
800
  *Effects:* Equivalent to `a.swap(b)`.
801
 
802
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
803
 
804
  ``` cpp
805
  template<class T, class U>
806
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
807
  template<class T, class U>
808
- shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
809
  ```
810
 
811
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
812
  well-formed.
813
 
@@ -819,19 +844,18 @@ shared_ptr<T>(R, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
819
 
820
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
821
  second.
822
 
823
  [*Note 9*: The seemingly equivalent expression
824
- `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
825
- undefined behavior, attempting to delete the same object
826
- twice. — *end note*]
827
 
828
  ``` cpp
829
  template<class T, class U>
830
- shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
831
  template<class T, class U>
832
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
833
  ```
834
 
835
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
836
  well-formed. The expression
837
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
@@ -847,19 +871,18 @@ well-defined behavior.
847
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
848
  is `r` for the first overload, and `std::move(r)` for the second.
849
  - Otherwise, `shared_ptr<T>()`.
850
 
851
  [*Note 10*: The seemingly equivalent expression
852
- `shared_ptr<T>(dynamic_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> const_pointer_cast(const shared_ptr<U>& r) noexcept;
859
  template<class T, class U>
860
- 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,13 +893,12 @@ shared_ptr<T>(R, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
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()))` will eventually result in
876
- undefined behavior, attempting to delete the same object
877
- twice. — *end note*]
878
 
879
  ``` cpp
880
  template<class T, class U>
881
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
882
  template<class T, class U>
@@ -894,19 +916,18 @@ shared_ptr<T>(R, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()
894
 
895
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
896
  second.
897
 
898
  [*Note 12*: The seemingly equivalent expression
899
- `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
900
- undefined behavior, attempting to delete the same object
901
- twice. — *end note*]
902
 
903
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
904
 
905
  ``` cpp
906
  template<class D, class T>
907
- D* get_deleter(const shared_ptr<T>& p) noexcept;
908
  ```
909
 
910
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
911
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
912
  remains valid as long as there exists a `shared_ptr` instance that owns
@@ -943,43 +964,48 @@ namespace std {
943
  using element_type = remove_extent_t<T>;
944
 
945
  // [util.smartptr.weak.const], constructors
946
  constexpr weak_ptr() noexcept;
947
  template<class Y>
948
- weak_ptr(const shared_ptr<Y>& r) noexcept;
949
- weak_ptr(const weak_ptr& r) noexcept;
950
  template<class Y>
951
- weak_ptr(const weak_ptr<Y>& r) noexcept;
952
- weak_ptr(weak_ptr&& r) noexcept;
953
  template<class Y>
954
- weak_ptr(weak_ptr<Y>&& r) noexcept;
955
 
956
  // [util.smartptr.weak.dest], destructor
957
- ~weak_ptr();
958
 
959
  // [util.smartptr.weak.assign], assignment
960
- weak_ptr& operator=(const weak_ptr& r) noexcept;
961
  template<class Y>
962
- weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
963
  template<class Y>
964
- weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
965
- weak_ptr& operator=(weak_ptr&& r) noexcept;
966
  template<class Y>
967
- weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
968
 
969
  // [util.smartptr.weak.mod], modifiers
970
- void swap(weak_ptr& r) noexcept;
971
- void reset() noexcept;
972
 
973
  // [util.smartptr.weak.obs], observers
974
- long use_count() const noexcept;
975
- bool expired() const noexcept;
976
- shared_ptr<T> lock() const noexcept;
977
  template<class U>
978
- bool owner_before(const shared_ptr<U>& b) const noexcept;
979
  template<class U>
980
- bool owner_before(const weak_ptr<U>& b) const noexcept;
 
 
 
 
 
981
  };
982
 
983
  template<class T>
984
  weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
985
  }
@@ -999,13 +1025,13 @@ constexpr weak_ptr() noexcept;
999
  pointer value.
1000
 
1001
  *Ensures:* `use_count() == 0`.
1002
 
1003
  ``` cpp
1004
- weak_ptr(const weak_ptr& r) noexcept;
1005
- template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
1006
- template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
1007
  ```
1008
 
1009
  *Constraints:* For the second and third constructors, `Y*` is compatible
1010
  with `T*`.
1011
 
@@ -1015,12 +1041,12 @@ that shares ownership with `r` and stores a copy of the pointer stored
1015
  in `r`.
1016
 
1017
  *Ensures:* `use_count() == r.use_count()`.
1018
 
1019
  ``` cpp
1020
- weak_ptr(weak_ptr&& r) noexcept;
1021
- template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
1022
  ```
1023
 
1024
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1025
 
1026
  *Effects:* Move constructs a `weak_ptr` instance from `r`.
@@ -1029,95 +1055,112 @@ template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
1029
  null pointer value, and `r.use_count() == 0`.
1030
 
1031
  ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
1032
 
1033
  ``` cpp
1034
- ~weak_ptr();
1035
  ```
1036
 
1037
  *Effects:* Destroys this `weak_ptr` object but has no effect on the
1038
  object its stored pointer points to.
1039
 
1040
  ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
1041
 
1042
  ``` cpp
1043
- weak_ptr& operator=(const weak_ptr& r) noexcept;
1044
- template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
1045
- template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1046
  ```
1047
 
1048
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
1049
 
1050
  *Returns:* `*this`.
1051
 
1052
  *Remarks:* The implementation may meet the effects (and the implied
1053
  guarantees) via different means, without creating a temporary object.
1054
 
1055
  ``` cpp
1056
- weak_ptr& operator=(weak_ptr&& r) noexcept;
1057
- template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
1058
  ```
1059
 
1060
  *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
1061
 
1062
  *Returns:* `*this`.
1063
 
1064
  ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
1065
 
1066
  ``` cpp
1067
- void swap(weak_ptr& r) noexcept;
1068
  ```
1069
 
1070
  *Effects:* Exchanges the contents of `*this` and `r`.
1071
 
1072
  ``` cpp
1073
- void reset() noexcept;
1074
  ```
1075
 
1076
  *Effects:* Equivalent to `weak_ptr().swap(*this)`.
1077
 
1078
  ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
1079
 
1080
  ``` cpp
1081
- long use_count() const noexcept;
1082
  ```
1083
 
1084
  *Returns:* `0` if `*this` is empty; otherwise, the number of
1085
  `shared_ptr` instances that share ownership with `*this`.
1086
 
1087
  ``` cpp
1088
- bool expired() const noexcept;
1089
  ```
1090
 
1091
  *Returns:* `use_count() == 0`.
1092
 
1093
  ``` cpp
1094
- shared_ptr<T> lock() const noexcept;
1095
  ```
1096
 
1097
  *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
1098
  executed atomically.
1099
 
1100
  ``` cpp
1101
- template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
1102
- template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
1103
  ```
1104
 
1105
  *Returns:* An unspecified value such that
1106
 
1107
- - `x.owner_before(y)` defines a strict weak ordering as defined
1108
  in  [[alg.sorting]];
1109
- - under the equivalence relation defined by `owner_before`,
1110
- `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
1111
- `weak_ptr` instances are equivalent if and only if they share
1112
- ownership or are both empty.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1113
 
1114
  ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
1115
 
1116
  ``` cpp
1117
  template<class T>
1118
- void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
1119
  ```
1120
 
1121
  *Effects:* Equivalent to `a.swap(b)`.
1122
 
1123
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
@@ -1128,30 +1171,30 @@ of shared and weak pointers.
1128
  ``` cpp
1129
  namespace std {
1130
  template<class T = void> struct owner_less;
1131
 
1132
  template<class T> struct owner_less<shared_ptr<T>> {
1133
- bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
1134
- bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
1135
- bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
1136
  };
1137
 
1138
  template<class T> struct owner_less<weak_ptr<T>> {
1139
- bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
1140
- bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
1141
- bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
1142
  };
1143
 
1144
  template<> struct owner_less<void> {
1145
  template<class T, class U>
1146
- bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
1147
  template<class T, class U>
1148
- bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
1149
  template<class T, class U>
1150
- bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
1151
  template<class T, class U>
1152
- bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
1153
 
1154
  using is_transparent = unspecified;
1155
  };
1156
  }
1157
  ```
@@ -1162,17 +1205,83 @@ namespace std {
1162
 
1163
  Note that
1164
 
1165
  - `operator()` defines a strict weak ordering as defined in 
1166
  [[alg.sorting]];
1167
- - two `shared_ptr` or `weak_ptr` instances are equivalent under the
1168
- equivalence relation defined by `operator()`,
1169
- `!operator()(a, b) && !operator()(b, a)`, if and only if they share
1170
- ownership or are both empty.
1171
 
1172
  — *end note*]
1173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1174
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
1175
 
1176
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
1177
  `shared_from_this` member functions that obtain a `shared_ptr` instance
1178
  pointing to `*this`.
@@ -1184,64 +1293,64 @@ struct X: public enable_shared_from_this<X> { };
1184
 
1185
  int main() {
1186
  shared_ptr<X> p(new X);
1187
  shared_ptr<X> q = p->shared_from_this();
1188
  assert(p == q);
1189
- assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
1190
  }
1191
  ```
1192
 
1193
  — *end example*]
1194
 
1195
  ``` cpp
1196
  namespace std {
1197
  template<class T> class enable_shared_from_this {
1198
  protected:
1199
  constexpr enable_shared_from_this() noexcept;
1200
- enable_shared_from_this(const enable_shared_from_this&) noexcept;
1201
- enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
1202
- ~enable_shared_from_this();
1203
 
1204
  public:
1205
- shared_ptr<T> shared_from_this();
1206
- shared_ptr<T const> shared_from_this() const;
1207
- weak_ptr<T> weak_from_this() noexcept;
1208
- weak_ptr<T const> weak_from_this() const noexcept;
1209
 
1210
  private:
1211
- mutable weak_ptr<T> weak_this; // exposition only
1212
  };
1213
  }
1214
  ```
1215
 
1216
  The template parameter `T` of `enable_shared_from_this` may be an
1217
  incomplete type.
1218
 
1219
  ``` cpp
1220
  constexpr enable_shared_from_this() noexcept;
1221
- enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
1222
  ```
1223
 
1224
- *Effects:* Value-initializes `weak_this`.
1225
 
1226
  ``` cpp
1227
- enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
1228
  ```
1229
 
1230
  *Returns:* `*this`.
1231
 
1232
- [*Note 1*: `weak_this` is not changed. — *end note*]
1233
 
1234
  ``` cpp
1235
- shared_ptr<T> shared_from_this();
1236
- shared_ptr<T const> shared_from_this() const;
1237
  ```
1238
 
1239
- *Returns:* `shared_ptr<T>(weak_this)`.
1240
 
1241
  ``` cpp
1242
- weak_ptr<T> weak_from_this() noexcept;
1243
- weak_ptr<T const> weak_from_this() const noexcept;
1244
  ```
1245
 
1246
- *Returns:* `weak_this`.
1247
 
 
5
  ``` cpp
6
  namespace std {
7
  class bad_weak_ptr : public exception {
8
  public:
9
  // see [exception] for the specification of the special member functions
10
+ constexpr const char* what() const noexcept override;
11
  };
12
  }
13
  ```
14
 
15
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
16
  constructor taking a `weak_ptr`.
17
 
18
  ``` cpp
19
+ constexpr const char* what() const noexcept override;
20
  ```
21
 
22
  *Returns:* An *implementation-defined* NTBS.
23
 
24
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
 
40
 
41
  // [util.smartptr.shared.const], constructors
42
  constexpr shared_ptr() noexcept;
43
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
44
  template<class Y>
45
+ constexpr explicit shared_ptr(Y* p);
46
  template<class Y, class D>
47
+ constexpr shared_ptr(Y* p, D d);
48
  template<class Y, class D, class A>
49
+ constexpr shared_ptr(Y* p, D d, A a);
50
  template<class D>
51
+ constexpr shared_ptr(nullptr_t p, D d);
52
  template<class D, class A>
53
+ constexpr shared_ptr(nullptr_t p, D d, A a);
54
  template<class Y>
55
+ constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
56
  template<class Y>
57
+ constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
58
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
59
  template<class Y>
60
+ constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
61
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
62
  template<class Y>
63
+ constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
64
  template<class Y>
65
+ constexpr explicit shared_ptr(const weak_ptr<Y>& r);
66
  template<class Y, class D>
67
+ constexpr shared_ptr(unique_ptr<Y, D>&& r);
68
 
69
  // [util.smartptr.shared.dest], destructor
70
+ constexpr ~shared_ptr();
71
 
72
  // [util.smartptr.shared.assign], assignment
73
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
74
  template<class Y>
75
+ constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
76
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
77
  template<class Y>
78
+ constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
79
  template<class Y, class D>
80
+ constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
81
 
82
  // [util.smartptr.shared.mod], modifiers
83
+ constexpr void swap(shared_ptr& r) noexcept;
84
+ constexpr void reset() noexcept;
85
  template<class Y>
86
+ constexpr void reset(Y* p);
87
  template<class Y, class D>
88
+ constexpr void reset(Y* p, D d);
89
  template<class Y, class D, class A>
90
+ constexpr void reset(Y* p, D d, A a);
91
 
92
  // [util.smartptr.shared.obs], observers
93
+ constexpr element_type* get() const noexcept;
94
+ constexpr T& operator*() const noexcept;
95
+ constexpr T* operator->() const noexcept;
96
+ constexpr element_type& operator[](ptrdiff_t i) const;
97
+ constexpr long use_count() const noexcept;
98
+ constexpr explicit operator bool() const noexcept;
99
  template<class U>
100
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
101
  template<class U>
102
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
103
+ size_t owner_hash() const noexcept;
104
+ template<class U>
105
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
106
+ template<class U>
107
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
108
  };
109
 
110
  template<class T>
111
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
112
  template<class T, class D>
 
138
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
139
  objects themselves and not objects they refer to. Changes in
140
  `use_count()` do not reflect modifications that can introduce data
141
  races.
142
 
143
+ For the purposes of [[smartptr]], a pointer type `Y*` is said to be
144
+ *compatible with* a pointer type `T*` when either `Y*` is convertible to
145
+ `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
146
 
147
  ##### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
148
 
149
  In the constructor definitions below, enables `shared_from_this` with
150
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
 
152
  `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
153
  shall be implicitly convertible to `T*` and the constructor evaluates
154
  the statement:
155
 
156
  ``` cpp
157
+ if (p != nullptr && p->weak-this.expired())
158
+ p->weak-this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
159
  ```
160
 
161
+ The assignment to the *`weak-this`* member is not atomic and conflicts
162
  with any potentially concurrent access to the same object
163
  [[intro.multithread]].
164
 
165
  ``` cpp
166
  constexpr shared_ptr() noexcept;
167
  ```
168
 
169
  *Ensures:* `use_count() == 0 && get() == nullptr`.
170
 
171
  ``` cpp
172
+ template<class Y> constexpr explicit shared_ptr(Y* p);
173
  ```
174
 
175
  *Constraints:* When `T` is an array type, the expression `delete[] p` is
176
  well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
177
  `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
 
195
 
196
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
197
  resource other than memory cannot be obtained.
198
 
199
  ``` cpp
200
+ template<class Y, class D> constexpr shared_ptr(Y* p, D d);
201
+ template<class Y, class D, class A> constexpr shared_ptr(Y* p, D d, A a);
202
+ template<class D> constexpr shared_ptr(nullptr_t p, D d);
203
+ template<class D, class A> constexpr shared_ptr(nullptr_t p, D d, A a);
204
  ```
205
 
206
  *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
207
  well-formed expression. For the first two overloads:
208
 
 
227
 
228
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
229
  resource other than memory cannot be obtained.
230
 
231
  ``` cpp
232
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
233
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
234
  ```
235
 
236
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
237
  ownership with the initial value of `r`.
238
 
 
245
 
246
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
247
  instance with a non-null stored pointer. — *end note*]
248
 
249
  ``` cpp
250
+ constexpr shared_ptr(const shared_ptr& r) noexcept;
251
+ template<class Y> constexpr shared_ptr(const shared_ptr<Y>& r) noexcept;
252
  ```
253
 
254
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
255
 
256
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
 
258
  `r`.
259
 
260
  *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
261
 
262
  ``` cpp
263
+ constexpr shared_ptr(shared_ptr&& r) noexcept;
264
+ template<class Y> constexpr shared_ptr(shared_ptr<Y>&& r) noexcept;
265
  ```
266
 
267
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
268
 
269
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
270
 
271
  *Ensures:* `*this` contains the old value of `r`. `r` is empty, and
272
  `r.get() == nullptr`.
273
 
274
  ``` cpp
275
+ template<class Y> constexpr explicit shared_ptr(const weak_ptr<Y>& r);
276
  ```
277
 
278
  *Constraints:* `Y*` is compatible with `T*`.
279
 
280
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
 
284
  *Ensures:* `use_count() == r.use_count()`.
285
 
286
  *Throws:* `bad_weak_ptr` when `r.expired()`.
287
 
288
  ``` cpp
289
+ template<class Y, class D> constexpr shared_ptr(unique_ptr<Y, D>&& r);
290
  ```
291
 
292
  *Constraints:* `Y*` is compatible with `T*` and
293
  `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
294
 
 
299
  exception is thrown, the constructor has no effect.
300
 
301
  ##### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
302
 
303
  ``` cpp
304
+ constexpr ~shared_ptr();
305
  ```
306
 
307
  *Effects:*
308
 
309
  - If `*this` is empty or shares ownership with another `shared_ptr`
 
319
  value. — *end note*]
320
 
321
  ##### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
322
 
323
  ``` cpp
324
+ constexpr shared_ptr& operator=(const shared_ptr& r) noexcept;
325
+ template<class Y> constexpr shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
326
  ```
327
 
328
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
329
 
330
  *Returns:* `*this`.
 
346
  both assignments can be no-ops.
347
 
348
  — *end note*]
349
 
350
  ``` cpp
351
+ constexpr shared_ptr& operator=(shared_ptr&& r) noexcept;
352
+ template<class Y> constexpr shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
353
  ```
354
 
355
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
356
 
357
  *Returns:* `*this`.
358
 
359
  ``` cpp
360
+ template<class Y, class D> constexpr shared_ptr& operator=(unique_ptr<Y, D>&& r);
361
  ```
362
 
363
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
364
 
365
  *Returns:* `*this`.
366
 
367
  ##### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
368
 
369
  ``` cpp
370
+ constexpr void swap(shared_ptr& r) noexcept;
371
  ```
372
 
373
  *Effects:* Exchanges the contents of `*this` and `r`.
374
 
375
  ``` cpp
376
+ constexpr void reset() noexcept;
377
  ```
378
 
379
  *Effects:* Equivalent to `shared_ptr().swap(*this)`.
380
 
381
  ``` cpp
382
+ template<class Y> constexpr void reset(Y* p);
383
  ```
384
 
385
  *Effects:* Equivalent to `shared_ptr(p).swap(*this)`.
386
 
387
  ``` cpp
388
+ template<class Y, class D> constexpr void reset(Y* p, D d);
389
  ```
390
 
391
  *Effects:* Equivalent to `shared_ptr(p, d).swap(*this)`.
392
 
393
  ``` cpp
394
+ template<class Y, class D, class A> constexpr void reset(Y* p, D d, A a);
395
  ```
396
 
397
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
398
 
399
  ##### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
400
 
401
  ``` cpp
402
+ constexpr element_type* get() const noexcept;
403
  ```
404
 
405
  *Returns:* The stored pointer.
406
 
407
  ``` cpp
408
+ constexpr T& operator*() const noexcept;
409
  ```
410
 
411
  *Preconditions:* `get() != nullptr`.
412
 
413
  *Returns:* `*get()`.
 
417
  unspecified what its return type is, except that the declaration
418
  (although not necessarily the definition) of the function shall be
419
  well-formed.
420
 
421
  ``` cpp
422
+ constexpr T* operator->() const noexcept;
423
  ```
424
 
425
  *Preconditions:* `get() != nullptr`.
426
 
427
  *Returns:* `get()`.
 
430
  member function is declared. If it is declared, it is unspecified what
431
  its return type is, except that the declaration (although not
432
  necessarily the definition) of the function shall be well-formed.
433
 
434
  ``` cpp
435
+ constexpr element_type& operator[](ptrdiff_t i) const;
436
  ```
437
 
438
+ *Preconditions:* `get() != nullptr` is `true`.
439
+
440
+ `i` ≥ 0. If `T` is `U[N]`, `i` < `N`.
441
 
442
  *Returns:* `get()[i]`.
443
 
444
  *Throws:* Nothing.
445
 
 
447
  member function is declared. If it is declared, it is unspecified what
448
  its return type is, except that the declaration (although not
449
  necessarily the definition) of the function shall be well-formed.
450
 
451
  ``` cpp
452
+ constexpr long use_count() const noexcept;
453
  ```
454
 
455
  *Synchronization:* None.
456
 
457
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
 
467
  `use_count()`, the result is approximate. In particular,
468
  `use_count() == 1` does not imply that accesses through a previously
469
  destroyed `shared_ptr` have in any sense completed. — *end note*]
470
 
471
  ``` cpp
472
+ constexpr explicit operator bool() const noexcept;
473
  ```
474
 
475
  *Returns:* `get() != nullptr`.
476
 
477
  ``` cpp
478
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
479
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
480
  ```
481
 
482
  *Returns:* An unspecified value such that
483
 
484
+ - `owner_before(b)` defines a strict weak ordering as defined
485
  in  [[alg.sorting]];
486
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
487
+ `owner_equal(b)` is `true`.
488
+
489
+ ``` cpp
490
+ size_t owner_hash() const noexcept;
491
+ ```
492
+
493
+ *Returns:* An unspecified value such that, for any object `x` where
494
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
495
+
496
+ ``` cpp
497
+ template<class U>
498
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
499
+ template<class U>
500
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
501
+ ```
502
+
503
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
504
+ both empty. Otherwise returns `false`.
505
+
506
+ *Remarks:* `owner_equal` is an equivalence relation.
507
 
508
  ##### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
509
 
510
  The common requirements that apply to all `make_shared`,
511
  `allocate_shared`, `make_shared_for_overwrite`, and
512
  `allocate_shared_for_overwrite` overloads, unless specified otherwise,
513
  are described below.
514
 
515
  ``` cpp
516
  template<class T, ...>
517
+ constexpr shared_ptr<T> make_shared(args);
518
  template<class T, class A, ...>
519
+ constexpr shared_ptr<T> allocate_shared(const A& a, args);
520
  template<class T, ...>
521
+ constexpr shared_ptr<T> make_shared_for_overwrite(args);
522
  template<class T, class A, ...>
523
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
524
  ```
525
 
526
  *Preconditions:* `A` meets the *Cpp17Allocator*
527
  requirements [[allocator.requirements.general]].
528
 
 
563
  suitable to hold an object of type `U`.
564
  - When a (sub)object of a non-array type `U` is specified to have an
565
  initial value of `v`, or `U(l...)`, where `l...` is a list of
566
  constructor arguments, `allocate_shared` shall initialize this
567
  (sub)object via the expression
568
+ - `allocator_traits<A2>::construct(a2, pu, v)` or
569
+ - `allocator_traits<A2>::construct(a2, pu, l...)`
570
 
571
+ respectively, where `pu` is a pointer of type `remove_cv_t<U>*`
572
+ pointing to storage suitable to hold an object of type
573
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
574
+ of the allocator `a` passed to `allocate_shared`.
575
  - When a (sub)object of non-array type `U` is specified to have a
576
  default initial value, `make_shared` shall initialize this (sub)object
577
  via the expression `::new(pv) U()`, where `pv` has type `void*` and
578
  points to storage suitable to hold an object of type `U`.
579
  - When a (sub)object of non-array type `U` is specified to have a
580
+ default initial value, `allocate_shared` initializes this (sub)object
581
+ via the expression `allocator_traits<A2>::construct(a2, pu)`, where
582
+ `pu` is a pointer of type `remove_cv_t<U>*` pointing to storage
583
+ suitable to hold an object of type `remove_cv_t<U>` and `a2` of type
584
+ `A2` is a potentially rebound copy of the allocator `a` passed to
585
+ `allocate_shared`.
586
  - When a (sub)object of non-array type `U` is initialized by
587
  `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
588
  initialized via the expression `::new(pv) U`, where `pv` has type
589
  `void*` and points to storage suitable to hold an object of type `U`.
590
  - Array elements are initialized in ascending order of their addresses.
591
  - When the lifetime of the object managed by the return value ends, or
592
  when the initialization of an array element throws an exception, the
593
  initialized elements are destroyed in the reverse order of their
594
  original construction.
595
  - When a (sub)object of non-array type `U` that was initialized by
596
+ `make_shared`, `make_shared_for_overwrite`, or
597
+ `allocate_shared_for_overwrite` is to be destroyed, it is destroyed
598
+ via the expression `pu->~U()` where `pu` points to that object of type
599
+ `U`.
600
  - When a (sub)object of non-array type `U` that was initialized by
601
  `allocate_shared` is to be destroyed, it is destroyed via the
602
+ expression `allocator_traits<A2>::destroy(a2, pu)` where `pu` is a
603
+ pointer of type `remove_cv_t<U>*` pointing to that object of type
604
+ `remove_cv_t<U>` and `a2` of type `A2` is a potentially rebound copy
605
+ of the allocator `a` passed to `allocate_shared`.
606
 
607
  [*Note 7*: These functions will typically allocate more memory than
608
  `sizeof(T)` to allow for internal bookkeeping structures such as
609
  reference counts. — *end note*]
610
 
611
  ``` cpp
612
  template<class T, class... Args>
613
+ constexpr shared_ptr<T> make_shared(Args&&... args); // T is not array
614
  template<class T, class A, class... Args>
615
+ constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
616
  ```
617
 
618
  *Constraints:* `T` is not an array type.
619
 
620
  *Returns:* A `shared_ptr` to an object of type `T` with an initial value
 
633
  ```
634
 
635
  — *end example*]
636
 
637
  ``` cpp
638
+ template<class T>
639
+ constexpr shared_ptr<T> make_shared(size_t N); // T is U[]
640
  template<class T, class A>
641
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
642
  ```
643
 
644
  *Constraints:* `T` is of the form `U[]`.
645
 
646
  *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
 
657
 
658
  — *end example*]
659
 
660
  ``` cpp
661
  template<class T>
662
+ constexpr shared_ptr<T> make_shared(); // T is U[N]
663
  template<class T, class A>
664
+ constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]
665
  ```
666
 
667
  *Constraints:* `T` is of the form `U[N]`.
668
 
669
  *Returns:* A `shared_ptr` to an object of type `T` with a default
 
680
 
681
  — *end example*]
682
 
683
  ``` cpp
684
  template<class T>
685
+ constexpr shared_ptr<T> make_shared(size_t N,
686
  const remove_extent_t<T>& u); // T is U[]
687
  template<class T, class A>
688
+ constexpr shared_ptr<T> allocate_shared(const A& a, size_t N,
689
  const remove_extent_t<T>& u); // T is U[]
690
  ```
691
 
692
  *Constraints:* `T` is of the form `U[]`.
693
 
 
707
 
708
  — *end example*]
709
 
710
  ``` cpp
711
  template<class T>
712
+ constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
713
  template<class T, class A>
714
+ constexpr shared_ptr<T> allocate_shared(const A& a,
715
  const remove_extent_t<T>& u); // T is U[N]
716
  ```
717
 
718
  *Constraints:* `T` is of the form `U[N]`.
719
 
 
733
 
734
  — *end example*]
735
 
736
  ``` cpp
737
  template<class T>
738
+ constexpr shared_ptr<T> make_shared_for_overwrite();
739
  template<class T, class A>
740
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a);
741
  ```
742
 
743
  *Constraints:* `T` is not an array of unknown bound.
744
 
745
  *Returns:* A `shared_ptr` to an object of type `T`.
 
757
 
758
  — *end example*]
759
 
760
  ``` cpp
761
  template<class T>
762
+ constexpr shared_ptr<T> make_shared_for_overwrite(size_t N);
763
  template<class T, class A>
764
+ constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
765
  ```
766
 
767
  *Constraints:* `T` is an array of unknown bound.
768
 
769
  *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
 
780
 
781
  ##### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
782
 
783
  ``` cpp
784
  template<class T, class U>
785
+ constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
786
  ```
787
 
788
  *Returns:* `a.get() == b.get()`.
789
 
790
  ``` cpp
791
  template<class T>
792
+ constexpr bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
793
  ```
794
 
795
  *Returns:* `!a`.
796
 
797
  ``` cpp
798
  template<class T, class U>
799
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
800
  ```
801
 
802
  *Returns:* `compare_three_way()(a.get(), b.get())`.
803
 
804
  [*Note 8*: Defining a comparison operator function allows `shared_ptr`
805
  objects to be used as keys in associative containers. — *end note*]
806
 
807
  ``` cpp
808
  template<class T>
809
+ constexpr strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
810
  ```
811
 
812
  *Returns:*
813
 
814
  ``` cpp
815
+ compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))
816
  ```
817
 
818
  ##### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
819
 
820
  ``` cpp
821
  template<class T>
822
+ constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
823
  ```
824
 
825
  *Effects:* Equivalent to `a.swap(b)`.
826
 
827
  ##### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
828
 
829
  ``` cpp
830
  template<class T, class U>
831
+ constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
832
  template<class T, class U>
833
+ constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
834
  ```
835
 
836
  *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
837
  well-formed.
838
 
 
844
 
845
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
846
  second.
847
 
848
  [*Note 9*: The seemingly equivalent expression
849
+ `shared_ptr<T>(static_cast<T*>(r.get()))` can result in undefined
850
+ behavior, attempting to delete the same object twice. — *end note*]
 
851
 
852
  ``` cpp
853
  template<class T, class U>
854
+ constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
855
  template<class T, class U>
856
+ constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
857
  ```
858
 
859
  *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
860
  well-formed. The expression
861
  `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is
 
871
  returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
872
  is `r` for the first overload, and `std::move(r)` for the second.
873
  - Otherwise, `shared_ptr<T>()`.
874
 
875
  [*Note 10*: The seemingly equivalent expression
876
+ `shared_ptr<T>(dynamic_cast<T*>(r.get()))` can result in undefined
877
+ behavior, attempting to delete the same object twice. — *end note*]
 
878
 
879
  ``` cpp
880
  template<class T, class U>
881
+ constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
882
  template<class T, class U>
883
+ constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
884
  ```
885
 
886
  *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
887
 
888
  *Returns:*
 
893
 
894
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
895
  second.
896
 
897
  [*Note 11*: The seemingly equivalent expression
898
+ `shared_ptr<T>(const_cast<T*>(r.get()))` can result in undefined
899
+ behavior, attempting to delete the same object twice. — *end note*]
 
900
 
901
  ``` cpp
902
  template<class T, class U>
903
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
904
  template<class T, class U>
 
916
 
917
  where *`R`* is `r` for the first overload, and `std::move(r)` for the
918
  second.
919
 
920
  [*Note 12*: The seemingly equivalent expression
921
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` can result in undefined
922
+ behavior, attempting to delete the same object twice. — *end note*]
 
923
 
924
  ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
925
 
926
  ``` cpp
927
  template<class D, class T>
928
+ constexpr D* get_deleter(const shared_ptr<T>& p) noexcept;
929
  ```
930
 
931
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
932
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
933
  remains valid as long as there exists a `shared_ptr` instance that owns
 
964
  using element_type = remove_extent_t<T>;
965
 
966
  // [util.smartptr.weak.const], constructors
967
  constexpr weak_ptr() noexcept;
968
  template<class Y>
969
+ constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
970
+ constexpr weak_ptr(const weak_ptr& r) noexcept;
971
  template<class Y>
972
+ constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
973
+ constexpr weak_ptr(weak_ptr&& r) noexcept;
974
  template<class Y>
975
+ constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
976
 
977
  // [util.smartptr.weak.dest], destructor
978
+ constexpr ~weak_ptr();
979
 
980
  // [util.smartptr.weak.assign], assignment
981
+ constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
982
  template<class Y>
983
+ constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
984
  template<class Y>
985
+ constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
986
+ constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
987
  template<class Y>
988
+ constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
989
 
990
  // [util.smartptr.weak.mod], modifiers
991
+ constexpr void swap(weak_ptr& r) noexcept;
992
+ constexpr void reset() noexcept;
993
 
994
  // [util.smartptr.weak.obs], observers
995
+ constexpr long use_count() const noexcept;
996
+ constexpr bool expired() const noexcept;
997
+ constexpr shared_ptr<T> lock() const noexcept;
998
  template<class U>
999
+ constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
1000
  template<class U>
1001
+ constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
1002
+ size_t owner_hash() const noexcept;
1003
+ template<class U>
1004
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
1005
+ template<class U>
1006
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
1007
  };
1008
 
1009
  template<class T>
1010
  weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
1011
  }
 
1025
  pointer value.
1026
 
1027
  *Ensures:* `use_count() == 0`.
1028
 
1029
  ``` cpp
1030
+ constexpr weak_ptr(const weak_ptr& r) noexcept;
1031
+ template<class Y> constexpr weak_ptr(const weak_ptr<Y>& r) noexcept;
1032
+ template<class Y> constexpr weak_ptr(const shared_ptr<Y>& r) noexcept;
1033
  ```
1034
 
1035
  *Constraints:* For the second and third constructors, `Y*` is compatible
1036
  with `T*`.
1037
 
 
1041
  in `r`.
1042
 
1043
  *Ensures:* `use_count() == r.use_count()`.
1044
 
1045
  ``` cpp
1046
+ constexpr weak_ptr(weak_ptr&& r) noexcept;
1047
+ template<class Y> constexpr weak_ptr(weak_ptr<Y>&& r) noexcept;
1048
  ```
1049
 
1050
  *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
1051
 
1052
  *Effects:* Move constructs a `weak_ptr` instance from `r`.
 
1055
  null pointer value, and `r.use_count() == 0`.
1056
 
1057
  ##### Destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
1058
 
1059
  ``` cpp
1060
+ constexpr ~weak_ptr();
1061
  ```
1062
 
1063
  *Effects:* Destroys this `weak_ptr` object but has no effect on the
1064
  object its stored pointer points to.
1065
 
1066
  ##### Assignment <a id="util.smartptr.weak.assign">[[util.smartptr.weak.assign]]</a>
1067
 
1068
  ``` cpp
1069
+ constexpr weak_ptr& operator=(const weak_ptr& r) noexcept;
1070
+ template<class Y> constexpr weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
1071
+ template<class Y> constexpr weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
1072
  ```
1073
 
1074
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
1075
 
1076
  *Returns:* `*this`.
1077
 
1078
  *Remarks:* The implementation may meet the effects (and the implied
1079
  guarantees) via different means, without creating a temporary object.
1080
 
1081
  ``` cpp
1082
+ constexpr weak_ptr& operator=(weak_ptr&& r) noexcept;
1083
+ template<class Y> constexpr weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
1084
  ```
1085
 
1086
  *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
1087
 
1088
  *Returns:* `*this`.
1089
 
1090
  ##### Modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
1091
 
1092
  ``` cpp
1093
+ constexpr void swap(weak_ptr& r) noexcept;
1094
  ```
1095
 
1096
  *Effects:* Exchanges the contents of `*this` and `r`.
1097
 
1098
  ``` cpp
1099
+ constexpr void reset() noexcept;
1100
  ```
1101
 
1102
  *Effects:* Equivalent to `weak_ptr().swap(*this)`.
1103
 
1104
  ##### Observers <a id="util.smartptr.weak.obs">[[util.smartptr.weak.obs]]</a>
1105
 
1106
  ``` cpp
1107
+ constexpr long use_count() const noexcept;
1108
  ```
1109
 
1110
  *Returns:* `0` if `*this` is empty; otherwise, the number of
1111
  `shared_ptr` instances that share ownership with `*this`.
1112
 
1113
  ``` cpp
1114
+ constexpr bool expired() const noexcept;
1115
  ```
1116
 
1117
  *Returns:* `use_count() == 0`.
1118
 
1119
  ``` cpp
1120
+ constexpr shared_ptr<T> lock() const noexcept;
1121
  ```
1122
 
1123
  *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
1124
  executed atomically.
1125
 
1126
  ``` cpp
1127
+ template<class U> constexpr bool owner_before(const shared_ptr<U>& b) const noexcept;
1128
+ template<class U> constexpr bool owner_before(const weak_ptr<U>& b) const noexcept;
1129
  ```
1130
 
1131
  *Returns:* An unspecified value such that
1132
 
1133
+ - `owner_before(b)` defines a strict weak ordering as defined
1134
  in  [[alg.sorting]];
1135
+ - `!owner_before(b) && !b.owner_before(*this)` is `true` if and only if
1136
+ `owner_equal(b)` is `true`.
1137
+
1138
+ ``` cpp
1139
+ size_t owner_hash() const noexcept;
1140
+ ```
1141
+
1142
+ *Returns:* An unspecified value such that, for any object `x` where
1143
+ `owner_equal(x)` is `true`, `owner_hash() == x.owner_hash()` is `true`.
1144
+
1145
+ ``` cpp
1146
+ template<class U>
1147
+ constexpr bool owner_equal(const shared_ptr<U>& b) const noexcept;
1148
+ template<class U>
1149
+ constexpr bool owner_equal(const weak_ptr<U>& b) const noexcept;
1150
+ ```
1151
+
1152
+ *Returns:* `true` if and only if `*this` and `b` share ownership or are
1153
+ both empty. Otherwise returns `false`.
1154
+
1155
+ *Remarks:* `owner_equal` is an equivalence relation.
1156
 
1157
  ##### Specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
1158
 
1159
  ``` cpp
1160
  template<class T>
1161
+ constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
1162
  ```
1163
 
1164
  *Effects:* Equivalent to `a.swap(b)`.
1165
 
1166
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
 
1171
  ``` cpp
1172
  namespace std {
1173
  template<class T = void> struct owner_less;
1174
 
1175
  template<class T> struct owner_less<shared_ptr<T>> {
1176
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
1177
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
1178
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
1179
  };
1180
 
1181
  template<class T> struct owner_less<weak_ptr<T>> {
1182
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
1183
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
1184
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
1185
  };
1186
 
1187
  template<> struct owner_less<void> {
1188
  template<class T, class U>
1189
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
1190
  template<class T, class U>
1191
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
1192
  template<class T, class U>
1193
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
1194
  template<class T, class U>
1195
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
1196
 
1197
  using is_transparent = unspecified;
1198
  };
1199
  }
1200
  ```
 
1205
 
1206
  Note that
1207
 
1208
  - `operator()` defines a strict weak ordering as defined in 
1209
  [[alg.sorting]];
1210
+ - `!operator()(a, b) && !operator()(b, a)` is `true` if and only if
1211
+ `a.owner_equal(b)` is `true`.
 
 
1212
 
1213
  — *end note*]
1214
 
1215
+ #### Struct `owner_hash` <a id="util.smartptr.owner.hash">[[util.smartptr.owner.hash]]</a>
1216
+
1217
+ The class `owner_hash` provides ownership-based hashing.
1218
+
1219
+ ``` cpp
1220
+ namespace std {
1221
+ struct owner_hash {
1222
+ template<class T>
1223
+ size_t operator()(const shared_ptr<T>&) const noexcept;
1224
+
1225
+ template<class T>
1226
+ size_t operator()(const weak_ptr<T>&) const noexcept;
1227
+
1228
+ using is_transparent = unspecified;
1229
+ };
1230
+ }
1231
+ ```
1232
+
1233
+ ``` cpp
1234
+ template<class T>
1235
+ size_t operator()(const shared_ptr<T>& x) const noexcept;
1236
+ template<class T>
1237
+ size_t operator()(const weak_ptr<T>& x) const noexcept;
1238
+ ```
1239
+
1240
+ *Returns:* `x.owner_hash()`.
1241
+
1242
+ [*Note 1*: For any object `y` where `x.owner_equal(y)` is `true`,
1243
+ `x.owner_hash() == y.owner_hash()` is `true`. — *end note*]
1244
+
1245
+ #### Struct `owner_equal` <a id="util.smartptr.owner.equal">[[util.smartptr.owner.equal]]</a>
1246
+
1247
+ The class `owner_equal` provides ownership-based mixed equality
1248
+ comparisons of shared and weak pointers.
1249
+
1250
+ ``` cpp
1251
+ namespace std {
1252
+ struct owner_equal {
1253
+ template<class T, class U>
1254
+ constexpr bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
1255
+ template<class T, class U>
1256
+ constexpr bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
1257
+ template<class T, class U>
1258
+ constexpr bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
1259
+ template<class T, class U>
1260
+ constexpr bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
1261
+
1262
+ using is_transparent = unspecified;
1263
+ };
1264
+ }
1265
+ ```
1266
+
1267
+ ``` cpp
1268
+ template<class T, class U>
1269
+ constexpr bool operator()(const shared_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
1270
+ template<class T, class U>
1271
+ constexpr bool operator()(const shared_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
1272
+ template<class T, class U>
1273
+ constexpr bool operator()(const weak_ptr<T>& x, const shared_ptr<U>& y) const noexcept;
1274
+ template<class T, class U>
1275
+ constexpr bool operator()(const weak_ptr<T>& x, const weak_ptr<U>& y) const noexcept;
1276
+ ```
1277
+
1278
+ *Returns:* `x.owner_equal(y)`.
1279
+
1280
+ [*Note 1*: `x.owner_equal(y)` is `true` if and only if `x` and `y`
1281
+ share ownership or are both empty. — *end note*]
1282
+
1283
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
1284
 
1285
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
1286
  `shared_from_this` member functions that obtain a `shared_ptr` instance
1287
  pointing to `*this`.
 
1293
 
1294
  int main() {
1295
  shared_ptr<X> p(new X);
1296
  shared_ptr<X> q = p->shared_from_this();
1297
  assert(p == q);
1298
+ assert(p.owner_equal(q)); // p and q share ownership
1299
  }
1300
  ```
1301
 
1302
  — *end example*]
1303
 
1304
  ``` cpp
1305
  namespace std {
1306
  template<class T> class enable_shared_from_this {
1307
  protected:
1308
  constexpr enable_shared_from_this() noexcept;
1309
+ constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept;
1310
+ constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
1311
+ constexpr ~enable_shared_from_this();
1312
 
1313
  public:
1314
+ constexpr shared_ptr<T> shared_from_this();
1315
+ constexpr shared_ptr<T const> shared_from_this() const;
1316
+ constexpr weak_ptr<T> weak_from_this() noexcept;
1317
+ constexpr weak_ptr<T const> weak_from_this() const noexcept;
1318
 
1319
  private:
1320
+ mutable weak_ptr<T> weak-this; // exposition only
1321
  };
1322
  }
1323
  ```
1324
 
1325
  The template parameter `T` of `enable_shared_from_this` may be an
1326
  incomplete type.
1327
 
1328
  ``` cpp
1329
  constexpr enable_shared_from_this() noexcept;
1330
+ constexpr enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
1331
  ```
1332
 
1333
+ *Effects:* Value-initializes *weak-this*.
1334
 
1335
  ``` cpp
1336
+ constexpr enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
1337
  ```
1338
 
1339
  *Returns:* `*this`.
1340
 
1341
+ [*Note 1*: *weak-this* is not changed. — *end note*]
1342
 
1343
  ``` cpp
1344
+ constexpr shared_ptr<T> shared_from_this();
1345
+ constexpr shared_ptr<T const> shared_from_this() const;
1346
  ```
1347
 
1348
+ *Returns:* `shared_ptr<T>(`*`weak-this`*`)`.
1349
 
1350
  ``` cpp
1351
+ constexpr weak_ptr<T> weak_from_this() noexcept;
1352
+ constexpr weak_ptr<T const> weak_from_this() const noexcept;
1353
  ```
1354
 
1355
+ *Returns:* *weak-this*.
1356