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

8.4 KiB
Raw Blame History

[exec.on]

33 Execution control library [exec]

33.9 Senders [exec.snd]

33.9.12 Sender adaptors [exec.adapt]

33.9.12.8 execution::on [exec.on]

1

#

The on sender adaptor has two forms:

  • (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.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.

2

#

The name on denotes a pipeable sender adaptor object.

For subexpressions sch and sndr,on(sch, sndr) is ill-formed if any of the following is true:

decltype((sch)) does not satisfy scheduler, or

decltype((sndr)) does not satisfy sender andsndr is not a pipeable sender adaptor closure object ([exec.adapt.obj]), or

decltype((sndr)) satisfies sender andsndr is also a pipeable sender adaptor closure object.

3

#

Otherwise, if decltype((sndr)) satisfies sender, 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.

4

#

For subexpressions sndr, sch, and closure, if

decltype((sch)) does not satisfy scheduler, or

decltype((sndr)) does not satisfy sender, or

closure is not a pipeable sender adaptor closure object ([exec.adapt.obj]),

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.

5

#

Let out_sndr and env be subexpressions, let OutSndr be decltype((out_sndr)), and let Env be decltype((env)).

If sender-for<OutSndr, on_t> is false, then the expressions on.transform_env(out_sndr, env) andon.transform_sender(out_sndr, env) are ill-formed.

6

#

Otherwise: Let not-a-scheduler be an unspecified empty class type.

7

#

The expression on.transform_env(out_sndr, env) has effects equivalent to:auto&& [_, data, _] = out_sndr;if constexpr (scheduler<decltype(data)>) {return JOIN-ENV(SCHED-ENV(std::forward_like(data)), FWD-ENV(std::forward(env)));} else {return std::forward(env);}

8

#

The expression on.transform_sender(out_sndr, env) has effects equivalent to:auto&& [_, data, child] = out_sndr;if constexpr (scheduler<decltype(data)>) {auto orig_sch =query-with-default(get_scheduler, env, not-a-scheduler()); if constexpr (same_as<decltype(orig_sch), not-a-scheduler>) {return not-a-sender{}; } else {return continues_on( starts_on(std::forward_like(data), std::forward_like(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<decltype(orig_sch), not-a-scheduler>) {return not-a-sender{}; } else {return write_env( continues_on( std::forward_like(closure)( continues_on( write_env(std::forward_like(child), SCHED-ENV(orig_sch)), sch)), orig_sch), SCHED-ENV(sch)); }}

9

#

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

Let out_rcvr be a subexpression denoting a receiver that has an environment of type Env such that sender_in<OutSndr, Env> is true.

Let op be an lvalue referring to the operation state that results from connecting out_sndr with out_rcvr.

Calling start(op) shall

remember the current scheduler, get_scheduler(get_env(rcvr));

start sndr on an execution agent belonging tosch's associated execution resource;

upon sndr's completion, transfer execution back to the execution resource associated with the scheduler remembered in step 1; and

forward sndr's async result to out_rcvr.

If any scheduling operation fails, an error completion on out_rcvr shall be executed on an unspecified execution agent.

10

#

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

Let out_rcvr be a subexpression denoting a receiver that has an environment of type Env such that sender_in<OutSndr, Env> is true.

Let op be an lvalue referring to the operation state that results from connecting out_sndr with out_rcvr.

Calling start(op) shall

remember the current scheduler, which is the first of the following expressions that is well-formed:

get_completion_scheduler<set_value_t>(get_env(sndr))

get_scheduler(get_env(rcvr));

start sndr on the current execution agent;

upon sndr's completion, transfer execution to an agent owned by sch's associated execution resource;

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

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.

If any scheduling operation fails, an error completion on out_rcvr shall be executed on an unspecified execution agent.