Skip to content

Commit b05c952

Browse files
committed
fixup: add up to 34.9.10.4
1 parent f83d270 commit b05c952

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

source/exec.tex

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,6 +2609,231 @@
26092609
the implementation is allowed to omit
26102610
the \tcode{exception_ptr} error completion signature from the set.
26112611

2612+
\rSec3[exec.adapt.obj]{Closure objects}
2613+
2614+
\pnum
2615+
A \defnadj{pipeable}{sender adaptor closure object} is a function object
2616+
that accepts one or more \tcode{sender} arguments and returns a \tcode{sender}.
2617+
For a pipeable sender adaptor closure object \tcode{c} and
2618+
an expression \tcode{sndr}
2619+
such that \tcode{decltype((sndr))} models \tcode{sender},
2620+
the following expressions are equivalent and yield a \tcode{sender}:
2621+
\begin{codeblock}
2622+
c(sndr)
2623+
sndr | c
2624+
\end{codeblock}
2625+
Given an additional pipeable sender adaptor closure object \tcode{d},
2626+
the expression \tcode{c | d} produces
2627+
another pipeable sender adaptor closure object \tcode{e}:
2628+
2629+
\tcode{e} is a perfect forwarding call wrapper\iref{func.require}
2630+
with the following properties:
2631+
\begin{itemize}
2632+
\item
2633+
Its target object is an object \tcode{d2} of type \tcode{decltype(auto(d))}
2634+
direct-non-list-initialized with \tcode{d}.
2635+
\item
2636+
It has one bound argument entity,
2637+
an object \tcode{c2} of type \tcode{decltype(auto(c))}
2638+
direct-non-list-initialized with \tcode{c}.
2639+
\item
2640+
Its call pattern is \tcode{d2(c2(arg))},
2641+
where arg is the argument used in a function call expression of \tcode{e}.
2642+
\end{itemize}
2643+
The expression \tcode{c | d} is well-formed if and only if
2644+
the initializations of the state entities\iref{func.def} of \tcode{e}
2645+
are all well-formed.
2646+
2647+
\pnum
2648+
An object \tcode{t} of type \tcode{T} is
2649+
a pipeable sender adaptor closure object
2650+
if \tcode{T} models \tcode{\libconcept{derived_from}<sender_adaptor_closure<T>>},
2651+
\tcode{T} has no other base classes
2652+
of type \tcode{sender_adaptor_closure<U>} for any other type \tcode{U}, and
2653+
\tcode{T} does not satisfy \tcode{sender}.
2654+
2655+
\pnum
2656+
The template parameter \tcode{D} for sender_adaptor_closure can be
2657+
an incomplete type.
2658+
Before any expression of type \cv{} \tcode{D} appears as
2659+
an operand to the \tcode{|} operator,
2660+
\tcode{D} shall be complete and
2661+
model \tcode{\libconcept{derived_from}<sender_adaptor_closure<D>>}.
2662+
The behavior of an expression involving an object of type \cv{} \tcode{D}
2663+
as an operand to the \tcode{|} operator is undefined
2664+
if overload resolution selects a program-defined \tcode{operator|} function.
2665+
2666+
\pnum
2667+
A \defnadj{pipeable}{sender adaptor object} is a customization point object
2668+
that accepts a \tcode{sender} as its first argument and
2669+
returns a \tcode{sender}.
2670+
If a pipeable sender adaptor object accepts only one argument,
2671+
then it is a pipeable sender adaptor closure object.
2672+
2673+
\pnum
2674+
If a pipeable sender adaptor object adaptor accepts more than one argument,
2675+
then let \tcode{sndr} be an expression
2676+
such that \tcode{decltype((sndr))} models \libconcept{sender},
2677+
let \tcode{args...} be arguments
2678+
such that \tcode{adaptor(sndr, args...)} is a well-formed expression
2679+
as specified below, and
2680+
let \tcode{BoundArgs} be a pack that denotes \tcode{decltype(auto(args))...}.
2681+
The expression \tcode{adaptor(args...)} produces
2682+
a pipeable sender adaptor closure object \tcode{f}
2683+
that is a perfect forwarding call wrapper with the following properties:
2684+
\begin{itemize}
2685+
\item
2686+
Its target object is a copy of adaptor.
2687+
\item
2688+
Its bound argument entities \tcode{bound_args} consist of
2689+
objects of types \tcode{BoundArgs...} direct-non-list-initialized with
2690+
\tcode{std::forward<decltype((args))>(args)...}, respectively.
2691+
\item
2692+
Its call pattern is \tcode{adaptor(rcvr, bound_args...)},
2693+
where \tcode{rcvr} is
2694+
the argument used in a function call expression of \tcode{f}.
2695+
\end{itemize}
2696+
The expression \tcode{adaptor(args...)} is well-formed if and only if
2697+
the initializations of the bound argument entities of the result,
2698+
as specified above, are all well-formed.
2699+
2700+
\rSec3[exec.starts.on]{\tcode{execution::starts_on}}
2701+
2702+
\pnum
2703+
\tcode{starts_on} adapts an input sender into a sender
2704+
that will start on an execution agent belonging to
2705+
a particular scheduler's associated execution resource.
2706+
2707+
\pnum
2708+
The name \tcode{starts_on} denotes a customization point object.
2709+
For subexpressions \tcode{sch} and \tcode{sndr},
2710+
if \tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or
2711+
\tcode{decltype((sndr))} does not satisfy \libconcept{sender},
2712+
\tcode{starts_on(sch, sndr)} is ill-formed.
2713+
2714+
\pnum
2715+
Otherwise,
2716+
the expression \tcode{starts_on(sch, sndr)} is expression-equivalent to:
2717+
\begin{codeblock}
2718+
transform_sender(
2719+
@\exposid{query-or-default}@(get_domain, sch, default_domain()),
2720+
@\exposid{make-sender}@(starts_on, sch, sndr))
2721+
\end{codeblock}
2722+
except that \tcode{sch} is evaluated only once.
2723+
2724+
\pnum
2725+
Let \tcode{out_sndr} and \tcode{env} be subexpressions
2726+
such that \tcode{OutSndr} is \tcode{decltype((out_sndr))}.
2727+
If \tcode{\exposconcept{sender-for}<OutSndr, starts_on_t>} is \tcode{false},
2728+
then the expressions \tcode{starts_on.transform_env(out_sndr, env)} and
2729+
\tcode{starts_on.transform_sender(out_sndr, env)} are ill-formed; otherwise
2730+
\begin{itemize}
2731+
\item
2732+
\tcode{starts_on.transform_env(out_sndr, env)} is equivalent to:
2733+
\begin{codeblock}
2734+
auto&& [_, sch, _] = out_sndr;
2735+
return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ENV}@(sch), @\exposid{FWD-ENV}@(env));
2736+
\end{codeblock}
2737+
\item
2738+
\tcode{starts_on.transform_sender(out_sndr, env)} is equivalent to:
2739+
\begin{codeblock}
2740+
auto&& [_, sch, sndr] = out_sndr;
2741+
return let_value(
2742+
schedule(sch),
2743+
[sndr = std::forward_like<OutSndr>(sndr)]() mutable
2744+
noexcept(is_nothrow_move_constructible_v) {
2745+
return std::move(sndr);
2746+
});
2747+
\end{codeblock}
2748+
\end{itemize}
2749+
2750+
\pnum
2751+
Let \tcode{out_sndr} be a subexpression denoting
2752+
a sender returned from \tcode{starts_on(sch, sndr)} or one equal to such, and
2753+
let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}.
2754+
Let \tcode{out_rcvr} be a subexpression denoting a receiver
2755+
that has an environment of type \tcode{Env}
2756+
such that \tcode{\libconcept{sender_in}<OutSndr, Env>} is \tcode{true}.
2757+
Let \tcode{op} be an lvalue referring to the operation state
2758+
that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}.
2759+
Calling \tcode{start(op)} shall start \tcode{sndr}
2760+
on an execution agent of the associated execution resource of \tcode{sch}.
2761+
If scheduling onto \tcode{sch} fails,
2762+
an error completion on \tcode{out_rcvr} shall be executed
2763+
on an unspecified execution agent.
2764+
2765+
\rSec3[exec.continues.on]{\tcode{execution::continues_on}}
2766+
2767+
\pnum
2768+
\tcode{continues_on} adapts a sender into one
2769+
that completes on the specified scheduler.
2770+
2771+
\pnum
2772+
The name \tcode{continues_on} denotes a pipeable sender adaptor object.
2773+
For subexpressions \tcode{sch} and \tcode{sndr},
2774+
if \tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or
2775+
\tcode{decltype((sndr))} does not satisfy \libconcept{sender},
2776+
\tcode{continues_on(sndr, sch)} is ill-formed.
2777+
2778+
\pnum
2779+
Otherwise,
2780+
the expression \tcode{continues_on(sndr, sch)} is expression-equivalent to:
2781+
\begin{codeblock}
2782+
transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(continues_on, sch, sndr))
2783+
\end{codeblock}
2784+
except that \tcode{sndr} is evaluated only once.
2785+
2786+
\pnum
2787+
The exposition-only class template \exposid{impls-for}
2788+
is specialized for \tcode{continues_on_t} as follows:
2789+
\begin{codeblock}
2790+
namespace std::execution {
2791+
template<>
2792+
struct @\exposid{impls-for}@<continues_on_t> : @\exposid{default-impls}@ {
2793+
static constexpr auto get_attrs =
2794+
[](const auto& data, const auto& child) noexcept -> decltype(auto) {
2795+
return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ATTRS}@(data), @\exposid{FWD-ENV}@(get_env(child)));
2796+
};
2797+
};
2798+
}
2799+
\end{codeblock}
2800+
2801+
\pnum
2802+
Let \tcode{sndr} and \tcode{env} be subexpressions
2803+
such that \tcode{Sndr} is \tcode{decltype((sndr))}.
2804+
If \tcode{\exposconcept{sender-for}<Sndr, continues_on_t>} is \tcode{false},
2805+
then
2806+
the expression \tcode{continues_on.transform_sender(sndr, env)} is ill-formed;
2807+
otherwise, it is equal to:
2808+
\begin{codeblock}
2809+
auto [_, data, child] = sndr;
2810+
return schedule_from(std::move(data), std::move(child));
2811+
\end{codeblock}
2812+
\begin{note}
2813+
This causes the \tcode{continues_on(sndr, sch)} sender to become
2814+
\tcode{schedule_from(sch, sndr)} when it is connected with a receiver
2815+
whose execution domain does not customize \tcode{continues_on}.
2816+
\end{note}
2817+
2818+
\pnum
2819+
Let \tcode{out_sndr} be a subexpression denoting
2820+
a sender returned from \tcode{continues_on(sndr, sch)} or one equal to such, and
2821+
let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}.
2822+
Let \tcode{out_rcvr} be a subexpression denoting a receiver
2823+
that has an environment of type \tcode{Env}
2824+
such that \tcode{\libconcept{sender_in}<OutSndr, Env>} is \tcode{true}.
2825+
Let \tcode{op} be an lvalue referring to the operation state
2826+
that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}.
2827+
Calling \tcode{start(op)} shall
2828+
start \tcode{sndr} on the current execution agent and
2829+
execute completion operations on \tcode{out_rcvr}
2830+
on an execution agent of the execution resource associated with \tcode{sch}.
2831+
If scheduling onto \tcode{sch} fails,
2832+
an error completion on \tcode{out_rcvr} shall be executed
2833+
on an unspecified execution agent.
2834+
2835+
\rSec3[exec.schedule.from]{\tcode{execution::schedule_from}}
2836+
26122837
\rSec1[exec.util]{Sender/receiver utilities}
26132838

26142839

0 commit comments

Comments
 (0)