From Jason Turner

[util.sharedptr]

Diff to HTML by rtfpessoa

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