Difference between revisions of "Template:cpp/synopsis/execution"
From cppreference.com
(from current draft) |
m (Apply MRU exec.tex from draft/source. Some concepts are not ready yet.) |
||
Line 1: | Line 1: | ||
{{source|1= | {{source|1= | ||
namespace std { | namespace std { | ||
− | template<class T> struct is_execution_policy; | + | // execution policy type trait |
− | template<class T> constexpr bool is_execution_policy_v = is_execution_policy<T>::value; | + | template<class T> |
+ | struct is_execution_policy; | ||
+ | template<class T> | ||
+ | constexpr bool is_execution_policy_v = is_execution_policy<T>::value; | ||
} | } | ||
namespace std::execution { | namespace std::execution { | ||
+ | // sequenced execution policy | ||
class sequenced_policy; | class sequenced_policy; | ||
+ | // parallel execution policy | ||
class parallel_policy; | class parallel_policy; | ||
+ | // parallel and unsequenced execution policy | ||
class parallel_unsequenced_policy; | class parallel_unsequenced_policy; | ||
+ | // unsequenced execution policy | ||
class unsequenced_policy; | class unsequenced_policy; | ||
− | inline constexpr sequenced_policy | + | // execution policy objects |
− | inline constexpr parallel_policy | + | inline constexpr sequenced_policy seq{ /* unspecified */ }; |
− | inline constexpr parallel_unsequenced_policy par_unseq{ unspecified }; | + | inline constexpr parallel_policy par{ /* unspecified */ }; |
− | inline constexpr unsequenced_policy | + | inline constexpr parallel_unsequenced_policy par_unseq{ /* unspecified */ }; |
+ | inline constexpr unsequenced_policy unseq{ /* unspecified */ }; | ||
} | } | ||
namespace std { | namespace std { | ||
+ | // helper concepts | ||
template<class T> | template<class T> | ||
− | + | concept /*movable-value*/ = /* see description */; // exposition only | |
template<class From, class To> | template<class From, class To> | ||
− | + | concept /*decays-to*/ = same_as<decay_t<From>, To>; // exposition only | |
template<class T> | template<class T> | ||
− | + | concept /*class-type*/ = /*decays-to*/<T, T> && is_class_v<T>; // exposition only | |
+ | // queryable objects | ||
template<class T> | template<class T> | ||
− | + | concept /*queryable*/ = /* see description */; // exposition only | |
− | struct forwarding_query_t { /*unspecified*/ }; | + | // queries |
− | struct get_allocator_t { /*unspecified*/ }; | + | struct forwarding_query_t |
− | struct get_stop_token_t { /*unspecified*/ }; | + | { /* unspecified */ |
+ | }; | ||
+ | struct get_allocator_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct get_stop_token_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr forwarding_query_t forwarding_query{}; | inline constexpr forwarding_query_t forwarding_query{}; | ||
Line 42: | Line 59: | ||
template<class T> | template<class T> | ||
− | + | using stop_token_of_t = remove_cvref_t<decltype(get_stop_token(declval<T>()))>; | |
template<class T> | template<class T> | ||
− | + | concept /*forwarding-query*/ = forwarding_query(T{}); // exposition only | |
} | } | ||
namespace std::execution { | namespace std::execution { | ||
− | struct get_domain_t { /*unspecified*/ }; | + | // queries |
− | struct get_scheduler_t { /*unspecified*/ }; | + | struct get_domain_t |
− | struct get_delegation_scheduler_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct get_forward_progress_guarantee_t { /*unspecified*/ }; | + | }; |
+ | struct get_scheduler_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct get_delegation_scheduler_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct get_forward_progress_guarantee_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
template<class CPO> | template<class CPO> | ||
− | + | struct get_completion_scheduler_t | |
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr get_domain_t get_domain{}; | inline constexpr get_domain_t get_domain{}; | ||
Line 62: | Line 90: | ||
inline constexpr get_forward_progress_guarantee_t get_forward_progress_guarantee{}; | inline constexpr get_forward_progress_guarantee_t get_forward_progress_guarantee{}; | ||
template<class CPO> | template<class CPO> | ||
− | + | constexpr get_completion_scheduler_t<CPO> get_completion_scheduler{}; | |
− | struct empty_env {}; | + | struct empty_env |
− | struct get_env_t { /*unspecified*/ }; | + | {}; |
+ | struct get_env_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr get_env_t get_env{}; | inline constexpr get_env_t get_env{}; | ||
template<class T> | template<class T> | ||
− | + | using env_of_t = decltype(get_env(declval<T>())); | |
+ | // execution domains | ||
struct default_domain; | struct default_domain; | ||
− | struct scheduler_t {}; | + | // schedulers |
+ | struct scheduler_t | ||
+ | {}; | ||
template<class Sch> | template<class Sch> | ||
− | + | concept scheduler = /* see description */; | |
− | struct receiver_t {}; | + | // receivers |
+ | struct receiver_t | ||
+ | {}; | ||
template<class Rcvr> | template<class Rcvr> | ||
− | + | concept receiver = /* see description */; | |
template<class Rcvr, class Completions> | template<class Rcvr, class Completions> | ||
− | + | concept receiver_of = /* see description */; | |
− | struct set_value_t { /*unspecified*/ }; | + | struct set_value_t |
− | struct set_error_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct set_stopped_t { /*unspecified*/ }; | + | }; |
+ | struct set_error_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct set_stopped_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr set_value_t set_value{}; | inline constexpr set_value_t set_value{}; | ||
Line 94: | Line 136: | ||
inline constexpr set_stopped_t set_stopped{}; | inline constexpr set_stopped_t set_stopped{}; | ||
− | struct operation_state_t {}; | + | // operation states |
+ | struct operation_state_t | ||
+ | {}; | ||
template<class O> | template<class O> | ||
− | + | concept operation_state = /* see description */; | |
struct start_t; | struct start_t; | ||
inline constexpr start_t start{}; | inline constexpr start_t start{}; | ||
− | struct sender_t {}; | + | // senders |
+ | struct sender_t | ||
+ | {}; | ||
template<class Sndr> | template<class Sndr> | ||
− | + | concept sender = /* see description */; | |
template<class Sndr, class Env = empty_env> | template<class Sndr, class Env = empty_env> | ||
− | + | concept sender_in = /* see description */; | |
template<class Sndr, class Rcvr> | template<class Sndr, class Rcvr> | ||
− | + | concept sender_to = /* see description */; | |
template<class... Ts> | template<class... Ts> | ||
− | + | struct /*type-list*/; // exposition only | |
+ | // completion signatures | ||
struct get_completion_signatures_t; | struct get_completion_signatures_t; | ||
− | inline constexpr get_completion_signatures_t get_completion_signatures {}; | + | inline constexpr get_completion_signatures_t get_completion_signatures{}; |
template<class Sndr, class Env = empty_env> | template<class Sndr, class Env = empty_env> | ||
− | + | requires sender_in<Sndr, Env> | |
− | + | using completion_signatures_of_t = | |
+ | /*call-result-t*/<get_completion_signatures_t, Sndr, Env>; | ||
template<class... Ts> | template<class... Ts> | ||
− | + | using /*decayed-tuple*/ = tuple<decay_t<Ts>...>; // exposition only | |
template<class... Ts> | template<class... Ts> | ||
− | + | using /*variant-or-empty*/ = /* see description */; // exposition only | |
− | template<class Sndr, class Env = empty_env, | + | template<class Sndr, |
− | template<class...> class Tuple = /*decayed-tuple*/, | + | class Env = empty_env, |
+ | template<class...> class Tuple = /*decayed-tuple*/, | ||
template<class...> class Variant = /*variant-or-empty*/> | template<class...> class Variant = /*variant-or-empty*/> | ||
− | + | requires sender_in<Sndr, Env> | |
− | + | using value_types_of_t = /* see description */; | |
− | template<class Sndr, class Env = empty_env, | + | template<class Sndr, |
+ | class Env = empty_env, | ||
template<class...> class Variant = /*variant-or-empty*/> | template<class...> class Variant = /*variant-or-empty*/> | ||
− | + | requires sender_in<Sndr, Env> | |
− | + | using error_types_of_t = /* see description */; | |
template<class Sndr, class Env = empty_env> | template<class Sndr, class Env = empty_env> | ||
− | + | requires sender_in<Sndr, Env> | |
− | + | constexpr bool sends_stopped = /* see description */; | |
template<class Sndr, class Env> | template<class Sndr, class Env> | ||
− | + | using /*single-sender-value-type*/ = /* see description */; // exposition only | |
template<class Sndr, class Env> | template<class Sndr, class Env> | ||
− | + | concept /*single-sender*/ = /* see description */; // exposition only | |
template<sender Sndr> | template<sender Sndr> | ||
− | + | using tag_of_t = /* see description */; | |
− | template<class Domain, sender Sndr, queryable... Env> | + | // sender transformations |
− | + | template<class Domain, sender Sndr, /*queryable*/... Env> | |
− | + | requires(sizeof...(Env) <= 1) | |
− | + | constexpr sender decltype(auto) transform_sender( | |
+ | Domain dom, | ||
+ | Sndr&& sndr, | ||
+ | const Env&... env) noexcept(/* see description */); | ||
− | template<class Domain, sender Sndr, queryable Env> | + | // environment transformations |
− | + | template<class Domain, sender Sndr, /*queryable*/ Env> | |
− | + | constexpr /*queryable*/ decltype(auto) transform_env(Domain dom, | |
+ | Sndr&& sndr, | ||
+ | Env&& env) noexcept; | ||
+ | // sender algorithm application | ||
template<class Domain, class Tag, sender Sndr, class... Args> | template<class Domain, class Tag, sender Sndr, class... Args> | ||
− | + | constexpr decltype(auto) apply_sender(Domain dom, | |
− | + | Tag, | |
+ | Sndr&& sndr, | ||
+ | Args&&... args) noexcept(/* see description */); | ||
+ | // the connect sender algorithm | ||
struct connect_t; | struct connect_t; | ||
inline constexpr connect_t connect{}; | inline constexpr connect_t connect{}; | ||
template<class Sndr, class Rcvr> | template<class Sndr, class Rcvr> | ||
− | + | using connect_result_t = decltype(connect(declval<Sndr>(), declval<Rcvr>())); | |
− | + | ||
− | struct just_t { /*unspecified*/ }; | + | // sender factories |
− | struct just_error_t { /*unspecified*/ }; | + | struct just_t |
− | struct just_stopped_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct schedule_t { /*unspecified*/ }; | + | }; |
+ | struct just_error_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct just_stopped_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct schedule_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr just_t just{}; | inline constexpr just_t just{}; | ||
Line 182: | Line 249: | ||
inline constexpr just_stopped_t just_stopped{}; | inline constexpr just_stopped_t just_stopped{}; | ||
inline constexpr schedule_t schedule{}; | inline constexpr schedule_t schedule{}; | ||
− | inline constexpr unspecified read_env{}; | + | inline constexpr /* unspecified */ read_env{}; |
template<scheduler Sndr> | template<scheduler Sndr> | ||
− | + | using schedule_result_t = decltype(schedule(declval<Sndr>())); | |
− | template<class-type D> | + | // sender adaptors |
− | + | template</*class-type*/ D> | |
+ | struct sender_adaptor_closure | ||
+ | {}; | ||
− | struct starts_on_t { /*unspecified*/ }; | + | struct starts_on_t |
− | struct continues_on_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct on_t { /*unspecified*/ }; | + | }; |
− | struct schedule_from_t { /*unspecified*/ }; | + | struct continues_on_t |
− | struct then_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct upon_error_t { /*unspecified*/ }; | + | }; |
− | struct upon_stopped_t { /*unspecified*/ }; | + | struct on_t |
− | struct let_value_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct let_error_t { /*unspecified*/ }; | + | }; |
− | struct let_stopped_t { /*unspecified*/ }; | + | struct schedule_from_t |
− | struct bulk_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct split_t { /*unspecified*/ }; | + | }; |
− | struct when_all_t { /*unspecified*/ }; | + | struct then_t |
− | struct when_all_with_variant_t { /*unspecified*/ }; | + | { /* unspecified */ |
− | struct into_variant_t { /*unspecified*/ }; | + | }; |
− | struct stopped_as_optional_t { /*unspecified*/ }; | + | struct upon_error_t |
− | struct stopped_as_error_t { /*unspecified*/ }; | + | { /* unspecified */ |
+ | }; | ||
+ | struct upon_stopped_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct let_value_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct let_error_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct let_stopped_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct bulk_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct split_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct when_all_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct when_all_with_variant_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct into_variant_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct stopped_as_optional_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct stopped_as_error_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr starts_on_t starts_on{}; | inline constexpr starts_on_t starts_on{}; | ||
Line 225: | Line 328: | ||
inline constexpr stopped_as_optional_t stopped_as_optional{}; | inline constexpr stopped_as_optional_t stopped_as_optional{}; | ||
inline constexpr stopped_as_error_t stopped_as_error{}; | inline constexpr stopped_as_error_t stopped_as_error{}; | ||
+ | |||
+ | // sender and receiver utilities | ||
template<class Fn> | template<class Fn> | ||
− | + | concept /*completion-signature*/ = /* see description */; // exposition only | |
− | template<completion-signature... Fns> | + | template</*completion-signature*/... Fns> |
− | + | struct completion_signatures | |
+ | {}; | ||
template<class Sigs> | template<class Sigs> | ||
− | + | concept /*valid-completion-signatures*/ = /* see description */; // exposition only | |
− | template< | + | template</*valid-completion-signatures*/ InputSignatures, |
− | + | /*valid-completion-signatures*/ AdditionalSignatures = completion_signatures<>, | |
− | + | template<class...> class SetValue = /* see description */, | |
− | + | template<class> class SetError = /* see description */, | |
− | + | /*valid-completion-signatures*/ SetStopped = | |
− | + | completion_signatures<set_stopped_t()>> | |
− | using transform_completion_signatures = completion_signatures</*see description*/>; | + | using transform_completion_signatures = completion_signatures</* see description */>; |
− | template< | + | template<sender Sndr, |
− | + | class Env = empty_env, | |
− | + | /*valid-completion-signatures*/ AdditionalSignatures = completion_signatures<>, | |
− | + | template<class...> class SetValue = /* see description */, | |
− | + | template<class> class SetError = /* see description */, | |
− | + | /*valid-completion-signatures*/ SetStopped = | |
− | + | completion_signatures<set_stopped_t()>> | |
− | + | requires sender_in<Sndr, Env> | |
using transform_completion_signatures_of = | using transform_completion_signatures_of = | ||
− | transform_completion_signatures< | + | transform_completion_signatures<completion_signatures_of_t<Sndr, Env>, |
− | + | AdditionalSignatures, | |
− | + | SetValue, | |
+ | SetError, | ||
+ | SetStopped>; | ||
+ | // run_loop | ||
class run_loop; | class run_loop; | ||
} | } | ||
namespace std::this_thread { | namespace std::this_thread { | ||
− | struct sync_wait_t { /*unspecified*/ }; | + | // consumers |
− | struct sync_wait_with_variant_t { /*unspecified*/ }; | + | struct sync_wait_t |
+ | { /* unspecified */ | ||
+ | }; | ||
+ | struct sync_wait_with_variant_t | ||
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr sync_wait_t sync_wait{}; | inline constexpr sync_wait_t sync_wait{}; | ||
Line 268: | Line 382: | ||
namespace std::execution { | namespace std::execution { | ||
− | struct as_awaitable_t { /*unspecified*/ }; | + | struct as_awaitable_t |
+ | { /* unspecified */ | ||
+ | }; | ||
inline constexpr as_awaitable_t as_awaitable{}; | inline constexpr as_awaitable_t as_awaitable{}; | ||
− | template<class-type Promise> | + | template</*class-type*/ Promise> |
− | + | struct with_awaitable_senders; | |
+ | } | ||
+ | }} | ||
+ | |||
+ | ====Helper concepts==== | ||
+ | {{source|1= | ||
+ | namespace std { | ||
+ | template<class T> | ||
+ | concept /*movable-value*/ = // exposition only | ||
+ | move_constructible<decay_t<T>> && constructible_from<decay_t<T>, T> && | ||
+ | (!is_array_v<remove_reference_t<T>>); | ||
+ | } | ||
+ | |||
+ | namespace std { | ||
+ | template<class T> | ||
+ | concept /*queryable*/ = destructible<T>; // exposition only | ||
+ | } | ||
+ | |||
+ | namespace std::execution { | ||
+ | template<class Sndr, class Env> | ||
+ | concept /*single-sender*/ = sender_in<Sndr, Env> && requires { | ||
+ | typename /*single-sender-value-type*/<Sndr, Env>; | ||
+ | }; | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ====Helper classes==== | ||
+ | {{source|1= | ||
+ | namespace std::execution { | ||
+ | struct /*empty-variant*/ | ||
+ | { // exposition only | ||
+ | /*empty-variant*/() = delete; | ||
+ | }; | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ===={{tt|enum}} {{lc|std::forward_progress_guarantee}}==== | ||
+ | {{source|1= | ||
+ | namespace std::execution { | ||
+ | enum class forward_progress_guarantee | ||
+ | { | ||
+ | concurrent, | ||
+ | parallel, | ||
+ | weakly_parallel | ||
+ | }; | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ====Concept {{lconcept|scheduler}}==== | ||
+ | {{source|1= | ||
+ | namespace std::execution { | ||
+ | template<class Sch> | ||
+ | concept scheduler = | ||
+ | derived_from<typename remove_cvref_t<Sch>::scheduler_concept, scheduler_t> && | ||
+ | /*queryable*/<Sch> && | ||
+ | requires(Sch&& sch) { | ||
+ | { | ||
+ | schedule(std::forward<Sch>(sch)) | ||
+ | } -> sender; | ||
+ | { | ||
+ | auto(get_completion_scheduler<set_value_t>( | ||
+ | get_env(schedule(std::forward<Sch>(sch))))) | ||
+ | } -> same_as<remove_cvref_t<Sch>>; | ||
+ | } && equality_comparable<remove_cvref_t<Sch>> && | ||
+ | copy_constructible<remove_cvref_t<Sch>>; | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ====Concept {{lconcept|receiver}}==== | ||
+ | {{source|1= | ||
+ | namespace std::execution { | ||
+ | template<class Rcvr> | ||
+ | concept receiver = | ||
+ | derived_from<typename remove_cvref_t<Rcvr>::receiver_concept, receiver_t> && | ||
+ | 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 | ||
+ | |||
+ | template<class Signature, class Rcvr> | ||
+ | concept /*valid-completion-for*/ = 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*/ = 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>; | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ====Concept {{lconcept|operation_state}}==== | ||
+ | {{source|1= | ||
+ | namespace std::execution { | ||
+ | template<class O> | ||
+ | concept operation_state = | ||
+ | derived_from<typename O::operation_state_concept, operation_state_t> && | ||
+ | is_object_v<O> && requires(O& o) { | ||
+ | { | ||
+ | start(o) | ||
+ | } noexcept; | ||
+ | }; | ||
} | } | ||
}} | }} |
Latest revision as of 07:29, 4 October 2024
namespace std { // execution policy type trait template<class T> struct is_execution_policy; template<class T> constexpr bool is_execution_policy_v = is_execution_policy<T>::value; } namespace std::execution { // sequenced execution policy class sequenced_policy; // parallel execution policy class parallel_policy; // parallel and unsequenced execution policy class parallel_unsequenced_policy; // unsequenced execution policy class unsequenced_policy; // execution policy objects inline constexpr sequenced_policy seq{ /* unspecified */ }; inline constexpr parallel_policy par{ /* unspecified */ }; inline constexpr parallel_unsequenced_policy par_unseq{ /* unspecified */ }; inline constexpr unsequenced_policy unseq{ /* unspecified */ }; } namespace std { // helper concepts template<class T> concept /*movable-value*/ = /* see description */; // exposition only template<class From, class To> concept /*decays-to*/ = same_as<decay_t<From>, To>; // exposition only template<class T> concept /*class-type*/ = /*decays-to*/<T, T> && is_class_v<T>; // exposition only // queryable objects template<class T> concept /*queryable*/ = /* see description */; // exposition only // queries struct forwarding_query_t { /* unspecified */ }; struct get_allocator_t { /* unspecified */ }; struct get_stop_token_t { /* unspecified */ }; inline constexpr forwarding_query_t forwarding_query{}; inline constexpr get_allocator_t get_allocator{}; inline constexpr get_stop_token_t get_stop_token{}; template<class T> using stop_token_of_t = remove_cvref_t<decltype(get_stop_token(declval<T>()))>; template<class T> concept /*forwarding-query*/ = forwarding_query(T{}); // exposition only } namespace std::execution { // queries struct get_domain_t { /* unspecified */ }; struct get_scheduler_t { /* unspecified */ }; struct get_delegation_scheduler_t { /* unspecified */ }; struct get_forward_progress_guarantee_t { /* unspecified */ }; template<class CPO> struct get_completion_scheduler_t { /* unspecified */ }; inline constexpr get_domain_t get_domain{}; inline constexpr get_scheduler_t get_scheduler{}; inline constexpr get_delegation_scheduler_t get_delegation_scheduler{}; enum class forward_progress_guarantee; inline constexpr get_forward_progress_guarantee_t get_forward_progress_guarantee{}; template<class CPO> constexpr get_completion_scheduler_t<CPO> get_completion_scheduler{}; struct empty_env {}; struct get_env_t { /* unspecified */ }; inline constexpr get_env_t get_env{}; template<class T> using env_of_t = decltype(get_env(declval<T>())); // execution domains struct default_domain; // schedulers struct scheduler_t {}; template<class Sch> concept scheduler = /* see description */; // receivers struct receiver_t {}; template<class Rcvr> concept receiver = /* see description */; template<class Rcvr, class Completions> concept receiver_of = /* see description */; struct set_value_t { /* unspecified */ }; struct set_error_t { /* unspecified */ }; struct set_stopped_t { /* unspecified */ }; inline constexpr set_value_t set_value{}; inline constexpr set_error_t set_error{}; inline constexpr set_stopped_t set_stopped{}; // operation states struct operation_state_t {}; template<class O> concept operation_state = /* see description */; struct start_t; inline constexpr start_t start{}; // senders struct sender_t {}; template<class Sndr> concept sender = /* see description */; template<class Sndr, class Env = empty_env> concept sender_in = /* see description */; template<class Sndr, class Rcvr> concept sender_to = /* see description */; template<class... Ts> struct /*type-list*/; // exposition only // completion signatures struct get_completion_signatures_t; inline constexpr get_completion_signatures_t get_completion_signatures{}; template<class Sndr, class Env = empty_env> requires sender_in<Sndr, Env> using completion_signatures_of_t = /*call-result-t*/<get_completion_signatures_t, Sndr, Env>; template<class... Ts> using /*decayed-tuple*/ = tuple<decay_t<Ts>...>; // exposition only template<class... Ts> using /*variant-or-empty*/ = /* see description */; // exposition only template<class Sndr, class Env = empty_env, template<class...> class Tuple = /*decayed-tuple*/, template<class...> class Variant = /*variant-or-empty*/> requires sender_in<Sndr, Env> using value_types_of_t = /* see description */; template<class Sndr, class Env = empty_env, template<class...> class Variant = /*variant-or-empty*/> requires sender_in<Sndr, Env> using error_types_of_t = /* see description */; template<class Sndr, class Env = empty_env> requires sender_in<Sndr, Env> constexpr bool sends_stopped = /* see description */; template<class Sndr, class Env> using /*single-sender-value-type*/ = /* see description */; // exposition only template<class Sndr, class Env> concept /*single-sender*/ = /* see description */; // exposition only template<sender Sndr> using tag_of_t = /* see description */; // sender transformations template<class Domain, sender Sndr, /*queryable*/... Env> requires(sizeof...(Env) <= 1) constexpr sender decltype(auto) transform_sender( Domain dom, Sndr&& sndr, const Env&... env) noexcept(/* see description */); // environment transformations template<class Domain, sender Sndr, /*queryable*/ Env> constexpr /*queryable*/ decltype(auto) transform_env(Domain dom, Sndr&& sndr, Env&& env) noexcept; // sender algorithm application template<class Domain, class Tag, sender Sndr, class... Args> constexpr decltype(auto) apply_sender(Domain dom, Tag, Sndr&& sndr, Args&&... args) noexcept(/* see description */); // the connect sender algorithm struct connect_t; inline constexpr connect_t connect{}; template<class Sndr, class Rcvr> using connect_result_t = decltype(connect(declval<Sndr>(), declval<Rcvr>())); // sender factories struct just_t { /* unspecified */ }; struct just_error_t { /* unspecified */ }; struct just_stopped_t { /* unspecified */ }; struct schedule_t { /* unspecified */ }; inline constexpr just_t just{}; inline constexpr just_error_t just_error{}; inline constexpr just_stopped_t just_stopped{}; inline constexpr schedule_t schedule{}; inline constexpr /* unspecified */ read_env{}; template<scheduler Sndr> using schedule_result_t = decltype(schedule(declval<Sndr>())); // sender adaptors template</*class-type*/ D> struct sender_adaptor_closure {}; struct starts_on_t { /* unspecified */ }; struct continues_on_t { /* unspecified */ }; struct on_t { /* unspecified */ }; struct schedule_from_t { /* unspecified */ }; struct then_t { /* unspecified */ }; struct upon_error_t { /* unspecified */ }; struct upon_stopped_t { /* unspecified */ }; struct let_value_t { /* unspecified */ }; struct let_error_t { /* unspecified */ }; struct let_stopped_t { /* unspecified */ }; struct bulk_t { /* unspecified */ }; struct split_t { /* unspecified */ }; struct when_all_t { /* unspecified */ }; struct when_all_with_variant_t { /* unspecified */ }; struct into_variant_t { /* unspecified */ }; struct stopped_as_optional_t { /* unspecified */ }; struct stopped_as_error_t { /* unspecified */ }; inline constexpr starts_on_t starts_on{}; inline constexpr continues_on_t continues_on{}; inline constexpr on_t on{}; inline constexpr schedule_from_t schedule_from{}; inline constexpr then_t then{}; inline constexpr upon_error_t upon_error{}; inline constexpr upon_stopped_t upon_stopped{}; inline constexpr let_value_t let_value{}; inline constexpr let_error_t let_error{}; inline constexpr let_stopped_t let_stopped{}; inline constexpr bulk_t bulk{}; inline constexpr split_t split{}; inline constexpr when_all_t when_all{}; inline constexpr when_all_with_variant_t when_all_with_variant{}; inline constexpr into_variant_t into_variant{}; inline constexpr stopped_as_optional_t stopped_as_optional{}; inline constexpr stopped_as_error_t stopped_as_error{}; // sender and receiver utilities template<class Fn> concept /*completion-signature*/ = /* see description */; // exposition only template</*completion-signature*/... Fns> struct completion_signatures {}; template<class Sigs> concept /*valid-completion-signatures*/ = /* see description */; // exposition only template</*valid-completion-signatures*/ InputSignatures, /*valid-completion-signatures*/ AdditionalSignatures = completion_signatures<>, template<class...> class SetValue = /* see description */, template<class> class SetError = /* see description */, /*valid-completion-signatures*/ SetStopped = completion_signatures<set_stopped_t()>> using transform_completion_signatures = completion_signatures</* see description */>; template<sender Sndr, class Env = empty_env, /*valid-completion-signatures*/ AdditionalSignatures = completion_signatures<>, template<class...> class SetValue = /* see description */, template<class> class SetError = /* see description */, /*valid-completion-signatures*/ SetStopped = completion_signatures<set_stopped_t()>> requires sender_in<Sndr, Env> using transform_completion_signatures_of = transform_completion_signatures<completion_signatures_of_t<Sndr, Env>, AdditionalSignatures, SetValue, SetError, SetStopped>; // run_loop class run_loop; } namespace std::this_thread { // consumers struct sync_wait_t { /* unspecified */ }; struct sync_wait_with_variant_t { /* unspecified */ }; inline constexpr sync_wait_t sync_wait{}; inline constexpr sync_wait_with_variant_t sync_wait_with_variant{}; } namespace std::execution { struct as_awaitable_t { /* unspecified */ }; inline constexpr as_awaitable_t as_awaitable{}; template</*class-type*/ Promise> struct with_awaitable_senders; }
Contents |
[edit] Helper concepts
namespace std { template<class T> concept /*movable-value*/ = // exposition only move_constructible<decay_t<T>> && constructible_from<decay_t<T>, T> && (!is_array_v<remove_reference_t<T>>); } namespace std { template<class T> concept /*queryable*/ = destructible<T>; // exposition only } namespace std::execution { template<class Sndr, class Env> concept /*single-sender*/ = sender_in<Sndr, Env> && requires { typename /*single-sender-value-type*/<Sndr, Env>; }; }
[edit] Helper classes
namespace std::execution { struct /*empty-variant*/ { // exposition only /*empty-variant*/() = delete; }; }
[edit] enum
std::forward_progress_guarantee
namespace std::execution { enum class forward_progress_guarantee { concurrent, parallel, weakly_parallel }; }
[edit] Concept scheduler
namespace std::execution { template<class Sch> concept scheduler = derived_from<typename remove_cvref_t<Sch>::scheduler_concept, scheduler_t> && /*queryable*/<Sch> && requires(Sch&& sch) { { schedule(std::forward<Sch>(sch)) } -> sender; { auto(get_completion_scheduler<set_value_t>( get_env(schedule(std::forward<Sch>(sch))))) } -> same_as<remove_cvref_t<Sch>>; } && equality_comparable<remove_cvref_t<Sch>> && copy_constructible<remove_cvref_t<Sch>>; }
[edit] Concept receiver
namespace std::execution { template<class Rcvr> concept receiver = derived_from<typename remove_cvref_t<Rcvr>::receiver_concept, receiver_t> && 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 template<class Signature, class Rcvr> concept /*valid-completion-for*/ = 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*/ = 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>; }
[edit] Concept operation_state
namespace std::execution { template<class O> concept operation_state = derived_from<typename O::operation_state_concept, operation_state_t> && is_object_v<O> && requires(O& o) { { start(o) } noexcept; }; }