6.0 KiB
[exec.spawn]
33 Execution control library [exec]
33.9 Senders [exec.snd]
33.9.13 Sender consumers [exec.consumers]
33.9.13.3 execution::spawn [exec.spawn]
spawn attempts to associate the given input sender with the given token's async scope and, on success, eagerly starts the input sender.
The name spawn denotes a customization point object.
For subexpressions sndr, token, and env,
let Sndr be decltype((sndr)),
let Token be remove_cvref_t<decltype((token))>, and
let Env be remove_cvref_t<decltype((env))>.
If any ofsender,scope_token, orqueryable are not satisfied, the expression spawn(sndr, token, env) is ill-formed.
Let spawn-state-base be the exposition-only class:
namespace std::execution {struct spawn-state-base { // exposition onlyvirtual void complete() noexcept = 0; // exposition only};}
Let spawn-receiver be the exposition-only class:
namespace std::execution {struct spawn-receiver { // exposition onlyusing receiver_concept = receiver_t; spawn-state-base* state; // exposition onlyvoid set_value() && noexcept { state->complete(); }void set_stopped() && noexcept { state->complete(); }};}
Let spawn-state be the exposition-only class template:
namespace std::execution {template<class Alloc, scope_token Token, sender Sender>struct spawn-state : spawn-state-base { // exposition onlyusing op-t = connect_result_t<Sender, spawn-receiver>; // exposition only**spawn-state(Alloc alloc, Sender&& sndr, Token token); // exposition onlyvoid complete() noexcept override; // exposition onlyvoid run(); // exposition onlyprivate:using alloc-t = // exposition onlytypename allocator_traits::template rebind_alloc<spawn-state>; alloc-t alloc; // exposition only**op-t op; // exposition only Token token; // exposition onlyvoid destroy() noexcept; // exposition only};}
spawn-state(Alloc alloc, Sender&& sndr, Token token);
Effects: Initializesalloc with alloc,token with token, andop with:connect(std::move(sndr), spawn-receiver(this))
void run();
Effects: Equivalent to:if (token.try_associate()) start(op);elsedestroy();
void complete() noexcept override;
Effects: Equivalent to:auto token = std::move(this->token);
destroy(); token.disassociate();
void destroy() noexcept;
Effects: Equivalent to:auto alloc = std::move(this->alloc);
allocator_traits<alloc-t>::destroy(alloc, this); allocator_traits<alloc-t>::deallocate(alloc, this, 1);
For the expression spawn(sndr, token, env) let new_sender be the expression token.wrap(sndr) and let alloc and senv be defined as follows:
if the expression get_allocator(env) is well-formed, thenalloc is the result of get_allocator(env) andsenv is the expression env,
otherwise if the expression get_allocator(get_env(new_sender)) is well-formed, thenalloc is the result of get_allocator(get_env(new_sender)) andsenv is the expression JOIN-ENV(prop(get_allocator, alloc), env),
otherwisealloc is allocator() andsenv is the expression env.
The expression spawn(sndr, token, env) is of type void and has the following effects:
Uses alloc to allocate and construct an object o of type that is a specialization of spawn-state fromalloc, write_env(token.wrap(sndr), senv), and token and then invokes o.run(). If an exception is thrown then any constructed objects are destroyed and any allocated memory is deallocated.
The expression spawn(sndr, token) is expression-equivalent tospawn(sndr, token, execution::env<>()).