From Jason Turner

[expr.await]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpj2tyu074/{from.md → to.md} +21 -15
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 a *for-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-scope
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
- - *a* is the *cast-expression* if the *await-expression* was implicitly
30
- produced by a *yield-expression* [[expr.yield]], an initial suspend
31
- point, or a final suspend point [[dcl.fct.def.coroutine]]. Otherwise,
32
- the *unqualified-id* `await_transform` is looked up within the scope
33
- of `P` by class member access lookup [[basic.lookup.classref]], and if
34
- this lookup finds at 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,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 may 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 re-thrown [[except.throw]]. Otherwise, control flow
76
- returns to the current coroutine caller or resumer
77
- [[dcl.fct.def.coroutine]] without exiting any scopes [[stmt.jump]].
 
 
78
  - If the result of *await-ready* is `true`, or when the coroutine is
79
- resumed, the *await-resume* expression is evaluated, and its result is
80
- the result of the *await-expression*.
 
 
 
 
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