From Jason Turner

[exec.as.awaitable]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpmxqeaw7w/{from.md → to.md} +154 -0
tmp/tmpmxqeaw7w/{from.md → to.md} RENAMED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### `execution::as_awaitable` <a id="exec.as.awaitable">[[exec.as.awaitable]]</a>
2
+
3
+ `as_awaitable` transforms an object into one that is awaitable within a
4
+ particular coroutine. Subclause [[exec.coro.util]] makes use of the
5
+ following exposition-only entities:
6
+
7
+ ``` cpp
8
+ namespace std::execution {
9
+ template<class Sndr, class Promise>
10
+ concept awaitable-sender =
11
+ single-sender<Sndr, env_of_t<Promise>> &&
12
+ sender_to<Sndr, awaitable-receiver> && // see below
13
+ requires (Promise& p) {
14
+ { p.unhandled_stopped() } -> convertible_to<coroutine_handle<>>;
15
+ };
16
+
17
+ template<class Sndr>
18
+ concept has-queryable-await-completion-adaptor = // exposition only
19
+ sender<Sndr> &&
20
+ requires(Sndr&& sender) {
21
+ get_await_completion_adaptor(get_env(sender));
22
+ };
23
+
24
+ template<class Sndr, class Promise>
25
+ class sender-awaitable; // exposition only
26
+ }
27
+ ```
28
+
29
+ The type `sender-awaitable<Sndr, Promise>` is equivalent to:
30
+
31
+ ``` cpp
32
+ namespace std::execution {
33
+ template<class Sndr, class Promise>
34
+ class sender-awaitable {
35
+ struct unit {}; // exposition only
36
+ using value-type = // exposition only
37
+ single-sender-value-type<Sndr, env_of_t<Promise>>;
38
+ using result-type = // exposition only
39
+ conditional_t<is_void_v<value-type>, unit, value-type>;
40
+ struct awaitable-receiver; // exposition only
41
+
42
+ variant<monostate, result-type, exception_ptr> result{}; // exposition only
43
+ connect_result_t<Sndr, awaitable-receiver> state; // exposition only
44
+
45
+ public:
46
+ sender-awaitable(Sndr&& sndr, Promise& p);
47
+ static constexpr bool await_ready() noexcept { return false; }
48
+ void await_suspend(coroutine_handle<Promise>) noexcept { start(state); }
49
+ value-type await_resume();
50
+ };
51
+ }
52
+ ```
53
+
54
+ *`awaitable-receiver`* is equivalent to:
55
+
56
+ ``` cpp
57
+ struct awaitable-receiver {
58
+ using receiver_concept = receiver_t;
59
+ variant<monostate, result-type, exception_ptr>* result-ptr; // exposition only
60
+ coroutine_handle<Promise> continuation; // exposition only
61
+ // see below
62
+ };
63
+ ```
64
+
65
+ Let `rcvr` be an rvalue expression of type *`awaitable-receiver`*, let
66
+ `crcvr` be a const lvalue that refers to `rcvr`, let `vs` be a pack of
67
+ subexpressions, and let `err` be an expression of type `Err`. Then:
68
+
69
+ - If `constructible_from<result-type, decltype((vs))...>` is satisfied,
70
+ the expression `set_value( rcvr, vs...)` is equivalent to:
71
+ ``` cpp
72
+ try {
73
+ rcvr.result-ptr->template emplace<1>(vs...);
74
+ } catch(...) {
75
+ rcvr.result-ptr->template emplace<2>(current_exception());
76
+ }
77
+ rcvr.continuation.resume();
78
+ ```
79
+
80
+ Otherwise, `set_value(rcvr, vs...)` is ill-formed.
81
+ - The expression `set_error(rcvr, err)` is equivalent to:
82
+ ``` cpp
83
+ rcvr.result-ptr->template emplace<2>(AS-EXCEPT-PTR(err)); // see [exec.general]
84
+ rcvr.continuation.resume();
85
+ ```
86
+ - The expression `set_stopped(rcvr)` is equivalent to:
87
+ ``` cpp
88
+ static_cast<coroutine_handle<>>(rcvr.continuation.promise().unhandled_stopped()).resume();
89
+ ```
90
+ - For any expression `tag` whose type satisfies `forwarding-query` and
91
+ for any pack of subexpressions `as`,
92
+ `get_env(crcvr).query(tag, as...)` is expression-equivalent to:
93
+ ``` cpp
94
+ tag(get_env(as_const(crcvr.continuation.promise())), as...)
95
+ ```
96
+
97
+ ``` cpp
98
+ sender-awaitable(Sndr&& sndr, Promise& p);
99
+ ```
100
+
101
+ *Effects:* Initializes *state* with
102
+
103
+ ``` cpp
104
+ connect(std::forward<Sndr>(sndr),
105
+ awaitable-receiver{addressof(result), coroutine_handle<Promise>::from_promise(p)})
106
+ ```
107
+
108
+ ``` cpp
109
+ value-type await_resume();
110
+ ```
111
+
112
+ *Effects:* Equivalent to:
113
+
114
+ ``` cpp
115
+ if (result.index() == 2)
116
+ rethrow_exception(get<2>(result));
117
+ if constexpr (!is_void_v<value-type>)
118
+ return std::forward<value-type>(get<1>(result));
119
+ ```
120
+
121
+ `as_awaitable` is a customization point object. For subexpressions
122
+ `expr` and `p` where `p` is an lvalue, `Expr` names the type
123
+ `decltype((expr))` and `Promise` names the type
124
+ `decay_t<decltype((p))>`, `as_awaitable(expr, p)` is
125
+ expression-equivalent to, except that the evaluations of `expr` and `p`
126
+ are indeterminately sequenced:
127
+
128
+ - `expr.as_awaitable(p)` if that expression is well-formed. *Mandates:*
129
+ `is-awaitable<A, Promise>` is `true`, where `A` is the type of the
130
+ expression above.
131
+ - Otherwise, `(void(p), expr)` if `is-awaitable<Expr, U>` is `true`,
132
+ where `U` is an unspecified class type that is not `Promise` and that
133
+ lacks a member named `await_transform`. *Preconditions:*
134
+ `is-awaitable<Expr, Promise>` is `true` and the expression
135
+ `co_await expr` in a coroutine with promise type `U` is
136
+ expression-equivalent to the same expression in a coroutine with
137
+ promise type `Promise`.
138
+ - Otherwise, `sender-awaitable{adapted-expr, p}` if
139
+ ``` cpp
140
+ has-queryable-await-completion-adaptor<Expr>
141
+ ```
142
+
143
+ and
144
+ ``` cpp
145
+ awaitable-sender<decltype((adapted-expr)), Promise>
146
+ ```
147
+
148
+ are both satisfied, where *`adapted-expr`* is
149
+ `get_await_completion_adaptor(get_env(expr))(expr)`, except that
150
+ `expr` is evaluated only once.
151
+ - Otherwise, `sender-awaitable{expr, p}` if
152
+ `awaitable-sender<Expr, Promise>` is `true`.
153
+ - Otherwise, `(void(p), expr)`.
154
+