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

212 lines
8.4 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[exec.on]
# 33 Execution control library [[exec]](./#exec)
## 33.9 Senders [[exec.snd]](exec.snd#exec.on)
### 33.9.12 Sender adaptors [[exec.adapt]](exec.adapt#exec.on)
#### 33.9.12.8 execution::on [exec.on]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3561)
The on sender adaptor has two forms:
- [(1.1)](#1.1)
on(sch, sndr),
which starts a sender sndr on an execution agent
belonging to a scheduler sch's associated execution resource and
that, upon sndr's completion,
transfers execution back to the execution resource
on which the on sender was started[.](#1.1.sentence-1)
- [(1.2)](#1.2)
on(sndr, sch, closure),
which upon completion of a sender sndr,
transfers execution to an execution agent
belonging to a scheduler sch's associated execution resource,
then executes a sender adaptor closure closure with the async results of the sender, and
that then transfers execution back to the execution resource
on which sndr completed[.](#1.2.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3582)
The name on denotes a pipeable sender adaptor object[.](#2.sentence-1)
For subexpressions sch and sndr,on(sch, sndr) is ill-formed if any of the following is true:
- [(2.1)](#2.1)
decltype((sch)) does not satisfy [scheduler](exec.sched#concept:scheduler "33.6Schedulers[exec.sched]"), or
- [(2.2)](#2.2)
decltype((sndr)) does not satisfy [sender](exec.snd.concepts#concept:sender "33.9.3Sender concepts[exec.snd.concepts]") andsndr is not
a pipeable sender adaptor closure object ([[exec.adapt.obj]](exec.adapt.obj "33.9.12.2Closure objects")), or
- [(2.3)](#2.3)
decltype((sndr)) satisfies [sender](exec.snd.concepts#concept:sender "33.9.3Sender concepts[exec.snd.concepts]") andsndr is also a pipeable sender adaptor closure object[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3598)
Otherwise, if decltype((sndr)) satisfies [sender](exec.snd.concepts#concept:sender "33.9.3Sender concepts[exec.snd.concepts]"),
the expression on(sch, sndr) is expression-equivalent to:transform_sender(*query-with-default*(get_domain, sch, default_domain()), *make-sender*(on, sch, sndr)) except that sch is evaluated only once[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3608)
For subexpressions sndr, sch, and closure, if
- [(4.1)](#4.1)
decltype((sch)) does not satisfy [scheduler](exec.sched#concept:scheduler "33.6Schedulers[exec.sched]"), or
- [(4.2)](#4.2)
decltype((sndr)) does not satisfy [sender](exec.snd.concepts#concept:sender "33.9.3Sender concepts[exec.snd.concepts]"), or
- [(4.3)](#4.3)
closure is not a pipeable sender adaptor closure object ([[exec.adapt.obj]](exec.adapt.obj "33.9.12.2Closure objects")),
the expression on(sndr, sch, closure) is ill-formed;
otherwise, it is expression-equivalent to:transform_sender(*get-domain-early*(sndr), *make-sender*(on, *product-type*{sch, closure}, sndr)) except that sndr is evaluated only once[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3627)
Let out_sndr and env be subexpressions,
let OutSndr be decltype((out_sndr)), and
let Env be decltype((env))[.](#5.sentence-1)
If [*sender-for*](exec.snd.concepts#concept:sender-for "33.9.3Sender concepts[exec.snd.concepts]")<OutSndr, on_t> is false,
then the expressions on.transform_env(out_sndr, env) andon.transform_sender(out_sndr, env) are ill-formed[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3635)
Otherwise:
Let *not-a-scheduler* be an unspecified empty class type[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3639)
The expression on.transform_env(out_sndr, env) has effects equivalent to:auto&& [_, data, _] = out_sndr;if constexpr ([scheduler](exec.sched#concept:scheduler "33.6Schedulers[exec.sched]")<decltype(data)>) {return *JOIN-ENV*(*SCHED-ENV*(std::forward_like<OutSndr>(data)), *FWD-ENV*(std::forward<Env>(env)));} else {return std::forward<Env>(env);}
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3651)
The expression on.transform_sender(out_sndr, env) has effects equivalent to:auto&& [_, data, child] = out_sndr;if constexpr ([scheduler](exec.sched#concept:scheduler "33.6Schedulers[exec.sched]")<decltype(data)>) {auto orig_sch =*query-with-default*(get_scheduler, env, *not-a-scheduler*()); if constexpr ([same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<decltype(orig_sch), *not-a-scheduler*>) {return *not-a-sender*{}; } else {return continues_on( starts_on(std::forward_like<OutSndr>(data), std::forward_like<OutSndr>(child)),
std::move(orig_sch)); }} else {auto& [sch, closure] = data; auto orig_sch = *query-with-default*( get_completion_scheduler<set_value_t>,
get_env(child), *query-with-default*(get_scheduler, env, *not-a-scheduler*())); if constexpr ([same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<decltype(orig_sch), *not-a-scheduler*>) {return *not-a-sender*{}; } else {return write_env( continues_on( std::forward_like<OutSndr>(closure)( continues_on( write_env(std::forward_like<OutSndr>(child), *SCHED-ENV*(orig_sch)),
sch)),
orig_sch), *SCHED-ENV*(sch)); }}
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3689)
Let out_sndr be a subexpression denoting
a sender returned from on(sch, sndr) or one equal to such, and
let OutSndr be the type decltype((out_sndr))[.](#9.sentence-1)
Let out_rcvr be a subexpression denoting a receiver
that has an environment of type Env such that [sender_in](exec.snd.concepts#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<OutSndr, Env> is true[.](#9.sentence-2)
Let op be an lvalue referring to the operation state
that results from connecting out_sndr with out_rcvr[.](#9.sentence-3)
Calling start(op) shall
- [(9.1)](#9.1)
remember the current scheduler, get_scheduler(get_env(rcvr));
- [(9.2)](#9.2)
start sndr on an execution agent belonging tosch's associated execution resource;
- [(9.3)](#9.3)
upon sndr's completion,
transfer execution back to the execution resource
associated with the scheduler remembered in step 1; and
- [(9.4)](#9.4)
forward sndr's async result to out_rcvr[.](#9.sentence-4)
If any scheduling operation fails,
an error completion on out_rcvr shall be executed
on an unspecified execution agent[.](#9.sentence-5)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L3716)
Let out_sndr be a subexpression denoting
a sender returned from on(sndr, sch, closure) or one equal to such, and
let OutSndr be the type decltype((out_sndr))[.](#10.sentence-1)
Let out_rcvr be a subexpression denoting a receiver
that has an environment of type Env such that [sender_in](exec.snd.concepts#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<OutSndr, Env> is true[.](#10.sentence-2)
Let op be an lvalue referring to the operation state
that results from connecting out_sndr with out_rcvr[.](#10.sentence-3)
Calling start(op) shall
- [(10.1)](#10.1)
remember the current scheduler,
which is the first of the following expressions that is well-formed:
* [(10.1.1)](#10.1.1)
get_completion_scheduler<set_value_t>(get_env(sndr))
* [(10.1.2)](#10.1.2)
get_scheduler(get_env(rcvr));
- [(10.2)](#10.2)
start sndr on the current execution agent;
- [(10.3)](#10.3)
upon sndr's completion,
transfer execution to an agent
owned by sch's associated execution resource;
- [(10.4)](#10.4)
forward sndr's async result as if by
connecting and starting a sender closure(S),
where S is a sender
that completes synchronously with sndr's async result; and
- [(10.5)](#10.5)
upon completion of the operation started in the previous step,
transfer execution back to the execution resource
associated with the scheduler remembered in step 1 and
forward the operation's async result to out_rcvr[.](#10.sentence-4)
If any scheduling operation fails,
an error completion on out_rcvr shall be executed on
an unspecified execution agent[.](#10.sentence-5)