From Jason Turner

[util.smartptr.shared]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp9__7q8st/{from.md → to.md} +266 -172
tmp/tmp9__7q8st/{from.md → to.md} RENAMED
@@ -2,70 +2,73 @@
2
 
3
  The `shared_ptr` class template stores a pointer, usually obtained via
4
  `new`. `shared_ptr` implements semantics of shared ownership; the last
5
  remaining owner of the pointer is responsible for destroying the object,
6
  or otherwise releasing the resources associated with the stored pointer.
7
- A `shared_ptr` object is *empty* if it does not own a pointer.
8
 
9
  ``` cpp
10
  namespace std {
11
  template<class T> class shared_ptr {
12
  public:
13
- typedef T element_type;
 
14
 
15
- // [util.smartptr.shared.const], constructors:
16
  constexpr shared_ptr() noexcept;
17
  template<class Y> explicit shared_ptr(Y* p);
18
  template<class Y, class D> shared_ptr(Y* p, D d);
19
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
20
  template <class D> shared_ptr(nullptr_t p, D d);
21
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
22
- template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
23
  shared_ptr(const shared_ptr& r) noexcept;
24
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
25
  shared_ptr(shared_ptr&& r) noexcept;
26
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
27
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
28
- template<class Y> shared_ptr(auto_ptr<Y>&& r);
29
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
30
- constexpr shared_ptr(nullptr_t) : shared_ptr() { }
31
 
32
- // [util.smartptr.shared.dest], destructor:
33
  ~shared_ptr();
34
 
35
- // [util.smartptr.shared.assign], assignment:
36
  shared_ptr& operator=(const shared_ptr& r) noexcept;
37
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
38
  shared_ptr& operator=(shared_ptr&& r) noexcept;
39
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
40
- template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
41
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
42
 
43
- // [util.smartptr.shared.mod], modifiers:
44
  void swap(shared_ptr& r) noexcept;
45
  void reset() noexcept;
46
  template<class Y> void reset(Y* p);
47
  template<class Y, class D> void reset(Y* p, D d);
48
  template<class Y, class D, class A> void reset(Y* p, D d, A a);
49
 
50
- // [util.smartptr.shared.obs], observers:
51
- T* get() const noexcept;
52
  T& operator*() const noexcept;
53
  T* operator->() const noexcept;
 
54
  long use_count() const noexcept;
55
- bool unique() const noexcept;
56
  explicit operator bool() const noexcept;
57
- template<class U> bool owner_before(shared_ptr<U> const& b) const;
58
- template<class U> bool owner_before(weak_ptr<U> const& b) const;
59
  };
60
 
 
 
 
61
  // [util.smartptr.shared.create], shared_ptr creation
62
- template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
 
63
  template<class T, class A, class... Args>
64
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
65
 
66
- // [util.smartptr.shared.cmp], shared_ptr comparisons:
67
  template<class T, class U>
68
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
69
  template<class T, class U>
70
  bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
71
  template<class T, class U>
@@ -100,218 +103,252 @@ namespace std {
100
  template <class T>
101
  bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
102
  template <class T>
103
  bool operator>=(nullptr_t, const shared_ptr<T>& b) noexcept;
104
 
105
- // [util.smartptr.shared.spec], shared_ptr specialized algorithms:
106
- template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
 
107
 
108
- // [util.smartptr.shared.cast], shared_ptr casts:
109
  template<class T, class U>
110
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
111
  template<class T, class U>
112
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
113
  template<class T, class U>
114
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
 
 
115
 
116
- // [util.smartptr.getdeleter], shared_ptr get_deleter:
117
- template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
 
118
 
119
- // [util.smartptr.shared.io], shared_ptr I/O:
120
  template<class E, class T, class Y>
121
  basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
122
- } // namespace std
123
  ```
124
 
125
  Specializations of `shared_ptr` shall be `CopyConstructible`,
126
  `CopyAssignable`, and `LessThanComparable`, allowing their use in
127
  standard containers. Specializations of `shared_ptr` shall be
128
- convertible to `bool`, allowing their use in boolean expressions and
129
- declarations in conditions. The template parameter `T` of `shared_ptr`
130
- may be an incomplete type.
 
 
131
 
132
  ``` cpp
133
  if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
134
  // do something with px
135
  }
136
  ```
137
 
 
 
138
  For purposes of determining the presence of a data race, member
139
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
140
  objects themselves and not objects they refer to. Changes in
141
  `use_count()` do not reflect modifications that can introduce data
142
  races.
143
 
 
 
 
 
144
  ##### `shared_ptr` constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  ``` cpp
147
  constexpr shared_ptr() noexcept;
148
  ```
149
 
150
- *Effects:* Constructs an *empty* `shared_ptr` object.
151
 
152
  *Postconditions:* `use_count() == 0 && get() == nullptr`.
153
 
154
  ``` cpp
155
  template<class Y> explicit shared_ptr(Y* p);
