33 Execution control library [exec]

33.13 Coroutine utilities [exec.coro.util]

33.13.3 execution​::​affine [exec.affine]

affine adapts a sender into one that completes on the receiver's scheduler.
If the algorithm determines that the adapted sender already completes on the correct scheduler it can avoid any scheduling operation.
The name affine denotes a pipeable sender adaptor object.
For a subexpression sndr, if decltype((​sndr)) does not satisfy sender, affine(sndr) is ill-formed.
Otherwise, the expression affine(sndr) is expression-equivalent to make-sender(affine, env<>(), sndr).
For a subexpression sch whose type models scheduler, let UNSTOPPABLE-SCHEDULER(sch) be an expression e whose type models scheduler such that:
  • schedule(e) is expression-equivalent to unstoppable(schedule(sch)).
  • For any query object q and pack of subexpressions args..., e.query(q, args...) is expression-equivalent to sch.query(q, args...).
  • The expression e == UNSTOPPABLE-SCHEDULER(other) is expression-equivalent to sch == other.
Let sndr and ev be subexpressions such that Sndr is decltype((sndr)).
If sender-for<Sndr, affine_t> is false, then the expression affine.transform_sender(sndr, ev) is ill-formed; otherwise, it is equal to: auto& [_, _, child] = sndr; if constexpr (requires { std::forward_like<Sndr>(child).affine(); }) { return std::forward_like<Sndr>(child).affine(); } else { return continues_on(std::forward_like<Sndr>(child), UNSTOPPABLE-SCHEDULER(get_start_scheduler(ev))); }
Recommended practice: Implementations should provide affine member functions for senders that are known to resume on the scheduler where they were started.
Example senders for which that is the case are just, just_error, just_stopped, read_env, and write_env.
Let out_sndr be a subexpression denoting a sender returned from affine(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.
If get_start_scheduler(get_env(out_rcvr)) is ill-formed or does not satisfy infallible-scheduler<Env>, then evaluation of the expression get_completion_signatures<OutSndr, Env>() exits with an exception.
Let op be an lvalue referring to the operation state that results from connecting out_sndr to out_rcvr.
Calling start(op) will start sndr on the current execution agent and execute completion operations on out_rcvr on an execution agent of the execution resource associated with sch.
If the current execution resource is the same as the execution resource associated with sch, the completion operation on out_rcvr may be called before start(op) completes.