|
91 | 91 | \item
|
92 | 92 | \tcode{err} if \tcode{decay_t<Err>} denotes the type \tcode{exception_ptr}.
|
93 | 93 |
|
94 |
| -\mandates |
95 |
| -\tcode{err != exception_ptr()} is \tcode{true}. |
| 94 | +\expects |
| 95 | +\tcode{!err} is \tcode{false}. |
96 | 96 | \item
|
97 | 97 | Otherwise,
|
98 | 98 | \tcode{make_exception_ptr(system_error(err))}
|
|
229 | 229 | representing the execution-time properties of the operation's caller.
|
230 | 230 | The caller of an asynchronous operation is
|
231 | 231 | its parent operation or the function that created it.
|
232 |
| -An asynchronous operation's operation state owns the operation's environment. |
233 | 232 |
|
234 | 233 | \pnum
|
235 | 234 | An asynchronous operation has an associated receiver.
|
|
1012 | 1011 | -> @\libconcept{same_as}@<remove_cvref_t<Sch>>;
|
1013 | 1012 | } &&
|
1014 | 1013 | @\libconcept{equality_comparable}@<remove_cvref_t<Sch>> &&
|
1015 |
| - @\libconcept{copy_constructible}@<remove_cvref_t<Sch>>; |
| 1014 | + @\libconcept{copyable}@<remove_cvref_t<Sch>>; |
1016 | 1015 | }
|
1017 | 1016 | \end{codeblock}
|
1018 | 1017 |
|
|
1025 | 1024 | shall be modeled.
|
1026 | 1025 |
|
1027 | 1026 | \pnum
|
1028 |
| -None of a scheduler's |
1029 |
| -copy constructor, |
1030 |
| -destructor, |
1031 |
| -equality comparison, or |
1032 |
| -\tcode{swap} member functions |
| 1027 | +No operation required by |
| 1028 | +\tcode{\libconcept{copyable}<remove_cvref_t<Sch>>} and |
| 1029 | +\tcode{\libconcept{equality_comparable}<remove_cvref_t<Sch>>} |
1033 | 1030 | shall exit via an exception.
|
1034 |
| -None of these member functions, |
| 1031 | +None of these operations, |
1035 | 1032 | nor a scheduler type's \tcode{schedule} function,
|
1036 | 1033 | shall introduce data races
|
1037 | 1034 | as a result of potentially concurrent\iref{intro.races} invocations
|
1038 |
| -of those functions from different threads. |
| 1035 | +of those operations from different threads. |
1039 | 1036 |
|
1040 | 1037 | \pnum
|
1041 | 1038 | For any two values \tcode{sch1} and \tcode{sch2}
|
|
1727 | 1724 |
|
1728 | 1725 | \pnum
|
1729 | 1726 | The expression in the \tcode{noexcept} clause of
|
1730 |
| -the constructor of \exposid{basic-state} is: |
| 1727 | +the constructor of \exposid{basic-state} is |
1731 | 1728 | \begin{codeblock}
|
1732 | 1729 | is_nothrow_move_constructible_v<Rcvr> &&
|
1733 |
| -@\exposconcept{nothrow-callable}@<decltype(@\exposid{impls-for}@<tag_of_t<Sndr>>::@\exposid{get-state}@), Sndr, Rcvr&> |
| 1730 | +@\exposconcept{nothrow-callable}@<decltype(@\exposid{impls-for}@<tag_of_t<Sndr>>::@\exposid{get-state}@), Sndr, Rcvr&> && |
| 1731 | +(same_as<@\exposid{state-type}@<Sndr, Rcvr>, @\exposid{get-state-result}@> || |
| 1732 | + is_nothrow_constructible_v<@\exposid{state-type}@<Sndr, Rcvr>, @\exposid{get-state-result}@>) |
| 1733 | +\end{codeblock} |
| 1734 | +where \exposid{get-state-result} is |
| 1735 | +\begin{codeblock} |
| 1736 | +@\exposid{call-result-t}@<decltype(@\exposid{impls-for}@<tag_of_t<Sndr>>::@\exposid{get-state}@), Sndr, Rcvr&>. |
1734 | 1737 | \end{codeblock}
|
1735 | 1738 |
|
1736 | 1739 | \pnum
|
|
1879 | 1882 | struct @\exposid{impls-for}@<@\exposid{write-env-t}@> : @\exposid{default-impls}@ {
|
1880 | 1883 | static constexpr auto @\exposid{get-env}@ =
|
1881 | 1884 | [](auto, const auto& state, const auto& rcvr) noexcept {
|
1882 |
| - return @\exposid{JOIN-ENV}@(state, get_env(rcvr)); |
| 1885 | + return @\seebelow@; |
1883 | 1886 | };
|
1884 | 1887 | };
|
1885 | 1888 | \end{codeblock}
|
1886 | 1889 | \end{itemdescr}
|
| 1890 | +Invocation of |
| 1891 | +\tcode{\exposid{impls-for}<\exposid{write-env-t}>::\exposid{get-env}} |
| 1892 | +returns an object \tcode{e} such that |
| 1893 | +\begin{itemize} |
| 1894 | +\item |
| 1895 | +\tcode{decltype(e)} models \exposconcept{queryable} and |
| 1896 | +\item |
| 1897 | +given a query object \tcode{q}, |
| 1898 | +the expression \tcode{e.query(q)} is expression-equivalent |
| 1899 | +to \tcode{state.query(q)} if that expression is valid, |
| 1900 | +otherwise, \tcode{e.query(q)} is expression-equivalent |
| 1901 | +to \tcode{get_env(rcvr).query(q)}. |
| 1902 | +\end{itemize} |
1887 | 1903 |
|
1888 | 1904 | \rSec2[exec.snd.concepts]{Sender concepts}
|
1889 | 1905 |
|
|
2455 | 2471 | Let \exposid{operation-state-task} be the following exposition-only class:
|
2456 | 2472 | \begin{codeblock}
|
2457 | 2473 | namespace std::execution {
|
2458 |
| - struct @\exposid{operation-state-task}@ { |
| 2474 | + struct @\exposid{operation-state-task}@ { // \expos |
2459 | 2475 | using operation_state_concept = operation_state_t;
|
2460 | 2476 | using promise_type = @\exposid{connect-awaitable-promise}@;
|
2461 | 2477 |
|
2462 | 2478 | explicit @\exposid{operation-state-task}@(coroutine_handle<> h) noexcept : coro(h) {}
|
2463 |
| - @\exposid{operation-state-task}@(@\exposid{operation-state-task}@&& o) noexcept |
2464 |
| - : @\exposid{coro}@(exchange(o.@\exposid{coro}@, {})) {} |
2465 |
| - ~@\exposid{operation-state-task}@() { if (@\exposid{coro}@) @\exposid{coro}@.destroy(); } |
| 2479 | + @\exposid{operation-state-task}@(@\exposid{operation-state-task}@&&) = delete; |
| 2480 | + ~@\exposid{operation-state-task}@() { @\exposid{coro}@.destroy(); } |
2466 | 2481 |
|
2467 | 2482 | void start() & noexcept {
|
2468 | 2483 | @\exposid{coro}@.resume();
|
|
3053 | 3068 | using result_t = @\exposid{decayed-tuple}@<Tag, Args...>;
|
3054 | 3069 | constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>;
|
3055 | 3070 |
|
3056 |
| - @\exposid{TRY-EVAL}@(rcvr, [&]() noexcept(nothrow) { |
| 3071 | + try { |
3057 | 3072 | state.@\exposid{async-result}@.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
|
3058 |
| - }()); |
3059 |
| - |
3060 |
| - if (state.@\exposid{async-result}@.valueless_by_exception()) |
3061 |
| - return; |
3062 |
| - if (state.@\exposid{async-result}@.index() == 0) |
3063 |
| - return; |
3064 |
| - |
| 3073 | + } catch (...) { |
| 3074 | + if constexpr (!nothrow) { |
| 3075 | + set_error(std::move(rcvr), current_exception()); |
| 3076 | + return; |
| 3077 | + } |
| 3078 | + } |
3065 | 3079 | start(state.@\exposid{op-state}@);
|
3066 | 3080 | };
|
3067 | 3081 | \end{codeblock}
|
|
3448 | 3462 | }
|
3449 | 3463 |
|
3450 | 3464 | decltype(auto) get_env() const noexcept {
|
3451 |
| - return @\exposid{JOIN-ENV}@(@\exposid{env}@, @\exposid{FWD-ENV}@(execution::get_env(@\exposid{rcvr}@))); |
| 3465 | + return @\seebelow@; |
3452 | 3466 | }
|
3453 | 3467 |
|
3454 | 3468 | Rcvr& @\exposid{rcvr}@; // \expos
|
3455 | 3469 | Env @\exposid{env}@; // \expos
|
3456 | 3470 | };
|
3457 | 3471 | }
|
3458 | 3472 | \end{codeblock}
|
| 3473 | +Invocation of the function \tcode{\exposid{receiver2}::get_env} |
| 3474 | +returns an object \tcode{e} such that |
| 3475 | +\begin{itemize} |
| 3476 | +\item |
| 3477 | +\tcode{decltype(e)} models \exposconcept{queryable} and |
| 3478 | +\item |
| 3479 | +given a query object \tcode{q}, |
| 3480 | +the expression \tcode{e.query(q)} is expression-equivalent |
| 3481 | +to \tcode{\exposid{env}.query(q)} if that expression is valid, |
| 3482 | +otherwise \tcode{e.query(q)} is expression-equivalent |
| 3483 | +to \tcode{get_env(\exposid{rcvr}).query(q)}. |
| 3484 | +\end{itemize} |
3459 | 3485 |
|
3460 | 3486 | \pnum
|
3461 | 3487 | \tcode{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{let-cpo}>>::\exposid{get-state}}
|
|
3647 | 3673 | \item
|
3648 | 3674 | on a value completion operation,
|
3649 | 3675 | invokes \tcode{f(i, args...)}
|
3650 |
| -for every \tcode{i} of type \tcode{Shape} from \tcode{0} to \tcode{shape}, |
| 3676 | +for every \tcode{i} of type \tcode{Shape} in \range{\tcode{0}}{\tcode{shape}}, |
3651 | 3677 | where \tcode{args} is a pack of lvalue subexpressions
|
3652 | 3678 | referring to the value completion result datums of the input sender, and
|
3653 | 3679 | \item
|
|
4101 | 4127 | equivalent to the following lambda expression:
|
4102 | 4128 | \begin{codeblock}
|
4103 | 4129 | []<class State, class Rcvr>(auto&&, State& state, const Receiver& rcvr) noexcept {
|
4104 |
| - return @\exposid{JOIN-ENV}@( |
4105 |
| - @\exposid{MAKE-ENV}@(get_stop_token, state.@\exposid{stop_src}@.get_token()), get_env(rcvr)); |
| 4130 | + return @\seebelow@; |
4106 | 4131 | }
|
4107 | 4132 | \end{codeblock}
|
| 4133 | +Returns an object \tcode{e} such that |
| 4134 | +\begin{itemize} |
| 4135 | +\item |
| 4136 | +\tcode{decltype(e)} models \exposconcept{queryable}, and |
| 4137 | +\item |
| 4138 | +\tcode{e.query(get_stop_token)} is expression-equivalent to |
| 4139 | +\tcode{state.\exposid{stop-src}.get_token()}, and |
| 4140 | +\item |
| 4141 | +given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t}, |
| 4142 | +\tcode{e.query(q)} is expression-equivalent to \tcode{get_env(rcvr).query(q)}. |
| 4143 | +\end{itemize} |
4108 | 4144 |
|
4109 | 4145 | \pnum
|
4110 | 4146 | The member \tcode{\exposid{impls-for}<when_all_t>::\exposid{get-state}}
|
|
4957 | 4993 | A \tcode{run_loop} instance has an associated \defn{count}
|
4958 | 4994 | that corresponds to the number of work items that are in its queue.
|
4959 | 4995 | Additionally, a \tcode{run_loop} instance has an associated state
|
4960 |
| -that can be one of \defn{starting}, \defn{running}, or \defn{finishing}. |
| 4996 | +that can be one of |
| 4997 | +\defn{starting}, \defn{running}, \defn{finishing}, or \defn{finished}. |
4961 | 4998 |
|
4962 | 4999 | \pnum
|
4963 | 5000 | Concurrent invocations of the member functions of \tcode{run_loop}
|
|
5146 | 5183 | \begin{itemize}
|
5147 | 5184 | \item
|
5148 | 5185 | \exposid{count} is \tcode{0} and \exposid{state} is \exposid{finishing},
|
5149 |
| -in which case \exposid{pop-front} returns \tcode{nullptr}; or |
| 5186 | +in which case \exposid{pop-front} sets \exposid{state} to \exposid{finished} |
| 5187 | +and returns \tcode{nullptr}; or |
5150 | 5188 | \item
|
5151 | 5189 | \exposid{count} is greater than \tcode{0},
|
5152 | 5190 | in which case an item is removed from the front of the queue,
|
|
5191 | 5229 | \begin{itemdescr}
|
5192 | 5230 | \pnum
|
5193 | 5231 | \expects
|
5194 |
| -\exposid{state} is \exposid{starting}. |
| 5232 | +\exposid{state} is either \exposid{starting} or \exposid{finishing}. |
5195 | 5233 |
|
5196 | 5234 | \pnum
|
5197 | 5235 | \effects
|
5198 |
| -Sets the \exposid{state} to \exposid{running}. Then, equivalent to: |
| 5236 | +If \exposid{state} is \exposid{starting}, |
| 5237 | +sets the \exposid{state} to \exposid{running}, |
| 5238 | +otherwise leaves \exposid{state} unchanged. |
| 5239 | +Then, equivalent to: |
5199 | 5240 | \begin{codeblock}
|
5200 | 5241 | while (auto* op = @\exposid{pop-front}@()) {
|
5201 | 5242 | op->@\exposid{execute}@();
|
|
5213 | 5254 | \end{itemdecl}
|
5214 | 5255 |
|
5215 | 5256 | \begin{itemdescr}
|
| 5257 | +\pnum |
| 5258 | +\expects |
| 5259 | +\exposid{state} is either \exposid{starting} or \exposid{running}. |
| 5260 | + |
5216 | 5261 | \pnum
|
5217 | 5262 | \effects
|
5218 | 5263 | Changes \exposid{state} to \exposid{finishing}.
|
|
0 commit comments