156
  ```
157
 
158
- *Requires:* `p` shall be convertible to `T*`. `Y` shall be a complete
159
- type. The expression `delete p` shall be well formed, shall have well
160
- defined behavior, and shall not throw exceptions.
161
 
162
- *Effects:* Constructs a `shared_ptr` object that *owns* the pointer `p`.
 
 
 
 
 
163
 
164
  *Postconditions:* `use_count() == 1 && get() == p`.
165
 
166
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
167
  resource other than memory could not be obtained.
168
 
169
- If an exception is thrown, `delete p` is called.
 
 
 
 
 
 
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
- *Requires:* `p` shall be convertible to `T*`. `D` shall be
179
- `CopyConstructible`. The copy constructor and destructor of ` D` shall
180
- not throw exceptions. The expression `d(p)` shall be well formed, shall
181
- have well defined behavior, and shall not throw exceptions. `A` shall be
182
- an allocator ([[allocator.requirements]]). The copy constructor and
183
- destructor of `A` shall not throw exceptions.
184
 
185
- *Effects:* Constructs a `shared_ptr` object that *owns* the object `p`
186
- and the deleter `d`. The second and fourth constructors shall use a copy
187
- of `a` to allocate memory for internal use.
 
 
188
 
189
  *Postconditions:* `use_count() == 1 && get() == p`.
190
 
191
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
192
  resource other than memory could not be obtained.
193
 
194
- If an exception is thrown, `d(p)` is called.
 
 
 
 
 
 
 
195
 
196
  ``` cpp
197
- template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
198
  ```
199
 
200
- *Effects:* Constructs a `shared_ptr` instance that stores `p` and
201
- *shares ownership* with `r`.
202
 
203
- *Postconditions:* `get() == p && use_count() == r.use_count()`
204
 
205
- To avoid the possibility of a dangling pointer, the user of this
206
- constructor must ensure that `p` remains valid at least until the
207
- ownership group of `r` is destroyed.
208
 
209
- This constructor allows creation of an *empty* `shared_ptr` instance
210
- with a non-null stored pointer.
211
 
212
  ``` cpp
213
  shared_ptr(const shared_ptr& r) noexcept;
214
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
215
  ```
216
 
217
- The second constructor shall not participate in overload resolution
218
- unless `Y*` is implicitly convertible to `T*`.
219
 
220
- *Effects:* If `r` is *empty*, constructs an *empty* `shared_ptr` object;
221
- otherwise, constructs a `shared_ptr` object that *shares ownership* with
222
  `r`.
223
 
224
  *Postconditions:* `get() == r.get() && use_count() == r.use_count()`.
225
 
226
  ``` cpp
227
  shared_ptr(shared_ptr&& r) noexcept;
228
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
229
  ```
230
 
231
- The second constructor shall not participate in overload resolution
232
- unless `Y*` is convertible to `T*`.
233
 
234
- *Effects:* Move-constructs a `shared_ptr` instance from `r`.
235
 
236
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
237
- be *empty*. `r.get() == nullptr.`
238
 
239
  ``` cpp
240
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
241
  ```
242
 
243
- *Requires:* `Y*` shall be convertible to `T*`.
244
-
245
- *Effects:* Constructs a `shared_ptr` object that *shares ownership* with
246
- `r` and stores a copy of the pointer stored in `r`.
247
 
248
  *Postconditions:* `use_count() == r.use_count()`.
249
 
250
  *Throws:* `bad_weak_ptr` when `r.expired()`.
251
 
252
- If an exception is thrown, the constructor has no effect.
253
-
254
- ``` cpp
255
- template<class Y> shared_ptr(auto_ptr<Y>&& r);
256
- ```
257
-
258
- *Requires:* `r.release()` shall be convertible to `T*`. `Y` shall be a
259
- complete type. The expression `delete r.release()` shall be well formed,
260
- shall have well defined behavior, and shall not throw exceptions.
261
-
262
- *Effects:* Constructs a `shared_ptr` object that stores and *owns*
263
- `r.release()`.
264
-
265
- *Postconditions:* `use_count() == 1` `&&` `r.get() == nullptr`.
266
-
267
- *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
268
- resource other than memory could not be obtained.
269
-
270
- If an exception is thrown, the constructor has no effect.
271
 
272
  ``` cpp
273
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
274
  ```
275
 
276
- *Effects:* Equivalent to `shared_ptr(r.release(), r.get_deleter())` when
277
- `D` is not a reference type, otherwise
278
- `shared_ptr(r.release(), ref(r.get_deleter()))`.
279
 
280
- If an exception is thrown, the constructor has no effect.
 
 
 
 
281
 
282
  ##### `shared_ptr` destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
283
 
284
  ``` cpp
285
  ~shared_ptr();
286
  ```
287
 
288
  *Effects:*
289
 
290
- - If `*this` is *empty* or shares ownership with another `shared_ptr`
291
  instance (`use_count() > 1`), there are no side effects.
292
- - Otherwise, if `*this` *owns* an object `p` and a deleter `d`, `d(p)`
293
- is called.
294
- - Otherwise, `*this` *owns* a pointer `p`, and `delete p` is called.
295
 
296
- Since the destruction of `*this` decreases the number of instances that
297
- share ownership with `*this` by one, after `*this` has been destroyed
298
- all `shared_ptr` instances that shared ownership with `*this` will
299
- report a `use_count()` that is one less than its previous value.
 
300
 
301
  ##### `shared_ptr` assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
302
 
303
  ``` cpp
304
  shared_ptr& operator=(const shared_ptr& r) noexcept;
