33 Execution control library [exec]

33.9 Senders [exec.snd]

33.9.3 Sender concepts [exec.snd.concepts]

The sender concept defines the requirements for a sender type ([exec.async.ops]).
The sender_in concept defines the requirements for a sender type that can create asynchronous operations given an associated environment type.
The sender_to concept defines the requirements for a sender type that can connect with a specific receiver type.
The get_env customization point object is used to access a sender's associated attributes.
The connect customization point object is used to connect ([exec.async.ops]) a sender and a receiver to produce an operation state.
namespace std::execution { template<class Sigs> concept valid-completion-signatures = see below; // exposition only template<class Sndr> concept is-sender = // exposition only derived_from<typename Sndr::sender_concept, sender_t>; template<class Sndr> concept enable-sender = // exposition only is-sender<Sndr> || is-awaitable<Sndr, env-promise<empty_env>>; // [exec.awaitable] template<class Sndr> concept sender = bool(enable-sender<remove_cvref_t<Sndr>>) && requires (const remove_cvref_t<Sndr>& sndr) { { get_env(sndr) } -> queryable; } && move_constructible<remove_cvref_t<Sndr>> && constructible_from<remove_cvref_t<Sndr>, Sndr>; template<class Sndr, class Env = empty_env> concept sender_in = 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 Sndr, class Rcvr> concept sender_to = 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)); }; }
Given a subexpression sndr, let Sndr be decltype((sndr)) and let rcvr be a receiver with an associated environment whose type is Env.
A completion operation is a permissible completion for Sndr and Env if its completion signature appears in the argument list of the specialization of completion_signatures denoted by completion_signatures_of_t<Sndr, Env>.
Sndr and Env model sender_in<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.
A type models the exposition-only concept valid-completion-signatures if it denotes a specialization of the completion_signatures class template.
The exposition-only concepts sender-of and sender-in-of define the requirements for a sender type that completes with a given unique set of value result types.
namespace std::execution { template<class... As> using value-signature = set_value_t(As...); // exposition only template<class Sndr, class Env, class... Values> concept sender-in-of = sender_in<Sndr, Env> && MATCHING-SIG( // see [exec.general] set_value_t(Values...), value_types_of_t<Sndr, Env, value-signature, type_identity_t>); template<class Sndr, class... Values> concept sender-of = sender-in-of<Sndr, empty_env, Values...>; }
Let sndr be an expression such that decltype((sndr)) is Sndr.
The type tag_of_t<Sndr> is as follows:
  • If the declaration auto&& [tag, data, ...children] = sndr; would be well-formed, tag_of_t<Sndr> is an alias for decltype(auto(tag)).
  • Otherwise, tag_of_t<Sndr> is ill-formed.
Let sender-for be an exposition-only concept defined as follows: namespace std::execution { template<class Sndr, class Tag> concept sender-for = sender<Sndr> && same_as<tag_of_t<Sndr>, Tag>; }
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).
Library-provided sender types
  • always expose an overload of a member connect that accepts an rvalue sender and
  • only expose an overload of a member connect that accepts an lvalue sender if they model copy_constructible.