Files
cppdraft_translate/cppdraft/exec/snd/concepts.md
2025-10-25 03:02:53 +03:00

123 lines
9.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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)