Files
cppdraft_translate/cppdraft/exec/as/awaitable.md
2025-10-25 03:02:53 +03:00

7.0 KiB
Raw Blame History

[exec.as.awaitable]

33 Execution control library [exec]

33.13 Coroutine utilities [exec.coro.util]

33.13.1 execution::as_awaitable [exec.as.awaitable]

1

#

as_awaitable transforms an object into one that is awaitable within a particular coroutine.

Subclause [exec.coro.util] makes use of the following exposition-only entities:namespace std::execution {template<class Sndr, class Promise>concept awaitable-sender =single-sender<Sndr, env_of_t> &&sender_to<Sndr, awaitable-receiver> && // see belowrequires (Promise& p) {{ p.unhandled_stopped() } -> convertible_to<coroutine_handle<>>; }; templateconcept has-queryable-await-completion-adaptor = // exposition onlysender &&requires(Sndr&& sender) { get_await_completion_adaptor(get_env(sender)); }; template<class Sndr, class Promise>class sender-awaitable; // exposition only}

2

#

The type sender-awaitable<Sndr, Promise> is equivalent to:

namespace std::execution {template<class Sndr, class Promise>class sender-awaitable {struct unit {}; // exposition onlyusing value-type = // exposition only**single-sender-value-type<Sndr, env_of_t>; 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 onlypublic:sender-awaitable(Sndr&& sndr, Promise& p); static constexpr bool await_ready() noexcept { return false; }void await_suspend(coroutine_handle) noexcept { start(state); }value-type await_resume(); };}

3

#

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 continuation; // exposition only// see below};

4

#

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.

Then:

If constructible_from<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.

The expression set_error(rcvr, err) is equivalent to:rcvr.result-ptr->template emplace<2>(AS-EXCEPT-PTR(err)); // see [exec.general] rcvr.continuation.resume();

The expression set_stopped(rcvr) is equivalent to:static_cast<coroutine_handle<>>(rcvr.continuation.promise().unhandled_stopped()).resume();

For any expression tag whose type satisfies forwarding-query 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...)

🔗

sender-awaitable(Sndr&& sndr, Promise& p);

5

#

Effects: Initializes state withconnect(std::forward(sndr), awaitable-receiver{addressof(result), coroutine_handle::from_promise(p)})

🔗

value-type await_resume();

6

#

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

#

as_awaitable is a customization point object.

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)

    expr.as_awaitable(p) if that expression is well-formed. Mandates: is-awaitable<A, Promise> is true, where A is the type of the expression above.

  • (7.2)

    Otherwise, (void(p), expr) if is-awaitable<Expr, U> is true, where U is an unspecified class type that is not Promise and that lacks a member named await_transform. Preconditions: is-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.3)

    Otherwise, sender-awaitable{adapted-expr, p} ifhas-queryable-await-completion-adaptor andawaitable-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.4)

    Otherwise, sender-awaitable{expr, p} if awaitable-sender<Expr, Promise> is true.

  • (7.5)

    Otherwise, (void(p), expr).