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

5.3 KiB

[exec.awaitable]

33 Execution control library [exec]

33.9 Senders [exec.snd]

33.9.4 Awaitable helpers [exec.awaitable]

1

#

The sender concepts recognize awaitables as senders.

For [exec], an awaitable is an expression that would be well-formed as the operand of a co_await expression within a given context.

2

#

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 in a coroutine, resulting in lvalue e as described by [expr.await], where p is an lvalue referring to the coroutine's promise, which has type Promise.

[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.

— 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.

3

#

Let is-awaitable be the following exposition-only concept:namespace std {templateconcept await-suspend-result = see below; // exposition onlytemplate<class A, class... Promise>concept is-awaiter = // exposition onlyrequires (A& a, coroutine_handle<Promise...> h) { a.await_ready() ? 1 : 0; { a.await_suspend(h) } -> await-suspend-result; a.await_resume(); }; template<class C, class... Promise>concept is-awaitable = // exposition onlyrequires (C (*fc)() noexcept, Promise&... p) {{ GET-AWAITER(fc(), p...) } -> is-awaiter<Promise...>; };}

await-suspend-result is true if and only if one of the following is true:

T is void, or

T is bool, or

T is a specialization of coroutine_handle.

4

#

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()) andawait-result-type denotes the type decltype(GET-AWAITER(c).await_resume()).

5

#

Let with-await-transform be the exposition-only class template:namespace std::execution {template<class T, class Promise>concept has-as-awaitable = // exposition onlyrequires (T&& t, Promise& p) {{ std::forward(t).as_awaitable(p) } -> is-awaitable<Promise&>; }; templatestruct with-await-transform { // exposition onlytemplate T&& await_transform(T&& value) noexcept {return std::forward(value); }template<has-as-awaitable T>auto await_transform(T&& value)noexcept(noexcept(std::forward(value).as_awaitable(declval<Derived&>())))-> decltype(std::forward(value).as_awaitable(declval<Derived&>())) {return std::forward(value).as_awaitable(static_cast<Derived&>(*this)); }};}

6

#

Let env-promise be the exposition-only class template:namespace std::execution {templatestruct env-promise : with-await-transform<env-promise> { // 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:

Specializations of env-promise are used only for the purpose of type computation; its members need not be defined.

— end note]