I have opened
[cwg#250](https://github.com/cplusplus/CWG/issues/250) to give these
@@ -6118,18 +6126,18 @@ enum class forward_progress_guarantee {
template<class T>
concept
await-suspend-result =
see below;
- template<class A, class Promise>
+ template<class A, class... Promise>
concept
is-awaiter =
// exposition only
- requires (A& a, coroutine_handle<Promise> 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 Promise>
+ template<class C, class... Promise>
concept
is-awaitable =
- requires (C (*fc)() noexcept, Promise& p) {
- {
GET-AWAITER(fc(), p) } ->
is-awaiter<Promise>;
+ requires (C (*fc)() noexcept, Promise&... p) {
+ {
GET-AWAITER(fc(), p...) } ->
is-awaiter<Promise...>;
};
@@ -6142,7 +6150,9 @@ enum class forward_progress_guarantee {
4. For a subexpression `c` such that `decltype((c))` is type `C`, and
an lvalue `p` of type `Promise`,
await-result-type<C, Promise>
- denotes the type
decltype(GET-AWAITER(c, p).await_resume())
.
+ denotes the type
decltype(GET-AWAITER(c, p).await_resume())
,
+ and
await-result-type<C>
denotes the type
+
decltype(GET-AWAITER(c).await_resume())
.
5. Let
with-await-transform
be the exposition-only class template:
@@ -6317,30 +6327,64 @@ template<class Domain, class Tag, sender Sndr, class... Args>
### `execution::get_completion_signatures`
[exec.getcomplsigs] ### {#spec-execution.getcomplsigs}
-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. `get_completion_signatures` is a customization point object. For a
+ subexpression `sndr`, let `Sndr` be `decltype((sndr))`. Then
+ `get_completion_signatures(sndr)` is expression-equivalent to:
- 1. `decltype(sndr.get_completion_signatures(env)){}` if that
- expression is well-formed,
+ 1. `remove_cvref_t
::completion_signatures()` if that expression is
+ well-formed,
- 2. Otherwise, `remove_cvref_t::completion_signatures{}` if that expression is well-formed,
+ 2. Otherwise, `decltype(sndr.get_completion_signatures())()` if that
+ expression is well-formed,
- 3. Otherwise, if is-awaitable<Sndr, env-promise<Env>>
+ 3. Otherwise, if is-awaitable<Sndr>
is `true`, then:
-
- completion_signatures<
- SET-VALUE-SIG(await-result-type<Sndr,
- env-promise<Env>>), // see [exec.snd.concepts]
- set_error_t(exception_ptr),
- set_stopped_t()>{}
-
+
+ completion_signatures<
+ SET-VALUE-SIG(await-result-type<Sndr>), // see [exec.snd.concepts]
+ set_error_t(exception_ptr),
+ set_stopped_t()>()
+
+
+ 4. Otherwise, `get_completion_signatures(sndr)` is ill-formed.
+
+2. For a subexpression `env`, let `Env` be `decltype((env))`. Then
+ `get_completion_signatures(sndr, env)` is expression-equivalent to:
+
+ 1. `remove_cvref_t::completion_signatures()` if that expression is
+ well-formed,
+
+ 2. Otherwise, `decltype(sndr.get_completion_signatures(env))()` if that
+ expression is well-formed,
+
+ 3. Otherwise, if is-awaitable<Sndr,
+ env-promise<Env>>
is `true`, then:
+
+
+ completion_signatures<
+ 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(sndr, env)` is ill-formed.
-2. Let `rcvr` be an rvalue receiver of type `Rcvr`, and let `Sndr` be the type of a
+3. If `get_completion_signatures(sndr)` is well-formed and its type denotes a
+ specialization of the `completion_signatures` class template, then `Sndr` is
+ a non-dependent sender type ([async.ops]).
+
+4. Given a pack of subexpressions `se`, the expression
+ `get_completion_signatures(se...)` is ill-formed if `sizeof...(se)` is less
+ than `1` or greater than `2`.
+
+5. If `completion_signatures_of_t` and `completion_signatures_of_t` are both well-formed, they shall denote the same set of completion
+ signatures, disregarding the order of signatures and rvalue reference
+ qualification of arguments.
+
+6. 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
@@ -6374,7 +6418,7 @@ template<class Domain, class Tag, sender Sndr, class... Args>
[[noreturn]] void return_void() noexcept { terminate(); }
coroutine_handle<> unhandled_stopped() noexcept {
- set_stopped((DR&&) rcvr);
+ set_stopped(std::move(rcvr));
return noop_coroutine();
}
@@ -6584,6 +6628,10 @@ template<class Domain, class Tag, sender Sndr, class... Args>
`exception_ptr` argument, the implementation is allowed to omit the
`exception_ptr` error completion signature from the set.
+7. Unless otherwise specified, an adaptor whose child senders are all
+ non-dependent ([async.ops]) is itself non-dependent. This requirement applies
+ to any function that is selected by the implementation of the sender adaptor.
+
#### Sender adaptor closure objects [exec.adapt.objects] #### {#spec-execution.senders.adaptor.objects}
1. A pipeable sender adaptor closure object is a function object that
@@ -6909,13 +6957,23 @@ template<class Domain, class Tag, sender Sndr, class... Args>
of the invocable as a value completion.
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 `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(sndr, f)
is ill-formed.
-
-3. Otherwise, the expression then-cpo(sndr, f)
is
+ objects. For `then`, `upon_error`, and `upon_stopped`, let `set-cpo`
+ be `set_value`, `set_error`, and `set_stopped` respectively. Let the
+ expression then-cpo
be one of `then`, `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(sndr, f)
is
+ ill-formed.
+
+3. Let `invoke-result` be an alias template such that
+ invoke-result<Ts...>
denotes the type
+ `invoke_result_t`. If `sender_in` is `true` and
+ gather-signatures<tag_t<set-cpo>,
+ completion_signatures_of_t<Sndr>, invoke-result,
+ type-list>
is ill-formed, the program is ill-formed.
+
+4. Otherwise, the expression then-cpo(sndr, f)
is
expression-equivalent to:
@@ -6924,9 +6982,7 @@ template<class Domain, class Tag, sender Sndr, class... Args>
make-sender(then-cpo, f, sndr));
-4. For `then`, `upon_error`, and `upon_stopped`, let set-cpo
- be `set_value`, `set_error`, and `set_stopped` respectively. The
- exposition-only class template impls-for
+5. The exposition-only class template impls-for
([exec.snd.general]) is specialized for `then-cpo` as follows:
@@ -6991,7 +7047,14 @@ template<class Domain, class Tag, sender Sndr, class... Args>
make-sender(let-cpo, f, sndr));
-5. The exposition-only class template impls-for
+5. Let `invoke-result` be an alias template such that
+ invoke-result<Ts...>
denotes the type
+ `invoke_result_t`. If `sender_in` is `true` and
+ gather-signatures<tag_t<set-cpo>,
+ completion_signatures_of_t<Sndr>, invoke-result,
+ type-list>
is ill-formed, the program is ill-formed.
+
+6. The exposition-only class template impls-for
([exec.snd.general]) is specialized for let-cpo
as
follows:
@@ -7091,13 +7154,13 @@ template<class Domain, class Tag, sender Sndr, class... Args>
}
-6. Let `sndr` and `env` be subexpressions, and let `Sndr` be `decltype((sndr))`.
+7. Let `sndr` and `env` be subexpressions, and let `Sndr` be `decltype((sndr))`.
If sender-for<Sndr, tag_t<let-cpo>>
is
`false`, then the expression let-cpo.transform_env(sndr,
env)
is ill-formed. Otherwise, it is equal to
JOIN-ENV(let-env(sndr), FWD-ENV(env))
.
-7. Let the subexpression `out_sndr` denote the result of the invocation
+8. Let the subexpression `out_sndr` denote the result of the invocation
let-cpo(sndr, f)
or an object copied or moved from such,
and let the subexpression `rcvr` denote a receiver such that the expression
`connect(out_sndr, rcvr)` is well-formed. The expression `connect(out_sndr,
@@ -7132,7 +7195,14 @@ template<class Domain, class Tag, sender Sndr, class... Args>
make-sender(bulk, product-type{shape, f}, sndr));
-4. The exposition-only class template impls-for
+4. Let `invoke-result` be an alias template such that
+ invoke-result<Ts...>
denotes the type
+ `invoke_result_t`. If `sender_in` is `true` and
+ gather-signatures<tag_t<set-cpo>,
+ completion_signatures_of_t<Sndr>, invoke-result,
+ type-list>
is ill-formed, the program is ill-formed.
+
+5. The exposition-only class template impls-for
([exec.snd.general]) is specialized for `bulk_t` as follows:
@@ -7167,7 +7237,7 @@ template<class Domain, class Tag, sender Sndr, class... Args>
`true` if and only if `Tag` denotes a type other than `set_value_t`
or if the expression `f(auto(shape), args...)` is well-formed.
-5. Let the subexpression `out_sndr` denote the result of the invocation
+6. Let the subexpression `out_sndr` denote the result of the invocation
bulk(sndr, shape, f)
or an object copied or moved from such,
and let the subexpression `rcvr` denote a receiver such that the expression
`connect(out_sndr, rcvr)` is well-formed. The expression `connect(out_sndr,