From Jason Turner

[exec.awaitable]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp7hgrto1a/{from.md → to.md} +107 -0
tmp/tmp7hgrto1a/{from.md → to.md} RENAMED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Awaitable helpers <a id="exec.awaitable">[[exec.awaitable]]</a>
2
+
3
+ The sender concepts recognize awaitables as senders. For [[exec]], an
4
+ *awaitable* is an expression that would be well-formed as the operand of
5
+ a `co_await` expression within a given context.
6
+
7
+ For a subexpression `c`, let `GET-AWAITER(c, p)` be
8
+ expression-equivalent to the series of transformations and conversions
9
+ applied to `c` as the operand of an *await-expression* in a coroutine,
10
+ resulting in lvalue `e` as described by [[expr.await]], where `p` is an
11
+ lvalue referring to the coroutine’s promise, which has type `Promise`.
12
+
13
+ [*Note 1*: This includes the invocation of the promise type’s
14
+ `await_transform` member if any, the invocation of the
15
+ `operator co_await` picked by overload resolution if any, and any
16
+ necessary implicit conversions and materializations. — *end note*]
17
+
18
+ Let `GET-AWAITER(c)` be expression-equivalent to `GET-AWAITER(c, q)`
19
+ where `q` is an lvalue of an unspecified empty class type `none-such`
20
+ that lacks an `await_transform` member, and where
21
+ `coroutine_handle<none-such>` behaves as `coroutine_handle<void>`.
22
+
23
+ Let `is-awaitable` be the following exposition-only concept:
24
+
25
+ ``` cpp
26
+ namespace std {
27
+ template<class T>
28
+ concept await-suspend-result = see below; // exposition only
29
+
30
+ template<class A, class... Promise>
31
+ concept is-awaiter = // exposition only
32
+ requires (A& a, coroutine_handle<Promise...> h) {
33
+ a.await_ready() ? 1 : 0;
34
+ { a.await_suspend(h) } -> await-suspend-result;
35
+ a.await_resume();
36
+ };
37
+
38
+ template<class C, class... Promise>
39
+ concept is-awaitable = // exposition only
40
+ requires (C (*fc)() noexcept, Promise&... p) {
41
+ { GET-AWAITER(fc(), p...) } -> is-awaiter<Promise...>;
42
+ };
43
+ }
44
+ ```
45
+
46
+ `\defexposconcept{await-suspend-result}<T>` is `true` if and only if one
47
+ of the following is `true`:
48
+
49
+ - `T` is `void`, or
50
+ - `T` is `bool`, or
51
+ - `T` is a specialization of `coroutine_handle`.
52
+
53
+ For a subexpression `c` such that `decltype((c))` is type `C`, and an
54
+ lvalue `p` of type `Promise`, `await-result- type<C, Promise>` denotes
55
+ the type `decltype(GET-AWAITER(c, p).await_resume())` and
56
+ `await-result-type<C>` denotes the type
57
+ `decltype(GET-AWAITER(c).await_resume())`.
58
+
59
+ Let *`with-await-transform`* be the exposition-only class template:
60
+
61
+ ``` cpp
62
+ namespace std::execution {
63
+ template<class T, class Promise>
64
+ concept has-as-awaitable = // exposition only
65
+ requires (T&& t, Promise& p) {
66
+ { std::forward<T>(t).as_awaitable(p) } -> is-awaitable<Promise&>;
67
+ };
68
+
69
+ template<class Derived>
70
+ struct with-await-transform { // exposition only
71
+ template<class T>
72
+ T&& await_transform(T&& value) noexcept {
73
+ return std::forward<T>(value);
74
+ }
75
+
76
+ template<has-as-awaitable<Derived> T>
77
+ auto await_transform(T&& value)
78
+ noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>())))
79
+ -> decltype(std::forward<T>(value).as_awaitable(declval<Derived&>())) {
80
+ return std::forward<T>(value).as_awaitable(static_cast<Derived&>(*this));
81
+ }
82
+ };
83
+ }
84
+ ```
85
+
86
+ Let *`env-promise`* be the exposition-only class template:
87
+
88
+ ``` cpp
89
+ namespace std::execution {
90
+ template<class Env>
91
+ struct env-promise : with-await-transform<env-promise<Env>> { // exposition only
92
+ unspecified get_return_object() noexcept;
93
+ unspecified initial_suspend() noexcept;
94
+ unspecified final_suspend() noexcept;
95
+ void unhandled_exception() noexcept;
96
+ void return_void() noexcept;
97
+ coroutine_handle<> unhandled_stopped() noexcept;
98
+
99
+ const Env& get_env() const noexcept;
100
+ };
101
+ }
102
+ ```
103
+
104
+ [*Note 2*: Specializations of *`env-promise`* are used only for the
105
+ purpose of type computation; its members need not be
106
+ defined. — *end note*]
107
+