From Jason Turner

[util.smartptr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpzaxqa4nt/{from.md → to.md} +377 -291
tmp/tmpzaxqa4nt/{from.md → to.md} RENAMED
@@ -1,93 +1,96 @@
1
  ### Shared-ownership pointers <a id="util.smartptr">[[util.smartptr]]</a>
2
 
3
- #### Class `bad_weak_ptr` <a id="util.smartptr.weakptr">[[util.smartptr.weakptr]]</a>
4
 
5
  ``` cpp
6
  namespace std {
7
- class bad_weak_ptr: public std::exception {
8
  public:
9
  bad_weak_ptr() noexcept;
10
  };
11
- } // namespace std
12
  ```
13
 
14
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
15
  constructor taking a `weak_ptr`.
16
 
17
  ``` cpp
18
  bad_weak_ptr() noexcept;
19
  ```
20
 
21
- *Postconditions:* `what()` returns `"bad_weak_ptr"`.
22
 
23
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
24
 
25
  The `shared_ptr` class template stores a pointer, usually obtained via
26
  `new`. `shared_ptr` implements semantics of shared ownership; the last
27
  remaining owner of the pointer is responsible for destroying the object,
28
  or otherwise releasing the resources associated with the stored pointer.
29
- A `shared_ptr` object is *empty* if it does not own a pointer.
30
 
31
  ``` cpp
32
  namespace std {
33
  template<class T> class shared_ptr {
34
  public:
35
- typedef T element_type;
 
36
 
37
- // [util.smartptr.shared.const], constructors:
38
  constexpr shared_ptr() noexcept;
39
  template<class Y> explicit shared_ptr(Y* p);
40
  template<class Y, class D> shared_ptr(Y* p, D d);
41
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
42
  template <class D> shared_ptr(nullptr_t p, D d);
43
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
44
- template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
45
  shared_ptr(const shared_ptr& r) noexcept;
46
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
47
  shared_ptr(shared_ptr&& r) noexcept;
48
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
49
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
50
- template<class Y> shared_ptr(auto_ptr<Y>&& r);
51
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
52
- constexpr shared_ptr(nullptr_t) : shared_ptr() { }
53
 
54
- // [util.smartptr.shared.dest], destructor:
55
  ~shared_ptr();
56
 
57
- // [util.smartptr.shared.assign], assignment:
58
  shared_ptr& operator=(const shared_ptr& r) noexcept;
59
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
60
  shared_ptr& operator=(shared_ptr&& r) noexcept;
61
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
62
- template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
63
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
64
 
65
- // [util.smartptr.shared.mod], modifiers:
66
  void swap(shared_ptr& r) noexcept;
67
  void reset() noexcept;
68
  template<class Y> void reset(Y* p);
69
  template<class Y, class D> void reset(Y* p, D d);
70
  template<class Y, class D, class A> void reset(Y* p, D d, A a);
71
 
72
- // [util.smartptr.shared.obs], observers:
73
- T* get() const noexcept;
74
  T& operator*() const noexcept;
75
  T* operator->() const noexcept;
 
76
  long use_count() const noexcept;
77
- bool unique() const noexcept;
78
  explicit operator bool() const noexcept;
79
- template<class U> bool owner_before(shared_ptr<U> const& b) const;
80
- template<class U> bool owner_before(weak_ptr<U> const& b) const;
81
  };
82
 
 
 
 
83
  // [util.smartptr.shared.create], shared_ptr creation
84
- template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
 
85
  template<class T, class A, class... Args>
86
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
87
 
88
- // [util.smartptr.shared.cmp], shared_ptr comparisons:
89
  template<class T, class U>
90
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
91
  template<class T, class U>
92
  bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
93
  template<class T, class U>
@@ -122,218 +125,252 @@ namespace std {
122
  template <class T>
123
  bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
124
  template <class T>
125
  bool operator>=(nullptr_t, const shared_ptr<T>& b) noexcept;
126
 
127
- // [util.smartptr.shared.spec], shared_ptr specialized algorithms:
128
- template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
 
129
 
130
- // [util.smartptr.shared.cast], shared_ptr casts:
131
  template<class T, class U>
132
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
133
  template<class T, class U>
134
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
135
  template<class T, class U>
136
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
 
 
137
 
138
- // [util.smartptr.getdeleter], shared_ptr get_deleter:
139
- template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
 
140
 
141
- // [util.smartptr.shared.io], shared_ptr I/O:
142
  template<class E, class T, class Y>
143
  basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
144
- } // namespace std
145
  ```
146
 
147
  Specializations of `shared_ptr` shall be `CopyConstructible`,
148
  `CopyAssignable`, and `LessThanComparable`, allowing their use in
149
  standard containers. Specializations of `shared_ptr` shall be
150
- convertible to `bool`, allowing their use in boolean expressions and
151
- declarations in conditions. The template parameter `T` of `shared_ptr`
152
- may be an incomplete type.
 
 
153
 
154
  ``` cpp
155
  if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
156
  // do something with px
157
  }
158
  ```
159
 
 
 
160
  For purposes of determining the presence of a data race, member
161
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
162
  objects themselves and not objects they refer to. Changes in
163
  `use_count()` do not reflect modifications that can introduce data
164
  races.
165
 
 
 
 
 
166
  ##### `shared_ptr` constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  ``` cpp
169
  constexpr shared_ptr() noexcept;
170
  ```
171
 
172
- *Effects:* Constructs an *empty* `shared_ptr` object.
173
 
174
  *Postconditions:* `use_count() == 0 && get() == nullptr`.
175
 
176
  ``` cpp
177
  template<class Y> explicit shared_ptr(Y* p);
178
  ```
179
 
180
- *Requires:* `p` shall be convertible to `T*`. `Y` shall be a complete
181
- type. The expression `delete p` shall be well formed, shall have well
182
- defined behavior, and shall not throw exceptions.
183
 
184
- *Effects:* Constructs a `shared_ptr` object that *owns* the pointer `p`.
 
 
 
 
 
185
 
186
  *Postconditions:* `use_count() == 1 && get() == p`.
187
 
188
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
189
  resource other than memory could not be obtained.
190
 
191
- If an exception is thrown, `delete p` is called.
 
 
 
 
 
 
192
 
193
  ``` cpp
194
  template<class Y, class D> shared_ptr(Y* p, D d);
195
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
196
  template <class D> shared_ptr(nullptr_t p, D d);
197
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
198
  ```
199
 
200
- *Requires:* `p` shall be convertible to `T*`. `D` shall be
201
- `CopyConstructible`. The copy constructor and destructor of ` D` shall
202
- not throw exceptions. The expression `d(p)` shall be well formed, shall
203
- have well defined behavior, and shall not throw exceptions. `A` shall be
204
- an allocator ([[allocator.requirements]]). The copy constructor and
205
- destructor of `A` shall not throw exceptions.
206
 
207
- *Effects:* Constructs a `shared_ptr` object that *owns* the object `p`
208
- and the deleter `d`. The second and fourth constructors shall use a copy
209
- of `a` to allocate memory for internal use.
 
 
210
 
211
  *Postconditions:* `use_count() == 1 && get() == p`.
212
 
213
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
214
  resource other than memory could not be obtained.
215
 
216
- If an exception is thrown, `d(p)` is called.
 
 
 
 
 
 
 
217
 
218
  ``` cpp
219
- template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
220
  ```
221
 
222
- *Effects:* Constructs a `shared_ptr` instance that stores `p` and
223
- *shares ownership* with `r`.
224
 
225
- *Postconditions:* `get() == p && use_count() == r.use_count()`
226
 
227
- To avoid the possibility of a dangling pointer, the user of this
228
- constructor must ensure that `p` remains valid at least until the
229
- ownership group of `r` is destroyed.
230
 
231
- This constructor allows creation of an *empty* `shared_ptr` instance
232
- with a non-null stored pointer.
233
 
234
  ``` cpp
235
  shared_ptr(const shared_ptr& r) noexcept;
236
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
237
  ```
238
 
239
- The second constructor shall not participate in overload resolution
240
- unless `Y*` is implicitly convertible to `T*`.
241
 
242
- *Effects:* If `r` is *empty*, constructs an *empty* `shared_ptr` object;
243
- otherwise, constructs a `shared_ptr` object that *shares ownership* with
244
  `r`.
245
 
246
  *Postconditions:* `get() == r.get() && use_count() == r.use_count()`.
247
 
248
  ``` cpp
249
  shared_ptr(shared_ptr&& r) noexcept;
250
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
251
  ```
252
 
253
- The second constructor shall not participate in overload resolution
254
- unless `Y*` is convertible to `T*`.
255
 
256
- *Effects:* Move-constructs a `shared_ptr` instance from `r`.
257
 
258
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
259
- be *empty*. `r.get() == nullptr.`
260
 
261
  ``` cpp
262
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
263
  ```
264
 
265
- *Requires:* `Y*` shall be convertible to `T*`.
266
-
267
- *Effects:* Constructs a `shared_ptr` object that *shares ownership* with
268
- `r` and stores a copy of the pointer stored in `r`.
269
 
270
  *Postconditions:* `use_count() == r.use_count()`.
271
 
272
  *Throws:* `bad_weak_ptr` when `r.expired()`.
273
 
274
- If an exception is thrown, the constructor has no effect.
275
-
276
- ``` cpp
277
- template<class Y> shared_ptr(auto_ptr<Y>&& r);
278
- ```
279
-
280
- *Requires:* `r.release()` shall be convertible to `T*`. `Y` shall be a
281
- complete type. The expression `delete r.release()` shall be well formed,
282
- shall have well defined behavior, and shall not throw exceptions.
283
-
284
- *Effects:* Constructs a `shared_ptr` object that stores and *owns*
285
- `r.release()`.
286
-
287
- *Postconditions:* `use_count() == 1` `&&` `r.get() == nullptr`.
288
-
289
- *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
290
- resource other than memory could not be obtained.
291
-
292
- If an exception is thrown, the constructor has no effect.
293
 
294
  ``` cpp
295
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
296
  ```
297
 
298
- *Effects:* Equivalent to `shared_ptr(r.release(), r.get_deleter())` when
299
- `D` is not a reference type, otherwise
300
- `shared_ptr(r.release(), ref(r.get_deleter()))`.
301
 
302
- If an exception is thrown, the constructor has no effect.
 
 
 
 
303
 
304
  ##### `shared_ptr` destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
305
 
306
  ``` cpp
307
  ~shared_ptr();
308
  ```
309
 
310
  *Effects:*
311
 
312
- - If `*this` is *empty* or shares ownership with another `shared_ptr`
313
  instance (`use_count() > 1`), there are no side effects.
314
- - Otherwise, if `*this` *owns* an object `p` and a deleter `d`, `d(p)`
315
- is called.
316
- - Otherwise, `*this` *owns* a pointer `p`, and `delete p` is called.
317
 
318
- Since the destruction of `*this` decreases the number of instances that
319
- share ownership with `*this` by one, after `*this` has been destroyed
320
- all `shared_ptr` instances that shared ownership with `*this` will
321
- report a `use_count()` that is one less than its previous value.
 
322
 
323
  ##### `shared_ptr` assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
324
 
325
  ``` cpp
326
  shared_ptr& operator=(const shared_ptr& r) noexcept;
327
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
328
- template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
329
  ```
330
 
331
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
332
 
333
  *Returns:* `*this`.
334
 
 
 
335
  The use count updates caused by the temporary object construction and
336
  destruction are not observable side effects, so the implementation may
337
  meet the effects (and the implied guarantees) via different means,
338
  without creating a temporary. In particular, in the example:
339
 
@@ -344,10 +381,12 @@ p = p;
344
  q = p;
345
  ```
346
 
347
  both assignments may be no-ops.
348
 
 
 
349
  ``` cpp
350
  shared_ptr& operator=(shared_ptr&& r) noexcept;
351
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
352
  ```
353
 
@@ -359,11 +398,11 @@ template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
359
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
360
  ```
361
 
362
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
363
 
364
- *Returns:* `*this`
365
 
366
  ##### `shared_ptr` modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
367
 
368
  ``` cpp
369
  void swap(shared_ptr& r) noexcept;
@@ -396,64 +435,87 @@ template<class Y, class D, class A> void reset(Y* p, D d, A a);
396
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
397
 
398
  ##### `shared_ptr` observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
399
 
400
  ``` cpp
401
- T* get() const noexcept;
402
  ```
403
 
404
- *Returns:* the stored pointer.
405
 
406
  ``` cpp
407
  T& operator*() const noexcept;
408
  ```
409
 
410
  *Requires:* `get() != 0`.
411
 
412
  *Returns:* `*get()`.
413
 
414
- *Remarks:* When `T` is `void`, it is unspecified whether this member
415
- function is declared. If it is declared, it is unspecified what its
416
- return type is, except that the declaration (although not necessarily
417
- the definition) of the function shall be well formed.
 
418
 
419
  ``` cpp
420
  T* operator->() const noexcept;
421
  ```
422
 
423
  *Requires:* `get() != 0`.
424
 
425
  *Returns:* `get()`.
426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  ``` cpp
428
  long use_count() const noexcept;
429
  ```
430
 
431
- *Returns:* the number of `shared_ptr` objects, `*this` included, that
432
- *share ownership* with `*this`, or `0` when `*this` is *empty*.
433
 
434
- `use_count()` is not necessarily efficient.
435
 
436
- ``` cpp
437
- bool unique() const noexcept;
438
- ```
439
 
440
- *Returns:* `use_count() == 1`.
 
441
 
442
- `unique()` may be faster than `use_count()`. If you are using `unique()`
443
- to implement copy on write, do not rely on a specific value when
444
- `get() == nullptr`.
 
 
445
 
446
  ``` cpp
447
  explicit operator bool() const noexcept;
448
  ```
449
 
450
  *Returns:* `get() != 0`.
451
 
452
  ``` cpp
453
- template<class U> bool owner_before(shared_ptr<U> const& b) const;
454
- template<class U> bool owner_before(weak_ptr<U> const& b) const;
455
  ```
456
 
457
  *Returns:* An unspecified value such that
458
 
459
  - `x.owner_before(y)` defines a strict weak ordering as defined
@@ -464,59 +526,66 @@ template<class U> bool owner_before(weak_ptr<U> const& b) const;
464
  ownership or are both empty.
465
 
466
  ##### `shared_ptr` creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
467
 
468
  ``` cpp
469
- template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
 
470
  template<class T, class A, class... Args>
471
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
472
  ```
473
 
474
  *Requires:* The expression `::new (pv) T(std::forward<Args>(args)...)`,
475
  where `pv` has type `void*` and points to storage suitable to hold an
476
  object of type `T`, shall be well formed. `A` shall be an
477
- *allocator* ([[allocator.requirements]]). The copy constructor and
478
  destructor of `A` shall not throw exceptions.
479
 
480
  *Effects:* Allocates memory suitable for an object of type `T` and
481
- constructs an object in that memory via the placement new expression
482
  `::new (pv) T(std::forward<Args>(args)...)`. The template
483
  `allocate_shared` uses a copy of `a` to allocate memory. If an exception
484
  is thrown, the functions have no effect.
485
 
486
  *Returns:* A `shared_ptr` instance that stores and owns the address of
487
  the newly constructed object of type `T`.
488
 
489
- *Postconditions:* `get() != 0 && use_count() == 1`
490
 
491
  *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
492
  the constructor of `T`.
493
 
494
- *Remarks:* Implementations should perform no more than one memory
495
- allocation. This provides efficiency equivalent to an intrusive smart
496
- pointer.
 
497
 
498
- These functions will typically allocate more memory than `sizeof(T)` to
499
- allow for internal bookkeeping structures such as the reference counts.
 
 
 
 
500
 
501
  ##### `shared_ptr` comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
502
 
503
  ``` cpp
504
- template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
505
  ```
506
 
507
  *Returns:* `a.get() == b.get()`.
508
 
509
  ``` cpp
510
- template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
511
  ```
512
 
513
- *Returns:* `less<V>()(a.get(), b.get())`, where `V` is the composite
514
- pointer type (Clause  [[expr]]) of `T*` and `U*`.
515
 
516
- Defining a comparison operator allows `shared_ptr` objects to be used as
517
- keys in associative containers.
518
 
519
  ``` cpp
520
  template <class T>
521
  bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
522
  template <class T>
@@ -540,12 +609,13 @@ template <class T>
540
  template <class T>
541
  bool operator<(nullptr_t, const shared_ptr<T>& a) noexcept;
542
  ```
543
 
544
  *Returns:* The first function template returns
545
- `less<T*>()(a.get(), nullptr)`. The second function template returns
546
- `less<T*>()(nullptr, a.get())`.
 
547
 
548
  ``` cpp
549
  template <class T>
550
  bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
551
  template <class T>
@@ -576,94 +646,118 @@ template <class T>
576
  second function template returns `!(nullptr < a)`.
577
 
578
  ##### `shared_ptr` specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
579
 
580
  ``` cpp
581
- template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
 
582
  ```
583
 
584
  *Effects:* Equivalent to `a.swap(b)`.
585
 
586
  ##### `shared_ptr` casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
587
 
588
  ``` cpp
589
- template<class T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
 
590
  ```
591
 
592
- *Requires:* The expression `static_cast<T*>(r.get())` shall be well
593
  formed.
594
 
595
- *Returns:* If `r` is *empty*, an *empty* `shared_ptr<T>`; otherwise, a
596
- `shared_ptr<T>` object that stores `static_cast<T*>(r.get())` and
597
- *shares ownership* with `r`.
598
 
599
- *Postconditions:* `w.get() == static_cast<T*>(r.get())` and
600
- `w.use_count() == r.use_count()`, where `w` is the return value.
 
601
 
602
- The seemingly equivalent expression
603
  `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
604
- undefined behavior, attempting to delete the same object twice.
 
605
 
606
  ``` cpp
607
- template<class T, class U> shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
 
608
  ```
609
 
610
- *Requires:* The expression `dynamic_cast<T*>(r.get())` shall be well
611
  formed and shall have well defined behavior.
612
 
613
  *Returns:*
614
 
615
- - When `dynamic_cast<T*>(r.get())` returns a nonzero value, a
616
- `shared_ptr<T>` object that stores a copy of it and *shares ownership*
617
- with `r`;
618
- - Otherwise, an *empty* `shared_ptr<T>` object.
619
 
620
- `w.get() == dynamic_cast<T*>(r.get())`, where `w` is the return value.
621
-
622
- The seemingly equivalent expression
623
  `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
624
- undefined behavior, attempting to delete the same object twice.
 
625
 
626
  ``` cpp
627
- template<class T, class U> shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
 
628
  ```
629
 
630
- *Requires:* The expression `const_cast<T*>(r.get())` shall be well
631
- formed.
632
 
633
- *Returns:* If `r` is empty, an empty `shared_ptr<T>`; otherwise, a
634
- `shared_ptr<T>` object that stores `const_cast<T*>(r.get())` and shares
635
- ownership with `r`.
636
 
637
- *Postconditions:* `w.get() == const_cast<T*>(r.get())` and
638
- `w.use_count() == r.use_count()`, where `w` is the return value.
 
639
 
640
- The seemingly equivalent expression
641
  `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
642
- undefined behavior, attempting to delete the same object twice.
 
643
 
644
- ##### get_deleter <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
 
646
  ``` cpp
647
- template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
 
648
  ```
649
 
650
- *Returns:* If `p` *owns* a deleter `d` of type cv-unqualified `D`,
651
- returns `&d`; otherwise returns `nullptr`. The returned pointer remains
652
- valid as long as there exists a `shared_ptr` instance that owns `d`. It
653
- is unspecified whether the pointer remains valid longer than that. This
654
- can happen if the implementation doesn’t destroy the deleter until all
655
- `weak_ptr` instances that share ownership with `p` have been destroyed.
 
 
 
656
 
657
  ##### `shared_ptr` I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
658
 
659
  ``` cpp
660
  template<class E, class T, class Y>
661
- basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
662
  ```
663
 
664
- *Effects:* `os << p.get();`.
665
 
666
  *Returns:* `os`.
667
 
668
  #### Class template `weak_ptr` <a id="util.smartptr.weak">[[util.smartptr.weak]]</a>
669
 
@@ -673,27 +767,27 @@ can be converted to a `shared_ptr` using the member function `lock`.
673
 
674
  ``` cpp
675
  namespace std {
676
  template<class T> class weak_ptr {
677
  public:
678
- typedef T element_type;
679
 
680
  // [util.smartptr.weak.const], constructors
681
  constexpr weak_ptr() noexcept;
682
- template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
683
- weak_ptr(weak_ptr const& r) noexcept;
684
- template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
685
  weak_ptr(weak_ptr&& r) noexcept;
686
  template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
687
 
688
  // [util.smartptr.weak.dest], destructor
689
  ~weak_ptr();
690
 
691
  // [util.smartptr.weak.assign], assignment
692
- weak_ptr& operator=(weak_ptr const& r) noexcept;
693
- template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
694
- template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
695
  weak_ptr& operator=(weak_ptr&& r) noexcept;
696
  template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
697
 
698
  // [util.smartptr.weak.mod], modifiers
699
  void swap(weak_ptr& r) noexcept;
@@ -701,17 +795,20 @@ namespace std {
701
 
702
  // [util.smartptr.weak.obs], observers
703
  long use_count() const noexcept;
704
  bool expired() const noexcept;
705
  shared_ptr<T> lock() const noexcept;
706
- template<class U> bool owner_before(shared_ptr<U> const& b) const;
707
- template<class U> bool owner_before(weak_ptr<U> const& b) const;
708
  };
709
 
 
 
 
710
  // [util.smartptr.weak.spec], specialized algorithms
711
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
712
- } // namespace std
713
  ```
714
 
715
  Specializations of `weak_ptr` shall be `CopyConstructible` and
716
  `CopyAssignable`, allowing their use in standard containers. The
717
  template parameter `T` of `weak_ptr` may be an incomplete type.
@@ -720,41 +817,41 @@ template parameter `T` of `weak_ptr` may be an incomplete type.
720
 
721
  ``` cpp
722
  constexpr weak_ptr() noexcept;
723
  ```
724
 
725
- *Effects:* Constructs an *empty* `weak_ptr` object.
726
 
727
  *Postconditions:* `use_count() == 0`.
728
 
729
  ``` cpp
730
  weak_ptr(const weak_ptr& r) noexcept;
731
  template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
732
  template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
733
  ```
734
 
735
- The second and third constructors shall not participate in overload
736
- resolution unless `Y*` is implicitly convertible to `T*`.
737
 
738
- *Effects:* If `r` is *empty*, constructs an *empty* `weak_ptr` object;
739
- otherwise, constructs a `weak_ptr` object that *shares ownership* with
740
- `r` and stores a copy of the pointer stored in `r`.
741
 
742
  *Postconditions:* `use_count() == r.use_count()`.
743
 
744
  ``` cpp
745
  weak_ptr(weak_ptr&& r) noexcept;
746
  template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
747
  ```
748
 
749
- The second constructor shall not participate in overload resolution
750
- unless `Y*` is implicitly convertible to `T*`.
751
 
752
- *Effects:* Move-constructs a `weak_ptr` instance from `r`.
753
 
754
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
755
- be *empty*. `r.use_count() == 0`.
756
 
757
  ##### `weak_ptr` destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
758
 
759
  ``` cpp
760
  ~weak_ptr();
@@ -805,33 +902,29 @@ void reset() noexcept;
805
 
806
  ``` cpp
807
  long use_count() const noexcept;
808
  ```
809
 
810
- *Returns:* `0` if `*this` is *empty*; otherwise, the number of
811
- `shared_ptr` instances that *share ownership* with `*this`.
812
-
813
- `use_count()` is not necessarily efficient.
814
 
815
  ``` cpp
816
  bool expired() const noexcept;
817
  ```
818
 
819
  *Returns:* `use_count() == 0`.
820
 
821
- `expired()` may be faster than `use_count()`.
822
-
823
  ``` cpp
824
  shared_ptr<T> lock() const noexcept;
825
  ```
826
 
827
- *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
828
  executed atomically.
829
 
830
  ``` cpp
831
- template<class U> bool owner_before(shared_ptr<U> const& b) const;
832
- template<class U> bool owner_before(weak_ptr<U> const& b) const;
833
  ```
834
 
835
  *Returns:* An unspecified value such that
836
 
837
  - `x.owner_before(y)` defines a strict weak ordering as defined
@@ -842,11 +935,12 @@ template<class U> bool owner_before(weak_ptr<U> const& b) const;
842
  ownership or are both empty.
843
 
844
  ##### `weak_ptr` specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
845
 
846
  ``` cpp
847
- template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
 
848
  ```
849
 
850
  *Effects:* Equivalent to `a.swap(b)`.
851
 
852
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
@@ -854,130 +948,125 @@ template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
854
  The class template `owner_less` allows ownership-based mixed comparisons
855
  of shared and weak pointers.
856
 
857
  ``` cpp
858
  namespace std {
859
- template<class T> struct owner_less;
860
 
861
  template<class T> struct owner_less<shared_ptr<T>> {
862
- typedef bool result_type;
863
- typedef shared_ptr<T> first_argument_type;
864
- typedef shared_ptr<T> second_argument_type;
865
- bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const;
866
- bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;
867
- bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;
868
  };
869
 
870
  template<class T> struct owner_less<weak_ptr<T>> {
871
- typedef bool result_type;
872
- typedef weak_ptr<T> first_argument_type;
873
- typedef weak_ptr<T> second_argument_type;
874
- bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const;
875
- bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;
876
- bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;
 
 
 
 
 
 
 
 
 
 
877
  };
878
  }
879
  ```
880
 
881
- `operator()(x,y)` shall return `x.owner_before(y)`. Note that
 
 
 
 
882
 
883
  - `operator()` defines a strict weak ordering as defined in 
884
  [[alg.sorting]];
885
  - under the equivalence relation defined by `operator()`,
886
  `!operator()(a, b) && !operator()(b, a)`, two `shared_ptr` or
887
  `weak_ptr` instances are equivalent if and only if they share
888
  ownership or are both empty.
889
 
 
 
890
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
891
 
892
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
893
- `shared_from_this` member functions that obtain a *shared_ptr* instance
894
  pointing to `*this`.
895
 
 
 
896
  ``` cpp
897
- struct X: public enable_shared_from_this<X> {
898
- };
899
 
900
  int main() {
901
  shared_ptr<X> p(new X);
902
  shared_ptr<X> q = p->shared_from_this();
903
  assert(p == q);
904
- assert(!(p < q ) && !(q < p)); // p and q share ownership
905
  }
906
  ```
907
 
 
 
908
  ``` cpp
909
  namespace std {
910
  template<class T> class enable_shared_from_this {
911
  protected:
912
  constexpr enable_shared_from_this() noexcept;
913
- enable_shared_from_this(enable_shared_from_this const&) noexcept;
914
- enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
915
  ~enable_shared_from_this();
916
  public:
917
  shared_ptr<T> shared_from_this();
918
  shared_ptr<T const> shared_from_this() const;
 
 
 
 
919
  };
920
- } // namespace std
921
  ```
922
 
923
  The template parameter `T` of `enable_shared_from_this` may be an
924
  incomplete type.
925
 
926
  ``` cpp
927
  constexpr enable_shared_from_this() noexcept;
928
  enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
929
  ```
930
 
931
- *Effects:* Constructs an `enable_shared_from_this<T>` object.
932
 
933
  ``` cpp
934
  enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
935
  ```
936
 
937
  *Returns:* `*this`.
938
 
939
- ``` cpp
940
- ~enable_shared_from_this();
941
- ```
942
-
943
- *Effects:* Destroys `*this`.
944
 
945
  ``` cpp
946
  shared_ptr<T> shared_from_this();
947
  shared_ptr<T const> shared_from_this() const;
948
  ```
949
 
950
- *Requires:* `enable_shared_from_this<T>` shall be an accessible base
951
- class of `T`. `*this` shall be a subobject of an object `t` of type `T`.
952
- There shall be at least one `shared_ptr` instance `p` that *owns* `&t`.
953
-
954
- *Returns:* A `shared_ptr<T>` object `r` that *shares ownership with*
955
- `p`.
956
-
957
- *Postconditions:* `r.get() == this`.
958
-
959
- A possible implementation is shown below:
960
 
961
  ``` cpp
962
- template<class T> class enable_shared_from_this {
963
- private:
964
- weak_ptr<T> __weak_this;
965
- protected:
966
- constexpr enable_shared_from_this() : __weak_this() { }
967
- enable_shared_from_this(enable_shared_from_this const &) { }
968
- enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; }
969
- ~enable_shared_from_this() { }
970
- public:
971
- shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); }
972
- shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); }
973
- };
974
  ```
975
 
976
- The `shared_ptr` constructors that create unique pointers can detect the
977
- presence of an `enable_shared_from_this` base and assign the newly
978
- created `shared_ptr` to its `__weak_this` member.
979
 
980
  #### `shared_ptr` atomic access <a id="util.smartptr.shared.atomic">[[util.smartptr.shared.atomic]]</a>
981
 
982
  Concurrent access to a `shared_ptr` object from multiple threads does
983
  not introduce a data race if the access is done exclusively via the
@@ -1029,11 +1118,11 @@ template<class T>
1029
  void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
1030
  ```
