From Jason Turner

[util.smartptr.shared]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp8b0tqeqb/{from.md → to.md} +424 -263
tmp/tmp8b0tqeqb/{from.md → to.md} RENAMED
@@ -1,6 +1,6 @@
1
- #### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
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.
@@ -13,130 +13,88 @@ namespace std {
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>
75
- bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
76
- template<class T, class U>
77
- bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
78
- template<class T, class U>
79
- bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
80
- template<class T, class U>
81
- bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
82
-
83
  template<class T>
84
- bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
85
- template <class T>
86
- bool operator==(nullptr_t, const shared_ptr<T>& b) noexcept;
87
- template <class T>
88
- bool operator!=(const shared_ptr<T>& a, nullptr_t) noexcept;
89
- template <class T>
90
- bool operator!=(nullptr_t, const shared_ptr<T>& b) noexcept;
91
- template <class T>
92
- bool operator<(const shared_ptr<T>& a, nullptr_t) noexcept;
93
- template <class T>
94
- bool operator<(nullptr_t, const shared_ptr<T>& b) noexcept;
95
- template <class T>
96
- bool operator<=(const shared_ptr<T>& a, nullptr_t) noexcept;
97
- template <class T>
98
- bool operator<=(nullptr_t, const shared_ptr<T>& b) noexcept;
99
- template <class T>
100
- bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
101
- template <class T>
102
- bool operator>(nullptr_t, const shared_ptr<T>& b) noexcept;
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)) {
@@ -150,173 +108,168 @@ 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
 
@@ -332,22 +285,22 @@ thrown, the constructor has no effect.
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:
@@ -378,11 +331,11 @@ template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
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;
387
  ```
388
 
@@ -410,11 +363,11 @@ template<class Y, class D> void reset(Y* p, D d);
410
  template<class Y, class D, class A> void reset(Y* p, D d, A a);
411
  ```
412
 
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
 
@@ -422,45 +375,45 @@ element_type* get() const noexcept;
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;
@@ -469,17 +422,17 @@ long use_count() const noexcept;
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
 
@@ -501,217 +454,425 @@ template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
501
  - under the equivalence relation defined by `owner_before`,
502
  `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
503
  `weak_ptr` instances are equivalent if and only if they share
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>
570
- bool operator==(nullptr_t, const shared_ptr<T>& a) noexcept;
571
  ```
572
 
573
  *Returns:* `!a`.
574
 
575
  ``` cpp
576
- template <class T>
577
- bool operator!=(const shared_ptr<T>& a, nullptr_t) noexcept;
578
- template <class T>
579
- bool operator!=(nullptr_t, const shared_ptr<T>& a) noexcept;
580
- ```
581
-
582
- *Returns:* `(bool)a`.
583
-
584
- ``` cpp
585
- template <class T>
586
- bool operator<(const shared_ptr<T>& a, nullptr_t) noexcept;
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>
600
- bool operator>(nullptr_t, const shared_ptr<T>& a) noexcept;
601
  ```
602
 
603
- *Returns:* The first function template returns `nullptr < a`. The second
604
- function template returns `a < nullptr`.
605
-
606
- ``` cpp
607
- template <class T>
608
- bool operator<=(const shared_ptr<T>& a, nullptr_t) noexcept;
609
- template <class T>
610
- bool operator<=(nullptr_t, const shared_ptr<T>& a) noexcept;
611
- ```
612
 
613
- *Returns:* The first function template returns `!(nullptr < a)`. The
614
- second function template returns `!(a < nullptr)`.
615
 
616
  ``` cpp
617
  template<class T>
618
- bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
619
- template <class T>
620
- bool operator>=(nullptr_t, const shared_ptr<T>& a) noexcept;
621
  ```
622
 
623
- *Returns:* The first function template returns `!(a < nullptr)`. The
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
  ```
@@ -719,16 +880,16 @@ template<class D, class T>
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
  ```
 
1
+ ### Class template `shared_ptr` <a id="util.smartptr.shared">[[util.smartptr.shared]]</a>
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.
 
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
  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
19
+ template<class Y>
20
+ explicit shared_ptr(Y* p);
21
+ template<class Y, class D>
22
+ shared_ptr(Y* p, D d);
23
+ template<class Y, class D, class A>
24
+ shared_ptr(Y* p, D d, A a);
25
+ template<class D>
26
+ shared_ptr(nullptr_t p, D d);
27
+ template<class D, class A>
28
+ shared_ptr(nullptr_t p, D d, A a);
29
+ template<class Y>
30
+ shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
31
+ template<class Y>
32
+ shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
33
+ shared_ptr(const shared_ptr& r) noexcept;
34
+ template<class Y>
35
+ shared_ptr(const shared_ptr<Y>& r) noexcept;
36
+ shared_ptr(shared_ptr&& r) noexcept;
37
+ template<class Y>
38
+ shared_ptr(shared_ptr<Y>&& r) noexcept;
39
+ template<class Y>
40
+ explicit shared_ptr(const weak_ptr<Y>& r);
41
+ template<class Y, class D>
42
+ shared_ptr(unique_ptr<Y, D>&& r);
43
 
44
  // [util.smartptr.shared.dest], destructor
45
  ~shared_ptr();
46
 
47
  // [util.smartptr.shared.assign], assignment
48
  shared_ptr& operator=(const shared_ptr& r) noexcept;
49
+ template<class Y>
50
+ shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
51
  shared_ptr& operator=(shared_ptr&& r) noexcept;
52
+ template<class Y>
53
+ shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
54
+ template<class Y, class D>
55
+ shared_ptr& operator=(unique_ptr<Y, D>&& r);
56
 
57
  // [util.smartptr.shared.mod], modifiers
58
  void swap(shared_ptr& r) noexcept;
59
  void reset() noexcept;
60
+ template<class Y>
61
+ void reset(Y* p);
62
+ template<class Y, class D>
63
+ void reset(Y* p, D d);
64
+ template<class Y, class D, class A>
65
+ void reset(Y* p, D d, A a);
66
 
67
  // [util.smartptr.shared.obs], observers
68
  element_type* get() const noexcept;
69
  T& operator*() const noexcept;
70
  T* operator->() const noexcept;
71
  element_type& operator[](ptrdiff_t i) const;
72
  long use_count() const noexcept;
73
  explicit operator bool() const noexcept;
74
+ template<class U>
75
+ bool owner_before(const shared_ptr<U>& b) const noexcept;
76
+ template<class U>
77
+ bool owner_before(const weak_ptr<U>& b) const noexcept;
78
  };
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  template<class T>
81
+ shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
82
+ template<class T, class D>
83
+ shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  }
85
  ```
86
 
87
+ Specializations of `shared_ptr` shall be *Cpp17CopyConstructible*,
88
+ *Cpp17CopyAssignable*, and *Cpp17LessThanComparable*, allowing their use
89
+ in standard containers. Specializations of `shared_ptr` shall be
90
  contextually convertible to `bool`, allowing their use in boolean
91
+ expressions and declarations in conditions.
92
+
93
+ The template parameter `T` of `shared_ptr` may be an incomplete type.
94
+
95
+ [*Note 1*: `T` may be a function type. — *end note*]
96
 
97
  [*Example 1*:
98
 
99
  ``` cpp
