From Jason Turner

[util.smartptr.atomic]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp01xqpxgg/{from.md → to.md} +83 -70
tmp/tmp01xqpxgg/{from.md → to.md} RENAMED
@@ -65,33 +65,36 @@ namespace std {
65
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
66
  bool is_lock_free() const noexcept;
67
 
68
  constexpr atomic() noexcept;
69
  constexpr atomic(nullptr_t) noexcept : atomic() { }
70
- atomic(shared_ptr<T> desired) noexcept;
71
  atomic(const atomic&) = delete;
72
  void operator=(const atomic&) = delete;
73
 
74
- shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
75
- operator shared_ptr<T>() const noexcept;
76
- void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
77
- void operator=(shared_ptr<T> desired) noexcept;
 
 
78
 
79
- shared_ptr<T> exchange(shared_ptr<T> desired,
80
  memory_order order = memory_order::seq_cst) noexcept;
81
- bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
82
  memory_order success, memory_order failure) noexcept;
83
- bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
84
  memory_order success, memory_order failure) noexcept;
85
- bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
86
  memory_order order = memory_order::seq_cst) noexcept;
87
- bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
88
  memory_order order = memory_order::seq_cst) noexcept;
89
 
90
- void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
91
- void notify_one() noexcept;
92
- void notify_all() noexcept;
 
93
 
94
  private:
95
  shared_ptr<T> p; // exposition only
96
  };
97
  }
@@ -99,14 +102,14 @@ namespace std {
99
 
100
  ``` cpp
101
  constexpr atomic() noexcept;
102
  ```
103
 
104
- *Effects:* Initializes `p{}`.
105
 
106
  ``` cpp
107
- atomic(shared_ptr<T> desired) noexcept;
108
  ```
109
 
110
  *Effects:* Initializes the object with the value `desired`.
111
  Initialization is not an atomic operation [[intro.multithread]].
112
 
@@ -116,63 +119,70 @@ the just-constructed object `A` to another thread via
116
  `memory_order::relaxed` operations on a suitable atomic pointer
117
  variable, and then immediately accessing `A` in the receiving thread.
118
  This results in undefined behavior. — *end note*]
119
 
120
  ``` cpp
121
- void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
122
  ```
123
 
124
- *Preconditions:* `order` is neither `memory_order::consume`,
125
- `memory_order::acquire`, nor `memory_order::acq_rel`.
126
 
127
  *Effects:* Atomically replaces the value pointed to by `this` with the
128
  value of `desired` as if by `p.swap(desired)`. Memory is affected
129
  according to the value of `order`.
130
 
131
  ``` cpp
132
- void operator=(shared_ptr<T> desired) noexcept;
133
  ```
134
 
135
  *Effects:* Equivalent to `store(desired)`.
136
 
137
  ``` cpp
138
- shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
139
  ```
140
 
141
- *Preconditions:* `order` is neither `memory_order::release` nor
142
- `memory_order::acq_rel`.
 
 
 
 
 
 
143
 
144
  *Effects:* Memory is affected according to the value of `order`.
145
 
146
  *Returns:* Atomically returns `p`.
147
 
148
  ``` cpp
149
- operator shared_ptr<T>() const noexcept;
150
  ```
151
 
152
  *Effects:* Equivalent to: `return load();`
153
 
154
  ``` cpp
155
- shared_ptr<T> exchange(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
 
156
  ```
157
 
158
  *Effects:* Atomically replaces `p` with `desired` as if by
159
  `p.swap(desired)`. Memory is affected according to the value of `order`.
160
  This is an atomic read-modify-write operation [[intro.races]].
161
 
162
  *Returns:* Atomically returns the value of `p` immediately before the
163
  effects.
164
 
165
  ``` cpp
166
- bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
167
  memory_order success, memory_order failure) noexcept;
168
- bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
169
  memory_order success, memory_order failure) noexcept;
170
  ```
171
 
172
- *Preconditions:* `failure` is neither `memory_order::release` nor
173
- `memory_order::acq_rel`.
174
 
175
  *Effects:* If `p` is equivalent to `expected`, assigns `desired` to `p`
176
  and has synchronization semantics corresponding to the value of
177
  `success`, otherwise assigns `p` to `expected` and has synchronization
178
  semantics corresponding to the value of `failure`.
@@ -193,11 +203,11 @@ object in the attempted atomic update. The `use_count` update
193
  corresponding to the write to `expected` is part of the atomic
