33 Execution control library [exec]

33.7 Receivers [exec.recv]

33.7.1 Receiver concepts [exec.recv.concepts]

A receiver represents the continuation of an asynchronous operation.
The receiver concept defines the requirements for a receiver type ([exec.async.ops]).
The exposition-only concept receiver-of defines the requirements for a receiver type that is usable as the first argument of a set of completion operations corresponding to a set of completion signatures.
The get_env customization point object is used to access a receiver's associated environment.
namespace std::execution { template<class Rcvr> concept receiver = derived_from<typename remove_cvref_t<Rcvr>::receiver_concept, receiver_tag> && requires(const remove_cvref_t<Rcvr>& rcvr) { { get_env(rcvr) } -> queryable; } && move_constructible<remove_cvref_t<Rcvr>> && // rvalues are movable, and constructible_from<remove_cvref_t<Rcvr>, Rcvr> && // lvalues are copyable, and is_nothrow_move_constructible_v<remove_cvref_t<Rcvr>>; // no-throw-movable 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<Rcvr>, Args...> {}(sig); }; template<class Rcvr, class Completions> concept has-completions = // exposition only requires (Completions* completions) { []<valid-completion-for<Rcvr>...Sigs>(completion_signatures<Sigs...>*) {}(completions); }; template<class Rcvr, class Completions> concept receiver-of = receiver<Rcvr> && has-completions<Rcvr, Completions>; }
Class types that are marked final do not model the receiver concept.
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 ([exec.async.ops]).
[Note 1: 
This means that, unless it knows about further guarantees provided by the type of rcvr, the implementation of op_state cannot 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.
— end note]
namespace std::execution { template<class Rcvr, class ChildOp> concept inlinable_receiver = receiver<Rcvr> && requires (ChildOp* child) { { remove_cvref_t<Rcvr>::make_receiver_for(child) } noexcept -> same_as<remove_cvref_t<Rcvr>>; }; }
The inlinable_receiver concept defines the requirements for a receiver that can be reconstructed on demand from a pointer to the operation state object created when the receiver was connected to a sender.
Given a receiver object rcvr of type Rcvr which was connected to a sender producing an operation state object op of type Op, Rcvr models inlinable_receiver<Op> only if the expression Rcvr​::​make_receiver_for(addressof(op)) evaluates to a receiver that is equal to rcvr ([concepts.equality]).
[Note 2: 
Such a receiver does not need to be stored as a data member of op as it can be recreated on demand.
— end note]
ChildOp may be an incomplete type.
Given objects , is transitively constructed from if
  • remove_cvref_t<decltype()> denotes the same type as remove_cvref_t<decltype()> and
  • either
    • was initialized by decay-copying a reference to , or
    • and is transitively constructed from and was initialized from a non-const, non-volatile rvalue reference to .
Let E be some well-formed expression connect(sndr, rcvr).
E inlines the receiver rcvr if the lifetimes of all objects transitively constructed from rcvr during the evaluation of E end within the evaluation of E.
[Note 3: 
This means such an expression does not store the receiver in the operation state.
— end note]
Let E be some well-formed expression connect(sndr, rcvr) where
  • sndr denotes a sender type defined by this document and
  • E inlines the receiver rcvr.
Then, let op be the result of the evaluation of E, and wherever the specification of the operation associated with op contains a glvalue which would denote an object transitively constructed from rcvr, that glvalue instead denotes the result of applying the temporary materialization conversion to the expression remove_cvref_t<decltype(rcvr)>​::​make_receiver_for(addressof(op)).
Let StdRcvr be a receiver type defined by this document.
Given some operation state type Op, it is unspecified whether StdRcvr models inlinable_receiver<Op>.
Let StdOp be some operation state type defined by this document, and let Sndr and Rcvr be types such that is_same_v<connect_result_t<Sndr, Rcvr>, StdOp> is true.
If Rcvr models inlinable_receiver<StdOp> then it is implementation-defined whether, given an object rcvr of type Rcvr, the connect operation which produces an object of type StdOp inlines the receiver rcvr.