100
  if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
 
108
  functions shall access and modify only the `shared_ptr` and `weak_ptr`
109
  objects themselves and not objects they refer to. Changes in
110
  `use_count()` do not reflect modifications that can introduce data
111
  races.
112
 
113
+ For the purposes of subclause [[smartptr]], a pointer type `Y*` is said
114
+ to be *compatible with* a pointer type `T*` when either `Y*` is
115
  convertible to `T*` or `Y` is `U[N]` and `T` is cv `U[]`.
116
 
117
+ #### Constructors <a id="util.smartptr.shared.const">[[util.smartptr.shared.const]]</a>
118
 
119
  In the constructor definitions below, enables `shared_from_this` with
120
  `p`, for a pointer `p` of type `Y*`, means that if `Y` has an
121
  unambiguous and accessible base class that is a specialization of
122
+ `enable_shared_from_this` [[util.smartptr.enab]], then `remove_cv_t<Y>*`
123
+ shall be implicitly convertible to `T*` and the constructor evaluates
124
+ the statement:
125
 
126
  ``` cpp
127
  if (p != nullptr && p->weak_this.expired())
128
  p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
129
  ```
130
 
131
  The assignment to the `weak_this` member is not atomic and conflicts
132
+ with any potentially concurrent access to the same object
133
+ [[intro.multithread]].
134
 
135
  ``` cpp
136
  constexpr shared_ptr() noexcept;
137
  ```
138
 
139
+ *Ensures:* `use_count() == 0 && get() == nullptr`.
 
 
140
 
141
  ``` cpp
142
  template<class Y> explicit shared_ptr(Y* p);
143
  ```
144
 
