tmp/tmpj2tyu074/{from.md → to.md}
RENAMED
|
@@ -10,30 +10,30 @@ await-expression:
|
|
| 10 |
```
|
| 11 |
|
| 12 |
An *await-expression* shall appear only in a potentially-evaluated
|
| 13 |
expression within the *compound-statement* of a *function-body* outside
|
| 14 |
of a *handler* [[except.pre]]. In a *declaration-statement* or in the
|
| 15 |
-
*simple-declaration* (if any) of
|
| 16 |
*await-expression* shall appear only in an *initializer* of that
|
| 17 |
*declaration-statement* or *simple-declaration*. An *await-expression*
|
| 18 |
shall not appear in a default argument [[dcl.fct.default]]. An
|
| 19 |
-
*await-expression* shall not appear in the initializer of a block
|
| 20 |
variable with static or thread storage duration. A context within a
|
| 21 |
function where an *await-expression* can appear is called a *suspension
|
| 22 |
context* of the function.
|
| 23 |
|
| 24 |
Evaluation of an *await-expression* involves the following auxiliary
|
| 25 |
types, expressions, and objects:
|
| 26 |
|
| 27 |
- *p* is an lvalue naming the promise object [[dcl.fct.def.coroutine]]
|
| 28 |
of the enclosing coroutine and `P` is the type of that object.
|
| 29 |
-
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
the
|
| 33 |
-
|
| 34 |
-
|
| 35 |
*p*`.await_transform(`*cast-expression*`)`; otherwise, *a* is the
|
| 36 |
*cast-expression*.
|
| 37 |
- *o* is determined by enumerating the applicable `operator co_await`
|
| 38 |
functions for an argument *a* [[over.match.oper]], and choosing the
|
| 39 |
best one through overload resolution [[over.match]]. If overload
|
|
@@ -61,25 +61,31 @@ and the *await-ready* expression, then:
|
|
| 61 |
- If the result of *await-ready* is `false`, the coroutine is considered
|
| 62 |
suspended. Then:
|
| 63 |
- If the type of *await-suspend* is `std::coroutine_handle<Z>`,
|
| 64 |
*await-suspend*`.resume()` is evaluated. \[*Note 1*: This resumes
|
| 65 |
the coroutine referred to by the result of *await-suspend*. Any
|
| 66 |
-
number of coroutines
|
| 67 |
eventually returning control flow to the current coroutine caller or
|
| 68 |
resumer [[dcl.fct.def.coroutine]]. — *end note*]
|
| 69 |
- Otherwise, if the type of *await-suspend* is `bool`, *await-suspend*
|
| 70 |
is evaluated, and the coroutine is resumed if the result is `false`.
|
| 71 |
- Otherwise, *await-suspend* is evaluated.
|
| 72 |
|
| 73 |
If the evaluation of *await-suspend* exits via an exception, the
|
| 74 |
exception is caught, the coroutine is resumed, and the exception is
|
| 75 |
-
immediately
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
| 78 |
- If the result of *await-ready* is `true`, or when the coroutine is
|
| 79 |
-
resumed
|
| 80 |
-
the
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
[*Example 1*:
|
| 83 |
|
| 84 |
``` cpp
|
| 85 |
template <typename T>
|
|
@@ -106,11 +112,11 @@ auto operator co_await(std::chrono::duration<Rep, Period> d) {
|
|
| 106 |
using namespace std::chrono;
|
| 107 |
|
| 108 |
my_future<int> h();
|
| 109 |
|
| 110 |
my_future<void> g() {
|
| 111 |
-
std::cout << "just about go to sleep...\n";
|
| 112 |
co_await 10ms;
|
| 113 |
std::cout << "resumed\n";
|
| 114 |
co_await h();
|
| 115 |
}
|
| 116 |
|
|
|
|
| 10 |
```
|
| 11 |
|
| 12 |
An *await-expression* shall appear only in a potentially-evaluated
|
| 13 |
expression within the *compound-statement* of a *function-body* outside
|
| 14 |
of a *handler* [[except.pre]]. In a *declaration-statement* or in the
|
| 15 |
+
*simple-declaration* (if any) of an *init-statement*, an
|
| 16 |
*await-expression* shall appear only in an *initializer* of that
|
| 17 |
*declaration-statement* or *simple-declaration*. An *await-expression*
|
| 18 |
shall not appear in a default argument [[dcl.fct.default]]. An
|
| 19 |
+
*await-expression* shall not appear in the initializer of a block
|
| 20 |
variable with static or thread storage duration. A context within a
|
| 21 |
function where an *await-expression* can appear is called a *suspension
|
| 22 |
context* of the function.
|
| 23 |
|
| 24 |
Evaluation of an *await-expression* involves the following auxiliary
|
| 25 |
types, expressions, and objects:
|
| 26 |
|
| 27 |
- *p* is an lvalue naming the promise object [[dcl.fct.def.coroutine]]
|
| 28 |
of the enclosing coroutine and `P` is the type of that object.
|
| 29 |
+
- Unless the *await-expression* was implicitly produced by a
|
| 30 |
+
*yield-expression* [[expr.yield]], an initial await expression, or a
|
| 31 |
+
final await expression [[dcl.fct.def.coroutine]], a search is
|
| 32 |
+
performed for the name `await_transform` in the scope of `P`
|
| 33 |
+
[[class.member.lookup]]. If this search is performed and finds at
|
| 34 |
+
least one declaration, then *a* is
|
| 35 |
*p*`.await_transform(`*cast-expression*`)`; otherwise, *a* is the
|
| 36 |
*cast-expression*.
|
| 37 |
- *o* is determined by enumerating the applicable `operator co_await`
|
| 38 |
functions for an argument *a* [[over.match.oper]], and choosing the
|
| 39 |
best one through overload resolution [[over.match]]. If overload
|
|
|
|
| 61 |
- If the result of *await-ready* is `false`, the coroutine is considered
|
| 62 |
suspended. Then:
|
| 63 |
- If the type of *await-suspend* is `std::coroutine_handle<Z>`,
|
| 64 |
*await-suspend*`.resume()` is evaluated. \[*Note 1*: This resumes
|
| 65 |
the coroutine referred to by the result of *await-suspend*. Any
|
| 66 |
+
number of coroutines can be successively resumed in this fashion,
|
| 67 |
eventually returning control flow to the current coroutine caller or
|
| 68 |
resumer [[dcl.fct.def.coroutine]]. — *end note*]
|
| 69 |
- Otherwise, if the type of *await-suspend* is `bool`, *await-suspend*
|
| 70 |
is evaluated, and the coroutine is resumed if the result is `false`.
|
| 71 |
- Otherwise, *await-suspend* is evaluated.
|
| 72 |
|
| 73 |
If the evaluation of *await-suspend* exits via an exception, the
|
| 74 |
exception is caught, the coroutine is resumed, and the exception is
|
| 75 |
+
immediately rethrown [[except.throw]]. Otherwise, control flow returns
|
| 76 |
+
to the current coroutine caller or resumer [[dcl.fct.def.coroutine]]
|
| 77 |
+
without exiting any scopes [[stmt.jump]]. The point in the coroutine
|
| 78 |
+
immediately prior to control returning to its caller or resumer is a
|
| 79 |
+
coroutine *suspend point*.
|
| 80 |
- If the result of *await-ready* is `true`, or when the coroutine is
|
| 81 |
+
resumed other than by rethrowing an exception from *await-suspend*,
|
| 82 |
+
the *await-resume* expression is evaluated, and its result is the
|
| 83 |
+
result of the *await-expression*.
|
| 84 |
+
|
| 85 |
+
[*Note 2*: With respect to sequencing, an *await-expression* is
|
| 86 |
+
indivisible [[intro.execution]]. — *end note*]
|
| 87 |
|
| 88 |
[*Example 1*:
|
| 89 |
|
| 90 |
``` cpp
|
| 91 |
template <typename T>
|
|
|
|
| 112 |
using namespace std::chrono;
|
| 113 |
|
| 114 |
my_future<int> h();
|
| 115 |
|
| 116 |
my_future<void> g() {
|
| 117 |
+
std::cout << "just about to go to sleep...\n";
|
| 118 |
co_await 10ms;
|
| 119 |
std::cout << "resumed\n";
|
| 120 |
co_await h();
|
| 121 |
}
|
| 122 |
|