305
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
306
- template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
307
  ```
308
 
309
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
310
 
311
  *Returns:* `*this`.
312
 
 
 
313
  The use count updates caused by the temporary object construction and
314
  destruction are not observable side effects, so the implementation may
315
  meet the effects (and the implied guarantees) via different means,
316
  without creating a temporary. In particular, in the example:
317
 
@@ -322,10 +359,12 @@ p = p;
322
  q = p;
323
  ```
324
 
325
  both assignments may be no-ops.
326
 
 
 
327
  ``` cpp
328
  shared_ptr& operator=(shared_ptr&& r) noexcept;
329
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
330
  ```
331
 
@@ -337,11 +376,11 @@ template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
337
  template <class Y, class D> 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
  ##### `shared_ptr` modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
345
 
346
  ``` cpp
347
  void swap(shared_ptr& r) noexcept;
@@ -374,64 +413,87 @@ template<class Y, class D, class A> void reset(Y* p, D d, A a);
374
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
375
 
376
  ##### `shared_ptr` observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
377
 
378
  ``` cpp
379
- T* get() const noexcept;
380
  ```
381
 
382
- *Returns:* the stored pointer.
383
 
384
  ``` cpp
385
  T& operator*() const noexcept;
386
  ```
387
 
388
  *Requires:* `get() != 0`.
389
 
390
  *Returns:* `*get()`.
391
 
392
- *Remarks:* When `T` is `void`, it is unspecified whether this member
393
- function is declared. If it is declared, it is unspecified what its
394
- return type is, except that the declaration (although not necessarily
395
- the definition) of the function shall be well formed.
 
396
 
397
  ``` cpp
398
  T* operator->() const noexcept;
399
  ```
400
 
401
  *Requires:* `get() != 0`.
402
 
403
  *Returns:* `get()`.
404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  ``` cpp
406
  long use_count() const noexcept;
407
  ```
408
 
409
- *Returns:* the number of `shared_ptr` objects, `*this` included, that
410
- *share ownership* with `*this`, or `0` when `*this` is *empty*.
411
 
412
- `use_count()` is not necessarily efficient.
413
 
414
- ``` cpp
415
- bool unique() const noexcept;
416
- ```
417
 
418
- *Returns:* `use_count() == 1`.
 
419
 
420
- `unique()` may be faster than `use_count()`. If you are using `unique()`
421
- to implement copy on write, do not rely on a specific value when
422
- `get() == nullptr`.
 
 
423
 
424
  ``` cpp
425
  explicit operator bool() const noexcept;
426
  ```
427
 
428
  *Returns:* `get() != 0`.
429
 
430
  ``` cpp
431
- template<class U> bool owner_before(shared_ptr<U> const& b) const;
432
- template<class U> bool owner_before(weak_ptr<U> const& b) const;
433
  ```
434
 
435
  *Returns:* An unspecified value such that
436
 
437
  - `x.owner_before(y)` defines a strict weak ordering as defined
@@ -442,59 +504,66 @@ template<class U> bool owner_before(weak_ptr<U> const& b) const;
442
  ownership or are both empty.
443
 
444
  ##### `shared_ptr` creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
445
 
446
  ``` cpp
447
- template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
 
448
  template<class T, class A, class... Args>
449
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
450
  ```
451
 
452
  *Requires:* The expression `::new (pv) T(std::forward<Args>(args)...)`,
453
  where `pv` has type `void*` and points to storage suitable to hold an
454
  object of type `T`, shall be well formed. `A` shall be an
455
- *allocator* ([[allocator.requirements]]). The copy constructor and
456
  destructor of `A` shall not throw exceptions.
457
 
458
  *Effects:* Allocates memory suitable for an object of type `T` and
459
- constructs an object in that memory via the placement new expression
460
  `::new (pv) T(std::forward<Args>(args)...)`. The template
461
  `allocate_shared` uses a copy of `a` to allocate memory. If an exception
462
  is thrown, the functions have no effect.
463
 
464
  *Returns:* A `shared_ptr` instance that stores and owns the address of
465
  the newly constructed object of type `T`.
466
 
467
- *Postconditions:* `get() != 0 && use_count() == 1`
468
 
469
  *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
470
  the constructor of `T`.
471
 
472
- *Remarks:* Implementations should perform no more than one memory
473
- allocation. This provides efficiency equivalent to an intrusive smart
474
- pointer.
 
475
 
476
- These functions will typically allocate more memory than `sizeof(T)` to
477
- allow for internal bookkeeping structures such as the reference counts.
 
 
 
 
478
 
479
  ##### `shared_ptr` comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
480
 
481
  ``` cpp
482
- template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
483
  ```
484
 
485
  *Returns:* `a.get() == b.get()`.
486
 
487
  ``` cpp
488
- template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
489
  ```
490
 
491
- *Returns:* `less<V>()(a.get(), b.get())`, where `V` is the composite
492
- pointer type (Clause  [[expr]]) of `T*` and `U*`.
493
 
494
- Defining a comparison operator allows `shared_ptr` objects to be used as
495
- keys in associative containers.
496
 
497
  ``` cpp
498
  template <class T>
499
  bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
500
  template <class T>
@@ -518,12 +587,13 @@ template <class T>
518
  template <class T>
519
  bool operator<(nullptr_t, const shared_ptr<T>& a) noexcept;