1031
 
1032
  *Requires:* `p` shall not be null.
1033
 
1034
- *Effects:* `atomic_store_explicit(p, r, memory_order_seq_cst)`.
1035
 
1036
  *Throws:* Nothing.
1037
 
1038
  ``` cpp
1039
  template<class T>
@@ -1043,11 +1132,11 @@ template<class T>
1043
  *Requires:* `p` shall not be null.
1044
 
1045
  *Requires:* `mo` shall not be `memory_order_acquire` or
1046
  `memory_order_acq_rel`.
1047
 
1048
- *Effects:* `p->swap(r)`.
1049
 
1050
  *Throws:* Nothing.
1051
 
1052
  ``` cpp
1053
  template<class T>
@@ -1060,43 +1149,46 @@ template<class T>
1060
 
1061
  *Throws:* Nothing.
1062
 
1063
  ``` cpp
1064
  template<class T>
1065
- shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r,
1066
- memory_order mo);
1067
  ```
1068
 
1069
  *Requires:* `p` shall not be null.
1070
 
1071
- *Effects:* `p->swap(r)`.
1072
 
1073
  *Returns:* The previous value of `*p`.
1074
 
1075
  *Throws:* Nothing.
1076
 
1077
  ``` cpp
1078
  template<class T>
1079
- bool atomic_compare_exchange_weak(
1080
- shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
1081
  ```
