Init
This commit is contained in:
123
cppdraft/exec/as/awaitable.md
Normal file
123
cppdraft/exec/as/awaitable.md
Normal file
@@ -0,0 +1,123 @@
|
||||
[exec.as.awaitable]
|
||||
|
||||
# 33 Execution control library [[exec]](./#exec)
|
||||
|
||||
## 33.13 Coroutine utilities [[exec.coro.util]](exec.coro.util#exec.as.awaitable)
|
||||
|
||||
### 33.13.1 execution::as_awaitable [exec.as.awaitable]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6609)
|
||||
|
||||
as_awaitable transforms an object into one
|
||||
that is awaitable within a particular coroutine[.](#1.sentence-1)
|
||||
|
||||
Subclause [[exec.coro.util]](exec.coro.util "33.13 Coroutine utilities") makes use of
|
||||
the following exposition-only entities:namespace std::execution {template<class Sndr, class Promise>concept [*awaitable-sender*](#concept:awaitable-sender "33.13.1 execution::as_awaitable [exec.as.awaitable]") =[*single-sender*](execution.syn#concept:single-sender "33.4 Header <execution> synopsis [execution.syn]")<Sndr, env_of_t<Promise>> &&[sender_to](exec.snd.concepts#concept:sender_to "33.9.3 Sender concepts [exec.snd.concepts]")<Sndr, *awaitable-receiver*> && // *see below*requires (Promise& p) {{ p.unhandled_stopped() } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<coroutine_handle<>>; }; template<class Sndr>concept [*has-queryable-await-completion-adaptor*](#concept:has-queryable-await-completion-adaptor "33.13.1 execution::as_awaitable [exec.as.awaitable]") = // *exposition only*[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]")<Sndr> &&requires(Sndr&& sender) { get_await_completion_adaptor(get_env(sender)); }; template<class Sndr, class Promise>class *sender-awaitable*; // *exposition only*}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6636)
|
||||
|
||||
The type *sender-awaitable*<Sndr, Promise> is equivalent to:
|
||||
|
||||
namespace std::execution {template<class Sndr, class Promise>class *sender-awaitable* {struct *unit* {}; // *exposition only*using *value-type* = // *exposition only**single-sender-value-type*<Sndr, env_of_t<Promise>>; using *result-type* = // *exposition only* conditional_t<is_void_v<*value-type*>, unit, *value-type*>; struct *awaitable-receiver*; // *exposition only* variant<monostate, *result-type*, exception_ptr> *result*{}; // *exposition only* connect_result_t<Sndr, *awaitable-receiver*> *state*; // *exposition only*public:*sender-awaitable*(Sndr&& sndr, Promise& p); static constexpr bool await_ready() noexcept { return false; }void await_suspend(coroutine_handle<Promise>) noexcept { start(*state*); }*value-type* await_resume(); };}
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6662)
|
||||
|
||||
*awaitable-receiver* is equivalent to:struct *awaitable-receiver* {using receiver_concept = receiver_t;
|
||||
variant<monostate, *result-type*, exception_ptr>* *result-ptr*; // *exposition only* coroutine_handle<Promise> *continuation*; // *exposition only*// *see below*};
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6673)
|
||||
|
||||
Let rcvr be an rvalue expression of type *awaitable-receiver*,
|
||||
let crcvr be a const lvalue that refers to rcvr,
|
||||
let vs be a pack of subexpressions, and
|
||||
let err be an expression of type Err[.](#4.sentence-1)
|
||||
|
||||
Then:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
If [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<*result-type*, decltype((vs))...> is satisfied,
|
||||
the expression set_value(
|
||||
rcvr, vs...) is equivalent to:try { rcvr.*result-ptr*->template emplace<1>(vs...);} catch(...) { rcvr.*result-ptr*->template emplace<2>(current_exception());} rcvr.*continuation*.resume();
|
||||
Otherwise, set_value(rcvr, vs...) is ill-formed[.](#4.1.sentence-2)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
The expression set_error(rcvr, err) is equivalent to:rcvr.*result-ptr*->template emplace<2>(*AS-EXCEPT-PTR*(err)); // see [[exec.general]](exec.general "33.1 General") rcvr.*continuation*.resume();
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
The expression set_stopped(rcvr) is equivalent to:static_cast<coroutine_handle<>>(rcvr.*continuation*.promise().unhandled_stopped()).resume();
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
For any expression tag whose type satisfies [*forwarding-query*](execution.syn#concept:forwarding-query "33.4 Header <execution> synopsis [execution.syn]") and
|
||||
for any pack of subexpressions as,get_env(crcvr).query(tag, as...) is expression-equivalent to:tag(get_env(as_const(crcvr.*continuation*.promise())), as...)
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`sender-awaitable(Sndr&& sndr, Promise& p);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6718)
|
||||
|
||||
*Effects*: Initializes *state* withconnect(std::forward<Sndr>(sndr), *awaitable-receiver*{addressof(result), coroutine_handle<Promise>::from_promise(p)})
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`value-type await_resume();
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6732)
|
||||
|
||||
*Effects*: Equivalent to:if (*result*.index() == 2) rethrow_exception(get<2>(*result*));if constexpr (!is_void_v<*value-type*>)return std::forward<*value-type*>(get<1>(*result*));
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6743)
|
||||
|
||||
as_awaitable is a customization point object[.](#7.sentence-1)
|
||||
|
||||
For subexpressions expr and p where p is an lvalue,Expr names the type decltype((expr)) andPromise names the type decay_t<decltype((p))>,as_awaitable(expr, p) is expression-equivalent to,
|
||||
except that the evaluations of expr and p are indeterminately sequenced:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
expr.as_awaitable(p) if that expression is well-formed[.](#7.1.sentence-1)
|
||||
*Mandates*: [*is-awaitable*](exec.awaitable#concept:is-awaitable "33.9.4 Awaitable helpers [exec.awaitable]")<A, Promise> is true,
|
||||
where A is the type of the expression above[.](#7.1.sentence-2)
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
Otherwise, (void(p), expr) if [*is-awaitable*](exec.awaitable#concept:is-awaitable "33.9.4 Awaitable helpers [exec.awaitable]")<Expr, U> is true,
|
||||
where U is an unspecified class type
|
||||
that is not Promise and
|
||||
that lacks a member named await_transform[.](#7.2.sentence-1)
|
||||
*Preconditions*: [*is-awaitable*](exec.awaitable#concept:is-awaitable "33.9.4 Awaitable helpers [exec.awaitable]")<Expr, Promise> is true and
|
||||
the expression co_await expr in a coroutine with promise type U is expression-equivalent to
|
||||
the same expression in a coroutine with promise type Promise[.](#7.2.sentence-2)
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
Otherwise, *sender-awaitable*{*adapted-expr*, p} if*has-queryable-await-completion-adaptor*<Expr> and*awaitable-sender*<decltype((*adapted-expr*)), Promise> are both satisfied, where *adapted-expr* isget_await_completion_adaptor(get_env(expr))(expr),
|
||||
except that expr is evaluated only once[.](#7.3.sentence-1)
|
||||
|
||||
- [(7.4)](#7.4)
|
||||
|
||||
Otherwise, *sender-awaitable*{expr, p} if [*awaitable-sender*](#concept:awaitable-sender "33.13.1 execution::as_awaitable [exec.as.awaitable]")<Expr, Promise> is true[.](#7.4.sentence-1)
|
||||
|
||||
- [(7.5)](#7.5)
|
||||
|
||||
Otherwise, (void(p), expr)[.](#7.5.sentence-1)
|
||||
Reference in New Issue
Block a user