520
  ```
521
 
522
  *Returns:* The first function template returns
523
- `less<T*>()(a.get(), nullptr)`. The second function template returns
524
- `less<T*>()(nullptr, a.get())`.
 
525
 
526
  ``` cpp
527
  template <class T>
528
  bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
529
  template <class T>
@@ -554,92 +624,116 @@ template <class T>
554
  second function template returns `!(nullptr < a)`.
555
 
556
  ##### `shared_ptr` specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
557
 
558
  ``` cpp
559
- template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
 
560
  ```
561
 
562
  *Effects:* Equivalent to `a.swap(b)`.
563
 
564
  ##### `shared_ptr` casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
565
 
566
  ``` cpp
567
- template<class T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
 
568
  ```
569
 
570
- *Requires:* The expression `static_cast<T*>(r.get())` shall be well
571
  formed.
572
 
573
- *Returns:* If `r` is *empty*, an *empty* `shared_ptr<T>`; otherwise, a
574
- `shared_ptr<T>` object that stores `static_cast<T*>(r.get())` and
575
- *shares ownership* with `r`.
576
 
577
- *Postconditions:* `w.get() == static_cast<T*>(r.get())` and
578
- `w.use_count() == r.use_count()`, where `w` is the return value.
 
579
 
580
- The seemingly equivalent expression
581
  `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
582
- undefined behavior, attempting to delete the same object twice.
 
583
 
584
  ``` cpp
585
- template<class T, class U> shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
 
586
  ```
587
 
588
- *Requires:* The expression `dynamic_cast<T*>(r.get())` shall be well
589
  formed and shall have well defined behavior.
590
 
591
  *Returns:*
592
 
593
- - When `dynamic_cast<T*>(r.get())` returns a nonzero value, a
594
- `shared_ptr<T>` object that stores a copy of it and *shares ownership*
595
- with `r`;
596
- - Otherwise, an *empty* `shared_ptr<T>` object.
597
 
598
- `w.get() == dynamic_cast<T*>(r.get())`, where `w` is the return value.
599
-
600
- The seemingly equivalent expression
601
  `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
602
- undefined behavior, attempting to delete the same object twice.
 
603
 
604
  ``` cpp
605
- template<class T, class U> shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
 
606
  ```
607
 
608
- *Requires:* The expression `const_cast<T*>(r.get())` shall be well
609
- formed.
610
 
611
- *Returns:* If `r` is empty, an empty `shared_ptr<T>`; otherwise, a
612
- `shared_ptr<T>` object that stores `const_cast<T*>(r.get())` and shares
613
- ownership with `r`.
614
 
615
- *Postconditions:* `w.get() == const_cast<T*>(r.get())` and
616
- `w.use_count() == r.use_count()`, where `w` is the return value.
 
617
 
618
- The seemingly equivalent expression
619
  `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
620
- undefined behavior, attempting to delete the same object twice.
 
621
 
622
- ##### get_deleter <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
 
624
  ``` cpp
625
- template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
 
626
  ```
627
 
628
- *Returns:* If `p` *owns* a deleter `d` of type cv-unqualified `D`,
629
- returns `&d`; otherwise returns `nullptr`. The returned pointer remains
630
- valid as long as there exists a `shared_ptr` instance that owns `d`. It
631
- is unspecified whether the pointer remains valid longer than that. This
632
- can happen if the implementation doesn’t destroy the deleter until all
633
- `weak_ptr` instances that share ownership with `p` have been destroyed.
 
 
 
634
 
635
  ##### `shared_ptr` I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
636
 
637
  ``` cpp
638
  template<class E, class T, class Y>
639
- basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
640
  ```
641
 
642
- *Effects:* `os << p.get();`.
643
 
644
  *Returns:* `os`.
645
 
 
2
 
3
  The `shared_ptr` class template stores a pointer, usually obtained via
4
  `new`. `shared_ptr` implements semantics of shared ownership; the last
5
  remaining owner of the pointer is responsible for destroying the object,
6
  or otherwise releasing the resources associated with the stored pointer.
7
+ A `shared_ptr` is said to be empty if it does not own a pointer.
8
 
9
  ``` cpp
10
  namespace std {
11
  template<class T> class shared_ptr {
12
  public:
13
+ using element_type = remove_extent_t<T>;
14
+ using weak_type = weak_ptr<T>;
15
 
16
+ // [util.smartptr.shared.const], constructors
17
  constexpr shared_ptr() noexcept;
18
  template<class Y> explicit shared_ptr(Y* p);
19
  template<class Y, class D> shared_ptr(Y* p, D d);
20
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
21
  template <class D> shared_ptr(nullptr_t p, D d);
22
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
23
+ template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
24
  shared_ptr(const shared_ptr& r) noexcept;
25
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
26
  shared_ptr(shared_ptr&& r) noexcept;
27
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
28
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
 
29
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
30
+ constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
31
 
32
+ // [util.smartptr.shared.dest], destructor
33
  ~shared_ptr();
34
 
35
+ // [util.smartptr.shared.assign], assignment
36
  shared_ptr& operator=(const shared_ptr& r) noexcept;
37
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
38
  shared_ptr& operator=(shared_ptr&& r) noexcept;
39
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
 
40
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
41
 
42
+ // [util.smartptr.shared.mod], modifiers
43
  void swap(shared_ptr& r) noexcept;
44
  void reset() noexcept;
45
  template<class Y> void reset(Y* p);
46
  template<class Y, class D> void reset(Y* p, D d);
47
  template<class Y, class D, class A> void reset(Y* p, D d, A a);
48
 
49
+ // [util.smartptr.shared.obs], observers
50
+ element_type* get() const noexcept;
51
  T& operator*() const noexcept;
52
  T* operator->() const noexcept;
53
+ element_type& operator[](ptrdiff_t i) const;
54
  long use_count() const noexcept;
 
55
  explicit operator bool() const noexcept;
56
+ template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
57
+ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
58
  };
59
 
60
+ template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
61
+ template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
62
+
63
  // [util.smartptr.shared.create], shared_ptr creation
64
+ template<class T, class... Args>
65
+ shared_ptr<T> make_shared(Args&&... args);
66
  template<class T, class A, class... Args>
67
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
68
 
69
+ // [util.smartptr.shared.cmp], shared_ptr comparisons
70
  template<class T, class U>
71
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
72
  template<class T, class U>
73
  bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
74
  template<class T, class U>
 
103
  template <class T>
104
  bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
105
  template <class T>
106
  bool operator>=(nullptr_t, const shared_ptr<T>& b) noexcept;
107
 
108
+ // [util.smartptr.shared.spec], shared_ptr specialized algorithms
109
+ template<class T>
110
+ void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
111
 
112
+ // [util.smartptr.shared.cast], shared_ptr casts
113
  template<class T, class U>
114
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
115
  template<class T, class U>
116
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
117
  template<class T, class U>
118
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
119
+ template<class T, class U>
120
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
121
 
122
+ // [util.smartptr.getdeleter], shared_ptr get_deleter
123
+ template<class D, class T>
124
+ D* get_deleter(const shared_ptr<T>& p) noexcept;
125
 
126
+ // [util.smartptr.shared.io], shared_ptr I/O
127
  template<class E, class T, class Y>
128
  basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
129
+ }
130
  ```
131
 
132
  Specializations of `shared_ptr` shall be `CopyConstructible`,
133
  `CopyAssignable`, and `LessThanComparable`, allowing their use in
134
  standard containers. Specializations of `shared_ptr` shall be
135
+ contextually convertible to `bool`, allowing their use in boolean
136
+ expressions and declarations in conditions. The template parameter `T`
137
+ of `shared_ptr` may be an incomplete type.
138
+
139
+ [*Example 1*:
140
 
141
  ``` cpp
142
  if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
143
  // do something with px
144
  }
145
  ```
146
 
147
+ — *end example*]
148
+
149
  For purposes of determining the presence of a data race, member
150
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
151
  objects themselves and not objects they refer to. Changes in
152
  `use_count()` do not reflect modifications that can introduce data
153
  races.
154
 
155
+ For the purposes of subclause [[util.smartptr]], a pointer type `Y*` is
156
+ said to be *compatible with* a pointer type `T*` when either `Y*` is
157
+ convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
158
+
159
  ##### `shared_ptr` constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
160
 
161
+ In the constructor definitions below, enables `shared_from_this` with
162
+ `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
163
+ unambiguous and accessible base class that is a specialization of
164
+ `enable_shared_from_this` ([[util.smartptr.enab]]), then
165
+ `remove_cv_t<Y>*` shall be implicitly convertible to `T*` and the
166
+ constructor evaluates the statement:
167
+
168
+ ``` cpp
169
+ if (p != nullptr && p->weak_this.expired())
170
+ p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
171
+ ```
172
+
173
+ The assignment to the `weak_this` member is not atomic and conflicts
174
+ with any potentially concurrent access to the same object (
175
+ [[intro.multithread]]).
176
+
177
  ``` cpp
178
  constexpr shared_ptr() noexcept;
179
  ```
180
 
181
+ *Effects:* Constructs an empty `shared_ptr` object.
182
 
183
  *Postconditions:* `use_count() == 0 && get() == nullptr`.
184
 
185
  ``` cpp
186
  template<class Y> explicit shared_ptr(Y* p);
187
  ```
188
 
189
+ *Requires:* `Y` shall be a complete type. The expression `delete[] p`,
190
+ when `T` is an array type, or `delete p`, when `T` is not an array type,
191
+ shall have well-defined behavior, and shall not throw exceptions.
192
 
193
+ *Effects:* When `T` is not an array type, constructs a `shared_ptr`
194
+ object that owns the pointer `p`. Otherwise, constructs a `shared_ptr`
195
+ that owns `p` and a deleter of an unspecified type that calls
196
+ `delete[] p`. When `T` is not an array type, enables `shared_from_this`
197
+ with `p`. If an exception is thrown, `delete p` is called when `T` is
198
+ not an array type, `delete[] p` otherwise.
199
 
200
  *Postconditions:* `use_count() == 1 && get() == p`.
201
 
202
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
203
  resource other than memory could not be obtained.
204
 
205
+ *Remarks:* When `T` is an array type, this constructor shall not
206
+ participate in overload resolution unless the expression `delete[] p` is
207
+ well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
208
+ `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
209
+ not an array type, this constructor shall not participate in overload
210
+ resolution unless the expression `delete p` is well-formed and `Y*` is
211
+ convertible to `T*`.
212
 
213
  ``` cpp
