This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
[exec.snd.concepts]
# 33 Execution control library [[exec]](./#exec)
## 33.9 Senders [[exec.snd]](exec.snd#concepts)
### 33.9.3 Sender concepts [exec.snd.concepts]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2127)
The [sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]") concept defines
the requirements for a sender type ([[exec.async.ops]](exec.async.ops "33.3Asynchronous operations"))[.](#1.sentence-1)
The [sender_in](#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]") concept defines
the requirements for a sender type
that can create asynchronous operations given an associated environment type[.](#1.sentence-2)
The [sender_to](#concept:sender_to "33.9.3Sender concepts[exec.snd.concepts]") concept defines
the requirements for a sender type
that can connect with a specific receiver type[.](#1.sentence-3)
The get_env customization point object is used to access
a sender's associated attributes[.](#1.sentence-4)
The connect customization point object is used to connect ([[exec.async.ops]](exec.async.ops "33.3Asynchronous operations"))
a sender and a receiver to produce an operation state[.](#1.sentence-5)
[🔗](#lib:is-dependent-sender-helper)
namespace std::execution {template<auto>concept [*is-constant*](#concept:is-constant "33.9.3Sender concepts[exec.snd.concepts]") = true; // *exposition only*template<class Sndr>concept [*is-sender*](#concept:is-sender "33.9.3Sender concepts[exec.snd.concepts]") = // *exposition only*[derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<typename Sndr::sender_concept, sender_t>; template<class Sndr>concept [*enable-sender*](#concept:enable-sender "33.9.3Sender concepts[exec.snd.concepts]") = // *exposition only*[*is-sender*](#concept:is-sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr> ||[*is-awaitable*](exec.awaitable#concept:is-awaitable "33.9.4Awaitable helpers[exec.awaitable]")<Sndr, *env-promise*<env<>>>; // [[exec.awaitable]](exec.awaitable "33.9.4Awaitable helpers")template<class Sndr>inline constexpr bool enable_sender = [*enable-sender*](#concept:enable-sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr>; template<class Sndr>consteval bool *is-dependent-sender-helper*() try { // *exposition only* get_completion_signatures<Sndr>(); return false; } catch (dependent_sender_error&) {return true; }template<class Sndr>concept [sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]") = enable_sender<remove_cvref_t<Sndr>> &&requires (const remove_cvref_t<Sndr>& sndr) {{ get_env(sndr) } -> [*queryable*](exec.queryable.concept#concept:queryable "33.2.2queryable concept[exec.queryable.concept]"); } &&[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13Concept move_­constructible[concept.moveconstructible]")<remove_cvref_t<Sndr>> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<remove_cvref_t<Sndr>, Sndr>; template<class Sndr, class... Env>concept [sender_in](#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]") =[sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr> &&(sizeof...(Env) <= 1) &&([*queryable*](exec.queryable.concept#concept:queryable "33.2.2queryable concept[exec.queryable.concept]")<Env> &&...) &&[*is-constant*](#concept:is-constant "33.9.3Sender concepts[exec.snd.concepts]")<get_completion_signatures<Sndr, Env...>()>; template<class Sndr>concept [dependent_sender](#concept:dependent_sender "33.9.3Sender concepts[exec.snd.concepts]") =[sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr> && bool_constant<*is-dependent-sender-helper*<Sndr>()>::value; template<class Sndr, class Rcvr>concept [sender_to](#concept:sender_to "33.9.3Sender concepts[exec.snd.concepts]") =[sender_in](#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, env_of_t<Rcvr>> &&[receiver_of](exec.recv.concepts#concept:receiver_of "33.7.1Receiver concepts[exec.recv.concepts]")<Rcvr, completion_signatures_of_t<Sndr, env_of_t<Rcvr>>> &&requires (Sndr&& sndr, Rcvr&& rcvr) { connect(std::forward<Sndr>(sndr), std::forward<Rcvr>(rcvr)); };}
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2197)
For a type Sndr, if[sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr> is true and[dependent_sender](#concept:dependent_sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr> is false,
then Sndr is a non-dependent sender ([[exec.async.ops]](exec.async.ops "33.3Asynchronous operations"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2203)
Given a subexpression sndr,
let Sndr be decltype((sndr)) and
let rcvr be a receiver
with an associated environment whose type is Env[.](#3.sentence-1)
A completion operation is a [*permissible completion*](#def:completion,permissible "33.9.3Sender concepts[exec.snd.concepts]") for Sndr and Env if its completion signature appears in the argument list of the specialization of completion_signatures denoted bycompletion_signatures_of_t<Sndr, Env>[.](#3.sentence-2)
Sndr and Env model [sender_in](#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, Env> if all the completion operations
that are potentially evaluated by connecting sndr to rcvr and
starting the resulting operation state
are permissible completions for Sndr and Env[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2218)
*Remarks*: Pursuant to [[namespace.std]](namespace.std "16.4.5.2.1Namespace std"),
users may specialize enable_sender totrue for cv-unqualified program-defined types that
model [sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]"), andfalse for types that do not[.](#4.sentence-1)
Such specializations shall
be usable in constant expressions ([[expr.const]](expr.const "7.7Constant expressions")) and
have type const bool[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2229)
The exposition-only concepts[*sender-of*](#concept:sender-of "33.9.3Sender concepts[exec.snd.concepts]") and [*sender-in-of*](#concept:sender-in-of "33.9.3Sender concepts[exec.snd.concepts]") define the requirements for a sender type
that completes with a given unique set of value result types[.](#5.sentence-1)
namespace std::execution {template<class... As>using *value-signature* = set_value_t(As...); // *exposition only*template<class Sndr, class SetValue, class... Env>concept [*sender-in-of-impl*](#concept:sender-in-of-impl "33.9.3Sender concepts[exec.snd.concepts]") = // *exposition only*[sender_in](#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, Env...> &&*MATCHING-SIG*(SetValue, // see [[exec.general]](exec.general "33.1General")*gather-signatures*<set_value_t, // see [[exec.cmplsig]](exec.cmplsig "33.10Completion signatures") completion_signatures_of_t<Sndr, Env...>, *value-signature*,
type_identity_t>); template<class Sndr, class Env, class... Values>concept [*sender-in-of*](#concept:sender-in-of "33.9.3Sender concepts[exec.snd.concepts]") = // *exposition only*[*sender-in-of-impl*](#concept:sender-in-of-impl "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, set_value_t(Values...), Env>; template<class Sndr, class... Values>concept [*sender-of*](#concept:sender-of "33.9.3Sender concepts[exec.snd.concepts]") = // *exposition only*[*sender-in-of-impl*](#concept:sender-in-of-impl "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, set_value_t(Values...)>;}
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2258)
Let sndr be an expression
such that decltype((sndr)) is Sndr[.](#6.sentence-1)
The type tag_of_t<Sndr> is as follows:
- [(6.1)](#6.1)
If the declarationauto&& [tag, data, ...children] = sndr; would be well-formed, tag_of_t<Sndr> is
an alias for decltype(auto(tag)).
- [(6.2)](#6.2)
Otherwise, tag_of_t<Sndr> is ill-formed.
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2274)
Let [*sender-for*](#concept:sender-for "33.9.3Sender concepts[exec.snd.concepts]") be an exposition-only concept defined as follows:namespace std::execution {template<class Sndr, class Tag>concept [*sender-for*](#concept:sender-for "33.9.3Sender concepts[exec.snd.concepts]") =[sender](#concept:sender "33.9.3Sender concepts[exec.snd.concepts]")<Sndr> &&[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<tag_of_t<Sndr>, Tag>;}
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2285)
For a type T,*SET-VALUE-SIG*(T) denotes the type set_value_t() if T is cv void;
otherwise, it denotes the type set_value_t(T)[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L2291)
Library-provided sender types
- [(9.1)](#9.1)
always expose an overload of a member connect that accepts an rvalue sender and
- [(9.2)](#9.2)
only expose an overload of a member connect that accepts an lvalue sender if they model [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14Concept copy_­constructible[concept.copyconstructible]")[.](#9.sentence-1)