145
+ *Mandates:* `Y` is a complete type.
146
+
147
+ *Constraints:* When `T` is an array type, the expression `delete[] p` is
148
+ well-formed and either `T` is `U[N]` and `Y(*)[N]` is convertible to
149
+ `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to `T*`. When `T` is
150
+ not an array type, the expression `delete p` is well-formed and `Y*` is
151
+ convertible to `T*`.
152
+
153
+ *Preconditions:* The expression `delete[] p`, when `T` is an array type,
154
+ or `delete p`, when `T` is not an array type, has well-defined behavior,
155
+ and does not throw exceptions.
156
 
157
  *Effects:* When `T` is not an array type, constructs a `shared_ptr`
158
  object that owns the pointer `p`. Otherwise, constructs a `shared_ptr`
159
  that owns `p` and a deleter of an unspecified type that calls
160
  `delete[] p`. When `T` is not an array type, enables `shared_from_this`
161
  with `p`. If an exception is thrown, `delete p` is called when `T` is
162
  not an array type, `delete[] p` otherwise.
163
 
164
+ *Ensures:* `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
  ``` cpp
170
  template<class Y, class D> shared_ptr(Y* p, D d);
171
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
172
  template<class D> shared_ptr(nullptr_t p, D d);
173
  template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
174
  ```
175
 
176
+ *Constraints:* `is_move_constructible_v<D>` is `true`, and `d(p)` is a
177
+ well-formed expression. For the first two overloads:
178
+
179
+ - If `T` is an array type, then either `T` is `U[N]` and `Y(*)[N]` is
180
+ convertible to `T*`, or `T` is `U[]` and `Y(*)[]` is convertible to
181
+ `T*`.
182
+ - If `T` is not an array type, then `Y*` is convertible to `T*`.
183
+
184
+ *Preconditions:* Construction of `d` and a deleter of type `D`
185
+ initialized with `std::move(d)` do not throw exceptions. The expression
186
+ `d(p)` has well-defined behavior and does not throw exceptions. `A`
187
+ meets the *Cpp17Allocator* requirements ([[cpp17.allocator]]).
188
 
189
  *Effects:* Constructs a `shared_ptr` object that owns the object `p` and
190
  the deleter `d`. When `T` is not an array type, the first and second
191
  constructors enable `shared_from_this` with `p`. The second and fourth
192
  constructors shall use a copy of `a` to allocate memory for internal
193
  use. If an exception is thrown, `d(p)` is called.
194
 
195
+ *Ensures:* `use_count() == 1 && get() == p`.
196
 
197
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
198
  resource other than memory could not be obtained.
199
 
 
 
 
 
 
 
 
 
 
200
  ``` cpp
201
  template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
202
+ template<class Y> shared_ptr(shared_ptr<Y>&& r, element_type* p) noexcept;
203
  ```
204
 
205
  *Effects:* Constructs a `shared_ptr` instance that stores `p` and shares
206
+ ownership with the initial value of `r`.
207
 
208
+ *Ensures:* `get() == p`. For the second overload, `r` is empty and
209
+ `r.get() == nullptr`.
210
 
211
  [*Note 1*: To avoid the possibility of a dangling pointer, the user of
212
+ this constructor should ensure that `p` remains valid at least until the
213
  ownership group of `r` is destroyed. — *end note*]
214
 
215
  [*Note 2*: This constructor allows creation of an empty `shared_ptr`
216
  instance with a non-null stored pointer. — *end note*]
217
 
218
  ``` cpp
219
  shared_ptr(const shared_ptr& r) noexcept;
220
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
221
  ```
222
 
223
+ *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
 
224
 
225
  *Effects:* If `r` is empty, constructs an empty `shared_ptr` object;
226
  otherwise, constructs a `shared_ptr` object that shares ownership with
227
  `r`.
228
 
229
+ *Ensures:* `get() == r.get() && use_count() == r.use_count()`.
230
 
231
  ``` cpp
232
  shared_ptr(shared_ptr&& r) noexcept;
233
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
234
  ```
235
 
236
+ *Constraints:* For the second constructor, `Y*` is compatible with `T*`.
 
237
 
238
  *Effects:* Move constructs a `shared_ptr` instance from `r`.
239
 
240
+ *Ensures:* `*this` shall contain the old value of `r`. `r` shall be
241
+ empty. `r.get() == nullptr`.
242
 
243
  ``` cpp
244
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
245
  ```
246
 
247
+ *Constraints:* `Y*` is compatible with `T*`.
248
+
249
  *Effects:* Constructs a `shared_ptr` object that shares ownership with
250
  `r` and stores a copy of the pointer stored in `r`. If an exception is
251
  thrown, the constructor has no effect.
252
 
253
+ *Ensures:* `use_count() == r.use_count()`.
254
 
255
  *Throws:* `bad_weak_ptr` when `r.expired()`.
