Init
This commit is contained in:
94
cppdraft/exec/awaitable.md
Normal file
94
cppdraft/exec/awaitable.md
Normal file
@@ -0,0 +1,94 @@
|
||||
[exec.awaitable]
|
||||
|
||||
# 33 Execution control library [[exec]](./#exec)
|
||||
|
||||
## 33.9 Senders [[exec.snd]](exec.snd#exec.awaitable)
|
||||
|
||||
### 33.9.4 Awaitable helpers [exec.awaitable]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2304)
|
||||
|
||||
The sender concepts recognize awaitables as senders[.](#1.sentence-1)
|
||||
|
||||
For [[exec]](exec "33 Execution control library"), an [*awaitable*](#def:awaitable "33.9.4 Awaitable helpers [exec.awaitable]") is an expression
|
||||
that would be well-formed as the operand of a co_await expression
|
||||
within a given context[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2310)
|
||||
|
||||
For a subexpression c,
|
||||
let *GET-AWAITER*(c, p) be expression-equivalent to
|
||||
the series of transformations and conversions applied to c as the operand of an [*await-expression*](expr.await#nt:await-expression "7.6.2.4 Await [expr.await]") in a coroutine,
|
||||
resulting in lvalue e as described by [[expr.await]](expr.await "7.6.2.4 Await"),
|
||||
where p is an lvalue referring to the coroutine's promise,
|
||||
which has type Promise[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This includes the invocation of
|
||||
the promise type's await_transform member if any,
|
||||
the invocation of the operator co_await picked by overload resolution if any, and
|
||||
any necessary implicit conversions and materializations[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Let *GET-AWAITER*(c) be
|
||||
expression-equivalent to *GET-AWAITER*(c, q) where q is an lvalue of
|
||||
an unspecified empty class type *none-such* that
|
||||
lacks an await_transform member, and
|
||||
where coroutine_handle<*none-such*> behaves ascoroutine_handle<void>[.](#2.sentence-3)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2334)
|
||||
|
||||
Let [*is-awaitable*](#concept:is-awaitable "33.9.4 Awaitable helpers [exec.awaitable]") be the following exposition-only concept:namespace std {template<class T>concept [*await-suspend-result*](#concept:await-suspend-result "33.9.4 Awaitable helpers [exec.awaitable]") = *see below*; // *exposition only*template<class A, class... Promise>concept [*is-awaiter*](#concept:is-awaiter "33.9.4 Awaitable helpers [exec.awaitable]") = // *exposition only*requires (A& a, coroutine_handle<Promise...> h) { a.await_ready() ? 1 : 0; { a.await_suspend(h) } -> [*await-suspend-result*](#concept:await-suspend-result "33.9.4 Awaitable helpers [exec.awaitable]");
|
||||
a.await_resume(); }; template<class C, class... Promise>concept [*is-awaitable*](#concept:is-awaitable "33.9.4 Awaitable helpers [exec.awaitable]") = // *exposition only*requires (C (*fc)() noexcept, Promise&... p) {{ *GET-AWAITER*(fc(), p...) } -> [*is-awaiter*](#concept:is-awaiter "33.9.4 Awaitable helpers [exec.awaitable]")<Promise...>; };}
|
||||
|
||||
[*await-suspend-result*](#concept:await-suspend-result "33.9.4 Awaitable helpers [exec.awaitable]")<T> is true if and only if one of the following is true:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
T is void, or
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
T is bool, or
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
T is a specialization of coroutine_handle[.](#3.sentence-2)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2365)
|
||||
|
||||
For a subexpression c such that decltype((c)) is type C, and
|
||||
an lvalue p of type Promise,*await-result-
|
||||
type*<C, Promise> denotes
|
||||
the type decltype(*GET-AWAITER*(c, p).await_resume()) and*await-result-type*<C> denotes
|
||||
the type decltype(*GET-AWAITER*(c).await_resume())[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2374)
|
||||
|
||||
Let *with-await-transform* be the exposition-only class template:namespace std::execution {template<class T, class Promise>concept [*has-as-awaitable*](#concept:has-as-awaitable "33.9.4 Awaitable helpers [exec.awaitable]") = // *exposition only*requires (T&& t, Promise& p) {{ std::forward<T>(t).as_awaitable(p) } -> [*is-awaitable*](#concept:is-awaitable "33.9.4 Awaitable helpers [exec.awaitable]")<Promise&>; }; template<class Derived>struct *with-await-transform* { // *exposition only*template<class T> T&& await_transform(T&& value) noexcept {return std::forward<T>(value); }template<[*has-as-awaitable*](#concept:has-as-awaitable "33.9.4 Awaitable helpers [exec.awaitable]")<Derived> T>auto await_transform(T&& value)noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>())))-> decltype(std::forward<T>(value).as_awaitable(declval<Derived&>())) {return std::forward<T>(value).as_awaitable(static_cast<Derived&>(*this)); }};}
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2401)
|
||||
|
||||
Let *env-promise* be the exposition-only class template:namespace std::execution {template<class Env>struct *env-promise* : *with-await-transform*<*env-promise*<Env>> { // *exposition only**unspecified* get_return_object() noexcept; *unspecified* initial_suspend() noexcept; *unspecified* final_suspend() noexcept; void unhandled_exception() noexcept; void return_void() noexcept;
|
||||
coroutine_handle<> unhandled_stopped() noexcept; const Env& get_env() const noexcept; };}
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
Specializations of *env-promise* are used only for the purpose of type computation;
|
||||
its members need not be defined[.](#6.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
Reference in New Issue
Block a user