From c6ebf4f863902e8f6ac6819656070b249136cb7a Mon Sep 17 00:00:00 2001
From: ericniebler
simple - allocator
([allocator.requirements.general]).
is a core constant expression and has value true
.
Let
be the type of a scheduler and let
be the type of an
execution environment for which
is
-satisfied. Then
shall be modeled.
sender - in - of < schedule_result_t < Sch > , Env >
shall be modeled.
None of a scheduler’s copy constructor, destructor, equality comparison, or
member functions shall exit via an exception. None of these member
functions, nor a scheduler type’s
function, shall introduce data
@@ -8436,15 +8436,15 @@
FWD - ENV ( env )
is an
-expression whose type satisfies *queryable
* such that for a query object q
and a pack of subexpressions as
, the expression FWD - ENV ( env ). query ( q , as ...)
is ill-formed if forwarding_query ( q )
is false
; otherwise, it is expression-equivalent
+expression whose type satisfies queryable
such that for a query object q
and a pack of subexpressions as
, the expression FWD - ENV ( env ). query ( q , as ...)
is ill-formed if forwarding_query ( q )
is false
; otherwise, it is expression-equivalent
to env . query ( q , as ...)
.
For a query object
and a subexpression
,
is an expression
whose type satisfies *
* such
+
For a query object
and a subexpression
,
is an expression
whose type satisfies
such
that the result of
has a value equal to
([concepts.equality]). Unless otherwise stated, the object to which
refers remains valid while
remains valid.
For two queryable objects
and
, a query object
and a
pack of subexpressions
,
is
-an expression
whose type satisfies *
* such that
is expression-equivalent to:
env3
whose type satisfies queryable
such that env3 . query ( q , as ...)
is expression-equivalent to:
if that expression is well-formed,
SCHED - ATTRS ( sch )
is an
-expression o1
whose type satisfied *queryable
* such that o1 . query ( get_completion_scheduler < Tag > )
is a
+expression o1
whose type satisfies queryable
such that o1 . query ( get_completion_scheduler < Tag > )
is a
expression with the same type and value as sch
where Tag
is
-one of set_value_t
or set_stopped_t
, and such that o1 . query ( get_domain )
is expression-equivalent to sch . query ( get_domain )
. SCHED - ENV ( sch )
is an expression o2
whose type satisfied *queryable
* such that o1 . query ( get_scheduler )
is a prvalue with the same type and
+one of set_value_t
or set_stopped_t
, and such that o1 . query ( get_domain )
is expression-equivalent to sch . query ( get_domain )
. SCHED - ENV ( sch )
is an expression o2
whose type satisfies queryable
such that o1 . query ( get_scheduler )
is a prvalue with the same type and
value as sch
, and such that o2 . query ( get_domain )
is
expression-equivalent to sch . query ( get_domain )
.
Domain
is the decayed type of the first of the
+ Effects: Equivalent to:
where
is the decayed type of the first of the
following expressions that is well-formed:
transfer
) and off of (schedule_from
) a given execution
-context. Thus, transfer
must ignore the domain of the
-predecessor and use the domain of the destination scheduler to
-select a customization, a property that is unique to transfer
.
-That is why it is given special treatment here.
+context. Thus, transfer
ignores the domain of the predecessor
+and uses the domain of the destination scheduler to select a
+customization, a property that is unique to transfer
. That is
+why it is given special treatment here.
Otherwise,
where
is
+
Otherwise,
where
is
the first of the following expressions that is well-formed and
-its type is not
:
void
:
template < class T 0 , class T 1 , ... class T n > struct product - type { // exposition only -using type 0 = T 0 ; // exposition only -using type 1 = T 1 ; // exposition only -... -using type n -1 = T n -1 ; // exposition only -T 0 t 0 ; // exposition only T 1 t 1 ; // exposition only ... -T n -1 t n -1 ; // exposition only +T n t n ; // exposition only + +template < size_t I , class Self > +constexpr decltype ( auto ) get ( this Self && self ) noexcept ; // exposition only + +template < class Self , class Fn > +constexpr decltype ( auto ) apply ( this Self && self , Fn && fn ) // exposition only +noexcept ( see below ); };
An expression of type
is usable as the initializer of a
structured binding declaration [dcl.struct.bind].
+template < size_t I , class Self > +constexpr decltype ( auto ) get ( this Self && self ) noexcept ; +
Effects: Equivalent to:
++auto & [... ts ] = self ; +return std :: forward_like < Self > ( ts ...[ I ]); +
+template < class Self , class Fn > +constexpr decltype ( auto ) apply ( this Self && self , Fn && fn ) noexcept ( see below ); +
Effects: Equivalent to:
++auto & [... ts ] = self ; +return std :: forward < Fn > ( fn )( std :: forward_like < Self > ( ts )...); +
Requires: The expression in the
statement above is
+well-formed.
Remarks: The expression in the
clause is true
if the
statement above is not potentially throwing; otherwise, false
.
template < class Tag , class Data = see below , class ... Child > @@ -8629,8 +8658,8 @@
( sender < Child > && ...)
Returns: A prvalue of type
where the
member has been default-initialized and the
and
members have been direct
-initialized from their respective forwarded arguments, where
is the following exposition-only
+
Returns: A prvalue of type
that has been
+direct-list-initialized with the forwarded arguments, where
is the following exposition-only
class template except as noted below:
namespace std :: execution { template < class Tag > @@ -8638,7 +8667,7 @@
Data template parameter -denotes an unspecified empty trivial class type. +denotes an unspecified empty trivially copyable class type that models.
semiregular
It is unspecified whether instances of
can be
-aggregate initialized.
It is unspecified whether a specialization of
is
+an aggregate.
An expression of type
is usable as the initializer of a
-structured binding declaration [dcl.struct.bind].
An expression of type
is usable as the initializer of a
+structured binding declaration [dcl.struct.bind].
The expression in the
clause of the constructor of
is:
is_nothrow_move_constructible_v < Rcvr > && nothrow - callable < decltype ( impls - for < tag_of_t < Sndr >>:: get - state ), Sndr , Rcvr &>
The object
is initialized with the following
-lambda:
The object
is initialized with a callable object
+equivalent to the following lambda:
-[] < class Sndr , class Rcvr , size_t ... Is > ( -basic - state < Sndr , Rcvr >* op , Sndr && sndr , index_sequence < Is ... > ) noexcept ( noexcept ( E )) --> decltype ( E ) { -return E ; +basic - state < Sndr , Rcvr >* op , Sndr && sndr , index_sequence < Is ... > ) noexcept ( see below ) +-> decltype ( auto ) { +auto & [ _ , data , ... child ] = sndr ; +return product - type { connect ( +std :: forward_like < Sndr > ( child ), +basic - receiver < Sndr , Rcvr , integral_constant < size_t , Is >> { op })...}; }
where
is the following expression:
+product - type { connect ( -std :: forward < Sndr > ( sndr ). child Is , -basic - receiver < Sndr , Rcvr , integral_constant < size_t , Is >> { op })...} -
Requires: The expression in the
statement is well-formed.
Remarks: The expression in the
clause is true
if
+ the
statement is not potentially throwing; otherwise, false
.
The expression in the
clause of the constructor of
is:
is_nothrow_constructible_v < basic - state < Self , Rcvr > , Self , Rcvr > && +is_nothrow_constructible_v < basic - state < Self , Rcvr > , Self , Rcvr > && noexcept ( connect - all ( this , std :: forward < Sndr > ( sndr ), indices - for < Sndr > ()))
The expression in the
clause of the
member function of
is:
is_nothrow_constructible_v < basic - operation < Self , Rcvr > , Self , Rcvr > +is_nothrow_constructible_v < basic - operation < Self , Rcvr > , Self , Rcvr >
The member
is
initialized with a callable object equivalent to the following
lambda:
[]( const auto & data , const auto & ... child ) noexcept -> decltype ( auto ) { +[]( const auto & , const auto & ... child ) noexcept -> decltype ( auto ) { if constexpr ( sizeof ...( child ) == 1 ) return ( FWD - ENV ( get_env ( child )), ...); else @@ -8822,7 +8847,7 @@
default - impls :: get - env is initialized with a callable object equivalent to the following lambda: -[] < class Rcvr > ( auto index , auto & state , const Rcvr & rcvr ) noexcept -> decltype ( auto ) { +@@ -8830,13 +8855,14 @@[]( auto , auto & , const auto & rcvr ) noexcept -> decltype ( auto ) { return FWD - ENV ( get_env ( rcvr )); }
default - impls :: get - state is initialized with a callable object equivalent to the following lambda:[] < class Sndr , class Rcvr > ( Sndr && sndr , Rcvr & rcvr ) noexcept -> decltype ( auto ) { -return ( std :: forward < Sndr > ( sndr ). data ); +auto & [ _ , data , ... child ] = sndr ; +return std :: forward_like < Sndr > ( data ); }
The member
is initialized
with a callable object equivalent to the following lambda:
[]( auto & state , auto & rcvr , auto & ... ops ) noexcept -> void { +@@ -8889,12 +8915,12 @@[]( auto & , auto & , auto & ... ops ) noexcept -> void { ( execution :: start ( ops ), ...); } template
< class Sndr > concept sender = -bool ( enable - sender < remove_cvref_t < Sndr >> ) && // atomic constraint +bool ( enable - sender < remove_cvref_t < Sndr >> ) && // atomic constraint ([temp.constr.atomic]) requires ( const remove_cvref_t < Sndr >& sndr ) { { get_env ( sndr ) } -> queryable ; } && -move_constructible < remove_cvref_t < Sndr >> && // rvalues are movable, and -constructible_from < remove_cvref_t < Sndr > , Sndr > ; // lvalues are copyable +move_constructible < remove_cvref_t < Sndr >> && // senders are movable and +constructible_from < remove_cvref_t < Sndr > , Sndr > ; // decay copyable template < class Sndr , class Env = empty_env > concept sender_in = @@ -8915,31 +8941,30 @@}
Given a subexpression
, let
be
, let
be
-the type of an environment, and let
be a receiver with an associated
-environment
. A completion operation is a permissible completion for
and
if its
+
Given a subexpression
, let
be
and let
be a receiver with an associated environment whose type is
.
+A completion operation is a permissible completion for
and
if its
completion signature appears in the argument list of the specialization of
denoted by
.
and
model
if all the completion
operations that are potentially evaluated by connecting
to
and
starting the resulting operation state are permissible completions for
and
.
A type
satisfies and models the exposition-only concept
if it denotes a specialization
+
A type models the exposition-only concept
if it denotes a specialization
of the
class template.
The exposition-only concepts
and
define the requirements for a sender
+
The exposition-only concepts
and
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 - of - in = +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 - of - in < Sndr , empty_env , Values ... > ; +concept sender - of = sender - in - of < Sndr , empty_env , Values ... > ; }
Only expose an overload of a member
that accepts an lvalue
sender if they model
.
Model
if they satisfy
.
The sender concepts recognize awaitables as senders. For this clause -([exec]), an awaitable is an expression that would be +
The sender concepts recognize awaitables as senders. For [exec], an awaitable is an expression that would be
well-formed as the operand of a
expression within a given
context.
For a subexpression
, let
be
expression-equivalent to the series of transformations and conversions
applied to
as the operand of an await-expression in a coroutine,
-resulting in lvalue
as described by [expr.await]/3.2-4, where
is an lvalue referring to the coroutine’s promise type,
. This includes the invocation of the promise type’s
member if any, the invocation of the
picked by overload resolution if any, and any necessary implicit
+resulting in lvalue
as described by [expr.await], where
is an lvalue referring to the coroutine’s promise, which has type
. This includes the invocation of the promise type’s
member if any, the invocation of the
picked by overload resolution if any, and any necessary implicit
conversions and materializations.
I have opened cwg#250 to give these transformations a term-of-art so we can more easily refer to it here.
@@ -9000,7 +9022,7 @@namespace std { template < class T > -concept await - suspend - result = see below ; +concept await - suspend - result = see below ; // exposition only template < class A , class Promise > concept is - awaiter = // exposition only @@ -9047,9 +9069,8 @@}
template < has - as - awaitable < Derived > T > -auto await_transform ( T && value ) -noexcept ( noexcept ( std :: forward < T > ( value ). as_awaitable ( declval < Derived &> ()))) --> decltype ( std :: forward < T > ( value ). as_awaitable ( declval < Derived &> ())) { +decltype ( auto ) await_transform ( T && value ) +noexcept ( noexcept ( std :: forward < T > ( value ). as_awaitable ( declval < Derived &> ()))) { return std :: forward < T > ( value ). as_awaitable ( static_cast < Derived &> ( * this )); } }; @@ -9187,27 +9208,26 @@
+expression such that
is a customization point object. Let
get_completion_signatures be an expression such that
sndr is
decltype (( sndr )) , and let
Sndr be an -expression such that
env is
decltype (( env )) . Then
Env is expression-equivalent to:
get_completion_signatures ( sndr , env ) is
decltype (( env )) . Then
Env is expression-equivalent to
get_completion_signatures ( sndr , env ) except that
( void ( sndr ), void ( env ), CS ()) and
void ( sndr ) are indeterminately sequenced, where
void ( env ) is:
CS
- -
+
if that -expression is well-formed,
decltype ( sndr . get_completion_signatures ( env )){}
if that +type is well-formed,
decltype ( sndr . get_completion_signatures ( env )) - -
Otherwise,
+if that expression is well-formed,
remove_cvref_t < Sndr >:: completion_signatures {} Otherwise,
if that type is well-formed,
remove_cvref_t < Sndr >:: completion_signatures Otherwise, if
is
is - awaitable < Sndr , env - promise < Env >> 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 () > {} +set_stopped_t () > - -
Otherwise,
+is ill-formed.
get_completion_signatures ( sndr , env ) Otherwise,
is ill-formed.
CS - -
Let
be an rvalue receiver of type
rcvr , and let
Rcvr be the type of a -sender such that
Sndr is
sender_in < Sndr , env_of_t < Rcvr >> true
. Letbe the +
Sigs ... Let
be an rvalue whose type
rcvr models
Rcvr , and let
receiver be the type of a sender such that
Sndr is
sender_in < Sndr , env_of_t < Rcvr >> true
. Letbe the template arguments of the
Sigs ... specialization named by
completion_signatures . Let
completion_signatures_of_t < Sndr , env_of_t < Rcvr >> be a completion function. If sender
CSO or its operation state cause the expression
Sndr to be potentially evaluated @@ -9219,13 +9239,12 @@
CSO ( rcvr , args ...)
connect connects ([async.ops]) a sender with a receiver.- -
The name
+denotes a customization point object. For subexpressions
connect and
sndr , let
rcvr be
Sndr and
decltype (( sndr )) be
Rcvr , and let
decltype (( rcvr )) and
DS be the decayed types of
DR and
Sndr , respectively.
Rcvr The name
denotes a customization point object. For subexpressions
connect and
sndr , let
rcvr be
Sndr and
decltype (( sndr )) be
Rcvr , and let
decltype (( rcvr )) and
DS be
DR and
decay_t < Sndr > , respectively.
decay_t < Rcvr > - -
Let
+be the following class:
connect - awaitable - promise Let
be the following exposition-only class:
connect - awaitable - promise namespace std :: execution { struct connect - awaitable - promise : with - await - transform < connect - awaitable - promise > { -DR & rcvr ; // exposition only connect - awaitable - promise ( DS & , DR & rcvr ) noexcept : rcvr ( rcvr ) {} @@ -9235,7 +9254,7 @@
operation - state - task be the following class: +Let
be the following exposition-only class:
operation - state - task namespace std :: execution { struct operation - state - task { using operation_state_concept = operation_state_t ; using promise_type = connect - awaitable - promise ; -coroutine_handle <> coro ; // exposition only explicit operation - state - task ( coroutine_handle <> h ) noexcept : coro ( h ) {} operation - state - task ( operation - state - task && o ) noexcept @@ -9266,6 +9287,9 @@
Sndr does not satisfyor if
sender does not satisfy
Rcvr ,
receiver is ill-formed. Otherwise, the expression
connect ( sndr , rcvr ) is +
connect ( sndr , rcvr ) The expression
is expression-equivalent to:
connect ( sndr , rcvr )
- @@ -9320,31 +9344,25 @@
operation_state .
Otherwise,
if that expression is
-well-formed.
Otherwise,
.
Otherwise,
is ill-formed.
Mandates:
is true
.
execution :: schedule
[exec.schedule]
obtains a schedule-sender ([async.ops]) from a scheduler.
obtains a schedule sender ([async.ops]) from a scheduler.
The name
denotes a customization point object. For a
-subexpression
, the expression
is expression-equivalent to:
sch
, the expression schedule ( sch )
is expression-equivalent to sch . schedule ()
.
if that expression is valid. If
does
-not return a sender whose
completion scheduler is equal
-to
, the behavior of calling
is undefined.
Mandates: The type of
satisfies
.
If the expression
is ill-formed or evaluates
+to false
, the behavior of calling
is undefined.
Otherwise,
is ill-formed.
Mandates: The type of
satisfies
.
execution :: just
, execution :: just_error
, execution :: just_stopped
[exec.just]just_stopped
and sizeof ...( ts ) == 0
is false
;
- Otherwise, it is expression-equivalent to
.
Otherwise, it is expression-equivalent to
.
For
,
, and
, let
be
,
, and
respectively. The
exposition-only class template
([exec.snd.general]) is specialized for
as
@@ -9409,31 +9427,33 @@
Subclause [exec.adapt] specifies a set of sender adaptors.
+[exec.adapt] specifies a set of sender adaptors.
The bitwise OR operator is overloaded for the purpose of creating sender +
The bitwise inclusive OR operator is overloaded for the purpose of creating sender chains. The adaptors also support function call syntax with equivalent semantics.
Unless otherwise specified, a sender adaptor is prohibited from causing
-observable effects, apart from moving and copying its arguments, before the
-returned sender is connected with a receiver using
, and
is
-called on the resulting operation state. This requirement applies to any
-function that is selected by the implementation of the sender adaptor.
Unless otherwise specified, a parent sender ([async.ops]) with a single child
-sender
has an associated attribute object equal to
([exec.fwd.env]). Unless
-otherwise specified, a parent sender with more than one child senders has an
-associated attributes object equal to
. These
-requirements apply to any function that is selected by the implementation of
-the sender adaptor.
Unless otherwise specified, when a parent sender is connected to a receiver
, any receiver used to connect a child sender has an associated
-environment equal to
. This
-requirement applies to any sender returned from a function that is selected
-by the implementation of such sender adaptor.
If a sender returned from a sender adaptor specified in this subclause is +
Unless otherwise specified:
+A sender adaptor is prohibited from causing observable effects, apart
+from moving and copying its arguments, before the returned sender is
+connected with a receiver using
, and
is called on the
+resulting operation state.
A parent sender ([async.ops]) with a single child
+sender
has an associated attribute object equal to
([exec.fwd.env]).
A parent sender with more than one child sender has an
+associated attributes object equal to
.
When a parent sender is connected to a receiver
, any receiver used
+to connect a child sender has an associated environment equal to
.
These requirement apply to any function that is selected by the implementation +of the sender adaptor.
+If a sender returned from a sender adaptor specified in [exec.adapt] is
specified to include
among its set of completion signatures
where
denotes the type
, but the implementation
does not potentially evaluate an error completion operation with an
argument, the implementation is allowed to omit the
error completion signature from the set.
sender
. For a sender
+accepts one or more sender
arguments and returns a sender
. For a pipeable sender
adaptor closure object c
and an expression sndr
such that decltype (( sndr ))
models sender
, the following expressions are equivalent
and yield a sender
:
c ( sndr ) @@ -9454,20 +9474,20 @@
d2 of typedirect-non-list-initialized with
decay_t < decltype (( d )) > . +
d Its target object is an object
of type
d2 direct-non-list-initialized with
decltype ( auto ( d )) .
d
It has one bound argument entity, an object
of type
direct-non-list-initialized with
.
It has one bound argument entity, an object
of type
direct-non-list-initialized with
.
Its call pattern is
, where
is the argument used in a
function call expression of
.
The expression
is well-formed if and only if the initializations of
- the state entities of
are all well-formed.
e
are all well-formed.
An object
of type
is a pipeable sender adaptor closure object if
models
,
has no other base
-classes of type
for any other type
, and
does not model
.
sender_adaptor_closure < U >
for any other type U
, and T
does not satisfy sender
.
The template parameter
for
can be an incomplete
type. Before any expression of type
appears as an
@@ -9482,10 +9502,9 @@
sndr
be an expression such that decltype (( sndr ))
models sender
, let args ...
be arguments such that adaptor ( sndr , args ...)
is a
-well-formed expression as specified in the rest of this subclause
-([exec.adapt.objects]), and let BoundArgs
be a pack that denotes decay_t < decltype (( args )) > ...
. The expression adaptor ( args ...)
produces a
-pipeable sender adaptor closure object f
that is a perfect forwarding call
-wrapper with the following properties:
+well-formed expression as specified below, and let BoundArgs
be a pack
+that denotes decltype ( auto ( args ))...
. The expression adaptor ( args ...)
produces a pipeable sender adaptor closure object f
that is a perfect
+forwarding call wrapper with the following properties:
Its target object is a copy of
.
The name
denotes a customization point object. For some subexpressions
and
, if
does not satisfy
, or
does not satisfy
,
is ill-formed.
The name
denotes a customization point object. For subexpressions
and
, if
does not satisfy
, or
does not satisfy
,
is ill-formed.
Otherwise, the expression
is expression-equivalent to:
+transform_sender ( query - or - default ( get_domain , sch , default_domain ()), -make - sender ( on , sch , sndr )); +make - sender ( on , sch , sndr ))
except that
is evaluated only once.
Let
and
be subexpressions such that
is
. If
is false
, then the expressions
and
are ill-formed;
otherwise:
is equivalent to:
auto && [ ign1 , sch , ign2 ] = out_sndr ; +auto && [ _ , sch , _ ] = out_sndr ; return JOIN - ENV ( SCHED - ENV ( sch ), FWD - ENV ( env ));
is equivalent to:
auto && [ ign , sch , sndr ] = out_sndr ; ++auto && [ _ , sch , sndr ] = out_sndr ; return let_value ( schedule ( sch ), -[ sndr = std :: forward_like < OutSndr > ( sndr )]() mutable { +[ sndr = std :: forward_like < OutSndr > ( sndr )]() mutable +noexcept ( is_nothrow_move_constructible_v ) { return std :: move ( sndr ); }); -
Let
be a subexpression denoting a sender returned from
or one equal to such, and let
be the type
. Let
be a subexpression denoting a receiver that has an environment of
type
such that
is true
. Let
be an lvalue
referring to the operation state that results from connecting
with
. Calling
shall start
on an execution agent of the
-associated execution resource of
, or failing that, shall execute an
-error completion on
.
sch
. If scheduling onto sch
fails, an error
+completion on out_rcvr
shall be executed on an unspecified execution agent.
execution :: transfer
[exec.transfer]
adapts a sender into one with a different associated
completion scheduler. It results in a transition
-between different execution resources when executed.
adapts a sender into one that completes on the specified scheduler.
The name
denotes a customization point object. For some
+
The name
denotes a customization point object. For
subexpressions
and
, if
does not satisfy
, or
does not satisfy
,
is ill-formed.
Otherwise, the expression
is expression-equivalent to:
+transform_sender ( get - domain - early ( sndr ), -make - sender ( transfer , sch , sndr )); +make - sender ( transfer , sch , sndr ))
except that
is evaluated only once.
The exposition-only class template
is specialized
for
as follows:
env
be subexpressions such that Sndr
is decltype (( sndr ))
. If sender - for < Sndr , transfer_t >
is false
, then the expression transfer . transform_sender ( sndr , env )
is ill-formed; otherwise, it
is equal to:
-auto [ tag , data , child ] = sndr ; +-auto [ _ , data , child ] = sndr ; return schedule_from ( std :: move ( data ), std :: move ( child )); This causes the
+sender to become
transfer ( sndr , sch ) when it is connected with a receiver with an -execution domain that does not customize
schedule_from ( sch , sndr ) .
transfer This causes the
sender to become
transfer ( sndr , sch ) when it is connected with a receiver whose +execution domain does not customize
schedule_from ( sch , sndr ) .
transfer
Let
be a subexpression denoting a sender returned from
or one equal to such, and let
be the type
. Let
be a subexpression denoting a
receiver that has an environment of type
such that
is true
. Let
be an lvalue referring to the operation state that
results from connecting
with
. Calling
shall start
on the current execution agent and execute completion
operations on
on an execution agent of the execution resource
-associated with
. If scheduling onto
fails, execute an error
-completion on
on an unspecified execution agent.
sch
. If scheduling onto sch
fails, an error completion
+on out_rcvr
shall be executed on an unspecified execution agent.
execution :: schedule_from
[exec.schedule.from]sch
and sndr
, let Sch
be decltype (( sch ))
and Sndr
be decltype (( sndr ))
. If Sch
does not satisfy scheduler
, or Sndr
does not
-satisfy sender
, schedule_from
is ill-formed.
+satisfy sender
, schedule_from ( sch , sndr )
is ill-formed.
Otherwise, the expression
is expression-equivalent
to:
+transform_sender ( query - or - default ( get_domain , sch , default_domain ()), -make - sender ( schedule_from , sch , sndr )); +make - sender ( schedule_from , sch , sndr ))
except that
is evaluated only once.
The exposition-only class template
([exec.snd.general]) is specialized for
as
follows:
[] < class Sndr , class Rcvr > ( Sndr && sndr , Rcvr & rcvr ) +[] < class Sndr , class Rcvr > ( Sndr && sndr , Rcvr & rcvr ) noexcept ( see below ) requires sender_in < child - type < Sndr > , env_of_t < Rcvr >> { -return apply ( -[ & ] < class Sch , class Child > ( auto , Sch sch , Child && child ) { -using variant - type = see below ; -using receiver - type = see below ; -using operation - type = connect_result_t < schedule_result_t < Sch > , receiver - type > ; - -struct state - type { -Rcvr & rcvr ; -variant - type async - result ; -operation - type op - state ; - -explicit state - type ( Sch sch , Rcvr & rcvr ) -: rcvr ( rcvr ), op - state ( connect ( schedule ( sch ), receiver - type { {}, this })) {} -}; -return state - type { sch , rcvr }; -}, -std :: forward < Sndr > ( sndr )); +auto & [ _ , sch , child ] = sndr ; + +using sched - t = decltype ( auto ( sch )); +using variant - type = see below ; +using receiver - type = see below ; +using operation - type = connect_result_t < schedule_result_t < sched - t > , receiver - type > ; +constexpr bool nothrow = noexcept ( connect ( schedule ( sch ), receiver - type { nullptr })); + +struct state - type { +Rcvr & rcvr ; +variant - type async - result ; +operation - type op - state ; + +explicit state - type ( sched - t sch , Rcvr & rcvr ) noexcept ( nothrow ) +: rcvr ( rcvr ), op - state ( connect ( schedule ( sch ), receiver - type { this })) {} +}; + +return state - type { sch , rcvr }; }
- -
The local class
+is a structural type.
state - type Objects of the local class
can be used to + initialize a structured binding.
state - type Let
be a pack of the arguments to the
Sigs specialization named by
completion_signatures . Let
completion_signatures_of_t < Child , env_of_t < Rcvr >> be an alias template that transforms a completion signature
as - tuple into the
Tag ( Args ...) specialization
tuple . @@ -9659,9 +9683,6 @@
decayed - tuple < Tag , Args ... >
noexcept clause of the lambda istrue
if + the construction of the returnedobject is not + potentially throwing; otherwise,
state - type false
.
The member
is initialized with a callable object equivalent to the following lambda:
schedule_from ( sch , sndr )
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 , rcvr )
has undefined behavior unless it creates an
-asynchronous operation ([async.ops]) that, when started:
- eventually completes on an execution agent belonging to the associated
-execution resource of
, and
completes with the same async result as
.
Let
be a subexpression denoting a sender returned from
or one equal to such, and let
be the type
. Let
be a subexpression denoting a
+receiver that has an environment of type
such that
is true
. Let
be an lvalue referring to the operation state that
+results from connecting
with
. Calling
shall start
on the current execution agent and execute completion
+operations on
on an execution agent of the execution resource
+associated with
. If scheduling onto
fails, an error completion
+on
shall be executed on an unspecified execution agent.
execution :: then
, execution :: upon_error
, execution :: upon_stopped
[exec.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.
+objects. Let the expression then - cpo
be one of then
, upon_error
, or upon_stopped
. For subexpressions sndr
and f
, if decltype ( sndr )
does not satisfy sender
, or decltype ( f )
does not
+satisfy movable - value
, then - cpo ( sndr , f )
is ill-formed.
Otherwise, the expression
is
expression-equivalent to:
+transform_sender ( get - domain - early ( sndr ), -make - sender ( then - cpo , f , sndr )); +make - sender ( then - cpo , f , sndr ))
except that
is evaluated only once.
For
,
, and
, let
be
,
, and
respectively. The
exposition-only class template
([exec.snd.general]) is specialized for
as follows:
sndr
(for then
, upon_error
, and upon_stopped
respectively), using the result value of f
as out_sndr
’s value
+datums of sndr
for then
, upon_error
, and upon_stopped
respectively, using the result value of f
as out_sndr
’s value
completion, and
Forwards all other completion operations unchanged.
@@ -9777,8 +9799,8 @@let_value
, let_error
, or let_stopped
and let set - cpo
be the
-completion function that corresponds to let - cpo
(set_value
for let_value
, etc.). For a subexpression sndr
, let let - env ( sndr )
be expression-equivalent to the first
+ For
,
, and
, let
be
,
, and
respectively.
+Let the expression
be one of
,
, or
. For a subexpression
, let
be expression-equivalent to the first
well-formed expression below:
The names
,
, and
denote customization
-point objects. For subexpressions
and
, let
be
,
-let
be the decayed type of
. If
does not satisfy
or if
does not satisfy
, the expression
is ill-formed. If
does not satisfy
, the expression
is ill-formed.
sndr
and f
, let F
be the decayed
+type of f
. If decltype ( sndr )
does not satisfy sender
or if decltype ( f )
does not satisfy movable - value
, the expression let - cpo ( sndr , f )
is ill-formed. If F
does not satisfy invocable
, the expression let_stopped ( sndr , f )
is ill-formed.
Otherwise, the expression
is
expression-equivalent to:
+transform_sender ( get - domain - early ( sndr ), -make - sender ( let - cpo , f , sndr )); +make - sender ( let - cpo , f , sndr ))
except that
is evaluated only once.
The exposition-only class template
([exec.snd.general]) is specialized for
as
follows:
namespace std :: execution { template < class Rcvr , class Env > -struct receiver2 : Rcvr { -explicit receiver2 ( Rcvr rcvr , Env env ) -: Rcvr ( std :: move ( rcvr )), env ( std :: move ( env )) {} +struct receiver2 { +using receiver_concept = receiver_t ; -auto get_env () const noexcept { -const Rcvr & rcvr = * this ; +template < class ... Args > +void set_value ( Args && ... args ) && noexcept { +execution :: set_value ( std :: move ( rcvr ), std :: forward < Args > ( args )...); +} + +template < class Error > +void set_error ( Error && err ) && noexcept { +execution :: set_error ( std :: move ( rcvr ), std :: forward < Error > ( err )); +} + +void set_stopped () && noexcept { +execution :: set_stopped ( std :: move ( rcvr )); +} + +decltype ( auto ) get_env () const noexcept { return JOIN - ENV ( env , FWD - ENV ( execution :: get_env ( rcvr ))); } +Rcvr & rcvr ; // exposition only Env env ; // exposition only }; }
is
-is initialized with a callable object equivalent to the following:
[] < class Sndr , class Rcvr > ( Sndr && sndr , Rcvr & rcvr ) requires see below { -auto && [ tag , data , child ] = std :: forward < Sndr > ( sndr ); -return [ & ] < class Fn , class Env > ( Fn fn , Env env ) { -using args - variant - type = see below ; -using ops2 - variant - type = see below ; - -struct state - type { -Fn fn ; -Env env ; -args - variant - type args ; -ops2 - variant - type ops2 ; -}; -return state - type { std :: move ( fn ), std :: move ( env ), {}, {}}; -}( std :: forward_like < Sndr > ( data ), let - env ( child )); +auto & [ _ , fn , child ] = sndr ; +using fn - t = decay_t < decltype ( fn ) > ; +using env - t = decltype ( let - env ( child )); +using args - variant - type = see below ; +using ops2 - variant - type = see below ; + +struct state - type { +Fn fn ; +Env env ; +args - variant - type args ; +ops2 - variant - type ops2 ; +}; +return state - type { std :: forward_like < Sndr > ( fn ), let - env ( child ), {}, {}}; }
Let
be a pack of the arguments to the
specialization named by
. Let
be a pack of those types in
with a return type of
. Let
be an alias template such that
denotes the type
. Then
denotes the type
.
Let
be a pack of the arguments to the
specialization named by
. Let
be a pack of those types in
with a return type of
. Let
be an alias template such that
denotes the type
. Then
denotes the type
except with duplicate types removed.
Let
be an alias template such that
denotes the type
.
-Then
denotes the type
.
ops2 - variant - type
denotes the type variant < monostate , connect_result_t < as - sndr2 < LetSigs > , receiver2 < Rcvr , Env >> ... >
except with duplicate types removed.
The requires-clause constraining the above lambda is
satisfied if and only if the types
and
are well-formed.
The exposition-only function template
is equal to:
auto & args = state . args . emplace < decayed - tuple < Args ... >> ( std :: forward < Args > ( args )...); -auto sndr2 = apply ( std :: move ( state . fn ), args ); -auto rcvr2 = receiver2 { std :: move ( rcvr ), std :: move ( state . env )}; -auto mkop2 = [ & ] { return connect ( std :: move ( sndr2 ), std :: move ( rcvr2 )); }; -auto & op2 = state . ops2 . emplace < decltype ( mkop2 ()) > ( emplace - from { mkop2 }); -start ( op2 ); +The exposition-only function template
+has effects equivalent to:
let - bind using args_t = decayed - tuple < Args ... > ; +auto mkop2 = [ & ] { +return connect ( +apply ( std :: move ( state . fn ), state . args . emplace < args_t > ( std :: forward < Args > ( args )...)), +receiver2 { rcvr , std :: move ( state . env )}); +}; +start ( state . ops2 . emplace < decltype ( mkop2 ()) > ( emplace - from { mkop2 }));
is
@@ -9886,7 +9923,7 @@
env
be subexpressions, and let Sndr
be decltype (( sndr ))
.
If sender - for < Sndr , decayed - typeof < 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 ))
.
Let the subexpression
denote the result of the invocation
or an object copied or moved from such,
+
Let the subexpression
denote the result of the invocation
or an object equal to such,
and let the subexpression
denote a receiver such that the expression
is well-formed. The expression
has undefined behavior unless it creates an asynchronous operation
([async.ops]) that, when started:
The name
denotes a customization point object. For subexpressions
,
, and
, let
be
, let
be
-the decayed type of
, and let
be the decayed type of
. If
does not satisfy
, or if
does not satisfy
,
-or if
does not satisfy
,
is ill-formed.
The name
denotes a customization point object. For subexpressions
,
, and
, let
be
. If
does not satisfy
, or if
does not
+satisfy
, or if
does not satisfy
,
is ill-formed.
Otherwise, the expression
is
expression-equivalent to:
+transform_sender ( get - domain - early ( sndr ), -make - sender ( bulk , product - type { shape , f }, sndr )); +make - sender ( bulk , product - type { shape , f }, sndr ))
except that
is evaluated only once.
The exposition-only class template
([exec.snd.general]) is specialized for
as follows:
namespace std :: execution { @@ -9934,7 +9971,7 @@
out_sndr denote the result of the invocationor an object copied or moved from such, +
bulk ( sndr , shape , f ) Let the subexpression
denote the result of the invocation
out_sndr or an object equal to such, and let the subexpression
bulk ( sndr , shape , f ) denote a receiver such that the expression
rcvr is well-formed. The expression
connect ( out_sndr , rcvr ) has undefined behavior unless it creates an asynchronous operation ([async.ops]) that, when started:
connect ( out_sndr , rcvr )