194
  operation. The write to `expected` itself is not required to be part of
195
  the atomic operation.
196
 
197
  ``` cpp
198
- bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
199
  memory_order order = memory_order::seq_cst) noexcept;
200
  ```
201
 
202
  *Effects:* Equivalent to:
203
 
@@ -209,11 +219,11 @@ where `fail_order` is the same as `order` except that a value of
209
  `memory_order::acq_rel` shall be replaced by the value
210
  `memory_order::acquire` and a value of `memory_order::release` shall be
211
  replaced by the value `memory_order::relaxed`.
212
 
213
  ``` cpp
214
- bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
215
  memory_order order = memory_order::seq_cst) noexcept;
216
  ```
217
 
218
  *Effects:* Equivalent to:
219
 
@@ -225,15 +235,15 @@ where `fail_order` is the same as `order` except that a value of
225
  `memory_order::acq_rel` shall be replaced by the value
226
  `memory_order::acquire` and a value of `memory_order::release` shall be
227
  replaced by the value `memory_order::relaxed`.
228
 
229
  ``` cpp
230
- void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
231
  ```
232
 
233
- *Preconditions:* `order` is neither `memory_order::release` nor
234
- `memory_order::acq_rel`.
235
 
236
  *Effects:* Repeatedly performs the following steps, in order:
237
 
238
  - Evaluates `load(order)` and compares it to `old`.
239
  - If the two are not equivalent, returns.
@@ -243,22 +253,22 @@ void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const n
243
  *Remarks:* Two `shared_ptr` objects are equivalent if they store the
244
  same pointer and either share ownership or are both empty. This function
245
  is an atomic waiting operation [[atomics.wait]].
246
 
247
  ``` cpp
248
- void notify_one() noexcept;
249
  ```
250
 
251
  *Effects:* Unblocks the execution of at least one atomic waiting
252
  operation that is eligible to be unblocked [[atomics.wait]] by this
253
  call, if any such atomic waiting operations exist.
254
 
255
  *Remarks:* This function is an atomic notifying
256
  operation [[atomics.wait]].
257
 
258
  ``` cpp
259
- void notify_all() noexcept;
260
  ```
261
 
262
  *Effects:* Unblocks the execution of all atomic waiting operations that
263
  are eligible to be unblocked [[atomics.wait]] by this call.
264
 
@@ -274,33 +284,35 @@ namespace std {
274
 
275
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
276
  bool is_lock_free() const noexcept;
277
 
278
  constexpr atomic() noexcept;
279
- atomic(weak_ptr<T> desired) noexcept;
280
  atomic(const atomic&) = delete;
281
  void operator=(const atomic&) = delete;
282
 
283
- weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
284
- operator weak_ptr<T>() const noexcept;
285
- void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
286
- void operator=(weak_ptr<T> desired) noexcept;
 
287
 
288
- weak_ptr<T> exchange(weak_ptr<T> desired,
289
  memory_order order = memory_order::seq_cst) noexcept;
290
- bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
291
  memory_order success, memory_order failure) noexcept;
292
- bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
293
  memory_order success, memory_order failure) noexcept;
294
- bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
295
  memory_order order = memory_order::seq_cst) noexcept;
296
- bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
297
  memory_order order = memory_order::seq_cst) noexcept;
298
 
299
- void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
300
- void notify_one() noexcept;
301
- void notify_all() noexcept;
 
302
 
303
  private:
304
  weak_ptr<T> p; // exposition only
305
  };
306
  }
@@ -308,14 +320,14 @@ namespace std {
308
 
309
  ``` cpp
310
  constexpr atomic() noexcept;
311
  ```
312
 
313
- *Effects:* Initializes `p{}`.
314
 
315
  ``` cpp
316
- atomic(weak_ptr<T> desired) noexcept;
317
  ```
318
 
319
  *Effects:* Initializes the object with the value `desired`.
320
  Initialization is not an atomic operation [[intro.multithread]].
321
 
@@ -325,63 +337,64 @@ the just-constructed object `A` to another thread via
325
  `memory_order::relaxed` operations on a suitable atomic pointer
326
  variable, and then immediately accessing `A` in the receiving thread.
327
  This results in undefined behavior. — *end note*]
328
 
329
  ``` cpp
330
- void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
331
  ```
332
 
333
- *Preconditions:* `order` is neither `memory_order::consume`,
334
- `memory_order::acquire`, nor `memory_order::acq_rel`.
335
 