214
  template<class Y, class D> shared_ptr(Y* p, D d);
215
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
216
  template <class D> shared_ptr(nullptr_t p, D d);
217
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
218
  ```
219
 
220
+ *Requires:* Construction of `d` and a deleter of type `D` initialized
221
+ with `std::move(d)` shall not throw exceptions. The expression `d(p)`
222
+ shall have well-defined behavior and shall not throw exceptions. `A`
223
+ shall be an allocator ([[allocator.requirements]]).
 
 
224
 
225
+ *Effects:* Constructs a `shared_ptr` object that owns the object `p` and
226
+ the deleter `d`. When `T` is not an array type, the first and second
227
+ constructors enable `shared_from_this` with `p`. The second and fourth
228
+ constructors shall use a copy of `a` to allocate memory for internal
229
+ use. If an exception is thrown, `d(p)` is called.
230
 
231
  *Postconditions:* `use_count() == 1 && get() == p`.
232
 
233
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
234
  resource other than memory could not be obtained.
235
 
236
+ *Remarks:* When `T` is an array type, this constructor shall not
237
+ participate in overload resolution unless `is_move_constructible_v<D>`
238
+ is `true`, the expression `d(p)` is well-formed, and either `T` is
239
+ `U[N]` and `Y(*)[N]` is convertible to `T*`, or `T` is `U[]` and
240
+ `Y(*)[]` is convertible to `T*`. When `T` is not an array type, this
241
+ constructor shall not participate in overload resolution unless
242
+ `is_move_constructible_v<D>` is `true`, the expression `d(p)` is
243
+ well-formed, and `Y*` is convertible to `T*`.
244
 
245
  ``` cpp
246
+ template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
247
  ```
248
 
249
+ *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
250
+ ownership with `r`.
251
 
252
+ *Postconditions:* `get() == p && use_count() == r.use_count()`.
253
 
254
+ [*Note 1*: To avoid the possibility of a dangling pointer, the user of
255
+ this constructor must ensure that `p` remains valid at least until the
256
+ ownership group of `r` is destroyed. — *end note*]
257
 
258
+ [*Note 2*: This constructor allows creation of an empty `shared_ptr`
259
+ instance with a non-null stored pointer. — *end note*]
260
 
261
  ``` cpp
262
  shared_ptr(const shared_ptr& r) noexcept;
263
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
264
  ```
265
 
266
+ *Remarks:* The second constructor shall not participate in overload
267
+ resolution unless `Y*` is compatible with `T*`.
268
 
269
+ *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
270
+ otherwise, constructs a `shared_ptr` object that shares ownership with
271
  `r`.
272
 
273
  *Postconditions:* `get() == r.get() && use_count() == r.use_count()`.
274
 
275
  ``` cpp
276
  shared_ptr(shared_ptr&& r) noexcept;
277
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
278
  ```
279
 
280
+ *Remarks:* The second constructor shall not participate in overload
281
+ resolution unless `Y*` is compatible with `T*`.
282
 
283
+ *Effects:* Move constructs a `shared_ptr` instance from `r`.
284
 
285
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
286
+ be empty. `r.get() == nullptr`.
287
 
288
  ``` cpp
289
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
290
  ```
291
 
292
+ *Effects:* Constructs a `shared_ptr` object that shares ownership with
293
+ `r` and stores a copy of the pointer stored in `r`. If an exception is
294
+ thrown, the constructor has no effect.
 
295
 
296
  *Postconditions:* `use_count() == r.use_count()`.
297
 
298
  *Throws:* `bad_weak_ptr` when `r.expired()`.
299
 
300
+ *Remarks:* This constructor shall not participate in overload resolution
301
+ unless `Y*` is compatible with `T*`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
  ``` cpp
304
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
305
  ```
306
 
307
+ *Remarks:* This constructor shall not participate in overload resolution
308
+ unless `Y*` is compatible with `T*` and `unique_ptr<Y, D>::pointer` is
309
+ convertible to `element_type*`.
310
 
311
+ *Effects:* If `r.get() == nullptr`, equivalent to `shared_ptr()`.
312
+ Otherwise, if `D` is not a reference type, equivalent to
313
+ `shared_ptr(r.release(), r.get_deleter())`. Otherwise, equivalent to
314
+ `shared_ptr(r.release(), ref(r.get_deleter()))`. If an exception is
315
+ thrown, the constructor has no effect.
316
 
317
  ##### `shared_ptr` destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
318
 
319
  ``` cpp
320
  ~shared_ptr();
321
  ```
322
 
323
  *Effects:*
324
 
325
+ - If `*this` is empty or shares ownership with another `shared_ptr`
326
  instance (`use_count() > 1`), there are no side effects.
327
+ - Otherwise, if `*this` owns an object `p` and a deleter `d`, `d(p)` is
328
+ called.
329
+ - Otherwise, `*this` owns a pointer `p`, and `delete p` is called.
330
 
331
+ [*Note 1*: Since the destruction of `*this` decreases the number of
332
+ instances that share ownership with `*this` by one, after `*this` has
333
+ been destroyed all `shared_ptr` instances that shared ownership with
334
+ `*this` will report a `use_count()` that is one less than its previous
335
+ value. — *end note*]
336
 
337
  ##### `shared_ptr` assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
338
 
339
  ``` cpp