256
 
 
 
 
257
  ``` cpp
258
  template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
259
  ```
260
 
261
+ *Constraints:* `Y*` is compatible with `T*` and
262
+ `unique_ptr<Y, D>::pointer` is convertible to `element_type*`.
 
263
 
264
  *Effects:* If `r.get() == nullptr`, equivalent to `shared_ptr()`.
265
  Otherwise, if `D` is not a reference type, equivalent to
266
  `shared_ptr(r.release(), r.get_deleter())`. Otherwise, equivalent to
267
  `shared_ptr(r.release(), ref(r.get_deleter()))`. If an exception is
268
  thrown, the constructor has no effect.
269
 
270
+ #### Destructor <a id="util.smartptr.shared.dest">[[util.smartptr.shared.dest]]</a>
271
 
272
  ``` cpp
273
  ~shared_ptr();
274
  ```
275
 
 
285
  instances that share ownership with `*this` by one, after `*this` has
286
  been destroyed all `shared_ptr` instances that shared ownership with
287
  `*this` will report a `use_count()` that is one less than its previous
288
  value. — *end note*]
289
 
290
+ #### Assignment <a id="util.smartptr.shared.assign">[[util.smartptr.shared.assign]]</a>
291
 
292
  ``` cpp
293
  shared_ptr& operator=(const shared_ptr& r) noexcept;
294
  template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
295
  ```
296
 
297
  *Effects:* Equivalent to `shared_ptr(r).swap(*this)`.
298
 
299
  *Returns:* `*this`.
300
 