1082
 
1083
  *Requires:* `p` shall not be null and `v` shall not be null.
1084
 
1085
  *Returns:*
1086
- `atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)`.
 
 
 
1087
 
1088
  *Throws:* Nothing.
1089
 
1090
  ``` cpp
1091
  template<class T>
1092
- bool atomic_compare_exchange_strong(
1093
- shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
1094
  ```
1095
 
1096
- *Returns:* `atomic_compare_exchange_strong_explicit(p, v, w,`
1097
- `memory_order_seq_cst, memory_order_seq_cst)`.
 
 
 
1098
 
1099
  ``` cpp
1100
  template<class T>
1101
  bool atomic_compare_exchange_weak_explicit(
1102
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
@@ -1105,49 +1197,43 @@ template<class T>
1105
  bool atomic_compare_exchange_strong_explicit(
1106
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
1107
  memory_order success, memory_order failure);
1108
  ```
1109
 
1110
- *Requires:* `p` shall not be null and `v` shall not be null.
1111
-
1112
- *Requires:* `failure` shall not be `memory_order_release`,
1113
- `memory_order_acq_rel`, or stronger than `success`.
1114
 
1115
  *Effects:* If `*p` is equivalent to `*v`, assigns `w` to `*p` and has
1116
  synchronization semantics corresponding to the value of `success`,
