Skip to content

Commit b932bb8

Browse files
committed
fixup: add up to 34.9.11.5
1 parent b05c952 commit b932bb8

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed

source/exec.tex

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,6 +2834,178 @@
28342834

28352835
\rSec3[exec.schedule.from]{\tcode{execution::schedule_from}}
28362836

2837+
\pnum
2838+
\tcode{schedule_from} schedules work dependent on the completion of a sender
2839+
onto a scheduler's associated execution resource.
2840+
\begin{note}
2841+
\tcode{schedule_from} is not meant to be used in user code;
2842+
it is used in the implementation of \tcode{continues_on}.
2843+
\end{note}
2844+
2845+
\pnum
2846+
The name \tcode{schedule_from} denotes a customization point object.
2847+
For some subexpressions \tcode{sch} and \tcode{sndr},
2848+
let \tcode{Sch} be \tcode{decltype((sch))} and
2849+
\tcode{Sndr} be \tcode{decltype((sndr))}.
2850+
If \tcode{Sch} does not satisfy \libconcept{scheduler}, or
2851+
\tcode{Sndr} does not satisfy \libconcept{sender},
2852+
\tcode{schedule_from(sch, sndr)} is ill-formed.
2853+
2854+
\pnum
2855+
Otherwise,
2856+
the expression \tcode{schedule_from(sch, sndr)} is expression-equivalent to:
2857+
\begin{codeblock}
2858+
transform_sender(
2859+
@\exposid{query-or-default}@(get_domain, sch, default_domain()),
2860+
@\exposid{make-sender}@(schedule_from, sch, sndr))
2861+
\end{codeblock}
2862+
except that \tcode{sch} is evaluated only once.
2863+
2864+
\pnum
2865+
The exposition-only class template \exposid{impls-for}\iref{exec.snd.general}
2866+
is specialized for \tcode{schedule_from_t} as follows:
2867+
\begin{codeblock}
2868+
namespace std::execution {
2869+
template<>
2870+
struct @\exposid{impls-for}@<schedule_from_t> : @\exposid{default-impls}@ {
2871+
static constexpr auto @\exposid{get-attrs}@ = @\seebelow@;
2872+
static constexpr auto @\exposid{get-state}@ = @\seebelow@;
2873+
static constexpr auto @\exposid{complete}@ = @\seebelow@;
2874+
};
2875+
}
2876+
\end{codeblock}
2877+
2878+
\pnum
2879+
The member \tcode{\exposid{impls-for}<schedule_from_t>::\exposid{get-attrs}}
2880+
is initialized with a callable object equivalent to the following lambda:
2881+
\begin{codeblock}
2882+
[](const auto& data, const auto& child) noexcept -> decltype(auto) {
2883+
return @\exposid{JOIN-ENV}@(@\exposid{SCHED-ATTRS}@(data), @\exposid{FWD-ENV}@(get_env(child)));
2884+
}
2885+
\end{codeblock}
2886+
2887+
\pnum
2888+
The member \tcode{\exposid{impls-for}<schedule_from_t>::\exposid{get-state}}
2889+
is initialized with a callable object equivalent to the following lambda:
2890+
\begin{codeblock}
2891+
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept(see below)
2892+
requires @\libconcept{sender_in}@<@\exposid{child-type}@<Sndr>, env_of_t<Rcvr>> {
2893+
2894+
auto& [_, sch, child] = sndr;
2895+
2896+
using sched_t = decltype(auto(sch));
2897+
using variant_t = @\seebelow@;
2898+
using receiver_t = @\seebelow@;
2899+
using operation_t = connect_result_t<schedule_result_t<sched_t>, receiver_t>;
2900+
constexpr bool nothrow = noexcept(connect(schedule(sch), receiver_t{nullptr}));
2901+
2902+
struct @\exposid{state-type}@ {
2903+
Rcvr& @\exposid{rcvr}@; // \expos
2904+
variant_t @\exposid{async-result}@; // \expos
2905+
operation_t @\exposid{op-state}@; // \expos
2906+
2907+
explicit @\exposid{state-type}@(sched_t sch, Rcvr& rcvr) noexcept(nothrow)
2908+
: @\exposid{rcvr}@(rcvr), @\exposid{op-state}@(connect(schedule(sch), receiver_t{this})) {}
2909+
};
2910+
2911+
return @\exposid{state-type}@{sch, rcvr};
2912+
}
2913+
\end{codeblock}
2914+
2915+
\pnum
2916+
Objects of the local class \exposid{state-type} can be used
2917+
to initialize a structured binding.
2918+
2919+
\pnum
2920+
Let \tcode{Sigs} be
2921+
a pack of the arguments to the \tcode{completion_signatures} specialization
2922+
named by \tcode{completion_signatures_of_t<child-type<Sndr>, env_of_t<Rcvr>>}.
2923+
Let \exposid{as-tuple} be an alias template
2924+
that transforms a completion signature \tcode{Tag(Args...)} into
2925+
the tuple specialization \tcode{decayed-tuple<Tag, Args...>}.
2926+
Then \tcode{variant_t} denotes
2927+
the type \tcode{variant<monostate, \exposid{as-tuple}<Sigs>...>},
2928+
except with duplicate types removed.
2929+
2930+
\pnum
2931+
\tcode{receiver_t} is an alias for the following exposition-only class:
2932+
\begin{codeblock}
2933+
namespace std::execution {
2934+
struct @\exposid{receiver-type}@ {
2935+
using receiver_concept = receiver_t;
2936+
@\exposid{state-type}@* @\exposid{state}@; // exposition only
2937+
2938+
void set_value() && noexcept {
2939+
visit(
2940+
[this]<class Tuple>(Tuple& result) noexcept -> void {
2941+
if constexpr (!@\libconcept{same_as}@<monostate, Tuple>) {
2942+
auto& [tag, ...args] = result;
2943+
tag(std::move(@\exposid{state}@->@\exposid{rcvr}@), std::move(args)...);
2944+
}
2945+
},
2946+
@\exposid{state}@->@\exposid{async-result}@);
2947+
}
2948+
2949+
template<class Error>
2950+
void set_error(Error&& err) && noexcept {
2951+
execution::set_error(std::move(@\exposid{state}@->@\exposid{rcvr}@), std::forward<Error>(err));
2952+
}
2953+
2954+
void set_stopped() && noexcept {
2955+
execution::set_stopped(std::move(@\exposid{state}@->@\exposid{rcvr}@));
2956+
}
2957+
2958+
decltype(auto) get_env() const noexcept {
2959+
return @\exposid{FWD-ENV}@(execution::get_env(@\exposid{state}@->@\exposid{rcvr}@));
2960+
}
2961+
};
2962+
}
2963+
\end{codeblock}
2964+
2965+
\pnum
2966+
The expression in the \tcode{noexcept} clause of the lambda is \tcode{true}
2967+
if the construction of the returned \exposid{state-type} object
2968+
is not potentially throwing;
2969+
otherwise, \tcode{false}.
2970+
2971+
\pnum
2972+
The member \tcode{\exposid{impls-for}<schedule_from_t>::\exposid{complete}}
2973+
is initialized with a callable object equivalent to the following lambda:
2974+
\begin{codeblock}
2975+
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept -> void {
2976+
using result_t = @\exposid{decayed-tuple}@<Tag, Args...>;
2977+
constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>;
2978+
2979+
@\exposid{TRY-EVAL}@(rcvr, [&]() noexcept(nothrow) {
2980+
state.@\exposid{async-result}@.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
2981+
}());
2982+
2983+
if (state.@\exposid{async-result}@.valueless_by_exception())
2984+
return;
2985+
if (state.@\exposid{async-result}@.index() == 0)
2986+
return;
2987+
2988+
start(state.@\exposid{op-state}@);
2989+
};
2990+
\end{codeblock}
2991+
2992+
\pnum
2993+
Let \tcode{out_sndr} be a subexpression denoting
2994+
a sender returned from \tcode{schedule_from(sch, sndr)} or one equal to such,
2995+
and let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}.
2996+
Let \tcode{out_rcvr} be a subexpression denoting a receiver
2997+
that has an environment of type \tcode{Env}
2998+
such that \tcode{\libconcept{sender_in}<OutSndr, Env>} is \tcode{true}.
2999+
Let \tcode{op} be an lvalue referring to the operation state
3000+
that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}.
3001+
Calling \tcode{start(op)} shall
3002+
start \tcode{sndr} on the current execution agent and
3003+
execute completion operations on \tcode{out_rcvr}
3004+
on an execution agent of the execution resource associated with \tcode{sch}.
3005+
If scheduling onto \tcode{sch} fails,
3006+
an error completion on \tcode{out_rcvr} shall be executed
3007+
on an unspecified execution agent.
3008+
28373009
\rSec1[exec.util]{Sender/receiver utilities}
28383010

28393011

0 commit comments

Comments
 (0)