301
+ [*Note 1*:
302
 
303
  The use count updates caused by the temporary object construction and
304
  destruction are not observable side effects, so the implementation may
305
  meet the effects (and the implied guarantees) via different means,
306
  without creating a temporary. In particular, in the example:
 
331
 
332
  *Effects:* Equivalent to `shared_ptr(std::move(r)).swap(*this)`.
333
 
334
  *Returns:* `*this`.
335
 
336
+ #### Modifiers <a id="util.smartptr.shared.mod">[[util.smartptr.shared.mod]]</a>
337
 
338
  ``` cpp
339
  void swap(shared_ptr& r) noexcept;
340
  ```
341
 
 
363
  template<class Y, class D, class A> void reset(Y* p, D d, A a);
364
  ```
365
 
366
  *Effects:* Equivalent to `shared_ptr(p, d, a).swap(*this)`.
367
 
368
+ #### Observers <a id="util.smartptr.shared.obs">[[util.smartptr.shared.obs]]</a>
369
 
370
  ``` cpp
371
  element_type* get() const noexcept;
372
  ```
373
 
 
375
 
376
  ``` cpp
377
  T& operator*() const noexcept;
378
  ```
379
 
380
+ *Preconditions:* `get() != 0`.
381
 
382
  *Returns:* `*get()`.
383
 
384
  *Remarks:* When `T` is an array type or cv `void`, it is unspecified
385
  whether this member function is declared. If it is declared, it is
386
  unspecified what its return type is, except that the declaration
387
+ (although not necessarily the definition) of the function shall be
388
+ well-formed.
389
 
390
  ``` cpp
391
  T* operator->() const noexcept;
392
  ```
393
 
394
+ *Preconditions:* `get() != 0`.
395
 
396
  *Returns:* `get()`.
397
 
398
  *Remarks:* When `T` is an array type, it is unspecified whether this
399
  member function is declared. If it is declared, it is unspecified what
400
  its return type is, except that the declaration (although not
401
+ necessarily the definition) of the function shall be well-formed.
402
 
403
  ``` cpp
404
  element_type& operator[](ptrdiff_t i) const;
405
  ```
406
 
407
+ *Preconditions:* `get() != 0 && i >= 0`. If `T` is `U[N]`, `i < N`.
408
 
409
  *Returns:* `get()[i]`.
410
 
411
  *Remarks:* When `T` is not an array type, it is unspecified whether this
412
  member function is declared. If it is declared, it is unspecified what
413
  its return type is, except that the declaration (although not
414
+ necessarily the definition) of the function shall be well-formed.
415
 
416
  *Throws:* Nothing.
417
 
418
  ``` cpp
419
  long use_count() const noexcept;
 
422
  *Returns:* The number of `shared_ptr` objects, `*this` included, that
423
  share ownership with `*this`, or `0` when `*this` is empty.
424
 
425
  *Synchronization:* None.
426
 
427
+ [*Note 1*: `get() == nullptr` does not imply a specific return value of
428
  `use_count()`. — *end note*]
429
 
430
+ [*Note 2*: `weak_ptr<T>::lock()` can affect the return value of
431
  `use_count()`. — *end note*]
432
 
433
+ [*Note 3*: When multiple threads can affect the return value of
434
  `use_count()`, the result should be treated as approximate. In
435
  particular, `use_count() == 1` does not imply that accesses through a
436
  previously destroyed `shared_ptr` have in any sense
437
  completed. — *end note*]
438
 
 
454
  - under the equivalence relation defined by `owner_before`,
455
  `!a.owner_before(b) && !b.owner_before(a)`, two `shared_ptr` or
456
  `weak_ptr` instances are equivalent if and only if they share
457
  ownership or are both empty.
458
 
459
+ #### Creation <a id="util.smartptr.shared.create">[[util.smartptr.shared.create]]</a>
460
+
461
+ The common requirements that apply to all `make_shared`,
462
+ `allocate_shared`, `make_shared_for_overwrite`, and
463
+ `allocate_shared_for_overwrite` overloads, unless specified otherwise,
464
+ are described below.
465
 
466
  ``` cpp
467
+ template<class T, ...>
468
+ shared_ptr<T> make_shared(args);
469
+ template<class T, class A, ...>
470
+ shared_ptr<T> allocate_shared(const A& a, args);
471
+ template<class T, ...>
472
+ shared_ptr<T> make_shared_for_overwrite(args);
473
+ template<class T, class A, ...>
474
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, args);
475
  ```
476
 
477
+ *Preconditions:* `A` meets the *Cpp17Allocator* requirements
478
+ ([[cpp17.allocator]]).
 
 
 
479
 
480
+ *Effects:* Allocates memory for an object of type `T` (or `U[N]` when
481
+ `T` is `U[]`, where `N` is determined from *args* as specified by the
482
+ concrete overload). The object is initialized from *args* as specified
483
+ by the concrete overload. The `allocate_shared` and
484
+ `allocate_shared_for_overwrite` templates use a copy of `a` (rebound for
485
+ an unspecified `value_type`) to allocate memory. If an exception is
486
+ thrown, the functions have no effect.
487
 
488
  *Returns:* A `shared_ptr` instance that stores and owns the address of
489
+ the newly constructed object.
490
 
491
+ *Ensures:* `r.get() != 0 && r.use_count() == 1`, where `r` is the return
492
+ value.
493
 
494
+ *Throws:* `bad_alloc`, or an exception thrown from `allocate` or from
495
+ the initialization of the object.
496
 
497
+ *Remarks:*
 
 
 
498
 
499
+ - Implementations should perform no more than one memory allocation.
500
+ \[*Note 1*: This provides efficiency equivalent to an intrusive smart
501
  pointer. — *end note*]
502
+ - When an object of an array type `U` is specified to have an initial
503
+ value of `u` (of the same type), this shall be interpreted to mean
504
+ that each array element of the object has as its initial value the
505
+ corresponding element from `u`.
506
+ - When an object of an array type is specified to have a default initial
507
+ value, this shall be interpreted to mean that each array element of
508
+ the object has a default initial value.
509
+ - When a (sub)object of a non-array type `U` is specified to have an
510
+ initial value of `v`, or `U(l...)`, where `l...` is a list of
511
+ constructor arguments, `make_shared` shall initialize this (sub)object
512
+ via the expression `::new(pv) U(v)` or `::new(pv) U(l...)`
513
+ respectively, where `pv` has type `void*` and points to storage
514
+ suitable to hold an object of type `U`.
515
+ - When a (sub)object of a non-array type `U` is specified to have an
516
+ initial value of `v`, or `U(l...)`, where `l...` is a list of
517
+ constructor arguments, `allocate_shared` shall initialize this
518
+ (sub)object via the expression
519
+ - `allocator_traits<A2>::construct(a2, pv, v)` or
520
+ - `allocator_traits<A2>::construct(a2, pv, l...)`
521
 
522
+ respectively, where `pv` points to storage suitable to hold an object
523
+ of type `U` and `a2` of type `A2` is a rebound copy of the allocator
524
+ `a` passed to `allocate_shared` such that its `value_type` is
525
+ `remove_cv_t<U>`.
526
+ - When a (sub)object of non-array type `U` is specified to have a
527
+ default initial value, `make_shared` shall initialize this (sub)object
528
+ via the expression `::new(pv) U()`, where `pv` has type `void*` and
529
+ points to storage suitable to hold an object of type `U`.
530
+ - When a (sub)object of non-array type `U` is specified to have a
531
+ default initial value, `allocate_shared` shall initialize this
532
+ (sub)object via the expression
533
+ `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to
534
+ storage suitable to hold an object of type `U` and `a2` of type `A2`
535
+ is a rebound copy of the allocator `a` passed to `allocate_shared`
536
+ such that its `value_type` is `remove_cv_t<U>`.
537
+ - When a (sub)object of non-array type `U` is initialized by
538
+ `make_shared_for_overwrite` or `allocate_shared_for_overwrite`, it is
539
+ initialized via the expression `::new(pv) U`, where `pv` has type
540
+ `void*` and points to storage suitable to hold an object of type `U`.
541
+ - Array elements are initialized in ascending order of their addresses.
542
+ - When the lifetime of the object managed by the return value ends, or
543
+ when the initialization of an array element throws an exception, the
544
+ initialized elements are destroyed in the reverse order of their
545
+ original construction.
546
+ - When a (sub)object of non-array type `U` that was initialized by
547
+ `make_shared` is to be destroyed, it is destroyed via the expression
548
+ `pv->~U()` where `pv` points to that object of type `U`.
549
+ - When a (sub)object of non-array type `U` that was initialized by
550
+ `allocate_shared` is to be destroyed, it is destroyed via the
551
+ expression `allocator_traits<A2>::destroy(a2, pv)` where `pv` points
552
+ to that object of type `remove_cv_t<U>` and `a2` of type `A2` is a
553
+ rebound copy of the allocator `a` passed to `allocate_shared` such
554
+ that its `value_type` is `remove_cv_t<U>`.
555
+
556
+ [*Note 1*: These functions will typically allocate more memory than
557
+ `sizeof(T)` to allow for internal bookkeeping structures such as
558
  reference counts. — *end note*]
559
 
560
+ ``` cpp
561
+ template<class T, class... Args>
562
+ shared_ptr<T> make_shared(Args&&... args); // T is not array
563
+ template<class T, class A, class... Args>
564
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
565
+ ```
566
+
567
+ *Constraints:* `T` is not an array type.
568
+
569
+ *Returns:* A `shared_ptr` to an object of type `T` with an initial value
570
+ `T(forward<Args>(args)...)`.
571
+
572
+ *Remarks:* The `shared_ptr` constructors called by these functions
573
+ enable `shared_from_this` with the address of the newly constructed
574
+ object of type `T`.
575
+
576
+ [*Example 1*:
577
+
578
+ ``` cpp
579
+ shared_ptr<int> p = make_shared<int>(); // shared_ptr to int()
580
+ shared_ptr<vector<int>> q = make_shared<vector<int>>(16, 1);
581
+ // shared_ptr to vector of 16 elements with value 1
582
+ ```
583
+
584
+ — *end example*]
585
+
586
+ ``` cpp
587
+ template<class T> shared_ptr<T>
588
+ make_shared(size_t N); // T is U[]
589
+ template<class T, class A>
590
+ shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
591
+ ```
592
+
593
+ *Constraints:* `T` is of the form `U[]`.
594
+
595
+ *Returns:* A `shared_ptr` to an object of type `U[N]` with a default
596
+ initial value, where `U` is `remove_extent_t<T>`.
597
+
598
+ [*Example 2*:
599
+
600
+ ``` cpp
601
+ shared_ptr<double[]> p = make_shared<double[]>(1024);
602
+ // shared_ptr to a value-initialized double[1024]
603
+ shared_ptr<double[][2][2]> q = make_shared<double[][2][2]>(6);
604
+ // shared_ptr to a value-initialized double[6][2][2]
605
+ ```
606
+
607
+ — *end example*]
608
+
609
+ ``` cpp
610
+ template<class T>
611
+ shared_ptr<T> make_shared(); // T is U[N]
612
+ template<class T, class A>
613
+ shared_ptr<T> allocate_shared(const A& a); // T is U[N]
614
+ ```
615
+
616
+ *Constraints:* `T` is of the form `U[N]`.
617
+
618
+ *Returns:* A `shared_ptr` to an object of type `T` with a default
619
+ initial value.
620
+
621
+ [*Example 3*:
622
+
623
+ ``` cpp
624
+ shared_ptr<double[1024]> p = make_shared<double[1024]>();
625
+ // shared_ptr to a value-initialized double[1024]
626
+ shared_ptr<double[6][2][2]> q = make_shared<double[6][2][2]>();
627
+ // shared_ptr to a value-initialized double[6][2][2]
628
+ ```
629
+
630
+ — *end example*]
631
+
632
+ ``` cpp
633
+ template<class T>
634
+ shared_ptr<T> make_shared(size_t N,
635
+ const remove_extent_t<T>& u); // T is U[]
636
+ template<class T, class A>
637
+ shared_ptr<T> allocate_shared(const A& a, size_t N,
638
+ const remove_extent_t<T>& u); // T is U[]
639
+ ```
640
+
641
+ *Constraints:* `T` is of the form `U[]`.
642
+
643
+ *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
644
+ `remove_extent_t<T>` and each array element has an initial value of `u`.
645
+
646
+ [*Example 4*:
647
+
648
+ ``` cpp
649
+ shared_ptr<double[]> p = make_shared<double[]>(1024, 1.0);
650
+ // shared_ptr to a double[1024], where each element is 1.0
651
+ shared_ptr<double[][2]> q = make_shared<double[][2]>(6, {1.0, 0.0});
652
+ // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
653
+ shared_ptr<vector<int>[]> r = make_shared<vector<int>[]>(4, {1, 2});
654
+ // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
655
+ ```
656
+
657
+ — *end example*]
658
+
659
+ ``` cpp
660
+ template<class T>
661
+ shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]
662
+ template<class T, class A>
663
+ shared_ptr<T> allocate_shared(const A& a,
664
+ const remove_extent_t<T>& u); // T is U[N]
665
+ ```
666
+
667
+ *Constraints:* `T` is of the form `U[N]`.
668
+
669
+ *Returns:* A `shared_ptr` to an object of type `T`, where each array
670
+ element of type `remove_extent_t<T>` has an initial value of `u`.
671
+
672
+ [*Example 5*:
673
+
674
+ ``` cpp
675
+ shared_ptr<double[1024]> p = make_shared<double[1024]>(1.0);
676
+ // shared_ptr to a double[1024], where each element is 1.0
677
+ shared_ptr<double[6][2]> q = make_shared<double[6][2]>({1.0, 0.0});
678
+ // shared_ptr to a double[6][2], where each double[2] element is {1.0, 0.0}
679
+ shared_ptr<vector<int>[4]> r = make_shared<vector<int>[4]>({1, 2});
680
+ // shared_ptr to a vector<int>[4], where each vector has contents {1, 2}
681
+ ```
682
+
683
+ — *end example*]
684
+
685
+ ``` cpp
686
+ template<class T>
687
+ shared_ptr<T> make_shared_for_overwrite();
688
+ template<class T, class A>
689
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a);
690
+ ```
691
+
692
+ *Constraints:* `T` is not an array of unknown bound.
693
+
694
+ *Returns:* A `shared_ptr` to an object of type `T`.
695
+
696
+ [*Example 6*:
697
+
698
+ ``` cpp
699
+ struct X { double data[1024]; };
700
+ shared_ptr<X> p = make_shared_for_overwrite<X>();
701
+ // shared_ptr to a default-initialized X, where each element in X::data has an indeterminate value
702
+
703
+ shared_ptr<double[1024]> q = make_shared_for_overwrite<double[1024]>();
704
+ // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value
705
+ ```
706
+
707
+ — *end example*]
708
+
709
+ ``` cpp
710
+ template<class T>
711
+ shared_ptr<T> make_shared_for_overwrite(size_t N);
712
+ template<class T, class A>
713
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);
714
+ ```
715
+
716
+ *Constraints:* `T` is an array of unknown bound.
717
+
718
+ *Returns:* A `shared_ptr` to an object of type `U[N]`, where `U` is
719
+ `remove_extent_t<T>`.
720
+
721
+ [*Example 7*:
722
+
723
+ ``` cpp
724
+ shared_ptr<double[]> p = make_shared_for_overwrite<double[]>(1024);
725
+ // shared_ptr to a default-initialized double[1024], where each element has an indeterminate value
726
+ ```
727
+
728
+ — *end example*]
729
+
730
+ #### Comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
731
 
732
  ``` cpp