340
  shared_ptr& operator=(const shared_ptr& r) noexcept;
341
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
 
342
  ```
343
 
344
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
345
 
346
  *Returns:* `*this`.
347
 
348
+ [*Note 3*:
349
+
350
  The use count updates caused by the temporary object construction and
351
  destruction are not observable side effects, so the implementation may
352
  meet the effects (and the implied guarantees) via different means,
353
  without creating a temporary. In particular, in the example:
354
 
 
359
  q = p;
360
  ```
361
 
362
  both assignments may be no-ops.
363
 
364
+ — *end note*]
365
+
366
  ``` cpp
367
  shared_ptr& operator=(shared_ptr&& r) noexcept;
368
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
369
  ```
370
 
 
376
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
377
  ```
378
 
379
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
380
 
381
+ *Returns:* `*this`.
382
 
383
  ##### `shared_ptr` modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
384
 
385
  ``` cpp
386
  void swap(shared_ptr& r) noexcept;
 
413
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
414
 
415
  ##### `shared_ptr` observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
416
 
417
  ``` cpp
418
+ element_type* get() const noexcept;
419
  ```
420
 
421
+ *Returns:* The stored pointer.
422
 
423
  ``` cpp
424
  T& operator*() const noexcept;
425
  ```
426
 
427
  *Requires:* `get() != 0`.
428
 
429
  *Returns:* `*get()`.
430
 
431
+ *Remarks:* When `T` is an array type or cv `void`, it is unspecified
432
+ whether this member function is declared. If it is declared, it is
433
+ unspecified what its return type is, except that the declaration
434
+ (although not necessarily the definition) of the function shall be well
435
+ formed.
436
 
437
  ``` cpp
438
  T* operator->() const noexcept;
439
  ```
440
 
441
  *Requires:* `get() != 0`.
442
 
443
  *Returns:* `get()`.
444
 
445
+ *Remarks:* When `T` is an array type, it is unspecified whether this
446
+ member function is declared. If it is declared, it is unspecified what
447
+ its return type is, except that the declaration (although not
448
+ necessarily the definition) of the function shall be well formed.
449
+
450
+ ``` cpp
451
+ element_type& operator[](ptrdiff_t i) const;
452
+ ```
453
+
454
+ *Requires:* `get() != 0 && i >= 0`. If `T` is `U[N]`, `i < N`.
455
+
456
+ *Returns:* `get()[i]`.
457
+
458
+ *Remarks:* When `T` is not an array type, it is unspecified whether this
459
+ member function is declared. If it is declared, it is unspecified what
460
+ its return type is, except that the declaration (although not
461
+ necessarily the definition) of the function shall be well formed.
462
+
463
+ *Throws:* Nothing.
464
+
465
  ``` cpp
466
  long use_count() const noexcept;
467
  ```
468
 
469
+ *Returns:* The number of `shared_ptr` objects, `*this` included, that
470
+ share ownership with `*this`, or `0` when `*this` is empty.
471
 
472
+ *Synchronization:* None.
473
 
474
+ [*Note 4*: `get() == nullptr` does not imply a specific return value of
475
+ `use_count()`. *end note*]
 
476
 
477
+ [*Note 5*: `weak_ptr<T>::lock()` can affect the return value of
478
+ `use_count()`. — *end note*]
479
 
480
+ [*Note 6*: When multiple threads can affect the return value of
481
+ `use_count()`, the result should be treated as approximate. In
482
+ particular, `use_count() == 1` does not imply that accesses through a
483
+ previously destroyed `shared_ptr` have in any sense
484
+ completed. — *end note*]
485
 
486
  ``` cpp
487
  explicit operator bool() const noexcept;
488
  ```
489
 
490
  *Returns:* `get() != 0`.
491
 
492
  ``` cpp
493
+ template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
494
+ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
495
  ```
496
 
497
  *Returns:* An unspecified value such that
498
 
499
  - `x.owner_before(y)` defines a strict weak ordering as defined
 
504
  ownership or are both empty.
505
 
506
  ##### `shared_ptr` creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
507
 
508
  ``` cpp
509
+ template<class T, class... Args>
510
+ shared_ptr<T> make_shared(Args&&... args);
511
  template<class T, class A, class... Args>
512
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
513
  ```
514
 
515
  *Requires:* The expression `::new (pv) T(std::forward<Args>(args)...)`,
516
  where `pv` has type `void*` and points to storage suitable to hold an
517
  object of type `T`, shall be well formed. `A` shall be an
518
+ allocator ([[allocator.requirements]]). The copy constructor and
519
  destructor of `A` shall not throw exceptions.
520
 
521
  *Effects:* Allocates memory suitable for an object of type `T` and
522
+ constructs an object in that memory via the placement *new-expression*
523
  `::new (pv) T(std::forward<Args>(args)...)`. The template
524
  `allocate_shared` uses a copy of `a` to allocate memory. If an exception
525
  is thrown, the functions have no effect.
526
 
527
  *Returns:* A `shared_ptr` instance that stores and owns the address of
528
  the newly constructed object of type `T`.
529
 
530
+ *Postconditions:* `get() != 0 && use_count() == 1`.
531
 