1117
  otherwise assigns `*p` to `*v` and has synchronization semantics
1118
  corresponding to the value of `failure`.
1119
 
1120
  *Returns:* `true` if `*p` was equivalent to `*v`, `false` otherwise.
1121
 
1122
  *Throws:* Nothing.
1123
 
1124
- *Remarks:* two `shared_ptr` objects are equivalent if they store the
1125
- same pointer value and share ownership.
1126
-
1127
- *Remarks:* the weak forms may fail spuriously.
1128
- See  [[atomics.types.operations]].
1129
 
1130
  #### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
1131
 
1132
  ``` cpp
1133
  template <class T, class D> struct hash<unique_ptr<T, D>>;
1134
  ```
1135
 
1136
- The template specialization shall meet the requirements of class
1137
- template `hash` ([[unord.hash]]). For an object `p` of type `UP`, where
1138
- `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the same
1139
- value as `hash<typename UP::pointer>()(p.get())`.
1140
-
1141
- *Requires:* The specialization `hash<typename UP::pointer>` shall be
1142
- well-formed and well-defined, and shall meet the requirements of class
1143
- template `hash` ([[unord.hash]]).
1144
 
1145
  ``` cpp
1146
  template <class T> struct hash<shared_ptr<T>>;
1147
  ```
1148
 
1149
- The template specialization shall meet the requirements of class
1150
- template `hash` ([[unord.hash]]). For an object `p` of type
1151
- `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same
1152
- value as `hash<T*>()(p.get())`.
1153
 
 
1
  ### Shared-ownership pointers <a id="util.smartptr">[[util.smartptr]]</a>
2
 
3
+ #### Class `bad_weak_ptr` <a id="util.smartptr.weak.bad">[[util.smartptr.weak.bad]]</a>
4
 
5
  ``` cpp
6
  namespace std {
7
+ class bad_weak_ptr : public exception {
8
  public:
9
  bad_weak_ptr() noexcept;
10
  };
11
+ }
12
  ```
13
 
14
  An exception of type `bad_weak_ptr` is thrown by the `shared_ptr`
15
  constructor taking a `weak_ptr`.
16
 
17
  ``` cpp
18
  bad_weak_ptr() noexcept;
19
  ```
20
 
21
+ *Postconditions:* `what()` returns an *implementation-defined* NTBS.
22
 
23
  #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
24
 
25
  The `shared_ptr` class template stores a pointer, usually obtained via
26
  `new`. `shared_ptr` implements semantics of shared ownership; the last
27
  remaining owner of the pointer is responsible for destroying the object,
28
  or otherwise releasing the resources associated with the stored pointer.