733
  template<class T, class U>
734
  bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
735
  ```
736
 
737
  *Returns:* `a.get() == b.get()`.
738
 
 
 
 
 
 
 
 
 
 
 
739
  ``` cpp
740
  template<class T>
741
  bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
 
 
742
  ```
743
 
744
  *Returns:* `!a`.
745
 
746
  ``` cpp
747
+ template<class T, class U>
748
+ strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
749
  ```
750
 
751
+ *Returns:* `compare_three_way()(a.get(), b.get())`.
 
 
 
 
 
 
 
 
752
 
753
+ [*Note 1*: Defining a comparison function allows `shared_ptr` objects
754
+ to be used as keys in associative containers. — *end note*]
755
 
756
  ``` cpp
757
  template<class T>
758
+ strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;
 
 
759
  ```
760
 
761
+ *Returns:* `compare_three_way()(a.get(), nullptr)`.
 
762
 
763
+ #### Specialized algorithms <a id="util.smartptr.shared.spec">[[util.smartptr.shared.spec]]</a>
764
 
765
  ``` cpp
766
  template<class T>
767
  void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
768
  ```
769
 
770
  *Effects:* Equivalent to `a.swap(b)`.
771
 
772
+ #### Casts <a id="util.smartptr.shared.cast">[[util.smartptr.shared.cast]]</a>
773
 
774
  ``` cpp
