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