29
+ A `shared_ptr` is said to be empty if it does not own a pointer.
30
 
31
  ``` cpp
32
  namespace std {
33
  template<class T> class shared_ptr {
34
  public:
35
+ using element_type = remove_extent_t<T>;
36
+ using weak_type = weak_ptr<T>;
37
 
38
+ // [util.smartptr.shared.const], constructors
39
  constexpr shared_ptr() noexcept;
40
  template<class Y> explicit shared_ptr(Y* p);
41
  template<class Y, class D> shared_ptr(Y* p, D d);
42
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
43
  template <class D> shared_ptr(nullptr_t p, D d);
44
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
45
+ template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
46
  shared_ptr(const shared_ptr& r) noexcept;
47
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
48
  shared_ptr(shared_ptr&& r) noexcept;
49
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
50
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
 
51
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
52
+ constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
53
 
54
+ // [util.smartptr.shared.dest], destructor
55
  ~shared_ptr();
56
 
57
+ // [util.smartptr.shared.assign], assignment
58
  shared_ptr& operator=(const shared_ptr& r) noexcept;
59
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
60
  shared_ptr& operator=(shared_ptr&& r) noexcept;
61
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
 
62
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
63
 
64
+ // [util.smartptr.shared.mod], modifiers
65
  void swap(shared_ptr& r) noexcept;
66
  void reset() noexcept;
67
  template<class Y> void reset(Y* p);
68
  template<class Y, class D> void reset(Y* p, D d);
69
  template<class Y, class D, class A> void reset(Y* p, D d, A a);
70
 
71
+ // [util.smartptr.shared.obs], observers
72
+ element_type* get() const noexcept;
73
  T& operator*() const noexcept;
74
  T* operator->() const noexcept;
75
+ element_type& operator[](ptrdiff_t i) const;
76
  long use_count() const noexcept;
 
77
  explicit operator bool() const noexcept;
78
+ template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
79
+ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
80
  };
81
 
82
+ template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
83
+ template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
84
+
85
  // [util.smartptr.shared.create], shared_ptr creation
86
+ template<class T, class... Args>
87
+ shared_ptr<T> make_shared(Args&&... args);
88
  template<class T, class A, class... Args>
89
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
90
 
91
+ // [util.smartptr.shared.cmp], shared_ptr comparisons
92
  template<class T, class U>
93
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
94
  template<class T, class U>
95
  bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
96
  template<class T, class U>
 
125
  template <class T>
126
  bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
127
  template <class T>
128
  bool operator>=(nullptr_t, const shared_ptr<T>& b) noexcept;
129
 
130
+ // [util.smartptr.shared.spec], shared_ptr specialized algorithms
131
+ template<class T>
132
+ void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
133
 
134
+ // [util.smartptr.shared.cast], shared_ptr casts
135
  template<class T, class U>
136
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
137
  template<class T, class U>
138
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
139
  template<class T, class U>
140
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
141
+ template<class T, class U>
142
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
143
 
144
+ // [util.smartptr.getdeleter], shared_ptr get_deleter
145
+ template<class D, class T>
146
+ D* get_deleter(const shared_ptr<T>& p) noexcept;
147
 
148
+ // [util.smartptr.shared.io], shared_ptr I/O
149
  template<class E, class T, class Y>
150
  basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
151
+ }
152
  ```
153
 
154
  Specializations of `shared_ptr` shall be `CopyConstructible`,
155
  `CopyAssignable`, and `LessThanComparable`, allowing their use in
156
  standard containers. Specializations of `shared_ptr` shall be
157
+ contextually convertible to `bool`, allowing their use in boolean
158
+ expressions and declarations in conditions. The template parameter `T`
159
+ of `shared_ptr` may be an incomplete type.
160
+
161
+ [*Example 1*:
162
 
163
  ``` cpp
164
  if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
165
  // do something with px
166
  }
167
  ```
168
 
169
+ — *end example*]
170
+
171
  For purposes of determining the presence of a data race, member
172
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
173
  objects themselves and not objects they refer to. Changes in
174
  `use_count()` do not reflect modifications that can introduce data
175
  races.
176
 
177
+ For the purposes of subclause [[util.smartptr]], a pointer type `Y*` is
178
+ said to be *compatible with* a pointer type `T*` when either `Y*` is
179
+ convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
180
+
181
  ##### `shared_ptr` constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
182
 
183
+ In the constructor definitions below, enables `shared_from_this` with
184
+ `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
185
+ unambiguous and accessible base class that is a specialization of
186
+ `enable_shared_from_this` ([[util.smartptr.enab]]), then
187
+ `remove_cv_t<Y>*` shall be implicitly convertible to `T*` and the
188
+ constructor evaluates the statement:
189
+
190
+ ``` cpp
191
+ if (p != nullptr && p->weak_this.expired())
192
+ p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
193
+ ```
194
+
195
+ The assignment to the `weak_this` member is not atomic and conflicts
196
+ with any potentially concurrent access to the same object (
197
+ [[intro.multithread]]).
198
+
199
  ``` cpp
200
  constexpr shared_ptr() noexcept;
201
  ```
202
 
203
+ *Effects:* Constructs an empty `shared_ptr` object.
204
 
205
  *Postconditions:* `use_count() == 0 && get() == nullptr`.
206
 
207
  ``` cpp
208
  template<class Y> explicit shared_ptr(Y* p);
209
  ```
210
 
211
+ *Requires:* `Y` shall be a complete type. The expression `delete[] p`,
212
+ when `T` is an array type, or `delete p`, when `T` is not an array type,
213
+ shall have well-defined behavior, and shall not throw exceptions.
214
 
215
+ *Effects:* When `T` is not an array type, constructs a `shared_ptr`
216
+ object that owns the pointer `p`. Otherwise, constructs a `shared_ptr`
217
+ that owns `p` and a deleter of an unspecified type that calls
218
+ `delete[] p`. When `T` is not an array type, enables `shared_from_this`
219
+ with `p`. If an exception is thrown, `delete p` is called when `T` is
220
+ not an array type, `delete[] p` otherwise.
221
 
222
  *Postconditions:* `use_count() == 1 && get() == p`.
223
 
224
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
225
  resource other than memory could not be obtained.
226
 
227
+ *Remarks:* When `T` is an array type, this constructor shall not
228
+ participate in overload resolution unless the expression `delete[] p` is
229
+ well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
230
+ `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
231
+ not an array type, this constructor shall not participate in overload
232
+ resolution unless the expression `delete p` is well-formed and `Y*` is
233
+ convertible to `T*`.
234
 
235
  ``` cpp
236
  template<class Y, class D> shared_ptr(Y* p, D d);
237
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
238
  template <class D> shared_ptr(nullptr_t p, D d);
239
  template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
240
  ```
241
 
242
+ *Requires:* Construction of `d` and a deleter of type `D` initialized
243
+ with `std::move(d)` shall not throw exceptions. The expression `d(p)`
244
+ shall have well-defined behavior and shall not throw exceptions. `A`
245
+ shall be an allocator ([[allocator.requirements]]).
 
 
246
 
247
+ *Effects:* Constructs a `shared_ptr` object that owns the object `p` and
248
+ the deleter `d`. When `T` is not an array type, the first and second
249
+ constructors enable `shared_from_this` with `p`. The second and fourth
250
+ constructors shall use a copy of `a` to allocate memory for internal
251
+ use. If an exception is thrown, `d(p)` is called.
252
 
253
  *Postconditions:* `use_count() == 1 && get() == p`.
254
 
255
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
256
  resource other than memory could not be obtained.
257
 
258
+ *Remarks:* When `T` is an array type, this constructor shall not
259
+ participate in overload resolution unless `is_move_constructible_v<D>`
260
+ is `true`, the expression `d(p)` is well-formed, and either `T` is
261
+ `U[N]` and `Y(*)[N]` is convertible to `T*`, or `T` is `U[]` and
262
+ `Y(*)[]` is convertible to `T*`. When `T` is not an array type, this
263
+ constructor shall not participate in overload resolution unless
264
+ `is_move_constructible_v<D>` is `true`, the expression `d(p)` is
265
+ well-formed, and `Y*` is convertible to `T*`.
266
 
267
  ``` cpp
268
+ template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
269
  ```
270
 
271
+ *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
272
+ ownership with `r`.
273
 
274
+ *Postconditions:* `get() == p && use_count() == r.use_count()`.
275
 
276
+ [*Note 1*: To avoid the possibility of a dangling pointer, the user of
277
+ this constructor must ensure that `p` remains valid at least until the
278
+ ownership group of `r` is destroyed. — *end note*]
279
 
280
+ [*Note 2*: This constructor allows creation of an empty `shared_ptr`
281
+ instance with a non-null stored pointer. — *end note*]
282
 