336
  *Effects:* Atomically replaces the value pointed to by `this` with the
337
  value of `desired` as if by `p.swap(desired)`. Memory is affected
338
  according to the value of `order`.
339
 
340
  ``` cpp
341
- void operator=(weak_ptr<T> desired) noexcept;
342
  ```
343
 
344
  *Effects:* Equivalent to `store(desired)`.
345
 
346
  ``` cpp
347
- weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
348
  ```
349
 
350
- *Preconditions:* `order` is neither `memory_order::release` nor
351
- `memory_order::acq_rel`.
352
 
353
  *Effects:* Memory is affected according to the value of `order`.
354
 
355
  *Returns:* Atomically returns `p`.
356
 
357
  ``` cpp
358
- operator weak_ptr<T>() const noexcept;
359
  ```
360
 
361
  *Effects:* Equivalent to: `return load();`
362
 
363
  ``` cpp
364
- weak_ptr<T> exchange(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
 
365
  ```
366
 
367
  *Effects:* Atomically replaces `p` with `desired` as if by
368
  `p.swap(desired)`. Memory is affected according to the value of `order`.
369
  This is an atomic read-modify-write operation [[intro.races]].
370
 
371
  *Returns:* Atomically returns the value of `p` immediately before the
372
  effects.
373
 
374
  ``` cpp
375
- bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
376
  memory_order success, memory_order failure) noexcept;
377
- bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
378
  memory_order success, memory_order failure) noexcept;
379
  ```
380
 
381
- *Preconditions:* `failure` is neither `memory_order::release` nor
382
- `memory_order::acq_rel`.
383
 
384
  *Effects:* If `p` is equivalent to `expected`, assigns `desired` to `p`
385
  and has synchronization semantics corresponding to the value of
386
  `success`, otherwise assigns `p` to `expected` and has synchronization
387
  semantics corresponding to the value of `failure`.
@@ -402,11 +415,11 @@ object in the attempted atomic update. The `use_count` update
402
  corresponding to the write to `expected` is part of the atomic
403
  operation. The write to `expected` itself is not required to be part of
404
  the atomic operation.
405
 
406
  ``` cpp
407
- bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
408
  memory_order order = memory_order::seq_cst) noexcept;
409
  ```
410
 
411
  *Effects:* Equivalent to:
412
 
@@ -418,11 +431,11 @@ where `fail_order` is the same as `order` except that a value of
418
  `memory_order::acq_rel` shall be replaced by the value
419
  `memory_order::acquire` and a value of `memory_order::release` shall be
420
  replaced by the value `memory_order::relaxed`.
421
 
422
  ``` cpp
423
- bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
424
  memory_order order = memory_order::seq_cst) noexcept;
425
  ```
426
 
427
  *Effects:* Equivalent to:
428
 
@@ -434,15 +447,15 @@ where `fail_order` is the same as `order` except that a value of
434
  `memory_order::acq_rel` shall be replaced by the value
435
  `memory_order::acquire` and a value of `memory_order::release` shall be
436
  replaced by the value `memory_order::relaxed`.
437
 
438
  ``` cpp
439
- void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
440
  ```
441
 
442
- *Preconditions:* `order` is neither `memory_order::release` nor
443
- `memory_order::acq_rel`.
444
 
445
  *Effects:* Repeatedly performs the following steps, in order:
446
 
447
  - Evaluates `load(order)` and compares it to `old`.
448
  - If the two are not equivalent, returns.
@@ -452,22 +465,22 @@ void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noe
452
  *Remarks:* Two `weak_ptr` objects are equivalent if they store the same
453
  pointer and either share ownership or are both empty. This function is
454
  an atomic waiting operation [[atomics.wait]].
455
 
456
  ``` cpp
457
- void notify_one() noexcept;
458
  ```
459
 
460
  *Effects:* Unblocks the execution of at least one atomic waiting
461
  operation that is eligible to be unblocked [[atomics.wait]] by this
462
  call, if any such atomic waiting operations exist.
463
 
464
  *Remarks:* This function is an atomic notifying
465
  operation [[atomics.wait]].
466
 
467
  ``` cpp
468
- void notify_all() noexcept;
469
  ```
470
 
471
  *Effects:* Unblocks the execution of all atomic waiting operations that
472
  are eligible to be unblocked [[atomics.wait]] by this call.
