From Jason Turner

[support.coroutine]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpqbuw15me/{from.md → to.md} +364 -0
tmp/tmpqbuw15me/{from.md → to.md} RENAMED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Coroutines <a id="support.coroutine">[[support.coroutine]]</a>
2
+
3
+ The header `<coroutine>` defines several types providing compile and
4
+ run-time support for coroutines in a C++ program.
5
+
6
+ ### Header `<coroutine>` synopsis <a id="coroutine.syn">[[coroutine.syn]]</a>
7
+
8
+ ``` cpp
9
+ #include <compare> // see [compare.syn]
10
+
11
+ namespace std {
12
+ // [coroutine.traits], coroutine traits
13
+ template<class R, class... ArgTypes>
14
+ struct coroutine_traits;
15
+
16
+ // [coroutine.handle], coroutine handle
17
+ template<class Promise = void>
18
+ struct coroutine_handle;
19
+
20
+ // [coroutine.handle.compare], comparison operators
21
+ constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
22
+ constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;
23
+
24
+ // [coroutine.handle.hash], hash support
25
+ template<class T> struct hash;
26
+ template<class P> struct hash<coroutine_handle<P>>;
27
+
28
+ // [coroutine.noop], no-op coroutines
29
+ struct noop_coroutine_promise;
30
+
31
+ template<> struct coroutine_handle<noop_coroutine_promise>;
32
+ using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
33
+
34
+ noop_coroutine_handle noop_coroutine() noexcept;
35
+
36
+ // [coroutine.trivial.awaitables], trivial awaitables
37
+ struct suspend_never;
38
+ struct suspend_always;
39
+ }
40
+ ```
41
+
42
+ ### Coroutine traits <a id="coroutine.traits">[[coroutine.traits]]</a>
43
+
44
+ This subclause defines requirements on classes representing *coroutine
45
+ traits*, and defines the class template `coroutine_traits` that meets
46
+ those requirements.
47
+
48
+ #### Class template `coroutine_traits` <a id="coroutine.traits.primary">[[coroutine.traits.primary]]</a>
49
+
50
+ The header `<coroutine>` defines the primary template `coroutine_traits`
51
+ such that if `ArgTypes` is a parameter pack of types and if the
52
+ *qualified-id* `R::promise_type` is valid and denotes a type
53
+ [[temp.deduct]], then `coroutine_traits<R,ArgTypes...>` has the
54
+ following publicly accessible member:
55
+
56
+ ``` cpp
57
+ using promise_type = typename R::promise_type;
58
+ ```
59
+
60
+ Otherwise, `coroutine_traits<R,ArgTypes...>` has no members.
61
+
62
+ Program-defined specializations of this template shall define a publicly
63
+ accessible nested type named `promise_type`.
64
+
65
+ ### Class template `coroutine_handle` <a id="coroutine.handle">[[coroutine.handle]]</a>
66
+
67
+ ``` cpp
68
+ namespace std {
69
+ template<>
70
+ struct coroutine_handle<void>
71
+ {
72
+ // [coroutine.handle.con], construct/reset
73
+ constexpr coroutine_handle() noexcept;
74
+ constexpr coroutine_handle(nullptr_t) noexcept;
75
+ coroutine_handle& operator=(nullptr_t) noexcept;
76
+
77
+ // [coroutine.handle.export.import], export/import
78
+ constexpr void* address() const noexcept;
79
+ static constexpr coroutine_handle from_address(void* addr);
80
+
81
+ // [coroutine.handle.observers], observers
82
+ constexpr explicit operator bool() const noexcept;
83
+ bool done() const;
84
+
85
+ // [coroutine.handle.resumption], resumption
86
+ void operator()() const;
87
+ void resume() const;
88
+ void destroy() const;
89
+
90
+ private:
91
+ void* ptr; // exposition only
92
+ };
93
+
94
+ template<class Promise>
95
+ struct coroutine_handle : coroutine_handle<>
96
+ {
97
+ // [coroutine.handle.con], construct/reset
98
+ using coroutine_handle<>::coroutine_handle;
99
+ static coroutine_handle from_promise(Promise&);
100
+ coroutine_handle& operator=(nullptr_t) noexcept;
101
+
102
+ // [coroutine.handle.export.import], export/import
103
+ static constexpr coroutine_handle from_address(void* addr);
104
+
105
+ // [coroutine.handle.promise], promise access
106
+ Promise& promise() const;
107
+ };
108
+ }
109
+ ```
110
+
111
+ An object of type `coroutine_handle<T>` is called a *coroutine handle*
112
+ and can be used to refer to a suspended or executing coroutine. A
113
+ default-constructed `coroutine_handle` object does not refer to any
114
+ coroutine.
115
+
116
+ If a program declares an explicit or partial specialization of
117
+ `coroutine_handle`, the behavior is undefined.
118
+
119
+ #### Construct/reset <a id="coroutine.handle.con">[[coroutine.handle.con]]</a>
120
+
121
+ ``` cpp
122
+ constexpr coroutine_handle() noexcept;
123
+ constexpr coroutine_handle(nullptr_t) noexcept;
124
+ ```
125
+
126
+ *Ensures:* `address() == nullptr`.
127
+
128
+ ``` cpp
129
+ static coroutine_handle from_promise(Promise& p);
130
+ ```
131
+
132
+ *Preconditions:* `p` is a reference to a promise object of a coroutine.
133
+
134
+ *Returns:* A coroutine handle `h` referring to the coroutine.
135
+
136
+ *Ensures:* `addressof(h.promise()) == addressof(p)`.
137
+
138
+ ``` cpp
139
+ coroutine_handle& operator=(nullptr_t) noexcept;
140
+ ```
141
+
142
+ *Ensures:* `address() == nullptr`.
143
+
144
+ *Returns:* `*this`.
145
+
146
+ #### Export/import <a id="coroutine.handle.export.import">[[coroutine.handle.export.import]]</a>
147
+
148
+ ``` cpp
149
+ constexpr void* address() const noexcept;
150
+ ```
151
+
152
+ *Returns:* `ptr`.
153
+
154
+ ``` cpp
155
+ static constexpr coroutine_handle<> coroutine_handle<>::from_address(void* addr);
156
+ static constexpr coroutine_handle<Promise> coroutine_handle<Promise>::from_address(void* addr);
157
+ ```
158
+
159
+ *Preconditions:* `addr` was obtained via a prior call to `address`.
160
+
161
+ *Ensures:* `from_address(address()) == *this`.
162
+
163
+ #### Observers <a id="coroutine.handle.observers">[[coroutine.handle.observers]]</a>
164
+
165
+ ``` cpp
166
+ constexpr explicit operator bool() const noexcept;
167
+ ```
168
+
169
+ *Returns:* `address() != nullptr`.
170
+
171
+ ``` cpp
172
+ bool done() const;
173
+ ```
174
+
175
+ *Preconditions:* `*this` refers to a suspended coroutine.
176
+
177
+ *Returns:* `true` if the coroutine is suspended at its final suspend
178
+ point, otherwise `false`.
179
+
180
+ #### Resumption <a id="coroutine.handle.resumption">[[coroutine.handle.resumption]]</a>
181
+
182
+ Resuming a coroutine via `resume`, `operator()`, or `destroy` on an
183
+ execution agent other than the one on which it was suspended has
184
+ implementation-defined behavior unless each execution agent either is an
185
+ instance of `std::thread` or `std::jthread`, or is the thread that
186
+ executes `main`.
187
+
188
+ [*Note 1*: A coroutine that is resumed on a different execution agent
189
+ should avoid relying on consistent thread identity throughout, such as
190
+ holding a mutex object across a suspend point. — *end note*]
191
+
192
+ [*Note 2*: A concurrent resumption of the coroutine may result in a
193
+ data race. — *end note*]
194
+
195
+ ``` cpp
196
+ void operator()() const;
197
+ void resume() const;
198
+ ```
199
+
200
+ *Preconditions:* `*this` refers to a suspended coroutine. The coroutine
201
+ is not suspended at its final suspend point.
202
+
203
+ *Effects:* Resumes the execution of the coroutine.
204
+
205
+ ``` cpp
206
+ void destroy() const;
207
+ ```
208
+
209
+ *Preconditions:* `*this` refers to a suspended coroutine.
210
+
211
+ *Effects:* Destroys the coroutine [[dcl.fct.def.coroutine]].
212
+
213
+ #### Promise access <a id="coroutine.handle.promise">[[coroutine.handle.promise]]</a>
214
+
215
+ ``` cpp
216
+ Promise& promise() const;
217
+ ```
218
+
219
+ *Preconditions:* `*this` refers to a coroutine.
220
+
221
+ *Returns:* A reference to the promise of the coroutine.
222
+
223
+ #### Comparison operators <a id="coroutine.handle.compare">[[coroutine.handle.compare]]</a>
224
+
225
+ ``` cpp
226
+ constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
227
+ ```
228
+
229
+ *Returns:* `x.address() == y.address()`.
230
+
231
+ ``` cpp
232
+ constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;
233
+ ```
234
+
235
+ *Returns:* `compare_three_way()(x.address(), y.address())`.
236
+
237
+ #### Hash support <a id="coroutine.handle.hash">[[coroutine.handle.hash]]</a>
238
+
239
+ ``` cpp
240
+ template<class P> struct hash<coroutine_handle<P>>;
241
+ ```
242
+
243
+ The specialization is enabled [[unord.hash]].
244
+
245
+ ### No-op coroutines <a id="coroutine.noop">[[coroutine.noop]]</a>
246
+
247
+ #### Class `noop_coroutine_promise` <a id="coroutine.promise.noop">[[coroutine.promise.noop]]</a>
248
+
249
+ ``` cpp
250
+ struct noop_coroutine_promise {};
251
+ ```
252
+
253
+ The class `noop_coroutine_promise` defines the promise type for the
254
+ coroutine referred to by `noop_coroutine_handle` [[coroutine.syn]].
255
+
256
+ #### Class `coroutine_handle<noop_coroutine_promise>` <a id="coroutine.handle.noop">[[coroutine.handle.noop]]</a>
257
+
258
+ ``` cpp
259
+ namespace std {
260
+ template<>
261
+ struct coroutine_handle<noop_coroutine_promise> : coroutine_handle<>
262
+ {
263
+ // [coroutine.handle.noop.observers], observers
264
+ constexpr explicit operator bool() const noexcept;
265
+ constexpr bool done() const noexcept;
266
+
267
+ // [coroutine.handle.noop.resumption], resumption
268
+ constexpr void operator()() const noexcept;
269
+ constexpr void resume() const noexcept;
270
+ constexpr void destroy() const noexcept;
271
+
272
+ // [coroutine.handle.noop.promise], promise access
273
+ noop_coroutine_promise& promise() const noexcept;
274
+
275
+ // [coroutine.handle.noop.address], address
276
+ constexpr void* address() const noexcept;
277
+ private:
278
+ coroutine_handle(unspecified);
279
+ };
280
+ }
281
+ ```
282
+
283
+ ##### Observers <a id="coroutine.handle.noop.observers">[[coroutine.handle.noop.observers]]</a>
284
+
285
+ ``` cpp
286
+ constexpr explicit operator bool() const noexcept;
287
+ ```
288
+
289
+ *Returns:* `true`.
290
+
291
+ ``` cpp
292
+ constexpr bool done() const noexcept;
293
+ ```
294
+
295
+ *Returns:* `false`.
296
+
297
+ ##### Resumption <a id="coroutine.handle.noop.resumption">[[coroutine.handle.noop.resumption]]</a>
298
+
299
+ ``` cpp
300
+ constexpr void operator()() const noexcept;
301
+ constexpr void resume() const noexcept;
302
+ constexpr void destroy() const noexcept;
303
+ ```
304
+
305
+ *Effects:* None.
306
+
307
+ *Remarks:* If `noop_coroutine_handle` is converted to
308
+ `coroutine_handle<>`, calls to `operator()`, `resume` and `destroy` on
309
+ that handle will also have no observable effects.
310
+
311
+ ##### Promise access <a id="coroutine.handle.noop.promise">[[coroutine.handle.noop.promise]]</a>
312
+
313
+ ``` cpp
314
+ noop_coroutine_promise& promise() const noexcept;
315
+ ```
316
+
317
+ *Returns:* A reference to the promise object associated with this
318
+ coroutine handle.
319
+
320
+ ##### Address <a id="coroutine.handle.noop.address">[[coroutine.handle.noop.address]]</a>
321
+
322
+ ``` cpp
323
+ constexpr void* address() const noexcept;
324
+ ```
325
+
326
+ *Returns:* `ptr`.
327
+
328
+ *Remarks:* A `noop_coroutine_handle`’s `ptr` is always a non-null
329
+ pointer value.
330
+
331
+ #### Function `noop_coroutine` <a id="coroutine.noop.coroutine">[[coroutine.noop.coroutine]]</a>
332
+
333
+ ``` cpp
334
+ noop_coroutine_handle noop_coroutine() noexcept;
335
+ ```
336
+
337
+ *Returns:* A handle to a coroutine that has no observable effects when
338
+ resumed or destroyed.
339
+
340
+ *Remarks:* A handle returned from `noop_coroutine` may or may not
341
+ compare equal to a handle returned from another invocation of
342
+ `noop_coroutine`.
343
+
344
+ ### Trivial awaitables <a id="coroutine.trivial.awaitables">[[coroutine.trivial.awaitables]]</a>
345
+
346
+ ``` cpp
347
+ namespace std {
348
+ struct suspend_never {
349
+ constexpr bool await_ready() const noexcept { return true; }
350
+ constexpr void await_suspend(coroutine_handle<>) const noexcept {}
351
+ constexpr void await_resume() const noexcept {}
352
+ };
353
+ struct suspend_always {
354
+ constexpr bool await_ready() const noexcept { return false; }
355
+ constexpr void await_suspend(coroutine_handle<>) const noexcept {}
356
+ constexpr void await_resume() const noexcept {}
357
+ };
358
+ }
359
+ ```
360
+
361
+ [*Note 1*: The types `suspend_never` and `suspend_always` can be used
362
+ to indicate that an *await-expression* should either never suspend or
363
+ always suspend, and in either case not produce a value. — *end note*]
364
+