775
  template<class T, class U>
776
  shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
777
+ template<class T, class U>
778
+ shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
779
  ```
780
 
781
+ *Mandates:* The expression `static_cast<T*>((U*)nullptr)` is
782
+ well-formed.
783
 
784
  *Returns:*
785
 
786
  ``` cpp
787
+ shared_ptr<T>(R, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
788
  ```
789
 
790
+ where *`R`* is `r` for the first overload, and `std::move(r)` for the
791
+ second.
792
+
793
+ [*Note 1*: The seemingly equivalent expression
794
  `shared_ptr<T>(static_cast<T*>(r.get()))` will eventually result in
795
  undefined behavior, attempting to delete the same object
796
  twice. — *end note*]
797
 
798
  ``` cpp
799
  template<class T, class U>
800
  shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
801
+ template<class T, class U>
802
+ shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept;
803
  ```
804
 
805
+ *Mandates:* The expression `dynamic_cast<T*>((U*)nullptr)` is
806
+ well-formed. The expression
807
+ `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` is well
808
+ formed.
809
+
810
+ *Preconditions:* The expression
811
+ `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())` has
812
+ well-defined behavior.
813
 
814
  *Returns:*
815
 
816
  - When `dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())`
817
+ returns a non-null value `p`, `shared_ptr<T>(`*`R`*`, p)`, where *`R`*
818
+ is `r` for the first overload, and `std::move(r)` for the second.
819
  - Otherwise, `shared_ptr<T>()`.
820
 
821
+ [*Note 2*: The seemingly equivalent expression
822
  `shared_ptr<T>(dynamic_cast<T*>(r.get()))` will eventually result in
823
  undefined behavior, attempting to delete the same object
824
  twice. — *end note*]
825
 
826
  ``` cpp