532
  *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
533
  the constructor of `T`.
534
 
535
+ *Remarks:* The `shared_ptr` constructor called by this function enables
536
+ `shared_from_this` with the address of the newly constructed object of
537
+ type `T`. Implementations should perform no more than one memory
538
+ allocation.
539
 
540
+ [*Note 7*: This provides efficiency equivalent to an intrusive smart
541
+ pointer. *end note*]
542
+
543
+ [*Note 8*: These functions will typically allocate more memory than
544
+ `sizeof(T)` to allow for internal bookkeeping structures such as the
545
+ reference counts. — *end note*]
546
 
547
  ##### `shared_ptr` comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
548
 
549
  ``` cpp
550
+ template<class T, class U>
551
+ bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
552
  ```
553
 
554
  *Returns:* `a.get() == b.get()`.
555
 
556
  ``` cpp
557
+ template<class T, class U>
558
+ bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
559
  ```
560
 
561
+ *Returns:* `less<>()(a.get(), b.get())`.
 
562
 
563
+ [*Note 9*: Defining a comparison function allows `shared_ptr` objects
564
+ to be used as keys in associative containers. — *end note*]
565
 
566
  ``` cpp
567
  template <class T>
568
  bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
569
  template <class T>
 
587
  template <class T>
588
  bool operator<(nullptr_t, const shared_ptr<T>& a) noexcept;
589
  ```
590
 
591
  *Returns:* The first function template returns
592
+ `less<shared_ptr<T>::element_type*>()(a.get(), nullptr)`. The second
593
+ function template returns
594
+ `less<shared_ptr<T>::element_type*>()(nullptr, a.get())`.
595
 
596
  ``` cpp
597
  template <class T>
598
  bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
599
  template <class T>
 
624
  second function template returns `!(nullptr < a)`.
625
 
626
  ##### `shared_ptr` specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
627
 
628
  ``` cpp
629
+ template<class T>
630
+ void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
631
  ```
632
 
633
  *Effects:* Equivalent to `a.swap(b)`.
634
 
635
  ##### `shared_ptr` casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
636
 
637
  ``` cpp
638
+ template<class T, class U>
639
+ shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
640
  ```
641
 
642
+ *Requires:* The expression `static_cast<T*>((U*)0)` shall be well
643
  formed.
644
 
645
+ *Returns:*
 
 
646
 
647
+ ``` cpp
648
+ shared_ptr<T>(r, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
649
+ ```
650
 
651
+ [*Note 10*: The seemingly equivalent expression
652
  `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
653
+ undefined behavior, attempting to delete the same object
654
+ twice. — *end note*]
655
 
656
  ``` cpp
657
+ template<class T, class U>
658
+ shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
659
  ```
660
 
661
+ *Requires:* The expression `dynamic_cast<T*>((U*)0)` shall be well
662
  formed and shall have well defined behavior.
663
 
664
  *Returns:*
665
 
666
+ - When `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())`
667
+ returns a nonzero value `p`, `shared_ptr<T>(r, p)`.
668
+ - Otherwise, `shared_ptr<T>()`.
 
669
 
670
+ [*Note 11*: The seemingly equivalent expression
 
 
671
  `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
672
+ undefined behavior, attempting to delete the same object
673
+ twice. — *end note*]
674
 
675
  ``` cpp
676
+ template<class T, class U>
677
+ shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
678
  ```
679
 
680
+ *Requires:* The expression `const_cast<T*>((U*)0)` shall be well formed.
 
681
 
682
+ *Returns:*
 
 
683
 
684
+ ``` cpp
685
+ shared_ptr<T>(r, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
686
+ ```
687
 
688
+ [*Note 12*: The seemingly equivalent expression
689
  `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
690
+ undefined behavior, attempting to delete the same object
691
+ twice. — *end note*]
692
 
693
+ ``` cpp
694
+ template<class T, class U>
695
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
696
+ ```
697
+
698
+ *Requires:* The expression `reinterpret_cast<T*>((U*)0)` shall be well
699
+ formed.
700
+
701
+ *Returns:*
702
+
703
+ ``` cpp
704
+ shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()))
705
+ ```
706
+
707
+ [*Note 13*: The seemingly equivalent expression
708
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
709
+ undefined behavior, attempting to delete the same object
710
+ twice. — *end note*]
711
+
712
+ ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
713
 
714
  ``` cpp
715
+ template<class D, class T>
716
+ D* get_deleter(const shared_ptr<T>& p) noexcept;
717
  ```
718
 
719
+ *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
720
+ `addressof(d)`; otherwise returns `nullptr`. The returned pointer
721
+ remains valid as long as there exists a `shared_ptr` instance that owns
722
+ `d`.
723
+
724
+ [*Note 14*: It is unspecified whether the pointer remains valid longer
725
+ than that. This can happen if the implementation doesn’t destroy the
726
+ deleter until all `weak_ptr` instances that share ownership with `p`
727
+ have been destroyed. — *end note*]
728
 
729
  ##### `shared_ptr` I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
730
 
731
  ``` cpp
732
  template<class E, class T, class Y>
733
+ basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
734
  ```
735
 
736
+ *Effects:* As if by: `os << p.get();`
737
 
738
  *Returns:* `os`.
739