473
 
 
65
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
66
  bool is_lock_free() const noexcept;
67
 
68
  constexpr atomic() noexcept;
69
  constexpr atomic(nullptr_t) noexcept : atomic() { }
70
+ constexpr atomic(shared_ptr<T> desired) noexcept;
71
  atomic(const atomic&) = delete;
72
  void operator=(const atomic&) = delete;
73
 
74
+ constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
75
+ constexpr operator shared_ptr<T>() const noexcept;
76
+ constexpr void store(shared_ptr<T> desired,
77
+ memory_order order = memory_order::seq_cst) noexcept;
78
+ constexpr void operator=(shared_ptr<T> desired) noexcept;
79
+ constexpr void operator=(nullptr_t) noexcept;
80
 
81
+ constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
82
  memory_order order = memory_order::seq_cst) noexcept;
83
+ constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
84
  memory_order success, memory_order failure) noexcept;
85
+ constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
86
  memory_order success, memory_order failure) noexcept;
87
+ constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
88
  memory_order order = memory_order::seq_cst) noexcept;
89
+ constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
90
  memory_order order = memory_order::seq_cst) noexcept;
91
 
92
+ constexpr void wait(shared_ptr<T> old,
93
+ memory_order order = memory_order::seq_cst) const noexcept;
94
+ constexpr void notify_one() noexcept;
95
+ constexpr void notify_all() noexcept;
96
 
97
  private:
98
  shared_ptr<T> p; // exposition only
99
  };
100
  }
 
102
 
103
  ``` cpp
104
  constexpr atomic() noexcept;
105
  ```
106
 
107
+ *Effects:* Value-initializes `p`.
108
 
109
  ``` cpp
110
+ constexpr atomic(shared_ptr<T> desired) noexcept;
111
  ```
112
 
113
  *Effects:* Initializes the object with the value `desired`.
114
  Initialization is not an atomic operation [[intro.multithread]].
115
 
 
119
  `memory_order::relaxed` operations on a suitable atomic pointer
120
  variable, and then immediately accessing `A` in the receiving thread.
121
  This results in undefined behavior. — *end note*]
122
 
123
  ``` cpp
124
+ constexpr void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
125
  ```
126
 
127
+ *Preconditions:* `order` is `memory_order::relaxed`,
128
+ `memory_order::release`, or `memory_order::seq_cst`.
129
 
130
  *Effects:* Atomically replaces the value pointed to by `this` with the
131
  value of `desired` as if by `p.swap(desired)`. Memory is affected
132
  according to the value of `order`.
133
 
134
  ``` cpp
135
+ constexpr void operator=(shared_ptr<T> desired) noexcept;
136
  ```
137
 
138
  *Effects:* Equivalent to `store(desired)`.
139
 
140
  ``` cpp
141
+ constexpr void operator=(nullptr_t) noexcept;
142
  ```
143
 
144
+ *Effects:* Equivalent to `store(nullptr)`.
145
+
146
+ ``` cpp
147
+ constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
148
+ ```
149
+
150
+ *Preconditions:* `order` is `memory_order::relaxed`,
151
+ `memory_order::acquire`, or `memory_order::seq_cst`.
152
 
153
  *Effects:* Memory is affected according to the value of `order`.
154
 
155
  *Returns:* Atomically returns `p`.
156
 
157
  ``` cpp
158
+ constexpr operator shared_ptr<T>() const noexcept;
159
  ```
160
 
161
  *Effects:* Equivalent to: `return load();`
162
 
163
  ``` cpp
164
+ constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
165
+ memory_order order = memory_order::seq_cst) noexcept;
166
  ```
167
 
168
  *Effects:* Atomically replaces `p` with `desired` as if by
169
  `p.swap(desired)`. Memory is affected according to the value of `order`.
170
  This is an atomic read-modify-write operation [[intro.races]].
171
 
172
  *Returns:* Atomically returns the value of `p` immediately before the
173
  effects.
174
 
175
  ``` cpp
176
+ constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
177
  memory_order success, memory_order failure) noexcept;
178
+ constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
179
  memory_order success, memory_order failure) noexcept;
180
  ```
181
 
182
+ *Preconditions:* `failure` is `memory_order::relaxed`,
183
+ `memory_order::acquire`, or `memory_order::seq_cst`.
184
 
185
  *Effects:* If `p` is equivalent to `expected`, assigns `desired` to `p`
186
  and has synchronization semantics corresponding to the value of