283
  ``` cpp
284
  shared_ptr(const shared_ptr& r) noexcept;
285
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
286
  ```
287
 
288
+ *Remarks:* The second constructor shall not participate in overload
289
+ resolution unless `Y*` is compatible with `T*`.
290
 
291
+ *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
292
+ otherwise, constructs a `shared_ptr` object that shares ownership with
293
  `r`.
294
 
295
  *Postconditions:* `get() == r.get() && use_count() == r.use_count()`.
296
 
297
  ``` cpp
298
  shared_ptr(shared_ptr&& r) noexcept;
299
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
300
  ```
301
 
302
+ *Remarks:* The second constructor shall not participate in overload
303
+ resolution unless `Y*` is compatible with `T*`.
304
 
305
+ *Effects:* Move constructs a `shared_ptr` instance from `r`.
306
 
307
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
308
+ be empty. `r.get() == nullptr`.
309
 
310
  ``` cpp
311
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
312
  ```
313
 
314
+ *Effects:* Constructs a `shared_ptr` object that shares ownership with
315
+ `r` and stores a copy of the pointer stored in `r`. If an exception is
316
+ thrown, the constructor has no effect.
 
317
 
318
  *Postconditions:* `use_count() == r.use_count()`.
319
 
320
  *Throws:* `bad_weak_ptr` when `r.expired()`.
321
 
322
+ *Remarks:* This constructor shall not participate in overload resolution
323
+ unless `Y*` is compatible with `T*`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
 
325
  ``` cpp
326
  template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
327
  ```
328
 
329
+ *Remarks:* This constructor shall not participate in overload resolution
330
+ unless `Y*` is compatible with `T*` and `unique_ptr<Y, D>::pointer` is
331
+ convertible to `element_type*`.
332
 
333
+ *Effects:* If `r.get() == nullptr`, equivalent to `shared_ptr()`.
334
+ Otherwise, if `D` is not a reference type, equivalent to
335
+ `shared_ptr(r.release(), r.get_deleter())`. Otherwise, equivalent to
336
+ `shared_ptr(r.release(), ref(r.get_deleter()))`. If an exception is
337
+ thrown, the constructor has no effect.
338
 
339
  ##### `shared_ptr` destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
340
 
341
  ``` cpp
342
  ~shared_ptr();
343
  ```
344
 
345
  *Effects:*
346
 
347
+ - If `*this` is empty or shares ownership with another `shared_ptr`
348
  instance (`use_count() > 1`), there are no side effects.
349
+ - Otherwise, if `*this` owns an object `p` and a deleter `d`, `d(p)` is
350
+ called.
351
+ - Otherwise, `*this` owns a pointer `p`, and `delete p` is called.
352
 
353
+ [*Note 1*: Since the destruction of `*this` decreases the number of
354
+ instances that share ownership with `*this` by one, after `*this` has
355
+ been destroyed all `shared_ptr` instances that shared ownership with
356
+ `*this` will report a `use_count()` that is one less than its previous
357
+ value. — *end note*]
358
 
359
  ##### `shared_ptr` assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
360
 
361
  ``` cpp
362
  shared_ptr& operator=(const shared_ptr& r) noexcept;
363
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
 
364
  ```
365
 
366
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
367
 
368
  *Returns:* `*this`.
369
 
370
+ [*Note 3*:
371
+
372
  The use count updates caused by the temporary object construction and
373
  destruction are not observable side effects, so the implementation may
374
  meet the effects (and the implied guarantees) via different means,
375
  without creating a temporary. In particular, in the example:
376
 
 
381
  q = p;
382
  ```
383
 
384
  both assignments may be no-ops.
385
 
386
+ — *end note*]
387
+
388
  ``` cpp
389
  shared_ptr& operator=(shared_ptr&& r) noexcept;
390
  template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
391
  ```
392
 
 
398
  template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
399
  ```
400
 
401
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
402
 
403
+ *Returns:* `*this`.
404
 
405
  ##### `shared_ptr` modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
406
 
407
  ``` cpp
408
  void swap(shared_ptr& r) noexcept;
 
435
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
436
 
437
  ##### `shared_ptr` observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
438
 
439
  ``` cpp
440
+ element_type* get() const noexcept;
441
  ```
442
 
443
+ *Returns:* The stored pointer.
444
 
445
  ``` cpp
446
  T& operator*() const noexcept;
447
  ```
448
 
449
  *Requires:* `get() != 0`.
450
 
451
  *Returns:* `*get()`.
452
 
453
+ *Remarks:* When `T` is an array type or cv `void`, it is unspecified
454
+ whether this member function is declared. If it is declared, it is
455
+ unspecified what its return type is, except that the declaration
456
+ (although not necessarily the definition) of the function shall be well
457
+ formed.
458
 
459
  ``` cpp
460
  T* operator->() const noexcept;
461
  ```
462
 
463
  *Requires:* `get() != 0`.
464
 
465
  *Returns:* `get()`.
466
 
467
+ *Remarks:* When `T` is an array type, it is unspecified whether this
468
+ member function is declared. If it is declared, it is unspecified what
469
+ its return type is, except that the declaration (although not
470
+ necessarily the definition) of the function shall be well formed.
471
+
472
+ ``` cpp
473
+ element_type& operator[](ptrdiff_t i) const;
474
+ ```
475
+
476
+ *Requires:* `get() != 0 && i >= 0`. If `T` is `U[N]`, `i < N`.
477
+
478
+ *Returns:* `get()[i]`.
479
+
480
+ *Remarks:* When `T` is not an array type, it is unspecified whether this
481
+ member function is declared. If it is declared, it is unspecified what
482
+ its return type is, except that the declaration (although not
483
+ necessarily the definition) of the function shall be well formed.
484
+
485
+ *Throws:* Nothing.
486
+
487
  ``` cpp
488
  long use_count() const noexcept;
489
  ```
490
 
491
+ *Returns:* The number of `shared_ptr` objects, `*this` included, that
492
+ share ownership with `*this`, or `0` when `*this` is empty.
493
 
494
+ *Synchronization:* None.
495
 
496
+ [*Note 4*: `get() == nullptr` does not imply a specific return value of
497
+ `use_count()`. *end note*]
 
498
 
499
+ [*Note 5*: `weak_ptr<T>::lock()` can affect the return value of
500
+ `use_count()`. — *end note*]
501
 
502
+ [*Note 6*: When multiple threads can affect the return value of
503
+ `use_count()`, the result should be treated as approximate. In
504
+ particular, `use_count() == 1` does not imply that accesses through a
505
+ previously destroyed `shared_ptr` have in any sense
506
+ completed. — *end note*]
507
 
508
  ``` cpp
509
  explicit operator bool() const noexcept;
510
  ```
511
 
512
  *Returns:* `get() != 0`.
513
 
514
  ``` cpp
515
+ template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
516
+ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
517
  ```
518
 
519
  *Returns:* An unspecified value such that
520
 
521
  - `x.owner_before(y)` defines a strict weak ordering as defined
 
526
  ownership or are both empty.
527
 
528
  ##### `shared_ptr` creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
529
 
530
  ``` cpp
531
+ template<class T, class... Args>
532
+ shared_ptr<T> make_shared(Args&&... args);
533
  template<class T, class A, class... Args>
534
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);
535
  ```
536
 
537
  *Requires:* The expression `::new (pv) T(std::forward<Args>(args)...)`,
538
  where `pv` has type `void*` and points to storage suitable to hold an
539
  object of type `T`, shall be well formed. `A` shall be an
540
+ allocator ([[allocator.requirements]]). The copy constructor and
541
  destructor of `A` shall not throw exceptions.
542
 
543
  *Effects:* Allocates memory suitable for an object of type `T` and
544
+ constructs an object in that memory via the placement *new-expression*
545
  `::new (pv) T(std::forward<Args>(args)...)`. The template
546
  `allocate_shared` uses a copy of `a` to allocate memory. If an exception
547
  is thrown, the functions have no effect.
548
 
549
  *Returns:* A `shared_ptr` instance that stores and owns the address of
550
  the newly constructed object of type `T`.
551
 
552
+ *Postconditions:* `get() != 0 && use_count() == 1`.
553
 
554
  *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
555
  the constructor of `T`.
556
 
557
+ *Remarks:* The `shared_ptr` constructor called by this function enables
558
+ `shared_from_this` with the address of the newly constructed object of
559
+ type `T`. Implementations should perform no more than one memory
560
+ allocation.
561
 
562
+ [*Note 7*: This provides efficiency equivalent to an intrusive smart
563
+ pointer. *end note*]
564
+
565
+ [*Note 8*: These functions will typically allocate more memory than
566
+ `sizeof(T)` to allow for internal bookkeeping structures such as the
567
+ reference counts. — *end note*]
568
 
569
  ##### `shared_ptr` comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
570
 
571
  ``` cpp