827
  template<class T, class U>
828
  shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
829
+ template<class T, class U>
830
+ shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept;
831
  ```
832
 
833
+ *Mandates:* The expression `const_cast<T*>((U*)nullptr)` is well-formed.
834
 
835
  *Returns:*
836
 
837
  ``` cpp
838
+ shared_ptr<T>(R, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
839
  ```
840
 
841
+ where *`R`* is `r` for the first overload, and `std::move(r)` for the
842
+ second.
843
+
844
+ [*Note 3*: The seemingly equivalent expression
845
  `shared_ptr<T>(const_cast<T*>(r.get()))` will eventually result in
846
  undefined behavior, attempting to delete the same object
847
  twice. — *end note*]
848
 
849
  ``` cpp
850
  template<class T, class U>
851
  shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
852
+ template<class T, class U>
853
+ shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
854
  ```
855
 
856
+ *Mandates:* The expression `reinterpret_cast<T*>((U*)nullptr)` is
857
+ well-formed.
858
 
859
  *Returns:*
860
 
861
  ``` cpp
862
+ shared_ptr<T>(R, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()))
863
  ```
864
 
865
+ where *`R`* is `r` for the first overload, and `std::move(r)` for the
866
+ second.
867
+
868
+ [*Note 4*: The seemingly equivalent expression
869
  `shared_ptr<T>(reinterpret_cast<T*>(r.get()))` will eventually result in
870
  undefined behavior, attempting to delete the same object
871
  twice. — *end note*]
872
 
873
+ #### `get_deleter` <a id="util.smartptr.getdeleter">[[util.smartptr.getdeleter]]</a>
874
 
875
  ``` cpp
876
  template<class D, class T>
877
  D* get_deleter(const shared_ptr<T>& p) noexcept;
878
  ```
 
880
  *Returns:* If `p` owns a deleter `d` of type cv-unqualified `D`, returns
881
  `addressof(d)`; otherwise returns `nullptr`. The returned pointer
882
  remains valid as long as there exists a `shared_ptr` instance that owns
883
  `d`.
884
 
885
+ [*Note 1*: It is unspecified whether the pointer remains valid longer
886
  than that. This can happen if the implementation doesn’t destroy the
887
  deleter until all `weak_ptr` instances that share ownership with `p`
888
  have been destroyed. — *end note*]
889
 
890
+ #### I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
891
 
892
  ``` cpp
893
  template<class E, class T, class Y>
894
  basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p);
895
  ```