187
  `success`, otherwise assigns `p` to `expected` and has synchronization
188
  semantics corresponding to the value of `failure`.
 
203
  corresponding to the write to `expected` is part of the atomic
204
  operation. The write to `expected` itself is not required to be part of
205
  the atomic operation.
206
 
207
  ``` cpp
208
+ constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
209
  memory_order order = memory_order::seq_cst) noexcept;
210
  ```
211
 
212
  *Effects:* Equivalent to:
213
 
 
219
  `memory_order::acq_rel` shall be replaced by the value
220
  `memory_order::acquire` and a value of `memory_order::release` shall be
221
  replaced by the value `memory_order::relaxed`.
222
 
223
  ``` cpp
224
+ constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
225
  memory_order order = memory_order::seq_cst) noexcept;
226
  ```
227
 
228
  *Effects:* Equivalent to:
229
 
 
235
  `memory_order::acq_rel` shall be replaced by the value
236
  `memory_order::acquire` and a value of `memory_order::release` shall be
237
  replaced by the value `memory_order::relaxed`.
238
 
239
  ``` cpp
240
+ constexpr void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
241
  ```
242
 
243
+ *Preconditions:* `order` is `memory_order::relaxed`,
244
+ `memory_order::acquire`, or `memory_order::seq_cst`.
245
 
246
  *Effects:* Repeatedly performs the following steps, in order:
247
 
248
  - Evaluates `load(order)` and compares it to `old`.
249
  - If the two are not equivalent, returns.
 
253
  *Remarks:* Two `shared_ptr` objects are equivalent if they store the
254
  same pointer and either share ownership or are both empty. This function
255
  is an atomic waiting operation [[atomics.wait]].
256
 
257
  ``` cpp
258
+ constexpr void notify_one() noexcept;
259
  ```
260
 
261
  *Effects:* Unblocks the execution of at least one atomic waiting
262
  operation that is eligible to be unblocked [[atomics.wait]] by this
263
  call, if any such atomic waiting operations exist.
264
 
265
  *Remarks:* This function is an atomic notifying
266
  operation [[atomics.wait]].
267
 
268
  ``` cpp
269
+ constexpr void notify_all() noexcept;
270
  ```
271
 
272
  *Effects:* Unblocks the execution of all atomic waiting operations that
273
  are eligible to be unblocked [[atomics.wait]] by this call.
274
 
 
284
 
285
  static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
286
  bool is_lock_free() const noexcept;
287
 
288
  constexpr atomic() noexcept;
289
+ constexpr atomic(weak_ptr<T> desired) noexcept;
290
  atomic(const atomic&) = delete;
291
  void operator=(const atomic&) = delete;
292
 
293
+ constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
294
+ constexpr operator weak_ptr<T>() const noexcept;
295
+ constexpr void store(weak_ptr<T> desired,
296
+ memory_order order = memory_order::seq_cst) noexcept;
297
+ constexpr void operator=(weak_ptr<T> desired) noexcept;
298
 
299
+ constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
300
  memory_order order = memory_order::seq_cst) noexcept;
301
+ constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
302
  memory_order success, memory_order failure) noexcept;
303
+ constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
304
  memory_order success, memory_order failure) noexcept;
305
+ constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
306
  memory_order order = memory_order::seq_cst) noexcept;
307
+ constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
308
  memory_order order = memory_order::seq_cst) noexcept;
309
 
310
+ constexpr void wait(weak_ptr<T> old,
311
+ memory_order order = memory_order::seq_cst) const noexcept;
312
+ constexpr void notify_one() noexcept;
313
+ constexpr void notify_all() noexcept;
314
 
315
  private:
316
  weak_ptr<T> p; // exposition only
317
  };
318
  }
 
320
 
321
  ``` cpp
322
  constexpr atomic() noexcept;
323
  ```
324
 
325
+ *Effects:* Value-initializes `p`.
326
 
327
  ``` cpp
328
+ constexpr atomic(weak_ptr<T> desired) noexcept;
329
  ```
330
 
331
  *Effects:* Initializes the object with the value `desired`.
332
  Initialization is not an atomic operation [[intro.multithread]].
333
 
 
337
  `memory_order::relaxed` operations on a suitable atomic pointer
338
  variable, and then immediately accessing `A` in the receiving thread.
339
  This results in undefined behavior. — *end note*]
340
 
341
  ``` cpp
342
+ constexpr void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
343
  ```