572
+ template<class T, class U>
573
+ bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
574
  ```
575
 
576
  *Returns:* `a.get() == b.get()`.
577
 
578
  ``` cpp
579
+ template<class T, class U>
580
+ bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
581
  ```
582
 
583
+ *Returns:* `less<>()(a.get(), b.get())`.
 
584
 
585
+ [*Note 9*: Defining a comparison function allows `shared_ptr` objects
586
+ to be used as keys in associative containers. — *end note*]
587
 
588
  ``` cpp
589
  template <class T>
590
  bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
591
  template <class T>
 
609
  template <class T>
610
  bool operator<(nullptr_t, const shared_ptr<T>& a) noexcept;
611
  ```
612
 
613
  *Returns:* The first function template returns
614
+ `less<shared_ptr<T>::element_type*>()(a.get(), nullptr)`. The second
615
+ function template returns
616
+ `less<shared_ptr<T>::element_type*>()(nullptr, a.get())`.
617
 
618
  ``` cpp
619
  template <class T>
620
  bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
621
  template <class T>
 
646
  second function template returns `!(nullptr < a)`.
647
 
648
  ##### `shared_ptr` specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
649
 
650
  ``` cpp
651
+ template<class T>
652
+ void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
653
  ```
654
 
655
  *Effects:* Equivalent to `a.swap(b)`.
656
 
657
  ##### `shared_ptr` casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
658
 
659
  ``` cpp
660
+ template<class T, class U>
661
+ shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
662
  ```
663
 
664
+ *Requires:* The expression `static_cast<T*>((U*)0)` shall be well
665
  formed.
666
 
667
+ *Returns:*
 
 
668
 
669
+ ``` cpp
670
+ shared_ptr<T>(r, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
671
+ ```
672
 
673
+ [*Note 10*: The seemingly equivalent expression
674
  `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
675
+ undefined behavior, attempting to delete the same object
676
+ twice. — *end note*]
677
 
678
  ``` cpp
679
+ template<class T, class U>
680
+ shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
681
  ```
682
 
683
+ *Requires:* The expression `dynamic_cast<T*>((U*)0)` shall be well
684
  formed and shall have well defined behavior.
685
 
686
  *Returns:*
687
 
688
+ - When `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())`
689
+ returns a nonzero value `p`, `shared_ptr<T>(r, p)`.
690
+ - Otherwise, `shared_ptr<T>()`.
 
691
 
692
+ [*Note 11*: The seemingly equivalent expression
 
 
693
  `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
694
+ undefined behavior, attempting to delete the same object
695
+ twice. — *end note*]
696
 
697
  ``` cpp
698
+ template<class T, class U>
699
+ shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
700
  ```
701
 
702
+ *Requires:* The expression `const_cast<T*>((U*)0)` shall be well formed.
 
703
 
704
+ *Returns:*
 
 
705
 
706
+ ``` cpp
707
+ shared_ptr<T>(r, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
708
+ ```
709
 
710
+ [*Note 12*: The seemingly equivalent expression
711
  `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
712
+ undefined behavior, attempting to delete the same object
713
+ twice. — *end note*]
714
 
715
+ ``` cpp
716
+ template<class T, class U>
717
+ shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
718
+ ```
719
+
720
+ *Requires:* The expression `reinterpret_cast<T*>((U*)0)` shall be well
721
+ formed.
722
+
723
+ *Returns:*
724
+
725
+ ``` cpp
726
+ shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()))
727
+ ```
728
+
729
+ [*Note 13*: The seemingly equivalent expression
730
+ `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
731
+ undefined behavior, attempting to delete the same object
732
+ twice. — *end note*]
733
+
734
+ ##### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
735
 
736
  ``` cpp
737
+ template<class D, class T>
738
+ D* get_deleter(const shared_ptr<T>& p) noexcept;
739
  ```
740
 
741
+ *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
742
+ `addressof(d)`; otherwise returns `nullptr`. The returned pointer
743
+ remains valid as long as there exists a `shared_ptr` instance that owns
744
+ `d`.
745
+
746
+ [*Note 14*: It is unspecified whether the pointer remains valid longer
747
+ than that. This can happen if the implementation doesn’t destroy the
748
+ deleter until all `weak_ptr` instances that share ownership with `p`
749
+ have been destroyed. — *end note*]
750
 
751
  ##### `shared_ptr` I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
752
 
753
  ``` cpp
754
  template<class E, class T, class Y>
755
+ basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
756
  ```
757
 
758
+ *Effects:* As if by: `os << p.get();`
759
 
760
  *Returns:* `os`.
761
 
762
  #### Class template `weak_ptr` <a id="util.smartptr.weak">[[util.smartptr.weak]]</a>
763
 
 
767
 
768
  ``` cpp
769
  namespace std {
770
  template<class T> class weak_ptr {
771
  public:
772
+ using element_type = T;
773
 
774
  // [util.smartptr.weak.const], constructors
775
  constexpr weak_ptr() noexcept;
776
+ template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
777
+ weak_ptr(const weak_ptr& r) noexcept;
778
+ template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
779
  weak_ptr(weak_ptr&& r) noexcept;
780
  template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
781
 
782
  // [util.smartptr.weak.dest], destructor
783
  ~weak_ptr();
784
 
785
  // [util.smartptr.weak.assign], assignment
786
+ weak_ptr& operator=(const weak_ptr& r) noexcept;
787
+ template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
788
+ template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
789
  weak_ptr& operator=(weak_ptr&& r) noexcept;
790
  template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
791
 
792
  // [util.smartptr.weak.mod], modifiers
793
  void swap(weak_ptr& r) noexcept;
 
795
 
796
  // [util.smartptr.weak.obs], observers
797
  long use_count() const noexcept;
798
  bool expired() const noexcept;
799
  shared_ptr<T> lock() const noexcept;
800
+ template<class U> bool owner_before(const shared_ptr<U>& b) const;
801
+ template<class U> bool owner_before(const weak_ptr<U>& b) const;
802
  };
803
 
804
+ template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
805
+
806
+
807
  // [util.smartptr.weak.spec], specialized algorithms
808
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
809
+ }
810
  ```
811
 
812
  Specializations of `weak_ptr` shall be `CopyConstructible` and
813
  `CopyAssignable`, allowing their use in standard containers. The
814
  template parameter `T` of `weak_ptr` may be an incomplete type.
 
817
 
818
  ``` cpp
819
  constexpr weak_ptr() noexcept;
820
  ```
821
 
822
+ *Effects:* Constructs an empty `weak_ptr` object.
823
 
824
  *Postconditions:* `use_count() == 0`.
825
 
826
  ``` cpp
827
  weak_ptr(const weak_ptr& r) noexcept;
828
  template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
829
  template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
830
  ```
831
 
832
+ *Remarks:* The second and third constructors shall not participate in
833
+ overload resolution unless `Y*` is compatible with `T*`.
834
 
835
+ *Effects:* If `r` is empty, constructs an empty `weak_ptr` object;
836
+ otherwise, constructs a `weak_ptr` object that shares ownership with `r`
837
+ and stores a copy of the pointer stored in `r`.
838
 
839
  *Postconditions:* `use_count() == r.use_count()`.
840
 
841
  ``` cpp
842
  weak_ptr(weak_ptr&& r) noexcept;
843
  template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
844
  ```
845
 
846
+ *Remarks:* The second constructor shall not participate in overload
847
+ resolution unless `Y*` is compatible with `T*`.
848
 
849
+ *Effects:* Move constructs a `weak_ptr` instance from `r`.
850
 
851
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
852
+ be empty. `r.use_count() == 0`.
853
 
854
  ##### `weak_ptr` destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
855
 
856
  ``` cpp
857
  ~weak_ptr();
 
902
 
903
  ``` cpp
904
  long use_count() const noexcept;
905
  ```
906
 
907
+ *Returns:* `0` if `*this` is empty; otherwise, the number of
908
+ `shared_ptr` instances that share ownership with `*this`.
 
 
909
 
910
  ``` cpp
911
  bool expired() const noexcept;
912
  ```
913
 
914
  *Returns:* `use_count() == 0`.
915
 
 
 
916
  ``` cpp
917
  shared_ptr<T> lock() const noexcept;
918
  ```
919
 
920
+ *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
921
  executed atomically.
922
 
923
  ``` cpp
924
+ template<class U> bool owner_before(const shared_ptr<U>& b) const;
925
+ template<class U> bool owner_before(const weak_ptr<U>& b) const;
926
  ```
927
 
928
  *Returns:* An unspecified value such that
929
 
930
  - `x.owner_before(y)` defines a strict weak ordering as defined
 
935
  ownership or are both empty.
936
 
937
  ##### `weak_ptr` specialized algorithms <a id="util.smartptr.weak.spec">[[util.smartptr.weak.spec]]</a>
938
 
939
  ``` cpp
