From Jason Turner

[support.coroutine]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5mf4pee2/{from.md → to.md} +73 -16
tmp/tmp5mf4pee2/{from.md → to.md} RENAMED
@@ -1,13 +1,16 @@
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>
@@ -39,13 +42,15 @@ namespace std {
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
@@ -62,10 +67,12 @@ Otherwise, `coroutine_traits<R,ArgTypes...>` has no members.
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
  {
@@ -90,30 +97,49 @@ namespace std {
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>
@@ -129,36 +155,54 @@ constexpr coroutine_handle(nullptr_t) noexcept;
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
 
@@ -179,19 +223,19 @@ 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;
@@ -256,12 +300,15 @@ coroutine referred to by `noop_coroutine_handle` [[coroutine.syn]].
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
@@ -274,14 +321,24 @@ namespace std {
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
  ```
@@ -357,8 +414,8 @@ namespace std {
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
 
 
1
  ## Coroutines <a id="support.coroutine">[[support.coroutine]]</a>
2
 
3
+ ### General <a id="support.coroutine.general">[[support.coroutine.general]]</a>
4
+
5
  The header `<coroutine>` defines several types providing compile and
6
  run-time support for coroutines in a C++ program.
7
 
8
  ### Header `<coroutine>` synopsis <a id="coroutine.syn">[[coroutine.syn]]</a>
9
 
10
  ``` cpp
11
+ // all freestanding
12
  #include <compare> // see [compare.syn]
13
 
14
  namespace std {
15
  // [coroutine.traits], coroutine traits
16
  template<class R, class... ArgTypes>
 
42
  }
43
  ```
44
 
45
  ### Coroutine traits <a id="coroutine.traits">[[coroutine.traits]]</a>
46
 
47
+ #### General <a id="coroutine.traits.general">[[coroutine.traits.general]]</a>
48
+
49
+ Subclause [[coroutine.traits]] defines requirements on classes
50
+ representing *coroutine traits*, and defines the class template
51
+ `coroutine_traits` that meets those requirements.
52
 
53
  #### Class template `coroutine_traits` <a id="coroutine.traits.primary">[[coroutine.traits.primary]]</a>
54
 
55
  The header `<coroutine>` defines the primary template `coroutine_traits`
56
  such that if `ArgTypes` is a parameter pack of types and if the
 
67
  Program-defined specializations of this template shall define a publicly
68
  accessible nested type named `promise_type`.
69
 
70
  ### Class template `coroutine_handle` <a id="coroutine.handle">[[coroutine.handle]]</a>
71
 
72
+ #### General <a id="coroutine.handle.general">[[coroutine.handle.general]]</a>
73
+
74
  ``` cpp
75
  namespace std {
76
  template<>
77
  struct coroutine_handle<void>
78
  {
 
97
  private:
98
  void* ptr; // exposition only
99
  };
100
 
101
  template<class Promise>
102
+ struct coroutine_handle
103
  {
104
  // [coroutine.handle.con], construct/reset
105
+ constexpr coroutine_handle() noexcept;
106
+ constexpr coroutine_handle(nullptr_t) noexcept;
107
  static coroutine_handle from_promise(Promise&);
108
  coroutine_handle& operator=(nullptr_t) noexcept;
109
 
110
  // [coroutine.handle.export.import], export/import
111
+ constexpr void* address() const noexcept;
112
  static constexpr coroutine_handle from_address(void* addr);
113
 
114
+ // [coroutine.handle.conv], conversion
115
+ constexpr operator coroutine_handle<>() const noexcept;
116
+
117
+ // [coroutine.handle.observers], observers
118
+ constexpr explicit operator bool() const noexcept;
119
+ bool done() const;
120
+
121
+ // [coroutine.handle.resumption], resumption
122
+ void operator()() const;
123
+ void resume() const;
124
+ void destroy() const;
125
+
126
  // [coroutine.handle.promise], promise access
127
  Promise& promise() const;
128
+
129
+ private:
130
+ void* ptr; // exposition only
131
  };
132
  }
133
  ```
134
 
135
  An object of type `coroutine_handle<T>` is called a *coroutine handle*
136
  and can be used to refer to a suspended or executing coroutine. A
137
+ `coroutine_handle` object whose member `address()` returns a null
138
+ pointer value does not refer to any coroutine. Two `coroutine_handle`
139
+ objects refer to the same coroutine if and only if their member
140
+ `address()` returns the same non-null value.
141
 
142
  If a program declares an explicit or partial specialization of
143
  `coroutine_handle`, the behavior is undefined.
144
 
145
  #### Construct/reset <a id="coroutine.handle.con">[[coroutine.handle.con]]</a>
 
155
  static coroutine_handle from_promise(Promise& p);
156
  ```
157
 
158
  *Preconditions:* `p` is a reference to a promise object of a coroutine.
159
 
 
 
160
  *Ensures:* `addressof(h.promise()) == addressof(p)`.
161
 
162
+ *Returns:* A coroutine handle `h` referring to the coroutine.
163
+
164
  ``` cpp
165
  coroutine_handle& operator=(nullptr_t) noexcept;
166
  ```
167
 
168
  *Ensures:* `address() == nullptr`.
169
 
170
  *Returns:* `*this`.
171
 
172
+ #### Conversion <a id="coroutine.handle.conv">[[coroutine.handle.conv]]</a>
173
+
174
+ ``` cpp
175
+ constexpr operator coroutine_handle<>() const noexcept;
176
+ ```
177
+
178
+ *Effects:* Equivalent to:
179
+ `return coroutine_handle<>::from_address(address());`
180
+
181
  #### Export/import <a id="coroutine.handle.export.import">[[coroutine.handle.export.import]]</a>
182
 
183
  ``` cpp
184
  constexpr void* address() const noexcept;
185
  ```
186
 
187
  *Returns:* `ptr`.
188
 
189
  ``` cpp
190
  static constexpr coroutine_handle<> coroutine_handle<>::from_address(void* addr);
191
+ ```
192
+
193
+ *Preconditions:* `addr` was obtained via a prior call to `address` on an
194
+ object whose type is a specialization of `coroutine_handle`.
195
+
196
+ *Ensures:* `from_address(address()) == *this`.
197
+
198
+ ``` cpp
199
  static constexpr coroutine_handle<Promise> coroutine_handle<Promise>::from_address(void* addr);
200
  ```
201
 
202
+ *Preconditions:* `addr` was obtained via a prior call to `address` on an
203
+ object of type cv `coroutine_handle<Promise>`.
204
 
205
  *Ensures:* `from_address(address()) == *this`.
206
 
207
  #### Observers <a id="coroutine.handle.observers">[[coroutine.handle.observers]]</a>
208
 
 
223
 
224
  #### Resumption <a id="coroutine.handle.resumption">[[coroutine.handle.resumption]]</a>
225
 
226
  Resuming a coroutine via `resume`, `operator()`, or `destroy` on an
227
  execution agent other than the one on which it was suspended has
228
+ *implementation-defined* behavior unless each execution agent either is
229
+ an instance of `std::thread` or `std::jthread`, or is the thread that
230
  executes `main`.
231
 
232
  [*Note 1*: A coroutine that is resumed on a different execution agent
233
  should avoid relying on consistent thread identity throughout, such as
234
  holding a mutex object across a suspend point. — *end note*]
235
 
236
+ [*Note 2*: A concurrent resumption of the coroutine can result in a
237
  data race. — *end note*]
238
 
239
  ``` cpp
240
  void operator()() const;
241
  void resume() const;
 
300
  #### Class `coroutine_handle<noop_coroutine_promise>` <a id="coroutine.handle.noop">[[coroutine.handle.noop]]</a>
301
 
302
  ``` cpp
303
  namespace std {
304
  template<>
305
+ struct coroutine_handle<noop_coroutine_promise>
306
  {
307
+ // [coroutine.handle.noop.conv], conversion
308
+ constexpr operator coroutine_handle<>() const noexcept;
309
+
310
  // [coroutine.handle.noop.observers], observers
311
  constexpr explicit operator bool() const noexcept;
312
  constexpr bool done() const noexcept;
313
 
314
  // [coroutine.handle.noop.resumption], resumption
 
321
 
322
  // [coroutine.handle.noop.address], address
323
  constexpr void* address() const noexcept;
324
  private:
325
  coroutine_handle(unspecified);
326
+ void* ptr; // exposition only
327
  };
328
  }
329
  ```
330
 
331
+ ##### Conversion <a id="coroutine.handle.noop.conv">[[coroutine.handle.noop.conv]]</a>
332
+
333
+ ``` cpp
334
+ constexpr operator coroutine_handle<>() const noexcept;
335
+ ```
336
+
337
+ *Effects:* Equivalent to:
338
+ `return coroutine_handle<>::from_address(address());`
339
+
340
  ##### Observers <a id="coroutine.handle.noop.observers">[[coroutine.handle.noop.observers]]</a>
341
 
342
  ``` cpp
343
  constexpr explicit operator bool() const noexcept;
344
  ```
 
414
  };
415
  }
416
  ```
417
 
418
  [*Note 1*: The types `suspend_never` and `suspend_always` can be used
419
+ to indicate that an *await-expression* either never suspends or always
420
+ suspends, and in either case does not produce a value. — *end note*]
421