33 Execution control library [exec]

33.4 Header <execution> synopsis [execution.syn]

namespace std { // [execpol.type], execution policy type trait template<class T> struct is_execution_policy; // freestanding template<class T> constexpr bool is_execution_policy_v = // freestanding is_execution_policy<T>::value; } namespace std::execution { // [execpol.seq], sequenced execution policy class sequenced_policy; // [execpol.par], parallel execution policy class parallel_policy; // [execpol.parunseq], parallel and unsequenced execution policy class parallel_unsequenced_policy; // [execpol.unseq], unsequenced execution policy class unsequenced_policy; // [execpol.objects], 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 { // [exec.general], helper concepts template<class T> concept movable-value = see below; // 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 // [exec.queryable], queryable objects template<class T> concept queryable = see below; // exposition only // [exec.queries], 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 { // [exec.queries], 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 }; struct get_await_completion_adaptor_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{}; inline constexpr get_await_completion_adaptor_t get_await_completion_adaptor{}; struct get_env_t { unspecified }; inline constexpr get_env_t get_env{}; template<class T> using env_of_t = decltype(get_env(declval<T>())); // [exec.prop], class template prop template<class QueryTag, class ValueType> struct prop; // [exec.env], class template env template<queryable... Envs> struct env; // [exec.domain.default], execution domains struct default_domain; // [exec.sched], schedulers struct scheduler_t {}; template<class Sch> concept scheduler = see below; // [exec.recv], receivers struct receiver_t {}; template<class Rcvr> concept receiver = see below; template<class Rcvr, class Completions> concept receiver_of = see below; 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{}; // [exec.opstate], operation states struct operation_state_t {}; template<class O> concept operation_state = see below; struct start_t; inline constexpr start_t start{}; // [exec.snd], senders struct sender_t {}; template<class Sndr> concept sender = see below; template<class Sndr, class... Env> concept sender_in = see below; template<class Sndr> concept dependent_sender = see below; template<class Sndr, class Rcvr> concept sender_to = see below; template<class... Ts> struct type-list; // exposition only template<class... Ts> using decayed-tuple = tuple<decay_t<Ts>...>; // exposition only template<class... Ts> using variant-or-empty = see below; // exposition only template<class Sndr, class Env = 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 below; template<class Sndr, class Env = env<>, template<class...> class Variant = variant-or-empty> requires sender_in<Sndr, Env> using error_types_of_t = see below; template<class Sndr, class Env = env<>> requires sender_in<Sndr, Env> constexpr bool sends_stopped = see below; template<class Sndr, class... Env> using single-sender-value-type = see below; // exposition only template<class Sndr, class... Env> concept single-sender = see below; // exposition only template<sender Sndr> using tag_of_t = see below; // [exec.snd.transform], 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 below); // [exec.snd.transform.env], environment transformations template<class Domain, sender Sndr, queryable Env> constexpr queryable decltype(auto) transform_env( Domain dom, Sndr&& sndr, Env&& env) noexcept; // [exec.snd.apply], 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 below); // [exec.connect], 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>())); // [exec.factories], 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 Sch> using schedule_result_t = decltype(schedule(declval<Sch>())); // [exec.adapt], 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 bulk_chunked_t { unspecified }; struct bulk_unchunked_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 }; struct associate_t { unspecified }; struct spawn_future_t { unspecified }; inline constexpr unspecified write_env{}; inline constexpr unspecified unstoppable{}; 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 bulk_chunked_t bulk_chunked{}; inline constexpr bulk_unchunked_t bulk_unchunked{}; 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{}; inline constexpr associate_t associate{}; inline constexpr spawn_future_t spawn_future{}; // [exec.cmplsig], completion signatures template<class Fn> concept completion-signature = see below; // exposition only template<completion-signature... Fns> struct completion_signatures; template<class Sigs> concept valid-completion-signatures = see below; // exposition only struct dependent_sender_error : exception {}; // [exec.getcomplsigs] template<class Sndr, class... Env> consteval auto get_completion_signatures() -> valid-completion-signatures auto; template<class Sndr, class... Env> requires sender_in<Sndr, Env...> using completion_signatures_of_t = decltype(get_completion_signatures<Sndr, Env...>()); // [exec.run.loop], run_loop class run_loop; } namespace std::this_thread { // [exec.consumers], 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 { // [exec.consumers], consumers struct spawn_t { unspecified }; inline constexpr spawn_t spawn{}; // [exec.as.awaitable] struct as_awaitable_t { unspecified }; inline constexpr as_awaitable_t as_awaitable{}; // [exec.with.awaitable.senders] template<class-type Promise> struct with_awaitable_senders; // [exec.scope.concepts], scope concepts template<class Token> concept scope_token = see below; // [exec.scope.simple.counting] class simple_counting_scope; // [exec.scope.counting] class counting_scope; } namespace std::execution { // [exec.par.scheduler], parallel scheduler class parallel_scheduler { unspecified }; parallel_scheduler get_parallel_scheduler(); } // [exec.sysctxrepl], namespace system_context_replaceability namespace std::execution::system_context_replaceability { struct receiver_proxy; struct bulk_item_receiver_proxy; struct parallel_scheduler_backend; shared_ptr<parallel_scheduler_backend> query_parallel_scheduler_backend(); } namespace std::execution { // [exec.affine.on] struct affine_on_t { unspecified }; inline constexpr affine_on_t affine_on{}; // [exec.inline.scheduler] class inline_scheduler; // [exec.task.scheduler] class task_scheduler; template<class E> struct with_error { using type = remove_cvref_t<E>; type error; }; template<class E> with_error(E) -> with_error<E>; template<scheduler Sch> struct change_coroutine_scheduler { using type = remove_cvref_t<Sch>; type scheduler; }; template<scheduler Sch> change_coroutine_scheduler(Sch) -> change_coroutine_scheduler<Sch>; // [exec.task] template<class T, class Environment> class task; }
The exposition-only type variant-or-empty<Ts...> is defined as follows:
  • If sizeof...(Ts) is greater than zero, variant-or-empty<Ts...> denotes variant<Us...> where Us... is the pack decay_t<Ts>... with duplicate types removed.
  • Otherwise, variant-or-empty<Ts...> denotes the exposition-only class type: namespace std::execution { struct empty-variant { // exposition only empty-variant() = delete; }; }
For type Sndr and pack of types Env, let CS be completion_signatures_of_t<Sndr, Env...>.
Then single-sender-value-type<Sndr, Env...> is ill-formed if CS is ill-formed or if sizeof...(Env) > 1 is true; otherwise, it is an alias for:
  • gather-signatures<set_value_t, CS, decay_t, type_identity_t> if that type is well-formed,
  • Otherwise, void if gather-signatures<set_value_t, CS, tuple, variant> is variant<tuple<>> or variant<>,
  • Otherwise, gather-signatures<set_value_t, CS, decayed-tuple, type_identity_t> if that
    type is well-formed,
  • Otherwise, single-sender-value-type<Sndr, Env...> is ill-formed.
The exposition-only concept single-sender is defined as follows: namespace std::execution { template<class Sndr, class... Env> concept single-sender = sender_in<Sndr, Env...> && requires { typename single-sender-value-type<Sndr, Env...>; }; }
A type satisfies and models the exposition-only concept valid-completion-signatures if it is a specialization of the completion_signatures class template.