940
+ template<class T>
941
+ void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
942
  ```
943
 
944
  *Effects:* Equivalent to `a.swap(b)`.
945
 
946
  #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
 
948
  The class template `owner_less` allows ownership-based mixed comparisons
949
  of shared and weak pointers.
950
 
951
  ``` cpp
952
  namespace std {
953
+ template<class T = void> struct owner_less;
954
 
955
  template<class T> struct owner_less<shared_ptr<T>> {
956
+ bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
957
+ bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
958
+ bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
 
 
 
959
  };
960
 
961
  template<class T> struct owner_less<weak_ptr<T>> {
962
+ bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
963
+ bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
964
+ bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
965
+ };
966
+
967
+ template<> struct owner_less<void> {
968
+ template<class T, class U>
969
+ bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
970
+ template<class T, class U>
971
+ bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
972
+ template<class T, class U>
973
+ bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
974
+ template<class T, class U>
975
+ bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;
976
+
977
+ using is_transparent = unspecified;
978
  };
979
  }
980
  ```
981
 
982
+ `operator()(x, y)` shall return `x.owner_before(y)`.
983
+
984
+ [*Note 1*:
985
+
986
+ Note that
987
 
988
  - `operator()` defines a strict weak ordering as defined in 
989
  [[alg.sorting]];
990
  - under the equivalence relation defined by `operator()`,
991
  `!operator()(a, b) && !operator()(b, a)`, two `shared_ptr` or
992
  `weak_ptr` instances are equivalent if and only if they share
993
  ownership or are both empty.
994
 
995
+ — *end note*]
996
+
997
  #### Class template `enable_shared_from_this` <a id="util.smartptr.enab">[[util.smartptr.enab]]</a>
998
 
999
  A class `T` can inherit from `enable_shared_from_this<T>` to inherit the
1000
+ `shared_from_this` member functions that obtain a `shared_ptr` instance
1001
  pointing to `*this`.
1002
 
1003
+ [*Example 1*:
1004
+
1005
  ``` cpp
1006
+ struct X: public enable_shared_from_this<X> { };
 
1007
 
1008
  int main() {
1009
  shared_ptr<X> p(new X);
1010
  shared_ptr<X> q = p->shared_from_this();
1011
  assert(p == q);
1012
+ assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
1013
  }
1014
  ```
1015
 
1016
+ — *end example*]
1017
+
1018
  ``` cpp
1019
  namespace std {
1020
  template<class T> class enable_shared_from_this {
1021
  protected:
1022
  constexpr enable_shared_from_this() noexcept;
1023
+ enable_shared_from_this(const enable_shared_from_this&) noexcept;
1024
+ enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
1025
  ~enable_shared_from_this();
1026
  public:
1027
  shared_ptr<T> shared_from_this();
1028
  shared_ptr<T const> shared_from_this() const;
1029
+ weak_ptr<T> weak_from_this() noexcept;
1030
+ weak_ptr<T const> weak_from_this() const noexcept;
1031
+ private:
1032
+ mutable weak_ptr<T> weak_this; // exposition only
1033
  };
1034
+ }
1035
  ```
1036
 
1037
  The template parameter `T` of `enable_shared_from_this` may be an
1038
  incomplete type.
1039
 
1040
  ``` cpp
1041
  constexpr enable_shared_from_this() noexcept;
1042
  enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
1043
  ```
1044
 
1045
+ *Effects:* Value-initializes `weak_this`.
1046
 
1047
  ``` cpp
1048
  enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
1049
  ```
1050
 
1051
  *Returns:* `*this`.
1052
 
1053
+ [*Note 1*: `weak_this` is not changed. — *end note*]
 
 
 
 
1054
 
1055
  ``` cpp
1056
  shared_ptr<T> shared_from_this();
1057
  shared_ptr<T const> shared_from_this() const;
1058
  ```
1059
 
1060
+ *Returns:* `shared_ptr<T>(weak_this)`.
 
 
 
 
 
 
 
 
 
1061
 
1062
  ``` cpp
1063
+ weak_ptr<T> weak_from_this() noexcept;
1064
+ weak_ptr<T const> weak_from_this() const noexcept;
 
 
 
 
 
 
 
 
 
 
1065
  ```
1066
 
1067
+ *Returns:* `weak_this`.
 
 
1068
 
1069
  #### `shared_ptr` atomic access <a id="util.smartptr.shared.atomic">[[util.smartptr.shared.atomic]]</a>
1070
 
1071
  Concurrent access to a `shared_ptr` object from multiple threads does
1072
  not introduce a data race if the access is done exclusively via the
 
1118
  void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
1119
  ```
1120
 
1121
  *Requires:* `p` shall not be null.
1122
 
1123
+ *Effects:* As if by `atomic_store_explicit(p, r, memory_order_seq_cst)`.
1124
 
1125
  *Throws:* Nothing.
1126
 
1127
  ``` cpp
1128
  template<class T>
 
1132
  *Requires:* `p` shall not be null.
1133
 
1134
  *Requires:* `mo` shall not be `memory_order_acquire` or
1135
  `memory_order_acq_rel`.
1136
 
1137
+ *Effects:* As if by `p->swap(r)`.
1138
 
1139
  *Throws:* Nothing.
1140
 
1141
  ``` cpp
1142
  template<class T>
 
1149
 
1150
  *Throws:* Nothing.
1151
 
1152
  ``` cpp
1153
  template<class T>
1154
+ shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
 
1155
  ```
1156
 
1157
  *Requires:* `p` shall not be null.
1158
 
1159
+ *Effects:* As if by `p->swap(r)`.
1160
 
1161
  *Returns:* The previous value of `*p`.
1162
 
1163
  *Throws:* Nothing.
1164
 
1165
  ``` cpp
1166
  template<class T>
1167
+ bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
 
1168
  ```
1169
 
1170
  *Requires:* `p` shall not be null and `v` shall not be null.
1171
 
1172
  *Returns:*
1173
+
1174
+ ``` cpp
1175
+ atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)
1176
+ ```
1177
 
1178
  *Throws:* Nothing.
1179
 
1180
  ``` cpp
1181
  template<class T>
1182
+ bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
 
1183
  ```
1184
 
1185
+ *Returns:*
1186
+
1187
+ ``` cpp
1188
+ atomic_compare_exchange_strong_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)
1189
+ ```
1190
 
1191
  ``` cpp
1192
  template<class T>
1193
  bool atomic_compare_exchange_weak_explicit(
1194
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
 
1197
  bool atomic_compare_exchange_strong_explicit(
1198
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
1199
  memory_order success, memory_order failure);
1200
  ```
1201
 
1202
+ *Requires:* `p` shall not be null and `v` shall not be null. The
1203
+ `failure` argument shall not be `memory_order_release` nor
1204
+ `memory_order_acq_rel`.
 
1205
 
1206
  *Effects:* If `*p` is equivalent to `*v`, assigns `w` to `*p` and has
1207
  synchronization semantics corresponding to the value of `success`,
1208
  otherwise assigns `*p` to `*v` and has synchronization semantics
1209
  corresponding to the value of `failure`.
1210
 
1211
  *Returns:* `true` if `*p` was equivalent to `*v`, `false` otherwise.
1212
 
1213
  *Throws:* Nothing.
1214
 
1215
+ *Remarks:* Two `shared_ptr` objects are equivalent if they store the
1216
+ same pointer value and share ownership. The weak form may fail
1217
+ spuriously. See  [[atomics.types.operations]].
 
 
1218
 
1219
  #### Smart pointer hash support <a id="util.smartptr.hash">[[util.smartptr.hash]]</a>
1220
 
1221
  ``` cpp
1222
  template <class T, class D> struct hash<unique_ptr<T, D>>;
1223
  ```
1224
 
1225
+ Letting `UP` be `unique_ptr<T,D>`, the specialization `hash<UP>` is
1226
+ enabled ([[unord.hash]]) if and only if `hash<typename UP::pointer>` is
1227
+ enabled. When enabled, for an object `p` of type `UP`, `hash<UP>()(p)`
1228
+ shall evaluate to the same value as
1229
+ `hash<typename UP::pointer>()(p.get())`. The member functions are not
1230
+ guaranteed to be `noexcept`.
 
 
1231
 
1232
  ``` cpp
1233
  template <class T> struct hash<shared_ptr<T>>;
1234
  ```
1235
 
1236
+ For an object `p` of type `shared_ptr<T>`, `hash<shared_ptr<T>>()(p)`
1237
+ shall evaluate to the same value as
1238
+ `hash<typename shared_ptr<T>::element_type*>()(p.get())`.
 
1239