344
 
345
+ *Preconditions:* `order` is `memory_order::relaxed`,
346
+ `memory_order::release`, or `memory_order::seq_cst`.
347
 
348
  *Effects:* Atomically replaces the value pointed to by `this` with the
349
  value of `desired` as if by `p.swap(desired)`. Memory is affected
350
  according to the value of `order`.
351
 
352
  ``` cpp
353
+ constexpr void operator=(weak_ptr<T> desired) noexcept;
354
  ```
355
 
356
  *Effects:* Equivalent to `store(desired)`.
357
 
358
  ``` cpp
359
+ constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
360
  ```
361
 
362
+ *Preconditions:* `order` is `memory_order::relaxed`,
363
+ `memory_order::acquire`, or `memory_order::seq_cst`.
364
 
365
  *Effects:* Memory is affected according to the value of `order`.
366
 
367
  *Returns:* Atomically returns `p`.
368
 
369
  ``` cpp
370
+ constexpr operator weak_ptr<T>() const noexcept;
371
  ```
372
 
373
  *Effects:* Equivalent to: `return load();`
374
 
375
  ``` cpp
376
+ constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
377
+ memory_order order = memory_order::seq_cst) noexcept;
378
  ```
379
 
380
  *Effects:* Atomically replaces `p` with `desired` as if by
381
  `p.swap(desired)`. Memory is affected according to the value of `order`.
382
  This is an atomic read-modify-write operation [[intro.races]].
383
 
384
  *Returns:* Atomically returns the value of `p` immediately before the
385
  effects.
386
 
387
  ``` cpp
388
+ constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
389
  memory_order success, memory_order failure) noexcept;
390
+ constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
391
  memory_order success, memory_order failure) noexcept;
392
  ```
393
 
394
+ *Preconditions:* `failure` is `memory_order::relaxed`,
395
+ `memory_order::acquire`, or `memory_order::seq_cst`.
396
 
397
  *Effects:* If `p` is equivalent to `expected`, assigns `desired` to `p`
398
  and has synchronization semantics corresponding to the value of
399
  `success`, otherwise assigns `p` to `expected` and has synchronization
400
  semantics corresponding to the value of `failure`.
 
415
  corresponding to the write to `expected` is part of the atomic
416
  operation. The write to `expected` itself is not required to be part of
417
  the atomic operation.
418
 
419
  ``` cpp
420
+ constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
421
  memory_order order = memory_order::seq_cst) noexcept;
422
  ```
423
 
424
  *Effects:* Equivalent to:
425
 
 
431
  `memory_order::acq_rel` shall be replaced by the value
432
  `memory_order::acquire` and a value of `memory_order::release` shall be
433
  replaced by the value `memory_order::relaxed`.
434
 
435
  ``` cpp
436
+ constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
437
  memory_order order = memory_order::seq_cst) noexcept;
438
  ```
439
 
440
  *Effects:* Equivalent to:
441
 
 
447
  `memory_order::acq_rel` shall be replaced by the value
448
  `memory_order::acquire` and a value of `memory_order::release` shall be
449
  replaced by the value `memory_order::relaxed`.
450
 
451
  ``` cpp
452
+ constexpr void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
453
  ```
454
 
455
+ *Preconditions:* `order` is `memory_order::relaxed`,
456
+ `memory_order::acquire`, or `memory_order::seq_cst`.
457
 
458
  *Effects:* Repeatedly performs the following steps, in order:
459
 
460
  - Evaluates `load(order)` and compares it to `old`.
461
  - If the two are not equivalent, returns.
 
465
  *Remarks:* Two `weak_ptr` objects are equivalent if they store the same
466
  pointer and either share ownership or are both empty. This function is
467
  an atomic waiting operation [[atomics.wait]].
468
 
469
  ``` cpp
470
+ constexpr void notify_one() noexcept;
471
  ```
472
 
473
  *Effects:* Unblocks the execution of at least one atomic waiting
474
  operation that is eligible to be unblocked [[atomics.wait]] by this
475
  call, if any such atomic waiting operations exist.
476
 
477
  *Remarks:* This function is an atomic notifying
478
  operation [[atomics.wait]].
479
 
480
  ``` cpp
481
+ constexpr void notify_all() noexcept;
482
  ```
483
 
484
  *Effects:* Unblocks the execution of all atomic waiting operations that
485
  are eligible to be unblocked [[atomics.wait]] by this call.
486