q
, and a (possibly empty) pack of subexpressions
- `args`, the expression q(e, args...)
is equal to
+ `args`, the expression q(env, args...)
is equal to
([concepts.equality]) the expression q(c, args...)
where
`c` is a `const` lvalue reference to `o`.
3. The type of a query expression can not be `void`.
-4. The expression q(e, args...)
is equality-preserving
+4. The expression q(env, args...)
is equality-preserving
([concepts.equality]) and does not modify the function object or the
arguments.
-5. If tag_invoke(q, e, args...)
is well-formed, then
- q(e, args...)
is expression-equivalent to
- tag_invoke(q, e, args...)
.
+5. If tag_invoke(q, env, args...)
is well-formed, then
+ q(env, args...)
is expression-equivalent to
+ tag_invoke(q, env, args...)
.
6. Unless otherwise specified, the value returned by the expression
- q(e, args...)
is valid as long as `e` is valid.
+ q(env, args...)
is valid as long as `env` is valid.
### `queryable` concept [exec.queryable.concept] ### {#spec-execution.queryable.concept}
@@ -3876,10 +3876,10 @@ template<class C>
1. The `queryable` concept specifies the constraints on the types of queryable
objects.
-2. Let `e` be an object of type `E`. The type `E` models `queryable` if for each
+2. Let `env` be an object of type `Env`. The type `Env` models `queryable` if for each
callable object q
and a pack of subexpressions `args`,
- if requires { q(e, args...) }
is `true` then
- q(e, args...)
meets any semantic requirements imposed by
+ if requires { q(env, args...) }
is `true` then
+ q(env, args...)
meets any semantic requirements imposed by
q
.
## Asynchronous operations [async.ops] ## {#spec-execution-async.ops}
@@ -4036,11 +4036,11 @@ template<class C>
let `c` be the completion operation set(rcvr,
args...)
, and let `F` be the function type
decltype(auto(set))(decltype((args))...)
.
- A completion signature `S` is associated with `c` if and only if
- MATCHING-SIG(S, F)
is `true` ([exec.general]). Together,
- a sender type and an environment type `E` determine the set of completion
+ A completion signature `Sndr` is associated with `c` if and only if
+ MATCHING-SIG(Sndr, F)
is `true` ([exec.general]). Together,
+ a sender type and an environment type `Env` determine the set of completion
signatures of an asynchronous operation that results from connecting the
- sender with a receiver that has an environment of type `E`. The type of the receiver does not affect an asychronous
operation's completion signatures, only the type of the receiver's
environment.
@@ -4140,19 +4140,19 @@ namespace std::execution {
struct default_domain;
// [exec.sched], schedulers
- template<class S>
+ template<class Sndr>
concept scheduler = see below;
// [exec.recv], receivers
struct receiver_t {};
- template<class R>
+ template<class Rcvr>
inline constexpr bool enable_receiver = see below;
- template<class R>
+ template<class Rcvr>
concept receiver = see below;
- template<class R, class Completions>
+ template<class Rcvr, class Completions>
concept receiver_of = see below;
namespace receivers { // exposition only
@@ -4180,25 +4180,25 @@ namespace std::execution {
// [exec.snd], senders
struct sender_t {};
- template<class S>
+ template<class Sndr>
inline constexpr bool enable_sender = see below;
- template<class S>
+ template<class Sndr>
concept sender = see below;
- template<class S, class E = empty_env>
+ template<class Sndr, class Env = empty_env>
concept sender_in = see below;
- template<class S, class R>
+ template<class Sndr, class Rcvr>
concept sender_to = see below;
template<class... Ts>
struct type-list; // exposition only
- template<class S, class E = empty_env>
+ template<class Sndr, class Env = empty_env>
using single-sender-value-type = see below; // exposition only
- template<class S, class E = empty_env>
+ template<class Sndr, class Env = empty_env>
concept single-sender = see below; // exposition only
// [exec.getcomplsigs], completion signatures
@@ -4208,9 +4208,9 @@ namespace std::execution {
using completion-signatures::get_completion_signatures_t;
inline constexpr get_completion_signatures_t get_completion_signatures {};
- template<class S, class E = empty_env>
- requires sender_in<S, E>
- using completion_signatures_of_t = call-result-t<get_completion_signatures_t, S, E>;
+ template<class Sndr, class Env = empty_env>
+ requires sender_in<Sndr, Env>
+ using completion_signatures_of_t = call-result-t<get_completion_signatures_t, Sndr, Env>;
template<class... Ts>
using decayed-tuple = tuple<decay_t<Ts>...>; // exposition only
@@ -4218,39 +4218,39 @@ namespace std::execution {
template<class... Ts>
using variant-or-empty = see below; // exposition only
- template<class S,
- class E = empty_env,
+ template<class Sndr,
+ class Env = empty_env,
template<class...> class Tuple = decayed-tuple,
template<class...> class Variant = variant-or-empty>
- requires sender_in<S, E>
+ requires sender_in<Sndr, Env>
using value_types_of_t = see below;
- template<class S,
+ template<class Sndr,
class Env = empty_env,
template<class...> class Variant = variant-or-empty>
- requires sender_in<S, E>
+ requires sender_in<Sndr, Env>
using error_types_of_t = see below;
- template<class S, class E = empty_env>
- requires sender_in<S, E>
+ template<class Sndr, class Env = empty_env>
+ requires sender_in<Sndr, Env>
inline constexpr bool sends_stopped = see below;
- template <sender Sender>
+ template <sender Sndr>
using tag_of_t = see below;
// [exec.snd.transform], sender transformations
- template<class Domain, sender Sender>
- constexpr sender decltype(auto) transform_sender(Domain dom, Sender&& sndrv);
+ template<class Domain, sender Sndr>
+ constexpr sender decltype(auto) transform_sender(Domain dom, Sndr&& sndrv);
- template<class Domain, sender Sender, queryable Env>
- constexpr sender decltype(auto) transform_sender(Domain dom, Sender&& sndr, const Env& env);
+ template<class Domain, sender Sndr, queryable Env>
+ constexpr sender decltype(auto) transform_sender(Domain dom, Sndr&& sndr, const Env& env);
- template<class Domain, sender Sender, queryable Env>
- constexpr decltype(auto) transform_env(Domain dom, Sender&& sndr, Env&& env) noexcept;
+ template<class Domain, sender Sndr, queryable Env>
+ constexpr decltype(auto) transform_env(Domain dom, Sndr&& sndr, Env&& env) noexcept;
// [exec.snd.apply], sender algorithm application
- template<class Domain, class Tag, sender Sender, class... Args>
- constexpr decltype(auto) apply_sender(Domain dom, Tag, Sender&& sndr, Args&&... args) noexcept(see below);
+ template<class Domain, class Tag, sender Sndr, class... Args>
+ constexpr decltype(auto) apply_sender(Domain dom, Tag, Sndr&& sndr, Args&&... args) noexcept(see below);
// [exec.connect], the connect sender algorithm
namespace senders-connect { // exposition only
@@ -4259,8 +4259,8 @@ namespace std::execution {
using senders-connect::connect_t;
inline constexpr connect_t connect{};
- template<class S, class R>
- using connect_result_t = decltype(connect(declval<S>(), declval<R>()));
+ template<class Sndr, class Rcvr>
+ using connect_result_t = decltype(connect(declval<Sndr>(), declval<Rcvr>()));
// [exec.factories], sender factories
namespace sender-factories { // exposition only
@@ -4276,8 +4276,8 @@ namespace std::execution {
inline constexpr schedule_t schedule{};
inline constexpr unspecified read{};
- template<scheduler S>
- using schedule_result_t = decltype(schedule(declval<S>()));
+ template<scheduler Sndr>
+ using schedule_result_t = decltype(schedule(declval<Sndr>()));
// [exec.adapt], sender adaptors
namespace sender-adaptor-closure { // exposition only
@@ -4417,10 +4417,10 @@ namespace std::this_thread {
namespace this-thread { // exposition only
struct sync-wait-env; // exposition only
- template<class S>
- requires sender_in<S, sync-wait-env>
+ template<class Sndr>
+ requires sender_in<Sndr, sync-wait-env>
using sync-wait-type = see below; // exposition only
- template<class S>
+ template<class Sndr>
using sync-wait-with-variant-type = see below; // exposition only
struct sync_wait_t;
@@ -4472,24 +4472,6 @@ namespace std::execution {
## Queries [exec.queries] ## {#spec-execution.queries}
-### `std::get_env` [exec.get.env] ### {#spec-execution.environment.get_env}
-
-1. `get_env` is a customization point object. For some subexpression `o` of type
- `O`, `get_env(o)` is expression-equivalent to
-
- 1. `tag_invoke(std::get_env, const_castmandate-nothrow-call(tag_invoke, std::get_allocator,
- as_const(r))
.
+2. The name `get_allocator` denotes a query object. For some subexpression `env`,
+ `get_allocator(env)` is expression-equivalent to
+ mandate-nothrow-call(tag_invoke, get_allocator,
+ as_const(env))
.
* Mandates: The type of the expression above
satisfies Allocator.
-3. `forwarding_query(std::get_allocator)` is `true`.
+3. `forwarding_query(get_allocator)` is `true`.
4. `get_allocator()` (with no arguments) is expression-equivalent to
- `execution::read(std::get_allocator)` ([exec.read]).
+ `execution::read(get_allocator)` ([exec.read]).
### `std::get_stop_token` [exec.get.stop.token] ### {#spec-execution.get_stop_token}
1. `get_stop_token` asks an object for an associated stop token.
-2. The name `get_stop_token` denotes a query object. For some subexpression `r`,
- `get_stop_token(r)` is expression-equivalent to:
+2. The name `get_stop_token` denotes a query object. For some subexpression `env`,
+ `get_stop_token(env)` is expression-equivalent to:
- 1. mandate-nothrow-call(tag_invoke, std::get_stop_token,
- as_const(r))
, if this expression is well-formed.
+ 1. mandate-nothrow-call(tag_invoke, get_stop_token,
+ as_const(env))
, if this expression is well-formed.
* Mandates: The type of the expression above satisfies
`stoppable_token`.
2. Otherwise, `never_stop_token{}`.
-3. `forwarding_query(std::get_stop_token)` is a core constant
+3. `forwarding_query(get_stop_token)` is a core constant
expression and has value `true`.
4. `get_stop_token()` (with no arguments) is expression-equivalent to
- `execution::read(std::get_stop_token)` ([exec.read]).
+ `execution::read(get_stop_token)` ([exec.read]).
+
+### `execution::get_env` [exec.get.env] ### {#spec-execution.environment.get_env}
+
+1. `get_env` is a customization point object. For some subexpression `o` of type
+ `O`, `get_env(o)` is expression-equivalent to
+
+ 1. `tag_invoke(get_env, const_castmandate-nothrow-call(tag_invoke, get_domain, as_const(r))
,
+2. The name `get_domain` denotes a query object. For some subexpression `env`,
+ `get_domain(env)` is expression-equivalent to
+ mandate-nothrow-call(tag_invoke, get_domain, as_const(env))
,
if this expression is well-formed.
3. `forwarding_query(execution::get_domain)` is a core constant
@@ -4568,8 +4568,8 @@ namespace std::execution {
1. `get_scheduler` asks an object for its associated scheduler.
2. The name `get_scheduler` denotes a query object. For some
- subexpression `r`, `get_scheduler(r)` is expression-equivalent to
- mandate-nothrow-call(tag_invoke, get_scheduler, as_const(r))
.
+ subexpression `env`, `get_scheduler(env)` is expression-equivalent to
+ mandate-nothrow-call(tag_invoke, get_scheduler, as_const(env))
.
* Mandates: The type of the expression above satisfies `scheduler`.
@@ -4583,8 +4583,8 @@ namespace std::execution {
1. `get_delegatee_scheduler` asks an object for a scheduler that can be used to delegate work to for the purpose of forward progress delegation.
2. The name `get_delegatee_scheduler` denotes a query object. For some
- subexpression `r`, `get_delegatee_scheduler(r)` is expression-equivalent to
- mandate-nothrow-call(tag_invoke, get_delegatee_scheduler, as_const(r))
.
+ subexpression `env`, `get_delegatee_scheduler(env)` is expression-equivalent to
+ mandate-nothrow-call(tag_invoke, get_delegatee_scheduler, as_const(env))
.
* Mandates: The type of the expression above is satisfies `scheduler`.
@@ -4605,33 +4605,33 @@ enum class forward_progress_guarantee {
1. `get_forward_progress_guarantee` asks a scheduler about the forward progress guarantees of execution agents created by that scheduler.
-2. The name `get_forward_progress_guarantee` denotes a query object. For some subexpression `s`, let `S` be `decltype((s))`. If `S` does not satisfy `scheduler`, `get_forward_progress_guarantee` is ill-formed.
- Otherwise, `get_forward_progress_guarantee(s)` is expression-equivalent to:
+2. The name `get_forward_progress_guarantee` denotes a query object. For some subexpression `sch`, let `Sch` be `decltype((sch))`. If `Sch` does not satisfy `scheduler`, `get_forward_progress_guarantee` is ill-formed.
+ Otherwise, `get_forward_progress_guarantee(sch)` is expression-equivalent to:
- 1. mandate-nothrow-call(tag_invoke, get_forward_progress_guarantee, as_const(s))
, if this expression is well-formed.
+ 1. mandate-nothrow-call(tag_invoke, get_forward_progress_guarantee, as_const(sch))
, if this expression is well-formed.
* Mandates: The type of the expression above is
`forward_progress_guarantee`.
2. Otherwise, `forward_progress_guarantee::weakly_parallel`.
-3. If `get_forward_progress_guarantee(s)` for some scheduler `s` returns `forward_progress_guarantee::concurrent`, all execution agents created by that scheduler shall provide the concurrent forward progress guarantee. If it returns
+3. If `get_forward_progress_guarantee(sch)` for some scheduler `sch` returns `forward_progress_guarantee::concurrent`, all execution agents created by that scheduler shall provide the concurrent forward progress guarantee. If it returns
`forward_progress_guarantee::parallel`, all execution agents created by that scheduler shall provide at least the parallel forward progress guarantee.
### `this_thread::execute_may_block_caller` [exec.execute.may.block.caller] ### {#spec-execution.execute_may_block_caller}
-1. `this_thread::execute_may_block_caller` asks a scheduler `s` whether a call `execute(s, f)` with any invocable `f` may block the thread where such a call occurs.
+1. `this_thread::execute_may_block_caller` asks a scheduler `sch` whether a call `execute(sch, f)` with any invocable `f` may block the thread where such a call occurs.
-2. The name `this_thread::execute_may_block_caller` denotes a query object. For some subexpression `s`, let `S` be `decltype((s))`. If `S` does not satisfy `scheduler`, `this_thread::execute_may_block_caller` is ill-formed. Otherwise,
- `this_thread::execute_may_block_caller(s)` is expression-equivalent to:
+2. The name `this_thread::execute_may_block_caller` denotes a query object. For some subexpression `sch`, let `Sch` be `decltype((sch))`. If `Sch` does not satisfy `scheduler`, `this_thread::execute_may_block_caller` is ill-formed. Otherwise,
+ `this_thread::execute_may_block_caller(sch)` is expression-equivalent to:
- 1. mandate-nothrow-call(tag_invoke, this_thread::execute_may_block_caller, as_const(s))
, if this expression is well-formed.
+ 1. mandate-nothrow-call(tag_invoke, this_thread::execute_may_block_caller, as_const(sch))
, if this expression is well-formed.
* Mandates: The type of the expression above is `bool`.
2. Otherwise, `true`.
-3. If `this_thread::execute_may_block_caller(s)` for some scheduler `s` returns `false`, no `execute(s, f)` call with some invocable `f` shall block the calling thread.
+3. If `this_thread::execute_may_block_caller(sch)` for some scheduler `sch` returns `false`, no `execute(sch, f)` call with some invocable `f` shall block the calling thread.
### `execution::get_completion_scheduler` [exec.completion.scheduler] ### {#spec-execution.get_completion_scheduler}
@@ -4651,10 +4651,10 @@ enum class forward_progress_guarantee {
* Mandates: The type of the expression above satisfies
`scheduler`.
-3. If, for some sender `s` and completion function `C` that has an associated
- completion tag `Tag`, `get_completion_scheduler- template<class S> + template<class Sch> concept scheduler = - queryable<S> && - requires(S&& s, const get_completion_scheduler_t<set_value_t> tag) { - { schedule(std::forward<S>(s)) } -> sender; - { tag_invoke(tag, std::get_env( - schedule(std::forward<S>(s)))) } -> same_as<remove_cvref_t<S>>; + queryable<Sch> && + requires(Sch&& sch, const get_completion_scheduler_t<set_value_t> tag) { + { schedule(std::forward<Sch>(sch)) } -> sender; + { tag_invoke(tag, get_env( + schedule(std::forward<Sch>(sch)))) } -> same_as<remove_cvref_t<Sch>>; } && - equality_comparable<remove_cvref_t<S>> && - copy_constructible<remove_cvref_t<S>>; + equality_comparable<remove_cvref_t<Sch>> && + copy_constructible<remove_cvref_t<Sch>>;-2. Let `S` be the type of a scheduler and let `E` be the type of an execution - environment for which `sender_in
sender-of-in<schedule_result_t<S>, E>
shall be `true`.
+2. Let `Sch` be the type of a scheduler and let `Env` be the type of an execution
+ environment for which `sender_insender-of-in<schedule_result_t<Sch>, Env>
shall be `true`.
3. None of a scheduler's copy constructor, destructor, equality comparison, or
`swap` member functions shall exit via an exception.
@@ -4692,16 +4692,16 @@ enum class forward_progress_guarantee {
shall introduce data races as a result of concurrent invocations of those
functions from different threads.
-5. For any two (possibly `const`) values `s1` and `s2` of some scheduler type
- `S`, `s1 == s2` shall return `true` only if both `s1` and `s2` share the
+5. For any two (possibly `const`) values `sch1` and `sch2` of some scheduler type
+ `Sch`, `sch1 == sch2` shall return `true` only if both `sch1` and `sch2` share the
same associated execution resource.
-6. For a given scheduler expression `s`, the expression
- `get_completion_scheduler- template<class R> + template<class Rcvr> concept is-receiver = // exposition only - derived_from<typename R::receiver_concept, receiver_t>; + derived_from<typename Rcvr::receiver_concept, receiver_t>; - template<class R> - inline constexpr bool enable_receiver = is-receiver<R>; + template<class Rcvr> + inline constexpr bool enable_receiver = is-receiver<Rcvr>; - template<class R> + template<class Rcvr> concept receiver = - enable_receiver<remove_cvref_t<R>> && - requires(const remove_cvref_t<R>& r) { - { get_env(r) } -> queryable; + enable_receiver<remove_cvref_t<Rcvr>> && + requires(const remove_cvref_t<Rcvr>& rcvr) { + { get_env(rcvr) } -> queryable; } && - move_constructible<remove_cvref_t<R>> && // rvalues are movable, and - constructible_from<remove_cvref_t<R>, R>; // lvalues are copyable + move_constructible<remove_cvref_t<Rcvr>> && // rvalues are movable, and + constructible_from<remove_cvref_t<Rcvr>, Rcvr>; // lvalues are copyable - template<class Signature, class R> + template<class Signature, class Rcvr> concept valid-completion-for = // exposition only requires (Signature* sig) { []<class Tag, class... Args>(Tag(*)(Args...)) - requires callable<Tag, remove_cvref_t<R>, Args...> + requires callable<Tag, remove_cvref_t<Rcvr>, Args...> {}(sig); }; - template<class R, class Completions> + template<class Rcvr, class Completions> concept receiver_of = - receiver<R> && + receiver<Rcvr> && requires (Completions* completions) { - []<valid-completion-for<R>...Sigs>(completion_signatures<Sigs...>*) + []<valid-completion-for<Rcvr>...Sigs>(completion_signatures<Sigs...>*) {}(completions); };@@ -4760,12 +4760,12 @@ enum class forward_progress_guarantee { for types that do not. Such specializations shall be usable in constant expressions ([expr.const]) and have type `const bool`. -4. Let `r` be a receiver and let `op_state` be an operation state associated - with an asynchronous operation created by connecting `r` with a sender. Let - `token` be a stop token equal to `get_stop_token(get_env(r))`. `token` shall +4. Let `rcvr` be a receiver and let `op_state` be an operation state associated + with an asynchronous operation created by connecting `rcvr` with a sender. Let + `token` be a stop token equal to `get_stop_token(get_env(rcvr))`. `token` shall remain valid for the duration of the asynchronous operation's lifetime ([async.ops]). This means that, unless it knows about - further guarantees provided by the type of receiver `r`, the implementation + further guarantees provided by the type of receiver `rcvr`, the implementation of `op_state` can not use `token` after it executes a completion operation. This also implies that any stop callbacks registered on `token` must be destroyed before the invocation of the completion operation. @@ -4773,26 +4773,26 @@ enum class forward_progress_guarantee { ### `execution::set_value` [exec.set.value] ### {#spec-execution.receivers.set_value} 1. `set_value` is a value completion function ([async.ops]). Its associated - completion tag is `set_value_t`. The expression `set_value(R, Vs...)` for - some subexpression `R` and pack of subexpressions `Vs` is ill-formed if `R` + completion tag is `set_value_t`. The expression `set_value(rcvr, vs...)` for + some subexpression `rcvr` and pack of subexpressions `vs` is ill-formed if `rcvr` is an lvalue or a `const` rvalue. Otherwise, it is expression-equivalent to -
mandate-nothrow-call(tag_invoke, set_value, R, Vs...)
.
+ mandate-nothrow-call(tag_invoke, set_value, rcvr, vs...)
.
### `execution::set_error` [exec.set.error] ### {#spec-execution.receivers.set_error}
1. `set_error` is an error completion function. Its associated completion tag is
- `set_error_t`. The expression `set_error(R, E)` for some subexpressions `R`
- and `E` is ill-formed if `R` is an lvalue or a `const` rvalue. Otherwise, it is
+ `set_error_t`. The expression `set_error(rcvr, err)` for some subexpressions `rcvr`
+ and `err` is ill-formed if `rcvr` is an lvalue or a `const` rvalue. Otherwise, it is
expression-equivalent to mandate-nothrow-call(tag_invoke,
- set_error, R, E)
.
+ set_error, rcvr, err).
### `execution::set_stopped` [exec.set.stopped] ### {#spec-execution.receivers.set_stopped}
1. `set_stopped` is a stopped completion function. Its associated completion tag
- is `set_stopped_t`. The expression `set_stopped(R)` for some subexpression
- `R` is ill-formed if `R` is an lvalue or a `const` rvalue. Otherwise, it is
+ is `set_stopped_t`. The expression `set_stopped(rcvr)` for some subexpression
+ `rcvr` is ill-formed if `rcvr` is an lvalue or a `const` rvalue. Otherwise, it is
expression-equivalent to mandate-nothrow-call(tag_invoke,
- set_stopped, R)
.
+ set_stopped, rcvr).
## Operation states [exec.opstate] ## {#spec-execution.opstate}
@@ -4858,30 +4858,30 @@ enum class forward_progress_guarantee {
3. This subclause makes use of the following exposition-only entities.
- 1. For a queryable object `e`, let FWD-ENV(e)
be a
+ 1. For a queryable object `env`, let FWD-ENV(env)
be a
queryable object such that for a query object `q` and a pack of
subexpressions `as`, the expression tag_invoke(q,
- FWD-ENV(e), as...)
is ill-formed if
+ FWD-ENV(env), as...) is ill-formed if
`forwarding_query(q)` is `false`;
- otherwise, it is expression-equivalent to `tag_invoke(q, e, as...)`.
+ otherwise, it is expression-equivalent to `tag_invoke(q, env, as...)`.
2. For a query object `q` and a subexpression `v`, let
- MAKE-ENV(q, v)
be a queryable object `e` such that
- `tag_invoke(q, e)` is a `const` lvalue reference to an object
+ MAKE-ENV(q, v)
be a queryable object `env` such that
+ `tag_invoke(q, env)` is a `const` lvalue reference to an object
decay-copied from `v`. Unless otherwise stated, the object to which
- `tag_invoke(q, e)` refers remains valid while `e` remains valid.
+ `tag_invoke(q, env)` refers remains valid while `env` remains valid.
- 3. For two queryable objects `e1` and `e2`, a query object `q` and a pack of
- subexpressions `as`, let JOIN-ENV(e1, e2)
be an
- environment `e3` such that `tag_invoke(q, e3, as...)` is
+ 3. For two queryable objects `env1` and `env2`, a query object `q` and a pack of
+ subexpressions `as`, let JOIN-ENV(env1, env2)
be an
+ environment `env3` such that `tag_invoke(q, env3, as...)` is
expression-equivalent to:
- - `tag_invoke(q, e1, as...)` if that expression is well-formed,
+ - `tag_invoke(q, env1, as...)` if that expression is well-formed,
- - otherwise, `tag_invoke(q, e2, as...)` if that expression is
+ - otherwise, `tag_invoke(q, env2, as...)` if that expression is
well-formed,
- - otherwise, `tag_invoke(q, e3, as...)` is ill-formed.
+ - otherwise, `tag_invoke(q, env3, as...)` is ill-formed.
4. For a scheduler `sch`, let SCHED-ATTRS(sch)
be a
queryable object `o1` such that
@@ -4895,25 +4895,25 @@ enum class forward_progress_guarantee {
type and value as `sch`, and let tag_invoke(get_domain, o2)
be expression-equivalent to tag_invoke(get_domain, sch)
.
- 5. For two subexpressions `r` and `e`, let SET-VALUE(r,
- e)
be `(e, set_value(r))` if the type of `e` is `void`;
- otherwise, it is `set_value(r, e)`. Let TRY-SET-VALUE(r,
- e)
be:
+ 5. For two subexpressions `rcvr` and `expr`, let SET-VALUE(rcvr,
+ expr)
be `(expr, set_value(rcvr))` if the type of `expr` is `void`;
+ otherwise, it is `set_value(rcvr, expr)`. Let TRY-SET-VALUE(rcvr,
+ expr)
be:
try { - SET-VALUE(r, e); + SET-VALUE(rcvr, expr); } catch(...) { - set_error(r, current_exception()); + set_error(rcvr, current_exception()); }- if `e` is potentially-throwing, except that `r` is evaluated only once; - or
SET-VALUE(r, e)
otherwise.
+ if `expr` is potentially-throwing, except that `rcvr` is evaluated only once;
+ or SET-VALUE(rcvr, expr)
otherwise.
6. - template<class Default = default_domain, class Sender> - constexpr auto completion-domain(const Sender& sndr) noexcept; + template<class Default = default_domain, class Sndr> + constexpr auto completion-domain(const Sndr& sndr) noexcept;1. *Effects:* Let
COMPL-DOMAIN(T)
be the type of the expression
@@ -4948,8 +4948,8 @@ enum class forward_progress_guarantee {
8. - template<class Sender> - constexpr auto get-domain-early(const Sender& sndr) noexcept; + template<class Sndr> + constexpr auto get-domain-early(const Sndr& sndr) noexcept;1. Effects: Equivalent to the first of the following that is well-formed: @@ -4961,13 +4961,13 @@ enum class forward_progress_guarantee { - `return default_domain();` 9.
- template<class Sender, class Env> - constexpr auto get-domain-late(const Sender& sndr, const Env& env) noexcept; + template<class Sndr, class Env> + constexpr auto get-domain-late(const Sndr& sndr, const Env& env) noexcept;1. Effects: Equivalent to: - - If
sender-for<Sender, transfer_t>
is `true`, then
+ - If sender-for<Sndr, transfer_t>
is `true`, then
return query-or-default(get_domain, sch, default_domain())
where `sch`
is the scheduler that was used to construct `sndr`,
@@ -5157,7 +5157,7 @@ enum class forward_progress_guarantee {
[](const auto& data, const auto&... child) noexcept -> decltype(auto) { if constexpr (sizeof...(child) == 1) - return FWD-ENV(execution::get_env(child...)); // + return FWD-ENV(get_env(child...)); // else return empty_env(); } @@ -5168,8 +5168,8 @@ enum class forward_progress_guarantee {@@ -5299,24 +5299,24 @@ enum class forward_progress_guarantee { template<class... As> using value-signature = set_value_t(As...); // exposition only - template<class S, class E, class... Values> + template<class Sndr, class Env, class... Values> concept sender-of-in = - sender_in<S, E> && + sender_in<Sndr, Env> && MATCHING-SIG( // see [exec.general] set_value_t(Values...), - value_types_of_t<S, E, value-signature, type_identity_t>); + value_types_of_t<Sndr, Env, value-signature, type_identity_t>); - template<class S, class... Values> - concept sender-of = sender-of-in<S, empty_env, Values...>; + template<class Sndr, class... Values> + concept sender-of = sender-of-in<Sndr, empty_env, Values...>; -6. Let `s` be an expression such that `decltype((s))` is `S`. The type - `tag_of_t[]<class Rcvr>(auto index, auto& state, const Rcvr& rcvr) noexcept - -> decltype(FWD-ENV(execution::get_env(rcvr))) { - return FWD-ENV(execution::get_env(rcvr)); + -> decltype(FWD-ENV(get_env(rcvr))) { + return FWD-ENV(get_env(rcvr)); }@@ -5234,40 +5234,40 @@ enum class forward_progress_guarantee { template<class Sigs> concept valid-completion-signatures = see below; // exposition only - template<class S> + template<class Sndr> concept is-sender = // exposition only - derived_from<typename S::sender_concept, sender_t>; + derived_from<typename Sndr::sender_concept, sender_t>; - template<class S> - inline constexpr bool enable_sender = is-sender<S>; + template<class Sndr> + inline constexpr bool enable_sender = is-sender<Sndr>; - template<is-awaitable<env-promise<empty_env>> S> // [exec.awaitables] - inline constexpr bool enable_sender<S> = true; + template<is-awaitable<env-promise<empty_env>> Sndr> // [exec.awaitables] + inline constexpr bool enable_sender<Sndr> = true; - template<class S> + template<class Sndr> concept sender = - enable_sender<remove_cvref_t<S>> && - requires (const remove_cvref_t<S>& s) { - { get_env(s) } -> queryable; + enable_sender<remove_cvref_t<Sndr>> && + requires (const remove_cvref_t<Sndr>& sndr) { + { get_env(sndr) } -> queryable; } && - move_constructible<remove_cvref_t<S>> && // rvalues are movable, and - constructible_from<remove_cvref_t<S>, S>; // lvalues are copyable + move_constructible<remove_cvref_t<Sndr>> && // rvalues are movable, and + constructible_from<remove_cvref_t<Sndr>, Sndr>; // lvalues are copyable - template<class S, class E = empty_env> + template<class Sndr, class Env = empty_env> concept sender_in = - sender<S> && - queryable<E> && - requires (S&& s, E&& e) { - { get_completion_signatures(std::forward<S>(s), std::forward<E>(e)) } -> + sender<Sndr> && + queryable<Env> && + requires (Sndr&& sndr, Env&& env) { + { get_completion_signatures(std::forward<Sndr>(sndr), std::forward<Env>(env)) } -> valid-completion-signatures; }; - template<class S, class R> + template<class Sndr, class Rcvr> concept sender_to = - sender_in<S, env_of_t<R>> && - receiver_of<R, completion_signatures_of_t<S, env_of_t<R>>> && - requires (S&& s, R&& r) { - connect(std::forward<S>(s), std::forward<R>(r)); + sender_in<Sndr, env_of_t<Rcvr>> && + receiver_of<Rcvr, completion_signatures_of_t<Sndr, env_of_t<Rcvr>>> && + requires (Sndr&& sndr, Rcvr&& rcvr) { + connect(std::forward<Sndr>(sndr), std::forward<Rcvr>(rcvr)); };
sender-for
be an exposition-only concept defined as follows:
- template<class Sender, class Tag> + template<class Sndr, class Tag> concept sender-for = - sender<Sender> && - same_as<tag_of_t<Sender>, Tag>; + sender<Sndr> && + same_as<tag_of_t<Sndr>, Tag>;8. For a type `T`,
SET-VALUE-SIG(T)
names the type
@@ -5356,7 +5356,7 @@ enum class forward_progress_guarantee {
expression-equivalent to the series of transformations and conversions
applied to `c` as the operand of an *await-expression* in a coroutine,
resulting in lvalue `e` as described by [expr.await]/3.2-4, where `p`
- is an lvalue referring to the coroutine's promise type, `P`. This includes the invocation of the promise type's
`await_transform` member if any, the invocation of the `operator co_await`
picked by overload resolution if any, and any necessary implicit
@@ -5373,18 +5373,18 @@ enum class forward_progress_guarantee {
template<class T>
concept await-suspend-result = see below;
- template<class A, class P>
+ template<class A, class Promise>
concept is-awaiter = // exposition only
- requires (A& a, coroutine_handle<P> h) {
+ requires (A& a, coroutine_handle<Promise> h) {
a.await_ready() ? 1 : 0;
{ a.await_suspend(h) } -> await-suspend-result;
a.await_resume();
};
- template<class C, class P>
+ template<class C, class Promise>
concept is-awaitable =
- requires (C (*fc)() noexcept, P& p) {
- { GET-AWAITER(fc(), p) } -> is-awaiter<P>;
+ requires (C (*fc)() noexcept, Promise& p) {
+ { GET-AWAITER(fc(), p) } -> is-awaiter<Promise>;
};
@@ -5396,7 +5396,7 @@ enum class forward_progress_guarantee {
- `T` is a specialization of `coroutine_handle`.
3. For a subexpression `c` such that `decltype((c))` is type `C`, and
- an lvalue `p` of type `P`, await-result-type<C, P>
+ an lvalue `p` of type `Promise`, await-result-type<C, Promise>
names the type decltype(GET-AWAITER(c, p).await_resume())
.
4. Let with-await-transform
be the exposition-only class template:
@@ -5443,163 +5443,163 @@ enum class forward_progress_guarantee {
struct default_domain { - template <sender Sender> - static constexpr sender decltype(auto) transform_sender(Sender&& sndr) noexcept(see below); + template <sender Sndr> + static constexpr sender decltype(auto) transform_sender(Sndr&& sndr) noexcept(see below); - template <sender Sender, queryable Env> - static constexpr sender decltype(auto) transform_sender(Sender&& sndr, const Env& env) noexcept(see below); + template <sender Sndr, queryable Env> + static constexpr sender decltype(auto) transform_sender(Sndr&& sndr, const Env& env) noexcept(see below); - template <sender Sender, queryable Env> - static constexpr decltype(auto) transform_env(Sender&& sndr, Env&& env) noexcept; + template <sender Sndr, queryable Env> + static constexpr decltype(auto) transform_env(Sndr&& sndr, Env&& env) noexcept; - template<class Tag, sender Sender, class... Args> - static constexpr decltype(auto) apply_sender(Tag, Sender&& sndr, Args&&... args) noexcept(see below); + template<class Tag, sender Sndr, class... Args> + static constexpr decltype(auto) apply_sender(Tag, Sndr&& sndr, Args&&... args) noexcept(see below); };#### Static members [exec.domain.default.statics] #### {#spec-execution.default_domain.statics}
-template <sender Sender> - constexpr sender decltype(auto) default_domain::transform_sender(Sender&& sndr) noexcept(see below); +template <sender Sndr> + constexpr sender decltype(auto) default_domain::transform_sender(Sndr&& sndr) noexcept(see below);-1. Returns: `tag_of_t
- noexcept(tag_of_t<Sender>().transform_sender(std::forward<Sender>(sndr))) + noexcept(tag_of_t<Sndr>().transform_sender(std::forward<Sndr>(sndr)))if that expression is well-formed; otherwise, `true`;
-template <sender Sender, queryable Env> - constexpr sender decltype(auto) default_domain::transform_sender(Sender&& sndr, const Env& env) noexcept(see below); +template <sender Sndr, queryable Env> + constexpr sender decltype(auto) default_domain::transform_sender(Sndr&& sndr, const Env& env) noexcept(see below);-1. Returns: `tag_of_t
- noexcept(tag_of_t<Sender>().transform_sender(std::forward<Sender>(sndr), env)) + noexcept(tag_of_t<Sndr>().transform_sender(std::forward<Sndr>(sndr), env))if that expression is well-formed; otherwise, `true`;
-template <sender Sender, queryable Env> - constexpr decltype(auto) default_domain::transform_env(Sender&& sndr, Env&& env) noexcept; +template <sender Sndr, queryable Env> + constexpr decltype(auto) default_domain::transform_env(Sndr&& sndr, Env&& env) noexcept;-3. Returns: `tag_of_t
-template<class Tag, sender Sender, class... Args> - static constexpr decltype(auto) default_domain::apply_sender(Tag, Sender&& sndr, Args&&... args) noexcept(see below); +template<class Tag, sender Sndr, class... Args> + static constexpr decltype(auto) default_domain::apply_sender(Tag, Sndr&& sndr, Args&&... args) noexcept(see below);-5. Returns: `Tag().apply_sender(std::forward
- noexcept(Tag().apply_sender(std::forward<Sender>(sndr), std::forward<Args>(args)...)) + noexcept(Tag().apply_sender(std::forward<Sndr>(sndr), std::forward<Args>(args)...))### `execution::transform_sender` [exec.snd.transform] ### {#spec-execution.sender_transform}
-template<class Domain, sender Sender> - constexpr sender decltype(auto) transform_sender(Domain dom, Sender&& sndr); +template<class Domain, sender Sndr> + constexpr sender decltype(auto) transform_sender(Domain dom, Sndr&& sndr); -template<class Domain, sender Sender, queryable Env> - constexpr sender decltype(auto) transform_sender(Domain dom, Sender&& sndr, const Env& env); +template<class Domain, sender Sndr, queryable Env> + constexpr sender decltype(auto) transform_sender(Domain dom, Sndr&& sndr, const Env& env);1. Returns: Let
ENV
be a parameter pack consisting of
the single expression `env` for the second overload and an empty pack for
- the first. Let `s2` be the expression
- dom.transform_sender(std::forward<Sender>(sndr),
+ the first. Let `sndr2` be the expression
+ dom.transform_sender(std::forward<Sndr>(sndr),
ENV...)
if that expression is well-formed; otherwise,
- default_domain().transform_sender(std::forward<Sender>(sndr),
- ENV...)
. If `s2` and `sndr` have the same type ignoring *cv*
- qualifiers, returns `s2`; otherwise, transform_sender(dom, s2,
+ default_domain().transform_sender(std::forward<Sndr>(sndr),
+ ENV...)
. If `sndr2` and `sndr` have the same type ignoring *cv*
+ qualifiers, returns `sndr2`; otherwise, transform_sender(dom, sndr2,
ENV...)
.
-template<class Domain, sender Sender, queryable Env>
- constexpr decltype(auto) transform_env(Domain dom, Sender&& sndr, Env&& env) noexcept;
+template<class Domain, sender Sndr, queryable Env>
+ constexpr decltype(auto) transform_env(Domain dom, Sndr&& sndr, Env&& env) noexcept;
-3. Returns: `dom.transform_sender(std::forward(sndr), std::forward(env))` if that
+3. Returns: `dom.transform_sender(std::forward(sndr), std::forward(env))` if that
expression is well-formed; otherwise,
- `default_domain().transform_sender(std::forward(sndr), std::forward(env))`.
+ `default_domain().transform_sender(std::forward(sndr), std::forward(env))`.
### `execution::apply_sender` [exec.snd.apply] ### {#spec-execution.apply_sender}
-template<class Domain, class Tag, sender Sender, class... Args>
- constexpr decltype(auto) apply_sender(Domain dom, Tag, Sender&& sndr, Args&&... args) noexcept(see below);
+template<class Domain, class Tag, sender Sndr, class... Args>
+ constexpr decltype(auto) apply_sender(Domain dom, Tag, Sndr&& sndr, Args&&... args) noexcept(see below);
-1. Returns: `dom.apply_sender(Tag(), std::forward(sndr), std::forward(args)...)` if that
+1. Returns: `dom.apply_sender(Tag(), std::forward(sndr), std::forward(args)...)` if that
expression is well-formed; otherwise,
- `default_domain().apply_sender(Tag(), std::forward(sndr), std::forward(args)...)`
+ `default_domain().apply_sender(Tag(), std::forward(sndr), std::forward(args)...)`
if that expression is well-formed; otherwise, this function shall not participate in
overload resolution.
2. Remarks: The exception specification is equivalent to:
- noexcept(dom.apply_sender(Tag(), std::forward<Sender>(sndr), std::forward<Args>(args)...))
+ noexcept(dom.apply_sender(Tag(), std::forward<Sndr>(sndr), std::forward<Args>(args)...))
if that expression is well-formed; otherwise,
- noexcept(default_domain().apply_sender(Tag(), std::forward<Sender>(sndr), std::forward<Args>(args)...))
+ noexcept(default_domain().apply_sender(Tag(), std::forward<Sndr>(sndr), std::forward<Args>(args)...))
### `execution::get_completion_signatures` [exec.getcomplsigs] ### {#spec-execution.getcomplsigs}
-1. `get_completion_signatures` is a customization point object. Let `s` be an
- expression such that `decltype((s))` is `S`, and let `e` be an expression
- such that `decltype((e))` is `E`. Then `get_completion_signatures(s, e)` is
+1. `get_completion_signatures` is a customization point object. Let `sndr` be an
+ expression such that `decltype((sndr))` is `Sndr`, and let `env` be an expression
+ such that `decltype((env))` is `Env`. Then `get_completion_signatures(sndr, env)` is
expression-equivalent to:
- 1. `tag_invoke_result_t{}` if that
+ 1. `tag_invoke_result_t{}` if that
expression is well-formed,
- 2. Otherwise, `remove_cvref_t::completion_signatures{}` if that expression is well-formed,
+ 2. Otherwise, `remove_cvref_t::completion_signatures{}` if that expression is well-formed,
- 3. Otherwise, if is-awaitable<S, env-promise<E>>
+ 3. Otherwise, if is-awaitable<Sndr, env-promise<Env>>
is `true`, then:
completion_signatures<
- SET-VALUE-SIG(await-result-type<S, env-promise<E>>), // see [exec.snd.concepts]
+ SET-VALUE-SIG(await-result-type<Sndr, env-promise<Env>>), // see [exec.snd.concepts]
set_error_t(exception_ptr),
set_stopped_t()>{}
- 4. Otherwise, `get_completion_signatures(s, e)` is ill-formed.
+ 4. Otherwise, `get_completion_signatures(sndr, env)` is ill-formed.
-2. Let `r` be an rvalue receiver of type `R`, and let `S` be the type of a
- sender such that `sender_in>` is `true`. Let `Sigs...` be the
+2. Let `rcvr` be an rvalue receiver of type `Rcvr`, and let `Sndr` be the type of a
+ sender such that `sender_in>` is `true`. Let `Sigs...` be the
template arguments of the `completion_signatures` specialization named by
- `completion_signatures_of_t>`. Let CSO
be
- a completion function. If sender `S` or its operation state cause the
- expression CSO(r, args...)
to be potentially evaluated
+ `completion_signatures_of_t>`. Let CSO
be
+ a completion function. If sender `Sndr` or its operation state cause the
+ expression CSO(rcvr, args...)
to be potentially evaluated
([basic.def.odr]) then there shall be a signature `Sig` in `Sigs...` such
that MATCHING-SIG(tag_t<CSO>(decltype(args)...),
Sig)
is `true` ([exec.general]).
@@ -5609,8 +5609,8 @@ template<class Domain, class Tag, sender Sender, class... Args>
1. `connect` connects ([async.op]) a sender with a receiver.
2. The name `connect` denotes a customization point object. For subexpressions
- `s` and `r`, let `S` be `decltype((s))` and `R` be `decltype((r))`, and let
- `DS` and `DR` be the decayed types of `S` and `R`, respectively.
+ `sndr` and `rcvr`, let `Sndr` be `decltype((sndr))` and `Rcvr` be `decltype((rcvr))`, and let
+ `DS` and `DR` be the decayed types of `Sndr` and `Rcvr`, respectively.
3. Let connect-awaitable-promise
be the following class:
@@ -5618,12 +5618,12 @@ template<class Domain, class Tag, sender Sender, class... Args>
struct connect-awaitable-promise : with-await-transform<connect-awaitable-promise> {
DR& rcvr; // exposition only
- connect-awaitable-promise(DS&, DR& r) noexcept : rcvr(r) {}
+ connect-awaitable-promise(DS&, DR& rcvr) noexcept : rcvr(rcvr) {}
suspend_always initial_suspend() noexcept { return {}; }
- [[noreturn]] suspend_always final_suspend() noexcept { std::terminate(); }
- [[noreturn]] void unhandled_exception() noexcept { std::terminate(); }
- [[noreturn]] void return_void() noexcept { std::terminate(); }
+ [[noreturn]] suspend_always final_suspend() noexcept { terminate(); }
+ [[noreturn]] void unhandled_exception() noexcept { terminate(); }
+ [[noreturn]] void return_void() noexcept { terminate(); }
coroutine_handle<> unhandled_stopped() noexcept {
set_stopped((DR&&) rcvr);
@@ -5688,36 +5688,36 @@ template<class Domain, class Tag, sender Sender, class... Args>
return awaiter{fn};
};
- operation-state-task connect-awaitable(DS s, DR r) requires receiver_of<DR, Sigs> {
+ operation-state-task connect-awaitable(DS sndr, DR rcvr) requires receiver_of<DR, Sigs> {
exception_ptr ep;
try {
if constexpr (same_as<V, void>) {
- co_await std::move(s);
- co_await suspend-complete(set_value, std::move(r));
+ co_await std::move(sndr);
+ co_await suspend-complete(set_value, std::move(rcvr));
} else {
- co_await suspend-complete(set_value, std::move(r), co_await std::move(s));
+ co_await suspend-complete(set_value, std::move(rcvr), co_await std::move(sndr));
}
} catch(...) {
ep = current_exception();
}
- co_await suspend-complete(set_error, std::move(r), std::move(ep));
+ co_await suspend-complete(set_error, std::move(rcvr), std::move(ep));
}
-6. If `S` does not satisfy `sender` or if `R` does not satisfy `receiver`,
- `connect(s, r)` is ill-formed. Otherwise, the expression `connect(s, r)` is
+6. If `Sndr` does not satisfy `sender` or if `Rcvr` does not satisfy `receiver`,
+ `connect(sndr, rcvr)` is ill-formed. Otherwise, the expression `connect(sndr, rcvr)` is
expression-equivalent to:
- 1. `tag_invoke(connect, s, r)` if
- connectable-with-tag-invoke<S, R>
is modeled.
+ 1. `tag_invoke(connect, sndr, rcvr)` if
+ connectable-with-tag-invoke<Sndr, Rcvr>
is modeled.
* Mandates: The type of the `tag_invoke` expression above
satisfies `operation_state`.
- 2. Otherwise, connect-awaitable(s, r)
if that expression is
+ 2. Otherwise, connect-awaitable(sndr, rcvr)
if that expression is
well-formed.
- 3. Otherwise, `connect(s, r)` is ill-formed.
+ 3. Otherwise, `connect(sndr, rcvr)` is ill-formed.
### Sender factories [exec.factories] ### {#spec-execution.senders.factories}
@@ -5726,17 +5726,17 @@ template<class Domain, class Tag, sender Sender, class... Args>
1. `schedule` obtains a schedule-sender ([async.ops]) from a scheduler.
2. The name `schedule` denotes a customization point object. For some
- subexpression `s`, the expression `schedule(s)` is expression-equivalent to:
+ subexpression `sch`, the expression `schedule(sch)` is expression-equivalent to:
- 1. `tag_invoke(schedule, s)`, if that expression is valid. If the function
+ 1. `tag_invoke(schedule, sch)`, if that expression is valid. If the function
selected by `tag_invoke` does not return a sender whose `set_value`
- completion scheduler is equivalent to `s`, the behavior of calling
- `schedule(s)` is undefined.
+ completion scheduler is equivalent to `sch`, the behavior of calling
+ `schedule(sch)` is undefined.
* Mandates: The type of the `tag_invoke` expression above
satisfies `sender`.
- 2. Otherwise, `schedule(s)` is ill-formed.
+ 2. Otherwise, `schedule(sch)` is ill-formed.
#### `execution::just`, `execution::just_error`, `execution::just_stopped` [exec.just] #### {#spec-execution.senders.just}
@@ -5819,16 +5819,16 @@ template<class Domain, class Tag, sender Sender, class... Args>
of the sender adaptor.
4. Unless otherwise specified, a parent sender ([async.ops]) with a single child
- sender `s` has an associated attribute object equal to
- FWD-ENV(get_env(s))
([exec.fwd.env]). Unless
+ sender `sndr` has an associated attribute object equal to
+ FWD-ENV(get_env(sndr))
([exec.fwd.env]). Unless
otherwise specified, a parent sender with more than one child senders has an
associated attributes object equal to empty_env{}
. These
requirements apply to any function that is selected by the implementation of
the sender adaptor.
5. Unless otherwise specified, when a parent sender is connected to a receiver
- `r`, any receiver used to connect a child sender has an associated
- environment equal to FWD-ENV(get_env(r))
. This
+ `rcvr`, any receiver used to connect a child sender has an associated
+ environment equal to FWD-ENV(get_env(rcvr))
. This
requirements applies to any sender returned from a function that is selected
by the implementation of such sender adaptor.
@@ -5843,14 +5843,14 @@ template<class Domain, class Tag, sender Sender, class... Args>
namespace sender-adaptors { // exposition only
- template<class Sch, class S> // arguments are not associated entities ([lib.tmpl-heads])
+ template<class Sch, class Sndr> // arguments are not associated entities ([lib.tmpl-heads])
class on-sender {
// ...
};
struct on_t {
- template<scheduler Sch, sender S>
- on-sender<Sch, S> operator()(Sch&& sch, S&& s) const {
+ template<scheduler Sch, sender Sndr>
+ on-sender<Sch, Sndr> operator()(Sch&& sch, Sndr&& sndr) const {
// ...
}
};
@@ -5861,33 +5861,36 @@ template<class Domain, class Tag, sender Sender, class... Args>
-- end example]
7. If a sender returned from a sender adaptor specified in this subclause is
- specified to include `set_error_t(E)` among its set of completion signatures
- where `decay_t` names the type `exception_ptr`, but the implementation
+ specified to include `set_error_t(Err)` among its set of completion signatures
+ where `decay_t` names the type `exception_ptr`, but the implementation
does not potentially evaluate an error completion operation with an
`exception_ptr` argument, the implementation is allowed to omit the
`exception_ptr` error completion signature from the set.
#### Sender adaptor closure objects [exec.adapt.objects] #### {#spec-execution.senders.adaptor.objects}
-1. A pipeable sender adaptor closure object is a function object that accepts one or more `sender` arguments and returns a `sender`. For a sender adaptor closure object `C` and an expression `S` such that `decltype((S))` models `sender`, the following
- expressions are equivalent and yield a `sender`:
+1. A pipeable sender adaptor closure object is a function object that
+ accepts one or more `sender` arguments and returns a `sender`. For a sender
+ adaptor closure object `c` and an expression `sndr` such that
+ `decltype((sndr))` models `sender`, the following expressions are equivalent
+ and yield a `sender`:
- C(S)
- S | C
+ c(sndr)
+ sndr | c
- Given an additional pipeable sender adaptor closure object `D`, the expression `C | D` produces another pipeable sender adaptor closure object `E`:
+ Given an additional pipeable sender adaptor closure object `d`, the expression `c | d` produces another pipeable sender adaptor closure object `e`:
- `E` is a perfect forwarding call wrapper ([func.require]) with the following properties:
+ `e` is a perfect forwarding call wrapper ([func.require]) with the following properties:
- - Its target object is an object `d` of type `decay_t` direct-non-list-initialized with `D`.
+ - Its target object is an object `d2` of type `decay_t` direct-non-list-initialized with `d`.
- - It has one bound argument entity, an object `c` of type `decay_t` direct-non-list-initialized with `C`.
+ - It has one bound argument entity, an object `c2` of type `decay_t` direct-non-list-initialized with `C`.
- - Its call pattern is `d(c(arg))`, where `arg` is the argument used in a function call expression of `E`.
+ - Its call pattern is `d2(c2(arg))`, where `arg` is the argument used in a function call expression of `e`.
- The expression `C | D` is well-formed if and only if the initializations of the state entities of `E` are all well-formed.
+ The expression `c | d` is well-formed if and only if the initializations of the state entities of `e` are all well-formed.
2. An object `t` of type `T` is a pipeable sender adaptor closure object if `T` models `derived_from>`, `T` has no other base
classes of type `sender_adaptor_closure` for any other type `U`, and `T` does not model `sender`.
@@ -5901,8 +5904,8 @@ template<class Domain, class Tag, sender Sender, class... Args>
5. If a pipeable sender adaptor object accepts only one argument, then it is a pipeable sender adaptor closure object.
-6. If a pipeable sender adaptor object `adaptor` accepts more than one argument, then let `s` be an expression such that `decltype((s))` models `sender`,
- let `args...` be arguments such that `adaptor(s, args...)` is a well-formed expression as specified in the rest of this subclause
+6. If a pipeable sender adaptor object `adaptor` accepts more than one argument, then let `sndr` be an expression such that `decltype((sndr))` models `sender`,
+ let `args...` be arguments such that `adaptor(sndr, args...)` is a well-formed expression as specified in the rest of this subclause
([exec.adapt.objects]), and let `BoundArgs` be a pack that denotes `decay_t...`. The expression `adaptor(args...)`
produces a pipeable sender adaptor closure object `f` that is a perfect forwarding call wrapper with the following properties:
@@ -5910,7 +5913,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
- Its bound argument entities `bound_args` consist of objects of types `BoundArgs...` direct-non-list-initialized with `std::forward(args)...`, respectively.
- - Its call pattern is `adaptor(r, bound_args...)`, where `r` is the argument used in a function call expression of `f`.
+ - Its call pattern is `adaptor(rcvr, bound_args...)`, where `rcvr` is the argument used in a function call expression of `f`.
The expression `adaptor(args...)` is well-formed if and only if the initializations of the bound argument entities of the result, as specified above,
are all well-formed.
@@ -5921,48 +5924,48 @@ template<class Domain, class Tag, sender Sender, class... Args>
agent belonging to a particular scheduler's associated execution resource.
2. The name `on` denotes a customization point object. For some subexpressions
- `sch` and `s`, let `Sch` be `decltype((sch))` and `S` be `decltype((s))`. If
- `Sch` does not satisfy `scheduler`, or `S` does not satisfy `sender`,
- `on(sch, s)` is ill-formed. Otherwise, the expression `on(sch, s)` is
+ `sch` and `sndr`, let `Sch` be `decltype((sch))` and `Sndr` be `decltype((sndr))`. If
+ `Sch` does not satisfy `scheduler`, or `Sndr` does not satisfy `sender`,
+ `on(sch, sndr)` is ill-formed. Otherwise, the expression `on(sch, sndr)` is
expression-equivalent to:
transform_sender(
query-or-default(get_domain, sch, default_domain()),
- make-sender(on, sch, s));
+ make-sender(on, sch, sndr));
-3. Let `out_s` and `e` be subexpressions such that `OutS` is `decltype((out_s))`. If
- sender-for<OutS, on_t>
is `false`, then the expressions
- `on_t().transform_env(out_s, e)` and `on_t().transform_sender(out_s, e)` are ill-formed;
+3. Let `out_sndr` and `env` be subexpressions such that `OutSndr` is `decltype((out_sndr))`. If
+ sender-for<OutSndr, on_t>
is `false`, then the expressions
+ `on_t().transform_env(out_sndr, env)` and `on_t().transform_sender(out_sndr, env)` are ill-formed;
otherwise:
- - `on_t().transform_env(out_s, e)` is equivalent to:
+ - `on_t().transform_env(out_sndr, env)` is equivalent to:
- auto&& [ign1, sch, ign2] = out_s;
- return JOIN-ENV(SCHED-ENV(sch), FWD-ENV(e));
+ auto&& [ign1, sch, ign2] = out_sndr;
+ return JOIN-ENV(SCHED-ENV(sch), FWD-ENV(env));
- - `on_t().transform_sender(out_s, e)` is equivalent to:
+ - `on_t().transform_sender(out_sndr, env)` is equivalent to:
- auto&& [ign, sch, s] = out_s;
+ auto&& [ign, sch, sndr] = out_sndr;
return let_value(
schedule(sch),
- [s = std::forward_like<OutS>(s)]() mutable {
- return std::move(s);
+ [sndr = std::forward_like<OutSndr>(sndr)]() mutable {
+ return std::move(sndr);
});
-4. Let `out_s` be a subexpression denoting a sender returned from `on(sch, s)`
- or one equal to such, and let `OutS` be the type `decltype((out_s))`. Let
- `out_r` be a subexpression denoting a receiver that has an environment of
- type `E` such that `sender_in` is `true`. Let `op` be an lvalue
- referring to the operation state that results from connecting `out_s` with
- `out_r`. Calling `start(op)` shall start `s` on an execution agent of the
+4. 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` 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 start `sndr` on an execution agent of the
associated execution resource of `sch`, or failing that, shall execute an
- error completion on `out_r`.
+ error completion on `out_rcvr`.
#### `execution::transfer` [exec.transfer] #### {#spec-execution.senders.adapt.transfer}
@@ -5971,15 +5974,15 @@ template<class Domain, class Tag, sender Sender, class... Args>
transition between different execution resources when executed.
transform_sender( - get-domain-early(s), - make-sender(transfer, sch, s)); + get-domain-early(sndr), + make-sender(transfer, sch, sndr));3. The exposition-only class template
impls-for
is specialized
@@ -5995,29 +5998,29 @@ template<class Domain, class Tag, sender Sender, class... Args>
};
-4. Let `s` and `e` be subexpressions such that `S` is `decltype((s))`. If
- sender-for<S, transfer_t>
is `false`, then the expression
- `transfer_t().transform_sender(s, e)` is ill-formed; otherwise, it
+4. Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))`. If
+ sender-for<Sndr, transfer_t>
is `false`, then the expression
+ `transfer_t().transform_sender(sndr, env)` is ill-formed; otherwise, it
is equal to:
- auto [tag, data, child] = s; + auto [tag, data, child] = sndr; return schedule_from(std::move(data), std::move(child));- This causes the `transfer(s, sch)` sender to become - `schedule_from(sch, s)` when it is connected with a receiver with an + This causes the `transfer(sndr, sch)` sender to become + `schedule_from(sch, sndr)` when it is connected with a receiver with an execution domain that does not customize `transfer`. -4. Let `out_s` be a subexpression denoting a sender returned from `transfer(s, sch)` - or one equal to such, and let `OutS` be the type `decltype((out_s))`. Let - `out_r` be a subexpression denoting a receiver that has an environment of - type `E` such that `sender_in
transform_sender( query-or-default(get_domain, sch, default_domain()), - make-schedule-from-sender(sch, s)); + make-schedule-from-sender(sch, sndr));- where
make-schedule-from-sender(sch, s)
is expression-equivalent to
- make-sender(schedule_from, sch, s)
and returns a sender object
- `s2` that behaves as follows:
+ where make-schedule-from-sender(sch, sndr)
is expression-equivalent to
+ make-sender(schedule_from, sch, sndr)
and returns a sender object
+ `sndr2` that behaves as follows:
- 1. When `s2` is connected with some receiver `out_r`, it:
+ 1. When `sndr2` is connected with some receiver `out_rcvr`, it:
- 1. Constructs a receiver `r` such that when a receiver completion
- operation Tag(r, args...)
is called, it
+ 1. Constructs a receiver `rcvr` such that when a receiver completion
+ operation Tag(rcvr, args...)
is called, it
decay-copies `args...` into `op_state` (see below) as `args2...` and
- constructs a receiver `r2` such that:
+ constructs a receiver `rcvr2` such that:
- 1. When `set_value(r2)` is called, it calls
- Tag(out_r, std::move(args2)...)
.
+ 1. When `set_value(rcvr2)` is called, it calls
+ Tag(out_rcvr, std::move(args2)...)
.
- 2. `set_error(r2, e)` is expression-equivalent to `set_error(out_r, e)`.
+ 2. `set_error(rcvr2, err)` is expression-equivalent to `set_error(out_rcvr, err)`.
- 3. `set_stopped(r2)` is expression-equivalent to `set_stopped(out_r)`.
+ 3. `set_stopped(rcvr2)` is expression-equivalent to `set_stopped(out_rcvr)`.
- 4. `get_env(r2)` is equal to `get_env(r)`.
+ 4. `get_env(rcvr2)` is equal to `get_env(rcvr)`.
- It then calls `schedule(sch)`, resulting in a sender `s3`. It then
- calls `connect(s3, r2)`, resulting in an operation state
+ It then calls `schedule(sch)`, resulting in a sender `sndr3`. It then
+ calls `connect(sndr3, rcvr2)`, resulting in an operation state
`op_state3`. It then calls `start(op_state3)`. If any of these
- throws an exception, it catches it and calls `set_error(out_r,
+ throws an exception, it catches it and calls `set_error(out_rcvr,
current_exception())`. If any of these expressions would be
- ill-formed, then Tag(r, args...)
is ill-formed.
+ ill-formed, then Tag(rcvr, args...)
is ill-formed.
- 2. Calls `connect(s, r)` resulting in an operation state `op_state2`. If
- this expression would be ill-formed, `connect(s2, out_r)` is
+ 2. Calls `connect(sndr, rcvr)` resulting in an operation state `op_state2`. If
+ this expression would be ill-formed, `connect(sndr2, out_rcvr)` is
ill-formed.
3. Returns an operation state `op_state` that contains `op_state2`. When
`start(op_state)` is called, calls `start(op_state2)`. The lifetime
of `op_state3` ends when `op_state` is destroyed.
- 2. If a sender `S` returned from `schedule_from(sch, s)` is connected with a
- receiver `R` with environmment `E` such that
- transform_sender(get-domain-late(S, E), S, E)
does not
- return a sender that completes on an execution agent belonging to the
- associated execution resource of `sch` and completing with the same
- async result ([async.ops]) as `s`, the behavior of calling
- `connect(S, R)` is undefined.
+ 2. If a sender `out_sndr` returned from `schedule_from(sch, sndr)` is
+ connected with a receiver `rcvr` with environmment `env` such that
+ transform_sender(get-domain-late(out_sndr, env), out_sndr,
+ env)
does not return a sender that completes on an execution
+ agent belonging to the associated execution resource of `sch` and
+ completing with the same async result ([async.ops]) as `sndr`, the
+ behavior of calling `connect(out_sndr, rcvr)` is undefined.
-3. For a sender `t` returned from `schedule_from(sch, s)`, `get_env(t)` shall
- return a queryable object `q` such that `get_domain(q)` is
- expression-equivalent to `get_domain(sch)` and
+3. For a sender `out_sndr` returned from `schedule_from(sch, sndr)`,
+ `get_env(out_sndr)` shall return a queryable object `q` such that
+ `get_domain(q)` is expression-equivalent to `get_domain(sch)` and
`get_completion_schedulerQ
whose type satisfies
forwarding-query
, the expression Q(q,
- args...)
shall be equivalent to Q(get_env(s),
+ args...)
shall be equivalent to Q(get_env(sndr),
args...)
.
#### `execution::then`, `execution::upon_error`, `execution::upon_stopped` [exec.then] #### {#spec-execution.senders.adaptor.then}
@@ -6104,18 +6107,18 @@ template<class Domain, class Tag, sender Sender, class... Args>
2. The names `then`, `upon_error`, and `upon_stopped` denote customization point
objects. Let the expression then-cpo
be one of `then`,
- `upon_error`, or `upon_stopped`. For subexpressions `s` and `f`, let `S` be
- `decltype((s))` and let `F` be the decayed type of `f`. If `S` does not
+ `upon_error`, or `upon_stopped`. For subexpressions `sndr` and `f`, let `Sndr` be
+ `decltype((sndr))` and let `F` be the decayed type of `f`. If `Sndr` does not
satisfy `sender`, or `F` does not satisfy movable-value
,
- then-cpo(s, f)
is ill-formed.
+ then-cpo(sndr, f)
is ill-formed.
-3. Otherwise, the expression then-cpo(s, f)
is
+3. Otherwise, the expression then-cpo(sndr, f)
is
expression-equivalent to:
transform_sender( - get-domain-early(s), - make-sender(then-cpo, f, s)); + get-domain-early(sndr), + make-sender(then-cpo, f, sndr));4. For `then`, `upon_error`, and `upon_stopped`, let
set-cpo
@@ -6139,12 +6142,12 @@ template<class Domain, class Tag, sender Sender, class... Args>
};
-5. The expression then-cpo(s, f)
has undefined behavior
- unless it returns a sender `out_s` that:
+5. The expression then-cpo(sndr, f)
has undefined behavior
+ unless it returns a sender `out_sndr` that:
1. Invokes `f` or a copy of such with the value, error, or stopped result
- datums of `s` (for `then`, `upon_error`, and `upon_stopped`
- respectively), using the result value of `f` as `out_s`'s value
+ datums of `sndr` (for `then`, `upon_error`, and `upon_stopped`
+ respectively), using the result value of `f` as `out_sndr`'s value
completion, and
2. Forwards all other completion operations unchanged.
@@ -6159,226 +6162,226 @@ template<class Domain, class Tag, sender Sender, class... Args>
2. Let the expression let-cpo
be one of `let_value`,
`let_error`, or `let_stopped` and let set-cpo
be the
completion function that corresponds to let-cpo
- (`set_value` for `let_value`, etc.). For subexpressions `s` and `re`, let
- inner-env(s, re)
be an environment `e` such that:
+ (`set_value` for `let_value`, etc.). For subexpressions `sndr` and `rcvr_env`, let
+ inner-env(sndr, rcvr_env)
be an environment `env` such that:
- 1. `get_domain(e)` is expression-equivalent
- get-domain-late(s, re)
,
+ 1. `get_domain(env)` is expression-equivalent
+ get-domain-late(sndr, rcvr_env)
,
- 2. `get_scheduler(e)` is expression-equivalent to the first
+ 2. `get_scheduler(env)` is expression-equivalent to the first
well-formed expression below:
- - get_completion_scheduler<set-cpo-t>(get_env(s))
,
+ - get_completion_scheduler<set-cpo-t>(get_env(sndr))
,
where set-cpo-t
is the type of
set-cpo
.
- - `get_scheduler(re)`
+ - `get_scheduler(rcvr_env)`
- or if neither of them are, `get_scheduler(e)` is ill-formed.
+ or if neither of them are, `get_scheduler(env)` is ill-formed.
- 3. For all other query objects Q
and arguments `args...`,
- Q(e, args...)
is expression-equivalent to
- Q(re, args...)
.
+ 3. For all other query objects q
and arguments `args...`,
+ q(env, args...)
is expression-equivalent to
+ q(rcvr_env, args...)
.
3. The names `let_value`, `let_error`, and `let_stopped` denote customization
- point objects. For subexpressions `s` and `f`, let `S` be `decltype((s))`,
+ point objects. For subexpressions `sndr` and `f`, let `Sndr` be `decltype((sndr))`,
let `F` be the decayed type of `f`, and let `f2` be an xvalue that refers to
- an object decay-copied from `f`. If `S` does not satisfy `sender` or if `F`
+ an object decay-copied from `f`. If `Sndr` does not satisfy `sender` or if `F`
does not satisfy movable-value
, the expression
- let-cpo(s, f)
is ill-formed. If `F` does not satisfy
- `invocable`, the expression `let_stopped(s, f)` is ill-formed. Otherwise,
- the expression let-cpo(s, f)
is expression-equivalent
+ let-cpo(sndr, f)
is ill-formed. If `F` does not satisfy
+ `invocable`, the expression `let_stopped(sndr, f)` is ill-formed. Otherwise,
+ the expression let-cpo(sndr, f)
is expression-equivalent
to:
transform_sender( - get-domain-early(s), - make-let-sender(f, s)); + get-domain-early(sndr), + make-let-sender(f, sndr));- where
make-let-sender(f, s)
is expression-equivalent to
- make-sender(let-cpo, f, s)
and returns a sender
- object `s2` that behaves as follows:
+ where make-let-sender(f, sndr)
is expression-equivalent to
+ make-sender(let-cpo, f, sndr)
and returns a sender
+ object `sndr2` that behaves as follows:
- 1. When `s2` is connected to some receiver `out_r`, it:
+ 1. When `sndr2` is connected to some receiver `out_rcvr`, it:
- 1. Decay-copies `out_r` into `op_state2` (see below). `out_r2` is an
- xvalue referring to the copy of `out_r`.
+ 1. Decay-copies `out_rcvr` into `op_state2` (see below). `out_rcvr2` is an
+ xvalue referring to the copy of `out_rcvr`.
- 2. Constructs a receiver `r` such that:
+ 2. Constructs a receiver `rcvr` such that:
- 1. When set-cpo(r, args...)
is called, the
- receiver `r` decay-copies `args...` into `op_state2` as
+ 1. When set-cpo(rcvr, args...)
is called, the
+ receiver `rcvr` decay-copies `args...` into `op_state2` as
`args2...`, then calls `invoke(f2, args2...)`, resulting in a
- sender `s3`. It then calls `connect(s3, out_r3)`, resulting in
- an operation state `op_state3`, where `out_r3` is a receiver
+ sender `sndr3`. It then calls `connect(sndr3, out_rcvr3)`, resulting in
+ an operation state `op_state3`, where `out_rcvr3` is a receiver
described below. `op_state3` is saved as a part of `op_state2`.
It then calls `start(op_state3)`. If any of these throws an
- exception, it catches it and calls `set_error(out_r2,
+ exception, it catches it and calls `set_error(out_rcvr2,
current_exception())`. If any of these expressions would be
- ill-formed, set-cpo(r, args...)
is
+ ill-formed, set-cpo(rcvr, args...)
is
ill-formed.
- 2. CF(r, args...)
is expression-equivalent to
- CF(out_r2, args...)
, where
+ 2. CF(rcvr, args...)
is expression-equivalent to
+ CF(out_rcvr2, args...)
, where
CF
is a completion function other than
set-cpo
.
- 3. `get_env(r)` is expression-equivalent to `get_env(out_r)`.
+ 3. `get_env(rcvr)` is expression-equivalent to `get_env(out_rcvr)`.
- 4. `out_r3` is a receiver that forwards its completion operations
- to `out_r2` and for which `get_env(out_r3)` returns
- inner-env(get_env(s), get_env(out_r2))
.
+ 4. `out_rcvr3` is a receiver that forwards its completion operations
+ to `out_rcvr2` and for which `get_env(out_rcvr3)` returns
+ inner-env(get_env(sndr), get_env(out_rcvr2))
.
- 2. Calls `connect(s, r)` resulting in an operation state `op_state2`.
- If the expression `connect(s, r)` is ill-formed, `connect(s2,
- out_r)` is ill-formed.
+ 2. Calls `connect(sndr, rcvr)` resulting in an operation state `op_state2`.
+ If the expression `connect(sndr, rcvr)` is ill-formed, `connect(sndr2,
+ out_rcvr)` is ill-formed.
3. Returns an operation state `op_state` that stores `op_state2`.
`start(op_state)` is expression-equivalent to `start(op_state2)`.
-5. Let `s` and `e` be subexpressions such that `S` is `decltype((s))` and `E` is
- `decltype((e))`. If sender-for<S, let-cpo-t>
is `false` where
+5. Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))` and `Env` is
+ `decltype((env))`. If sender-for<Sndr, let-cpo-t>
is `false` where
let-cpo-t
is the type of let-cpo
, then the expression
- let-cpo-t().transform_env(s, e)
is ill-formed. Otherwise, it is equal
- to inner-env(get_env(s), e)
.
+ let-cpo-t().transform_env(sndr, env)
is ill-formed. Otherwise, it is equal
+ to inner-env(get_env(sndr), env)
.
-6. If a sender `S` returned from let-cpo(s, f)
is connected to a
- receiver `R` with environment `E` such that
- transform_sender(get-domain-late(S, E), S, E)
does not return a
+6. If a sender `out_sndr` returned from let-cpo(sndr, f)
is connected to a
+ receiver `rcvr` with environment `env` such that
+ transform_sender(get-domain-late(out_sndr, env), out_sndr, env)
does not return a
sender that:
- - invokes `f` when set-cpo
is called with `s`'s result datums,
+ - invokes `f` when set-cpo
is called with `sndr`'s result datums,
- makes its completion dependent on the completion of a sender returned by
`f`, and
- - propagates the other completion operations sent by `s`,
+ - propagates the other completion operations sent by `sndr`,
- the behavior of calling `connect(S, R)` is undefined.
+ the behavior of calling `connect(out_sndr, rcvr)` is undefined.
#### `execution::bulk` [exec.bulk] #### {#spec-execution.senders.adapt.bulk}
1. `bulk` runs a task repeatedly for every index in an index space.
-2. The name `bulk` denotes a customization point object. For some
- subexpressions `s`, `shape`, and `f`, let `S` be `decltype((s))`, `Shape` be
- `decltype((shape))`, and `F` be `decltype((f))`. If `S` does not satisfy
- `sender` or `Shape` does not satisfy `integral`,
- `bulk` is ill-formed. Otherwise, the expression
- `bulk(s, shape, f)` is expression-equivalent to:
+2. The name `bulk` denotes a customization point object. For some subexpressions
+ `sndr`, `shape`, and `f`, let `Sndr` be `decltype((sndr))`, `Shape` be
+ `decltype((shape))`, and `F` be `decltype((f))`. If `Sndr` does not satisfy
+ `sender` or `Shape` does not satisfy `integral`, `bulk` is ill-formed.
+ Otherwise, the expression `bulk(sndr, shape, f)` is expression-equivalent
+ to:
transform_sender( - get-domain-early(s), - make-bulk-sender(product-type{shape, f}, s)); + get-domain-early(sndr), + make-bulk-sender(product-type{shape, f}, sndr));- where
make-bulk-sender(t, s)
is expression-equivalent to
- make-sender(bulk, t, s)
for a subexpression `t` and
- returns a sender object `s2` that behaves as follows:
+ where make-bulk-sender(t, sndr)
is expression-equivalent to
+ make-sender(bulk, t, sndr)
for a subexpression `t` and
+ returns a sender object `sndr2` that behaves as follows:
- 3. When `s2` is connected with a receiver `out_r`, it:
+ 3. When `sndr2` is connected with a receiver `out_rcvr`, it:
- 1. Constructs a receiver `r`:
+ 1. Constructs a receiver `rcvr`:
- 1. When `set_value(r, args...)` is called, calls `f(i, args...)` for
+ 1. When `set_value(rcvr, args...)` is called, calls `f(i, args...)` for
each `i` of type `Shape` from `0` to `shape`, then calls
- `set_value(out_r, args...)`. If any of these throws an
- exception, it catches it and calls `set_error(out_r,
+ `set_value(out_rcvr, args...)`. If any of these throws an
+ exception, it catches it and calls `set_error(out_rcvr,
current_exception())`. If any of these expressions are
- ill-formed, `set_value(r, args...)` is ill-formed.
+ ill-formed, `set_value(rcvr, args...)` is ill-formed.
- 2. When `set_error(r, e)` is called, calls `set_error(out_r, e)`.
+ 2. When `set_error(rcvr, err)` is called, calls `set_error(out_rcvr, err)`.
- 3. When `set_stopped(r)` is called, calls `set_stopped(out_r, e)`.
+ 3. When `set_stopped(rcvr)` is called, calls `set_stopped(out_rcvr)`.
- 2. Calls `connect(s, r)`, which results in an operation state `op_state2`.
+ 2. Calls `connect(sndr, rcvr)`, which results in an operation state `op_state2`.
3. Returns an operation state `op_state` that contains `op_state2`. When
`start(op_state)` is called, calls `start(op_state2)`.
- 4. Let `S` be the result of calling `bulk(s, shape, f)` or a copy of such.
- If `S` is connected to a receiver `R` with environment `E` such that
- transform_sender(get-domain-late(S, E), S, E)
does
+ 4. Let `out_sndr` be the result of calling `bulk(sndr, shape, f)` or a copy of such.
+ If `out_sndr` is connected to a receiver `rcvr` with environment `env` such that
+ transform_sender(get-domain-late(out_sndr, env), out_sndr, env)
does
not return a sender that invokes `f(i, args...)` for each `i` of type
`Shape` from `0` to `shape` where `args` is a pack of subexpressions
referring to the value completion result datums of the input sender, or
does not execute a value completion operation with said datums, the
- behavior of calling `connect(S, R)` is undefined.
+ behavior of calling `connect(out_sndr, rcvr)` is undefined.
#### `execution::split` [exec.split] #### {#spec-execution.senders.adapt.split}
1. `split` adapts an arbitrary sender into a sender that can be connected multiple times.
2. Let split-env
be the type of an environment such that,
- given an instance `e`, the expression `get_stop_token(e)` is well-formed and
+ given an instance `env`, the expression `get_stop_token(env)` is well-formed and
has type `stop_token`.
3. The name `split` denotes a customization point object. For some
- subexpression `s`, let `S` be `decltype((s))`. If
- sender_in<S, split-env>
or
- `constructible_fromsender_in<Sndr, split-env>
or
+ `constructible_fromtransform_sender( - get-domain-early(s), - make-sender(split, s)); + get-domain-early(sndr), + make-sender(split, sndr));- 1. Let `s` be a subexpression such that `S` is `decltype((s))`, and let - `e...` be a pack of subexpressions such that `sizeof...(e) <= 1` is - `true`. If
sender-for<S, split_t>
is `false`,
- then the expression `split_t().transform_sender(s, e...)` is ill-formed;
- otherwise, it returns a sender `s2` that:
+ 1. Let `sndr` be a subexpression such that `Sndr` is `decltype((sndr))`, and let
+ `env...` be a pack of subexpressions such that `sizeof...(env) <= 1` is
+ `true`. If sender-for<Sndr, split_t>
is `false`,
+ then the expression `split_t().transform_sender(sndr, env...)` is ill-formed;
+ otherwise, it returns a sender `sndr2` that:
1. Creates an object `sh_state` that contains a `stop_source`, a list of
- pointers to operation states awaiting the completion of `s`, and that
+ pointers to operation states awaiting the completion of `sndr`, and that
also reserves space for storing:
- * the operation state that results from connecting `s` with `r` described below, and
- * the sets of values and errors with which `s` can complete, with
+ * the operation state that results from connecting `sndr` with `rcvr` described below, and
+ * the sets of values and errors with which `sndr` can complete, with
the addition of `exception_ptr`.
- * the result of decay-copying `get_env(s)`.
+ * the result of decay-copying `get_env(sndr)`.
- 2. Constructs a receiver `r` such that:
+ 2. Constructs a receiver `rcvr` such that:
- 1. When `set_value(r, args...)` is called, decay-copies
+ 1. When `set_value(rcvr, args...)` is called, decay-copies
the expressions `args...` into `sh_state`. It then notifies all
the operation states in `sh_state`'s list of operation states
that the results are ready. If any exceptions are thrown, the
- exception is caught and `set_error(r,
+ exception is caught and `set_error(rcvr,
current_exception())` is called instead.
- 2. When `set_error(r, e)` is called, decay-copies `e`
+ 2. When `set_error(rcvr, err)` is called, decay-copies `err`
into `sh_state`. It then notifies the operation states in
`sh_state`'s list of operation states that the results are ready.
- 3. When `set_stopped(r)` is called, notifies the
+ 3. When `set_stopped(rcvr)` is called, notifies the
operation states in `sh_state`'s list of operation states that
the results are ready.
- 4. `get_env(r)` is an expression e
of type
+ 4. `get_env(rcvr)` is an expression env
of type
split-env
such that
- get_stop_token(e)
is well-formed
+ get_stop_token(env)
is well-formed
and returns the results of calling `get_token()` on `sh_state`'s
stop source.
- 3. Calls `get_env(s)` and decay-copies the result into
+ 3. Calls `get_env(sndr)` and decay-copies the result into
`sh_state`.
- 4. Calls `connect(s, r)`, resulting in an operation state
+ 4. Calls `connect(sndr, rcvr)`, resulting in an operation state
`op_state2`. `op_state2` is saved in `sh_state`.
- 5. When `s2` is connected with a receiver `out_r` of type `OutR`, it
+ 5. When `sndr2` is connected with a receiver `out_rcvr` of type `OutRcvr`, it
returns an operation state object `op_state` that contains:
- * An object `out_r2` of type `OutR` decay-copied from `out_r`,
+ * An object `out_rcvr2` of type `OutRcvr` decay-copied from `out_rcvr`,
* A reference to `sh_state`,
* A stop callback of type
- optional<stop_token_of_t<env_of_t<OutR>>::callback_type<stop-callback-fn>>
,
+ optional<stop_token_of_t<env_of_t<OutRcvr>>::callback_type<stop-callback-fn>>
,
where stop-callback-fn
is the unspecified
class type:
@@ -6393,15 +6396,15 @@ template<class Domain, class Tag, sender Sender, class... Args>
6. When `start(op_state)` is called:
- * If one of `r`'s completion functions has executed, then let
+ * If one of `rcvr`'s completion functions has executed, then let
Tag
be the completion function that was
- called. Calls Tag(out_r2, args2...)
,
+ called. Calls Tag(out_rcvr2, args2...)
,
where `args2...` is a pack of const lvalues referencing the
subobjects of `sh_state` that have been saved by the original
- call to Tag(r, args...)
and returns.
+ call to Tag(rcvr, args...)
and returns.
* Otherwise, it emplace constructs the stop callback optional with
- the arguments `get_stop_token(get_env(out_r2))` and
+ the arguments `get_stop_token(get_env(out_rcvr2))` and
stop-callback-fn{stop-src}
, where
stop-src
refers to the stop source of
`sh_state`.
@@ -6412,37 +6415,37 @@ template<class Domain, class Tag, sender Sender, class... Args>
* If stop-src.stop_requested()
is `true`,
all of the operation states in `sh_state`'s list of operation
- states are notified as if `set_stopped(r)` had
+ states are notified as if `set_stopped(rcvr)` had
been called.
* Otherwise, `start(op_state2)` is called.
- 7. When `r` completes it will notify `op_state` that the result are
+ 7. When `rcvr` completes it will notify `op_state` that the result are
ready. Let Tag
be whichever
- completion function was called on receiver `r`. `op_state`'s
+ completion function was called on receiver `rcvr`. `op_state`'s
stop callback optional is reset. Then
- Tag(std::move(out_r2), args2...)
is called,
+ Tag(std::move(out_rcvr2), args2...)
is called,
where `args2...` is a pack of const lvalues referencing the subobjects of
`sh_state` that have been saved by the original call to
- Tag(r, args...)
.
+ Tag(rcvr, args...)
.
- 8. Ownership of `sh_state` is shared by `s2` and by every `op_state`
- that results from connecting `s2` to a receiver.
+ 8. Ownership of `sh_state` is shared by `sndr2` and by every `op_state`
+ that results from connecting `sndr2` to a receiver.
- 2. Given subexpressions `s2` where `s2` is a sender returned from `split`
- or a copy of such, `get_env(s2)` shall return an lvalue reference to the
- object in `sh_state` that was initialized with the result of `get_env(s)`.
+ 2. Given subexpressions `sndr2` where `sndr2` is a sender returned from `split`
+ or a copy of such, `get_env(sndr2)` shall return an lvalue reference to the
+ object in `sh_state` that was initialized with the result of `get_env(sndr)`.
-5. Let `s` be a sender expression, `r` be an instance of the receiver type
- described above, `s2` be a sender returned from `split(s)` or a copy of
- such, `r2` is the receiver to which `s2` is connected, and `args` is the
- pack of subexpressions passed to `r`'s completion function
- CSO
when `s` completes. `s2` shall invoke
- CSO(r2, args2...)
where `args2` is a pack of const
+5. Let `sndr` be a sender expression, `rcvr` be an instance of the receiver type
+ described above, `sndr2` be a sender returned from `split(sndr)` or a copy of
+ such, `rcvr2` is the receiver to which `sndr2` is connected, and `args` is the
+ pack of subexpressions passed to `rcvr`'s completion function
+ CSO
when `sndr` completes. `sndr2` shall invoke
+ CSO(rcvr2, args2...)
where `args2` is a pack of const
lvalue references to objects decay-copied from `args`, or by calling
- set_error(r2, e2)
for some subexpression `e2`. The objects
- passed to `r2`'s completion operation shall be valid until after the
- completion of the invocation of `r2`'s completion operation.
+ set_error(rcvr2, err2)
for some subexpression `err2`. The objects
+ passed to `rcvr2`'s completion operation shall be valid until after the
+ completion of the invocation of `rcvr2`'s completion operation.
#### `execution::when_all` [exec.when.all] #### {#spec-execution.senders.adaptor.when_all}
@@ -6450,81 +6453,81 @@ template<class Domain, class Tag, sender Sender, class... Args>
a sender that completes when all input senders have completed. `when_all`
only accepts senders with a single value completion signature and on success
concatenates all the input senders' value result datums into its own value
- completion operation. `when_all_with_variant(s...)` is semantically
- equivalent to `when_all(into_variant(s)...)`, where `s` is a pack of
+ completion operation. `when_all_with_variant(sndr...)` is semantically
+ equivalent to `when_all(into_variant(sndr)...)`, where `sndr` is a pack of
subexpressions of sender types.
2. The names `when_all` and `when_all_with_variant` denote customization point
- objects. For some subexpressions si...
, let
- Si...
be
- decltype((si))...
. The expressions
- when_all(si...)
and
- when_all_with_variant(si...)
are ill-formed if
+ objects. For some subexpressions sndri...
, let
+ Sndri...
be
+ decltype((sndri))...
. The expressions
+ when_all(sndri...)
and
+ when_all_with_variant(sndri...)
are ill-formed if
any of the following is true:
- * If the number of subexpressions si...
is 0, or
+ * If the number of subexpressions sndri...
is 0, or
- * If any type Si
does not satisfy `sender`.
+ * If any type Sndri
does not satisfy `sender`.
- * If the expression get-domain-early(si)
has a
+ * If the expression get-domain-early(sndri)
has a
different type for any other value of i
.
Otherwise, those expressions have the semantics specified below.
-3. The expression when_all(si...)
is
+3. The expression when_all(sndri...)
is
expression-equivalent to:
transform_sender( - get-domain-early(s0), - make-when-all-sender(s0, ... sn-1)); + get-domain-early(sndr0), + make-when-all-sender(sndr0, ... sndrn-1));- where
make-when-all-sender(si...)
is
+ where make-when-all-sender(sndri...)
is
expression-equivalent to make-sender(when_all,
- unspecified, si...)
and returns a sender
+ unspecified, sndri...) and returns a sender
object `w` of type `W` that behaves as follows:
- 1. When `w` is connected with some receiver `out_r` of type `OutR`, it
+ 1. When `w` is connected with some receiver `out_rcvr` of type `OutRcvr`, it
returns an operation state `op_state` specified as below:
- 1. For each sender si
, constructs a
- receiver ri
such that:
+ 1. For each sender sndri
, constructs a
+ receiver rcvri
such that:
- 1. If set_value(ri,
+ 1. If set_value(rcvri,
ti...)
is called for every
- ri
, `op_state`'s associated stop
- callback optional is reset and set_value(out_r,
+ rcvri
, `op_state`'s associated stop
+ callback optional is reset and set_value(out_rcvr,
t0..., t1..., ...,
tn-1...)
is called, where `n` the number
- of subexpressions in si...
.
+ of subexpressions in sndri...
.
2. Otherwise, `set_error` or `set_stopped` was called for at least
- one receiver ri
. If the first such
+ one receiver rcvri
. If the first such
to complete did so with the call
- set_error(ri, e)
, `request_stop`
+ set_error(rcvri, err)
, `request_stop`
is called on `op_state`'s associated stop source. When all child
operations have completed, `op_state`'s associated stop callback
- optional is reset and `set_error(out_r, e)` is called.
+ optional is reset and `set_error(out_rcvr, err)` is called.
3. Otherwise, `request_stop` is called on `op_state`'s associated
stop source. When all child operations have completed,
`op_state`'s associated stop callback optional is reset and
- `set_stopped(out_r)` is called.
+ `set_stopped(out_rcvr)` is called.
- 4. For each receiver ri
,
- get_env(ri)
is an expression
- e
such that
- get_stop_token(e)
is well-formed and returns
+ 4. For each receiver rcvri
,
+ get_env(rcvri)
is an expression
+ env
such that
+ get_stop_token(env)
is well-formed and returns
the results of calling `get_token()` on `op_state`'s associated
- stop source, and for which tag_invoke(tag, e,
- args...)
is expression-equivalent to `tag(get_env(out_r),
+ stop source, and for which tag_invoke(tag, env,
+ args...)
is expression-equivalent to `tag(get_env(out_rcvr),
args...)` for all arguments `args...` and all `tag` whose type
satisfies forwarding-query
and is not
`get_stop_token_t`.
- 2. For each sender si
, calls
- connect(si, ri)
,
+ 2. For each sender sndri
, calls
+ connect(sndri, rcvri)
,
resulting in operation states
child_opi
.
@@ -6535,7 +6538,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
* A stop source of type `in_place_stop_source`,
* A stop callback of type
- optional<stop_token_of_t<env_of_t<OutR>>::callback_type<stop-callback-fn>>
,
+ optional<stop_token_of_t<env_of_t<OutRcvr>>::callback_type<stop-callback-fn>>
,
where stop-callback-fn
is the unspecified
class type:
@@ -6551,54 +6554,52 @@ template<class Domain, class Tag, sender Sender, class... Args>
4. When `start(op_state)` is called it:
* Emplace constructs the stop callback optional with the arguments
- `get_stop_token(get_env(out_r))` and
+ `get_stop_token(get_env(out_rcvr))` and
stop-callback-fn{stop-src}
, where
stop-src
refers to the stop source of
`op_state`.
* Then, it checks to see if
stop-src.stop_requested()
is true. If so, it
- calls `set_stopped(out_r)`.
+ calls `set_stopped(out_rcvr)`.
* Otherwise, calls start(child_opi)
for each child_opi
.
-4. The expression when_all_with_variant(si...)
is
+4. The expression when_all_with_variant(sndri...)
is
expression-equivalent to:
transform_sender(
- get-domain-early(s0),
- make-sender(when_all_with_variant, unspecified, s0, ... sn-1));
+ get-domain-early(sndr0),
+ make-sender(when_all_with_variant, unspecified, sndr0, ... sndrn-1));
- where make-when-all-sender(si...)
is
+ where make-when-all-sender(sndri...)
is
expression-equivalent to make-sender(when_all,
- unspecified, si...)
and returns a sender
+ unspecified, sndri...)
and returns a sender
object `w` of type `W` that behaves as follows:
-5. Let `s` and `e` be subexpressions such that `S` is `decltype((s))`. If
- sender-for<S, when_all_with_variant_t>
is `false`,
- then the expression `when_all_with_variant_t().transform_sender(s, e)` is
+5. Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))`. If
+ sender-for<Sndr, when_all_with_variant_t>
is `false`,
+ then the expression `when_all_with_variant_t().transform_sender(sndr, env)` is
ill-formed; otherwise, it is equal to:
- const auto& env = e;
- auto domain = get-domain-late(s, env);
- auto [tag, data, ...child] = s;
+ auto [tag, data, ...child] = sndr;
return when_all(into_variant(std::move(child))...);
- This causes the `when_all_with_variant(s...)` sender
- to become `when_all(into_variant(s)...)` when it is connected with a
+ This causes the `when_all_with_variant(sndr...)` sender
+ to become `when_all(into_variant(sndr)...)` when it is connected with a
receiver with an execution domain that does not customize
`when_all_with_variant`.
-4. Given a pack of subexpressions `s...`, let `S` be an object returned from
- `when_all(s...)` or `when_all_with_variant(s...)` or a copy of such, and let
- `E` be the environment object returned from `get_env(S)`. Given a query
- object `Q`, `tag_invoke(Q, E)` is expression-equivalent to
- get-domain-early(s0)
when `Q` is
+4. Given a pack of subexpressions `sndr...`, let `out_sndr` be an object returned from
+ `when_all(sndr...)` or `when_all_with_variant(sndr...)` or a copy of such, and let
+ `env` be the environment object returned from `get_env(out_sndr)`. Given a query
+ object `q`, `tag_invoke(q, env)` is expression-equivalent to
+ get-domain-early(sndr0)
when `q` is
`get_domain`; otherwise, it is ill-formed.
#### `execution::into_variant` [exec.into.variant] #### {#spec-execution.senders.adapt.into_variant}
@@ -6610,45 +6611,45 @@ template<class Domain, class Tag, sender Sender, class... Args>
a sender returned from `into_variant`.
- template<class S, class E>
- requires sender_in<S, E>
+ template<class Sndr, class Env>
+ requires sender_in<Sndr, Env>
using into-variant-type =
- value_types_of_t<S, E>;
+ value_types_of_t<Sndr, Env>;
-3. `into_variant` is a customization point object. For some subexpression `s`,
- let `S` be `decltype((s))`. If `S` does not satisfy `sender`,
- `into_variant(s)` is ill-formed. Otherwise, `into_variant(s)` is
+3. `into_variant` is a customization point object. For some subexpression `sndr`,
+ let `Sndr` be `decltype((sndr))`. If `Sndr` does not satisfy `sender`,
+ `into_variant(sndr)` is ill-formed. Otherwise, `into_variant(sndr)` is
expression-equivalent to:
transform_sender(
- get-domain-early(s),
- make-into-variant-sender(s))
+ get-domain-early(sndr),
+ make-into-variant-sender(sndr))
- where make-into-variant-sender(s)
is
+ where make-into-variant-sender(sndr)
is
expression-equivalent to make-sender(into_variant,
- unspecified, s)
and returns a sender object `s2` that behaves
+ unspecified, sndr)
and returns a sender object `sndr2` that behaves
as follows:
- 1. When `s2` is connected with some receiver `out_r`, it:
+ 1. When `sndr2` is connected with some receiver `out_rcvr`, it:
- 1. Constructs a receiver `r` such that:
+ 1. Constructs a receiver `rcvr` such that:
- 1. If `set_value(r, ts...)` is called, calls set_value(out_r,
- into-variant-type<S,
- env_of_t<decltype((r))>>(decayed-tuple<decltype(ts)...>(ts...)))
.
- If this expression throws an exception, calls `set_error(out_r,
+ 1. If `set_value(rcvr, ts...)` is called, calls set_value(out_rcvr,
+ into-variant-type<Sndr,
+ env_of_t<decltype((rcvr))>>(decayed-tuple<decltype(ts)...>(ts...)))
.
+ If this expression throws an exception, calls `set_error(out_rcvr,
current_exception())`.
- 2. `set_error(r, e)` is expression-equivalent to `set_error(out_r,
- e)`.
+ 2. `set_error(rcvr, err)` is expression-equivalent to `set_error(out_rcvr,
+ err)`.
- 3. `set_stopped(r)` is expression-equivalent to
- `set_stopped(out_r)`.
+ 3. `set_stopped(rcvr)` is expression-equivalent to
+ `set_stopped(out_rcvr)`.
- 2. Calls `connect(s, r)`, resulting in an operation state `op_state2`.
+ 2. Calls `connect(sndr, rcvr)`, resulting in an operation state `op_state2`.
3. Returns an operation state `op_state` that contains `op_state2`. When
`start(op_state)` is called, calls `start(op_state2)`.
@@ -6657,24 +6658,22 @@ template<class Domain, class Tag, sender Sender, class... Args>
1. `stopped_as_optional` maps an input sender's stopped completion operation into the value completion operation as an empty optional. The input sender's value completion operation is also converted into an optional. The result is a sender that never completes with stopped, reporting cancellation by completing with an empty optional.
-2. The name `stopped_as_optional` denotes a customization point object. For some subexpression `s`, let `S` be `decltype((s))`.
- The expression `stopped_as_optional(s)` is expression-equivalent to:
+2. The name `stopped_as_optional` denotes a customization point object. For some subexpression `sndr`, let `Sndr` be `decltype((sndr))`.
+ The expression `stopped_as_optional(sndr)` is expression-equivalent to:
transform_sender( - get-sender-domain(s), - make-sender(stopped_as_optional, unspecified, s)) + get-sender-domain(sndr), + make-sender(stopped_as_optional, unspecified, sndr))-3. Let `s` and `e` be subexpressions such that `S` is `decltype((s))` and `E` is `decltype((e))`. - If either
sender-for<S, stopped_as_optional_t>
or single-sender<S, E>
is `false`
- then the expression `stopped_as_optional_t().transform_sender(s, e)` is ill-formed; otherwise, it is equal to:
+3. Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))` and `Env` is `decltype((env))`.
+ If either sender-for<Sndr, stopped_as_optional_t>
or single-sender<Sndr, Env>
is `false`
+ then the expression `stopped_as_optional_t().transform_sender(sndr, env)` is ill-formed; otherwise, it is equal to:
- const auto& env = e; - auto domain = get-env-domain(env); - auto [tag, data, child] = s; - using V = single-sender-value-type<S, E>; + auto [tag, data, child] = sndr; + using V = single-sender-value-type<Sndr, Env>; return let_stopped( then(std::move(child), []<class T>(T&& t) { return optional-4. If(std::forward (t)); }), @@ -6688,22 +6687,20 @@ template<class Domain, class Tag, sender Sender, class... Args> that never completes with stopped, reporting cancellation by completing with an error. -2. The name `stopped_as_error` denotes a customization point object. For some subexpressions `s` and `e`, let `S` be `decltype((s))` and let `E` be `decltype((e))`. If the type `S` does not satisfy `sender` or if the type `E` doesn't satisfy movable-value
, `stopped_as_error(s, e)` is ill-formed. Otherwise, the expression `stopped_as_error(s, e)` is expression-equivalent to: +2. The name `stopped_as_error` denotes a customization point object. For some subexpressions `sndr` and `err`, let `Sndr` be `decltype((sndr))` and let `Err` be `decltype((err))`. If the type `Sndr` does not satisfy `sender` or if the type `Err` doesn't satisfymovable-value
, `stopped_as_error(sndr, err)` is ill-formed. Otherwise, the expression `stopped_as_error(sndr, err)` is expression-equivalent to:transform_sender( - get-sender-domain(s), - make-sender(stopped_as_error, e, s)) + get-sender-domain(sndr), + make-sender(stopped_as_error, err, sndr))-3. Let `s` and `e` be subexpressions such that `S` is `decltype((s))` and `E` is `decltype((e))`. - Ifsender_for<S, stopped_as_error_t>
is `false`, then the expression - `stopped_as_error_t().transform_sender(s, e)` is ill-formed; otherwise, it is equal to: +3. Let `sndr` and `env` be subexpressions such that `Sndr` is `decltype((sndr))` and `Env` is `decltype((env))`. + Ifsender-for<Sndr, stopped_as_error_t>
is `false`, then the expression + `stopped_as_error_t().transform_sender(sndr, env)` is ill-formed; otherwise, it is equal to:- const auto& env = e; - auto domain = get-env-domain(env); - auto [tag, data, child] = s; + auto [tag, data, child] = sndr; return let_stopped( std::move(child), [err = std::move(data)]() mutable { return just_error(std::move(err)); }); @@ -6715,79 +6712,79 @@ template<class Domain, class Tag, sender Sender, class... Args> that is usable as intput to additional sender algorithms. 2. Let- `s2` transfers its ownership of `sh_state` to `op_state`. + `sndr2` transfers its ownership of `sh_state` to `op_state`. 6. When `start(op_state)` is called: - * If `r` has already been completed, then let + * If `rcvr` has already been completed, then letensure-started-env
be the type of an execution - environment such that, given an instance `e`, the expression - `get_stop_token(e)` is well-formed and has type `stop_token`. + environment such that, given an instance `env`, the expression + `get_stop_token(env)` is well-formed and has type `stop_token`. 3. The name `ensure_started` denotes a customization point object. - For some subexpression `s`, let `S` be `decltype((s))`. If -sender_in<S, ensure-started-env>
or - `constructible_from>, env_of_t >` is - `false`, `ensure_started(s)` is ill-formed. Otherwise, the - expression `ensure_started(s)` is expression-equivalent to: + For some subexpression `sndr`, let `Sndr` be `decltype((sndr))`. If +sender_in<Sndr, ensure-started-env>
or + `constructible_from>, env_of_t >` is + `false`, `ensure_started(sndr)` is ill-formed. Otherwise, the + expression `ensure_started(sndr)` is expression-equivalent to: transform_sender( - get-sender-domain(s), - make-sender(ensure_started, s)) + get-sender-domain(sndr), + make-sender(ensure_started, sndr))- 1. Let `s` be a subexpression such that `S` is `decltype((s))`, and let `e...` be a pack of - subexpressions such thatsizeof...(e) <= 1
is `true`. - Ifsender-for<S, ensure_started_t>
is `false`, then the expression - `ensure_started_t().transform_sender(s, e...)` is ill-formed; otherwise, it returns - a sender `s2`, that: + 1. Let `sndr` be a subexpression such that `Sndr` is `decltype((sndr))`, and let `env...` be a pack of + subexpressions such thatsizeof...(env) <= 1
is `true`. + Ifsender-for<Sndr, ensure_started_t>
is `false`, then the expression + `ensure_started_t().transform_sender(sndr, env...)` is ill-formed; otherwise, it returns + a sender `sndr2`, that: 1. Creates an object `sh_state` that contains a `stop_source`, an initially null pointer to an operation state awaitaing completion, and that also reserves space for storing: - * the operation state that results from connecting `s` with `r` described below, and - * the sets of values and errors with which `s` can complete, with + * the operation state that results from connecting `sndr` with `rcvr` described below, and + * the sets of values and errors with which `sndr` can complete, with the addition of `exception_ptr`. - * the result of decay-copying `get_env(s)`. + * the result of decay-copying `get_env(sndr)`. - `s2` shares ownership of `sh_state` with `r` described below. + `sndr2` shares ownership of `sh_state` with `rcvr` described below. - 2. Constructs a receiver `r` such that: + 2. Constructs a receiver `rcvr` such that: - 1. When `set_value(r, args...)` is called, decay-copies + 1. When `set_value(rcvr, args...)` is called, decay-copies the expressions `args...` into `sh_state`. It then checks `sh_state` to see if there is an operation state awaiting completion; if so, it notifies the operation state that the results are ready. If any exceptions are thrown, the exception - is caught and `set_error(r, current_exception())` is + is caught and `set_error(rcvr, current_exception())` is called instead. - 2. When `set_error(r, e)` is called, decay-copies `e` + 2. When `set_error(rcvr, err)` is called, decay-copies `err` into `sh_state`. If there is an operation state awaiting completion, it then notifies the operation state that the results are ready. - 3. When `set_stopped(r)` is called, it then notifies any + 3. When `set_stopped(rcvr)` is called, it then notifies any awaiting operation state that the results are ready. - 4. `get_env(r)` is an expressione
of type + 4. `get_env(rcvr)` is an expressionenv
of typeensure-started-env
such that -get_stop_token(e)
is well-formed +get_stop_token(env)
is well-formed and returns the results of calling `get_token()` on `sh_state`'s stop source. - 5. `r` shares ownership of `sh_state` with `s2`. After `r` + 5. `rcvr` shares ownership of `sh_state` with `sndr2`. After `rcvr` has been completed, it releases its ownership of `sh_state`. - 3. Calls `get_env(s)` and decay-copies the result into + 3. Calls `get_env(sndr)` and decay-copies the result into `sh_state`. - 4. Calls `connect(s, r)`, resulting in an operation state + 4. Calls `connect(sndr, rcvr)`, resulting in an operation state `op_state2`. `op_state2` is saved in `sh_state`. It then calls `start(op_state2)`. - 5. When `s2` is connected with a receiver `out_r` of type `OutR`, it + 5. When `sndr2` is connected with a receiver `out_rcvr` of type `OutRcvr`, it returns an operation state object `op_state` that contains: - * An object `out_r2` of type `OutR` decay-copied from `out_r`, + * An object `out_rcvr2` of type `OutRcvr` decay-copied from `out_rcvr`, * A reference to `sh_state`, * A stop callback of type -optional<stop_token_of_t<env_of_t<OutR>>::callback_type<stop-callback-fn>>
, +optional<stop_token_of_t<env_of_t<OutRcvr>>::callback_type<stop-callback-fn>>
, wherestop-callback-fn
is the unspecified class type: @@ -6800,62 +6797,62 @@ template<class Domain, class Tag, sender Sender, class... Args> };CF
be whichever completion function - was used to complete `r`. Calls -CF(out_r2, args2...)
, where `args2...` is a + was used to complete `rcvr`. Calls +CF(out_rcvr2, args2...)
, where `args2...` is a pack of xvalues referencing the subobjects of `sh_state` that have - been saved by the original call toCF(r, + been saved by the original call to
CF(rcvr, args...)
and returns. * Otherwise, it emplace constructs the stop callback optional with - the arguments `get_stop_token(get_env(out_r2))` and + the arguments `get_stop_token(get_env(out_rcvr2))` andstop-callback-fn{stop-src}
, wherestop-src
refers to the stop source of `sh_state`. * Then, it checks to see ifstop-src.stop_requested()
is `true`. If so, it - calls `set_stopped(out_r2)`. + calls `set_stopped(out_rcvr2)`. * Otherwise, it sets `sh_state` operation state pointer to the address of `op_state`, registering itself as awaiting the result - of the completion of `r`. + of the completion of `rcvr`. - 7. When `r` completes it will notify `op_state` that the result are + 7. When `rcvr` completes it will notify `op_state` that the result are ready. LetCF
be whichever - completion function was used to complete `r`. `op_state`'s stop + completion function was used to complete `rcvr`. `op_state`'s stop callback optional is reset. Then -CF(std::move(out_r2), args2...)
is called, +CF(std::move(out_rcvr2), args2...)
is called, where `args2...` is a pack of xvalues referencing the subobjects of `sh_state` that have been saved by the original call to -CF(r, args...)
. +CF(rcvr, args...)
. - 8. [*Note:* If sender `s2` is destroyed without being connected to a + 8. [*Note:* If sender `sndr2` is destroyed without being connected to a receiver, or if it is connected but the operation state is destroyed - without having been started, then when `r` + without having been started, then when `rcvr` completes and it releases its shared ownership of `sh_state`, `sh_state` will be destroyed and the results of the operation are discarded. -- *end note*] - 4. Given a subexpression `s`, let `s2` be the result of `ensure_started(s)`. - The result of `get_env(s2)` shall return an lvalue reference to the - object in `sh_state` that was initialized with the result of `get_env(s)`. + 4. Given a subexpression `sndr`, let `sndr2` be the result of `ensure_started(sndr)`. + The result of `get_env(sndr2)` shall return an lvalue reference to the + object in `sh_state` that was initialized with the result of `get_env(sndr)`. - 4. Let `s` be a sender expression, `r` be an instance of the receiver type - described above, `s2` be a sender returned - from `ensure_started(s)` or a copy of such, `r2` is the receiver - to which `s2` is connected, and `args` is the pack of subexpressions - passed to `r`'s completion functionCSO
- when `s` completes. `s2` shall invokeCSO(r2, args2...)
where + 4. Let `sndr` be a sender expression, `rcvr` be an instance of the receiver type + described above, `sndr2` be a sender returned + from `ensure_started(sndr)` or a copy of such, `rcvr2` is the receiver + to which `sndr2` is connected, and `args` is the pack of subexpressions + passed to `rcvr`'s completion functionCSO
+ when `sndr` completes. `sndr2` shall invokeCSO(rcvr2, args2...)
where `args2` is a pack of xvalue references to objects decay-copied from - `args`, or by callingset_error(r2, e2)
for some subexpression - `e2`. The objects passed to `r2`'s completion operation shall - be valid until after the completion of the invocation of `r2`'s completion + `args`, or by callingset_error(rcvr2, err2)
for some subexpression + `err2`. The objects passed to `rcvr2`'s completion operation shall + be valid until after the completion of the invocation of `rcvr2`'s completion operation. ### Sender consumers [exec.consumers] ### {#spec-execution.senders.consumers} @@ -6866,22 +6863,22 @@ template<class Domain, class Tag, sender Sender, class... Args> the lifetimes of any objects. 2. The name `start_detached` denotes a customization point object. For some - subexpression `s`, let `S` be `decltype((s))`. If `S` does not satisfy -sender_in<empty_env>
, `start_detached` is ill-formed. - Otherwise, the expression `start_detached(s)` is expression-equivalent to: + subexpression `sndr`, let `Sndr` be `decltype((sndr))`. If + `sender_in` is `false`, `start_detached` is ill-formed. + Otherwise, the expression `start_detached(sndr)` is expression-equivalent to: - apply_sender(get-sender-domain(s), start_detached, s) + apply_sender(get-sender-domain(sndr), start_detached, sndr)* Mandates: The type of the expression above is `void`. - If the expression above does not eagerly start the sender `s` after + If the expression above does not eagerly start the sender `sndr` after connecting it with a receiver that ignores value and stopped completion operations and calls `terminate()` on error completions, the behavior of - calling `start_detached(s)` is undefined. + calling `start_detached(sndr)` is undefined. -3. Let `s` be a subexpression such that `S` is `decltype((s))`, and let +3. Let `sndr` be a subexpression such that `Sndr` is `decltype((sndr))`, and letdetached-receiver
anddetached-operation
be the following exposition-only class types: @@ -6898,18 +6895,18 @@ template<class Domain, class Tag, sender Sender, class... Args> }; struct detached-operation { - connect_result_t<S, detached-receiver> op; // exposition only + connect_result_t<Sndr, detached-receiver> op; // exposition only - explicit detached-operation(S&& s) - : op(connect(std::forward<S>(s), detached-receiver{this})) + explicit detached-operation(Sndr&& sndr) + : op(connect(std::forward<Sndr>(sndr), detached-receiver{this})) {} };
sender_to<S, detached-receiver>
is `false`, the
- expression `start_detached.apply_sender(s)` is ill-formed; otherwise, it is
+4. If sender_to<Sndr, detached-receiver>
is `false`, the
+ expression `start_detached.apply_sender(sndr)` is ill-formed; otherwise, it is
expression-equivalent to start(*new
- detached-operation(s))
.
+ detached-operation(sndr)).
#### `this_thread::sync_wait` [exec.sync.wait] #### {#spec-execution.senders.consumers.sync_wait}
@@ -6918,9 +6915,9 @@ template<class Domain, class Tag, sender Sender, class... Args>
completed, and to obtain the values (if any) it completed with. `sync_wait`
requires that the input sender has exactly one value completion signature.
-2. For any receiver `r` created by an implementation of `sync_wait` and
- `sync_wait_with_variant`, the expressions `get_scheduler(get_env(r))` and
- `get_delegatee_scheduler(get_env(r))` shall be well-formed. For a receiver
+2. For any receiver `rcvr` created by an implementation of `sync_wait` and
+ `sync_wait_with_variant`, the expressions `get_scheduler(get_env(rcvr))` and
+ `get_delegatee_scheduler(get_env(rcvr))` shall be well-formed. For a receiver
created by the default implementation of `this_thread::sync_wait`, these
expressions shall return a scheduler to the same thread-safe,
first-in-first-out queue of work such that tasks scheduled to the queue
@@ -6932,61 +6929,61 @@ template<class Domain, class Tag, sender Sender, class... Args>
sync-wait-with-variant-type
are used to determine the
return types of `this_thread::sync_wait` and
`this_thread::sync_wait_with_variant`. Let sync-wait-env
- be the type of the expression `get_env(r)` where `r` is an instance of the
+ be the type of the expression `get_env(rcvr)` where `rcvr` is an instance of the
receiver created by the default implementation of `sync_wait`.
- template<sender_in<sync-wait-env> S> + template<sender_in<sync-wait-env> Sndr> using sync-wait-type = - optional<value_types_of_t<S, sync-wait-env, decayed-tuple, type_identity_t>>; + optional<value_types_of_t<Sndr, sync-wait-env, decayed-tuple, type_identity_t>>; - template<sender_in<sync-wait-env> S> - using sync-wait-with-variant-type = optional<into-variant-type<S, sync-wait-env>>; + template<sender_in<sync-wait-env> Sndr> + using sync-wait-with-variant-type = optional<into-variant-type<Sndr, sync-wait-env>>;4. The name `this_thread::sync_wait` denotes a customization point object. For - some subexpression `s`, let `S` be `decltype((s))`. If -
sender_in<S, sync-wait-env>
is `false`,
- or if the type `completion_signatures_of_t<S, sync-wait-env, type-list, type_identity_t>` is ill-formed,
- `this_thread::sync_wait(s)` is ill-formed.
- Otherwise, `this_thread::sync_wait(s)` is expression-equivalent to:
+ some subexpression `sndr`, let `Sndr` be `decltype((sndr))`. If
+ sender_in<Sndr, sync-wait-env>
is `false`,
+ or if the type completion_signatures_of_t<Sndr, sync-wait-env, type-list, type_identity_t>
is ill-formed,
+ `this_thread::sync_wait(sndr)` is ill-formed.
+ Otherwise, `this_thread::sync_wait(sndr)` is expression-equivalent to:
- apply_sender(get_sender-domain(s), sync_wait, s) + apply_sender(get_sender-domain(sndr), sync_wait, sndr)- * Mandates: The type of the expression above is
sync-wait-type<S, sync-wait-env>
.
+ * Mandates: The type of the expression above is sync-wait-type<Sndr, sync-wait-env>
.
-5. Let sync-wait-receiver
be a class type that satisfies `receiver`, let `r` be an xvalue of that type,
- and let `cr` be a const lvalue refering to `r` such that `get_env(cr)` has type sync-wait-env
.
- If sender_in<S, sync-wait-env>
is `false`, or if the type
- completion_signatures_of_t<S, sync-wait-env, type-list, type_identity_t>
is ill-formed,
- the expression `sync_wait_t().apply_sender(s)` is ill-formed; otherwise it has the following effects:
+5. Let sync-wait-receiver
be a class type that satisfies `receiver`, let `rcvr` be an xvalue of that type,
+ and let `crcvr` be a const lvalue refering to `rcvr` such that `get_env(crcvr)` has type sync-wait-env
.
+ If sender_in<Sndr, sync-wait-env>
is `false`, or if the type
+ completion_signatures_of_t<Sndr, sync-wait-env, type-list, type_identity_t>
is ill-formed,
+ the expression `sync_wait_t().apply_sender(sndr)` is ill-formed; otherwise it has the following effects:
- 1. Calls `connect(s, r)`, resulting in an operation state `op_state`, then calls `start(op_state)`.
+ 1. Calls `connect(sndr, rcvr)`, resulting in an operation state `op_state`, then calls `start(op_state)`.
- 2. Blocks the current thread until a completion operation of `r` is executed. When it is:
+ 2. Blocks the current thread until a completion operation of `rcvr` is executed. When it is:
- 1. If `set_value(r, ts...)` has been called, returns sync-wait-type<S, sync-wait-env>{decayed-tuple<decltype(ts)...>{ts...}}
. If that expression exits exceptionally, the exception is propagated to the caller of `sync_wait`.
+ 1. If `set_value(rcvr, ts...)` has been called, returns sync-wait-type<Sndr, sync-wait-env>{decayed-tuple<decltype(ts)...>{ts...}}
. If that expression exits exceptionally, the exception is propagated to the caller of `sync_wait`.
- 2. If `set_error(r, e)` has been called, let `E` be the decayed type of `e`. If `E` is `exception_ptr`, calls `std::rethrow_exception(e)`. Otherwise, if the `E` is `error_code`, throws `system_error(e)`. Otherwise, throws `e`.
+ 2. If `set_error(rcvr, err)` has been called, let `Err` be the decayed type of `err`. If `Err` is `exception_ptr`, calls `rethrow_exception(err)`. Otherwise, if the `Err` is `error_code`, throws `system_error(err)`. Otherwise, throws `err`.
- 3. If `set_stopped(r)` has been called, returns sync-wait-type<S, sync-wait-env>{}
.
+ 3. If `set_stopped(rcvr)` has been called, returns sync-wait-type<Sndr, sync-wait-env>{}
.
6. The name `this_thread::sync_wait_with_variant` denotes a customization point
- object. For some subexpression `s`, let `S` be the type of
- `into_variant(s)`. If sender_in<S,
+ object. For some subexpression `sndr`, let `Sndr` be the type of
+ `into_variant(sndr)`. If sender_in<Sndr,
sync-wait-env>
is `false`,
- `this_thread::sync_wait_with_variant(s)` is ill-formed. Otherwise,
- `this_thread::sync_wait_with_variant(s)` is expression-equivalent to:
+ `this_thread::sync_wait_with_variant(sndr)` is ill-formed. Otherwise,
+ `this_thread::sync_wait_with_variant(sndr)` is expression-equivalent to:
- apply_sender(get-sender-domain(s), sync_wait_with_variant, s)
+ apply_sender(get-sender-domain(sndr), sync_wait_with_variant, sndr)
- * Mandates: The type of the expression above is sync-wait-with-variant-type<S, sync-wait-env>
.
+ * Mandates: The type of the expression above is sync-wait-with-variant-type<Sndr, sync-wait-env>
.
-7. The expression `sync_wait_with_variant_t().apply_sender(s)` is expression-equivalent to `this_thread::sync_wait(into_variant(s))`.
+7. The expression `sync_wait_with_variant_t().apply_sender(sndr)` is expression-equivalent to `this_thread::sync_wait(into_variant(sndr))`.
## `execution::execute` [exec.execute] ## {#spec-execution.execute}
@@ -7002,10 +6999,10 @@ template<class Domain, class Tag, sender Sender, class... Args>
* Mandates: The type of the expression above is `void`.
-3. For some subexpressions `s` and `f` where `F` is `decltype((f))`,
+3. For some subexpressions `sndr` and `f` where `F` is `decltype((f))`,
if `F` does not satisfy `invocable`, the expression
- `execute_t().apply_sender(s, f)` is ill-formed; otherwise it is
- expression-equivalent to `start_detached(then(s, f))`.
+ `execute_t().apply_sender(sndr, f)` is ill-formed; otherwise it is
+ expression-equivalent to `start_detached(then(sndr, f))`.
## Sender/receiver utilities [exec.utils] ## {#spec-execution.snd_rec_utils}
@@ -7015,8 +7012,8 @@ template<class Domain, class Tag, sender Sender, class... Args>
// [Editorial note: copy_cvref_t as in [[P1450R3]] -- end note]
// Mandates: is_base_of_v<T, remove_reference_t<U>> is true
template<class T, class U>
- copy_cvref_t<U&&, T> c-style-cast(U&& u) noexcept requires decays-to<T, T> {
- return (copy_cvref_t<U&&, T>) std::forward<U>(u);
+ copy_cvref_t<U&&, T> c-style-cast(U&& u) noexcept requires decays-to<T, T> {
+ return (copy_cvref_t<U&&, T>) std::forward<U>(u);
}
@@ -7071,20 +7068,20 @@ template<class Domain, class Tag, sender Sender, class... Args>
// Member functions
template<class Self>
requires HAS-BASE
- decltype(auto) base(this Self&& self) noexcept {
+ decltype(auto) base(this Self&& self) noexcept {
return (std::forward<Self>(self).base_);
}
// [exec.utils.rcvr.adptr.nonmembers] Non-member functions
template<class... As>
- friend void tag_invoke(set_value_t, Derived&& self, As&&... as) noexcept;
+ friend void tag_invoke(set_value_t, Derived&& self, As&&... as) noexcept;
- template<class E>
- friend void tag_invoke(set_error_t, Derived&& self, E&& e) noexcept;
+ template<class Err>
+ friend void tag_invoke(set_error_t, Derived&& self, Err&& err) noexcept;
- friend void tag_invoke(set_stopped_t, Derived&& self) noexcept;
+ friend void tag_invoke(set_stopped_t, Derived&& self) noexcept;
- friend decltype(auto) tag_invoke(get_env_t, const Derived& self)
+ friend decltype(auto) tag_invoke(get_env_t, const Derived& self)
noexcept(see below);
[[no_unique_address]] Base base_; // present if and only if HAS-BASE is true
@@ -7100,14 +7097,14 @@ template<class Domain, class Tag, sender Sender, class... Args>
using _int_completion =
completion_signatures<set_value_t(int)>;
- template<receiver_of<_int_completion> R>
- class my_receiver : receiver_adaptor<my_receiver<R>, R> {
- friend receiver_adaptor<my_receiver, R>;
+ template<receiver_of<_int_completion> Rcvr>
+ class my_receiver : receiver_adaptor<my_receiver<Rcvr>, Rcvr> {
+ friend receiver_adaptor<my_receiver, Rcvr>;
void set_value() && {
set_value(std::move(*this).base(), 42);
}
public:
- using receiver_adaptor<my_receiver, R>::receiver_adaptor;
+ using receiver_adaptor<my_receiver, Rcvr>::receiver_adaptor;
};
-- end example]
@@ -7116,7 +7113,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
template<class... As>
- friend void tag_invoke(set_value_t, Derived&& self, As&&... as) noexcept;
+ friend void tag_invoke(set_value_t, Derived&& self, As&&... as) noexcept;
1. Let `SET-VALUE-MBR` be the expression `std::move(self).set_value(std::forward(as)...)`.
@@ -7132,13 +7129,13 @@ template<class Domain, class Tag, sender Sender, class... Args>
* Otherwise, set_value(GET-BASE(std::move(self)), std::forward<As>(as)...)
.
- template<class E>
- friend void tag_invoke(set_error_t, Derived&& self, E&& e) noexcept;
+ template<class Err>
+ friend void tag_invoke(set_error_t, Derived&& self, Err&& err) noexcept;
- 1. Let `SET-ERROR-MBR` be the expression `std::move(self).set_error(std::forward(e))`.
+ 1. Let `SET-ERROR-MBR` be the expression `std::move(self).set_error(std::forward(err))`.
- 2. Constraints: Either `SET-ERROR-MBR` is a valid expression or `typename Derived::set_error` denotes a type and callable<set_error_t, BASE-TYPE(Derived), E>
is `true`.
+ 2. Constraints: Either `SET-ERROR-MBR` is a valid expression or `typename Derived::set_error` denotes a type and callable<set_error_t, BASE-TYPE(Derived), Err>
is `true`.
3. Mandates: `SET-ERROR-MBR`, if that expression is valid, is not potentially-throwing.
@@ -7146,10 +7143,10 @@ template<class Domain, class Tag, sender Sender, class... Args>
* If `SET-ERROR-MBR` is a valid expression, `SET-ERROR-MBR`;
- * Otherwise, set_error(GET-BASE(std::move(self)), std::forward<E>(e))
.
+ * Otherwise, set_error(GET-BASE(std::move(self)), std::forward<Err>(err))
.
- friend void tag_invoke(set_stopped_t, Derived&& self) noexcept;
+ friend void tag_invoke(set_stopped_t, Derived&& self) noexcept;
1. Let `SET-STOPPED-MBR` be the expression `std::move(self).set_stopped()`.
@@ -7165,23 +7162,23 @@ template<class Domain, class Tag, sender Sender, class... Args>
* Otherwise, set_stopped(GET-BASE(std::move(self)))
.
- friend decltype(auto) tag_invoke(get_env_t, const Derived& self)
+ friend decltype(auto) tag_invoke(get_env_t, const Derived& self)
noexcept(see below);
- 1. Constraints: Either `self.get_env()` is a valid expression or `typename Derived::get_env` denotes a type and callable<get_env_t, BASE-TYPE(const Derived&)>
is `true`.
+ 1. Constraints: Either `self.get_env()` is a valid expression or `typename Derived::get_env` denotes a type and callable<get_env_t, BASE-TYPE(const Derived&)>
is `true`.
2. Effects: Equivalent to:
* If `self.get_env()` is a valid expression, `self.get_env()`;
- * Otherwise, std::get_env(GET-BASE(self))
.
+ * Otherwise, get_env(GET-BASE(self))
.
3. Remarks: The expression in the `noexcept` clause is:
* If `self.get_env()` is a valid expression, `noexcept(self.get_env())`;
- * Otherwise, noexcept(std::get_env(GET-BASE(self)))
.
+ * Otherwise, noexcept(get_env(GET-BASE(self)))
.
### `execution::completion_signatures` [exec.utils.cmplsigs] ### {#spec-execution.snd_rec_utils.completion_sigs}
@@ -7201,12 +7198,12 @@ template<class Domain, class Tag, sender Sender, class... Args>
};
// Declares my_sender to be a sender that can complete by calling
- // one of the following for a receiver expression R:
- // set_value(R)
- // set_value(R, int{...}, float{...})
- // set_error(R, exception_ptr{...})
- // set_error(R, error_code{...})
- // set_stopped(R)
+ // one of the following for a receiver expression rcvr:
+ // set_value(rcvr)
+ // set_value(rcvr, int{...}, float{...})
+ // set_error(rcvr, exception_ptr{...})
+ // set_error(rcvr, error_code{...})
+ // set_stopped(rcvr)
-- end example]
@@ -7229,7 +7226,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
1. A type `Fn` satisfies completion-signature
if and only if it is a function type with one of the following forms:
* set_value_t(Vs...)
, where Vs
is an arbitrary parameter pack.
- * set_error_t(E)
, where E
is an arbitrary type.
+ * set_error_t(Err)
, where Err
is an arbitrary type.
* `set_stopped_t()`
@@ -7269,27 +7266,27 @@ template<class Domain, class Tag, sender Sender, class... Args>
template<completion-signature... Fns>
struct completion_signatures {};
- template<class S,
- class E = empty_env,
+ template<class Sndr,
+ class Env = empty_env,
template<class...> class Tuple = decayed-tuple,
template<class...> class Variant = variant-or-empty>
- requires sender_in<S, E>
+ requires sender_in<Sndr, Env>
using value_types_of_t =
- gather-signatures<set_value_t, completion_signatures_of_t<S, E>, Tuple, Variant>;
+ gather-signatures<set_value_t, completion_signatures_of_t<Sndr, Env>, Tuple, Variant>;
- template<class S,
- class E = empty_env,
+ template<class Sndr,
+ class Env = empty_env,
template<class...> class Variant = variant-or-empty>
- requires sender_in<S, E>
+ requires sender_in<Sndr, Env>
using error_types_of_t =
- gather-signatures<set_error_t, completion_signatures_of_t<S, E>, type_identity_t, Variant>;
+ gather-signatures<set_error_t, completion_signatures_of_t<Sndr, Env>, type_identity_t, Variant>;
- template<class S, class E = empty_env>
- requires sender_in<S, E>
+ template<class Sndr, class Env = empty_env>
+ requires sender_in<Sndr, Env>
inline constexpr bool sends_stopped =
!same_as<
type-list<>,
- gather-signatures<set_stopped_t, completion_signatures_of_t<S, E>, type-list, type-list>>;
+ gather-signatures<set_stopped_t, completion_signatures_of_t<Sndr, Env>, type-list, type-list>>;
### `execution::transform_completion_signatures` [exec.utils.tfxcmplsigs] ### {#spec-execution.snd_rec_utils.transform_completion_sigs}
@@ -7302,8 +7299,8 @@ template<class Domain, class Tag, sender Sender, class... Args>
2. [Example:
- // Given a sender S and an environment Env, adapt the completion
- // signatures of S by lvalue-ref qualifying the values, adding an additional
+ // Given a sender Sndr and an environment Env, adapt the completion
+ // signatures of Sndr by lvalue-ref qualifying the values, adding an additional
// exception_ptr error completion if its not already there, and leaving the
// other completion signatures alone.
template<class... Args>
@@ -7313,7 +7310,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
using my_completion_signatures =
transform_completion_signatures<
- completion_signatures_of_t<S, Env>,
+ completion_signatures_of_t<Sndr, Env>,
completion_signatures<set_error_t(exception_ptr)>,
my_set_value_t>;
@@ -7401,7 +7398,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
run_loop* loop_;
run-loop-opstate-base* next_;
};
- template<receiver_of<completion_signatures<set_value_t()>> R>
+ template<receiver_of<completion_signatures<set_value_t()>> Rcvr>
using run-loop-opstate = unspecified; // exposition only
// [exec.run.loop.members] Member functions:
@@ -7447,28 +7444,28 @@ template<class Domain, class Tag, sender Sender, class... Args>
2. An instance of run-loop-sender
remains valid until the
end of the lifetime of its associated `run_loop` instance.
- 3. Let s
be an expression of type
- run-loop-sender
, let r
be an
- expression such that decltype(r)
models the
+ 3. Let sndr
be an expression of type
+ run-loop-sender
, let rcvr
be an
+ expression such that decltype(rcvr)
models the
`receiver_of` concept, and let `C` be either `set_value_t` or
`set_stopped_t`. Then:
- * The expression connect(s, r)
has type run-loop-opstate<decay_t<decltype(r)>>
and is potentially-throwing if and only if the initialiation of decay_t<decltype(r)>
from r
is potentially-throwing.
+ * The expression connect(sndr, rcvr)
has type run-loop-opstate<decay_t<decltype(rcvr)>>
and is potentially-throwing if and only if the initialiation of decay_t<decltype(rcvr)>
from rcvr
is potentially-throwing.
- * The expression get_completion_scheduler<C>(get_env(s))
is not potentially-throwing, has type run-loop-scheduler
, and compares equal to the run-loop-scheduler
instance from which s
was obtained.
+ * The expression get_completion_scheduler<C>(get_env(sndr))
is not potentially-throwing, has type run-loop-scheduler
, and compares equal to the run-loop-scheduler
instance from which sndr
was obtained.
- template<receiver_of<completion_signatures<set_value_t()>> R> // arguments are not associated entities ([lib.tmpl-heads])
+ template<receiver_of<completion_signatures<set_value_t()>> Rcvr> // arguments are not associated entities ([lib.tmpl-heads])
struct run-loop-opstate;
- 1. run-loop-opstate<R>
inherits unambiguously from run-loop-opstate-base
.
+ 1. run-loop-opstate<Rcvr>
inherits unambiguously from run-loop-opstate-base
.
- 2. Let o
be a non-`const` lvalue of type run-loop-opstate<R>
, and let REC(o)
be a non-`const` lvalue reference to an instance of type R
that was initialized with the expression r
passed to the invocation of `connect` that returned o
. Then:
+ 2. Let o
be a non-`const` lvalue of type run-loop-opstate<Rcvr>
, and let REC(o)
be a non-`const` lvalue reference to an instance of type Rcvr
that was initialized with the expression rcvr
passed to the invocation of `connect` that returned o
. Then:
* The object to which REC(o)
refers remains valid for the lifetime of the object to which o
refers.
- * The type run-loop-opstate<R>
overrides run-loop-opstate-base::execute()
such that o.execute()
is equivalent to the following:
+ * The type run-loop-opstate<Rcvr>
overrides run-loop-opstate-base::execute()
such that o.execute()
is equivalent to the following:
if (get_stop_token(REC(o)).stop_requested()) {
@@ -7561,54 +7558,51 @@ template<class Domain, class Tag, sender Sender, class... Args>
1. `as_awaitable` transforms an object into one that is awaitable within a particular coroutine. This subclause makes use of the following exposition-only entities:
- template<class S, class E>
+ template<class Sndr, class Env>
using single-sender-value-type = see below;
- template<class S, class E>
+ template<class Sndr, class Env>
concept single-sender =
- sender_in<S, E> &&
- requires { typename single-sender-value-type<S, E>; };
+ sender_in<Sndr, Env> &&
+ requires { typename single-sender-value-type<Sndr, Env>; };
- template<class S, class P>
+ template<class Sndr, class Promise>
concept awaitable-sender =
- single-sender<S, ENV-OF(P)> &&
- sender_to<S, awaitable-receiver> && // see below
- requires (P& p) {
+ single-sender<Sndr, env_of_t> &&
+ sender_to<Sndr, awaitable-receiver> && // see below
+ requires (Promise& p) {
{ p.unhandled_stopped() } -> convertible_to<coroutine_handle<>>;
};
- template<class S, class P>
+ template<class Sndr, class Promise>
class sender-awaitable;
- where ENV-OF(P)
names the type `env_of_t` if that type
- is well-formed, or empty_env
otherwise.
-
1. Alias template single-sender-value-type is defined as follows:
- 1. If `value_types_of_t` would have the form `Variant>`, then single-sender-value-type<S, E>
is an alias for type `decay_t`.
+ 1. If `value_types_of_t` would have the form `Variant>`, then single-sender-value-type<Sndr, Env>
is an alias for type `decay_t`.
- 2. Otherwise, if `value_types_of_t` would have the form `Variant>` or `Variant<>`, then single-sender-value-type<S, E>
is an alias for type `void`.
+ 2. Otherwise, if `value_types_of_t` would have the form `Variant>` or `Variant<>`, then single-sender-value-type<Sndr, Env>
is an alias for type `void`.
- 3. Otherwise, single-sender-value-type<S, E>
is ill-formed.
+ 3. Otherwise, single-sender-value-type<Sndr, Env>
is ill-formed.
- 2. The type sender-awaitable<S, P>
is equivalent to the following:
+ 2. The type sender-awaitable<Sndr, Promise>
is equivalent to the following:
- template<class S, class P> // arguments are not associated entities ([lib.tmpl-heads])
+ template<class Sndr, class Promise> // arguments are not associated entities ([lib.tmpl-heads])
class sender-awaitable {
struct unit {};
- using value_t = single-sender-value-type<S, ENV-OF(P)>;
+ using value_t = single-sender-value-type<Sndr, env_of_t>;
using result_t = conditional_t<is_void_v<value_t>, unit, value_t>;
struct awaitable-receiver;
variant<monostate, result_t, exception_ptr> result_{};
- connect_result_t<S, awaitable-receiver> state_;
+ connect_result_t<Sndr, awaitable-receiver> state_;
public:
- sender-awaitable(S&& s, P& p);
+ sender-awaitable(Sndr&& sndr, Promise& p);
bool await_ready() const noexcept { return false; }
- void await_suspend(coroutine_handle<P>) noexcept { start(state_); }
+ void await_suspend(coroutine_handle<Promise>) noexcept { start(state_); }
value_t await_resume();
};
@@ -7619,31 +7613,31 @@ template<class Domain, class Tag, sender Sender, class... Args>
struct awaitable-receiver {
using receiver_concept = receiver_t;
variant<monostate, result_t, exception_ptr>* result_ptr_;
- coroutine_handle<P> continuation_;
+ coroutine_handle<Promise> continuation_;
// ... see below
};
- Let `r` be an rvalue expression of type awaitable-receiver
, let `cr` be a `const` lvalue that refers to `r`, let `vs...` be an arbitrary function parameter pack of types `Vs...`, and let `err` be an arbitrary expression of type `Err`. Then:
+ Let `rcvr` be an rvalue expression of type awaitable-receiver
, let `crcvr` be a `const` lvalue that refers to `rcvr`, let `vs` be a parameter pack of types `Vs...`, and let `err` be an arbitrary expression of type `Err`. Then:
- 1. If `constructible_from` is satisfied, the expression `set_value(r, vs...)` is equivalent to:
+ 1. If `constructible_from` is satisfied, the expression `set_value(rcvr, vs...)` is equivalent to:
try {
- r.result_ptr_->emplace<1>(vs...);
+ rcvr.result_ptr_->emplace<1>(vs...);
} catch(...) {
- r.result_ptr_->emplace<2>(current_exception());
+ rcvr.result_ptr_->emplace<2>(current_exception());
}
- r.continuation_.resume();
+ rcvr.continuation_.resume();
- Otherwise, `set_value(r, vs...)` is ill-formed.
+ Otherwise, `set_value(rcvr, vs...)` is ill-formed.
- 2. The expression `set_error(r, err)` is equivalent to:
+ 2. The expression `set_error(rcvr, err)` is equivalent to:
- r.result_ptr_->emplace<2>(AS-EXCEPT-PTR(err));
- r.continuation_.resume();
+ rcvr.result_ptr_->emplace<2>(AS-EXCEPT-PTR(err));
+ rcvr.continuation_.resume();
where AS-EXCEPT-PTR(err)
is:
@@ -7654,49 +7648,49 @@ template<class Domain, class Tag, sender Sender, class... Args>
3. Otherwise, `make_exception_ptr(err)`.
- 3. The expression `set_stopped(r)` is equivalent to
- static_cast<coroutine_handle<>>(r.continuation_.promise().unhandled_stopped()).resume()
.
+ 3. The expression `set_stopped(rcvr)` is equivalent to
+ static_cast<coroutine_handle<>>(rcvr.continuation_.promise().unhandled_stopped()).resume()
.
4. For any expression `tag` whose type satisfies forwarding-query
- and for any pack of subexpressions `as`, `tag_invoke(tag, get_env(cr), as...)`
- is expression-equivalent to tag(get_env(as_const(cr.continuation_.promise())),
+ and for any pack of subexpressions `as`, `tag_invoke(tag, get_env(crcvr), as...)`
+ is expression-equivalent to tag(get_env(as_const(crcvr.continuation_.promise())),
as...)
when that expression is well-formed.
- 2. sender-awaitable::sender-awaitable(S&& s, P& p)
+ 2. sender-awaitable::sender-awaitable(Sndr&& sndr, Promise& p)
- - Effects: initializes `state_` with connect(std::forward<S>(s), awaitable-receiver{&result_, coroutine_handle<P>::from_promise(p)})
.
+ - Effects: initializes `state_` with connect(std::forward<Sndr>(sndr), awaitable-receiver{&result_, coroutine_handle<Promise>::from_promise(p)})
.
3. value_t sender-awaitable::await_resume()
- Effects: equivalent to:
- if (result_.index()) == 2)
+ if (result_.index() == 2)
rethrow_exception(get<2>(result_));
if constexpr (!is_void_v<value_t>)
return std::forward<value_t>(get<1>(result_));
-2. `as_awaitable` is a customization point object. For some subexpressions `e` and `p` where `p` is an lvalue, `E` names the type `decltype((e))` and `P` names the type `decltype((p))`, `as_awaitable(e, p)` is expression-equivalent to the following:
+2. `as_awaitable` is a customization point object. For some subexpressions `expr` and `p` where `p` is an lvalue, `Expr` names the type `decltype((expr))` and `Promise` names the type `decltype((p))`, `as_awaitable(expr, p)` is expression-equivalent to the following:
- 1. `tag_invoke(as_awaitable, e, p)` if that expression is well-formed.
+ 1. `tag_invoke(as_awaitable, expr, p)` if that expression is well-formed.
- * Mandates: is-awaitable<A, P>
is `true`, where `A` is the type of the `tag_invoke` expression above.
+ * Mandates: is-awaitable<A, Promise>
is `true`, where `A` is the type of the `tag_invoke` expression above.
- 2. Otherwise, `e` if is-awaitable<E, U>
is
+ 2. Otherwise, `expr` if is-awaitable<Expr, U>
is
`true`, where U
is an unspecified class type that
lacks a member named `await_transform`. The
- condition is not is-awaitable<E, P>
as that
+ condition is not is-awaitable<Expr, Promise>
as that
creates the potential for constraint recursion.
- * Preconditions: is-awaitable<E, P>
is
- `true` and the expression `co_await e` in a coroutine with promise
+ * Preconditions: is-awaitable<Expr, Promise>
is
+ `true` and the expression `co_await expr` in a coroutine with promise
type U
is expression-equivalent to the same
- expression in a coroutine with promise type `P`.
+ expression in a coroutine with promise type `Promise`.
- 3. Otherwise, sender-awaitable{e, p}
if awaitable-sender<E, P>
is `true`.
+ 3. Otherwise, sender-awaitable{expr, p}
if awaitable-sender<Expr, Promise>
is `true`.
- 4. Otherwise, `e`.
+ 4. Otherwise, `expr`.
### `execution::with_awaitable_senders` [exec.with.awaitable.senders] ### {#spec-execution.coro_utils.with_awaitable_senders}
@@ -7747,7 +7741,7 @@ template<class Domain, class Tag, sender Sender, class... Args>
}
- 3. call-result-t<as_awaitable_t, Value, Promise&> await_transform(Value&& value)
+ 3. call-result-t<as_awaitable_t, Value, Promise&> await_transform(Value&& value)
- Effects: equivalent to: