[exec.cmplsig] # 33 Execution control library [[exec]](./#exec) ## 33.10 Completion signatures [exec.cmplsig] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6027) completion_signatures is a type that encodes a set of completion signatures ([[exec.async.ops]](exec.async.ops "33.3 Asynchronous operations"))[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6031) [*Example [1](#example-1)*: struct my_sender {using sender_concept = sender_t; using completion_signatures = execution::completion_signatures< set_value_t(), set_value_t(int, float), set_error_t(exception_ptr), set_error_t(error_code), set_stopped_t()>;}; Declares my_sender to be a sender that can complete by calling one of the following for a receiver expression rcvr: - [(2.1)](#2.1) set_value(rcvr) - [(2.2)](#2.2) set_value(rcvr, int{...}, float{...}) - [(2.3)](#2.3) set_error(rcvr, exception_ptr{...}) - [(2.4)](#2.4) set_error(rcvr, error_code{...}) - [(2.5)](#2.5) set_stopped(rcvr) — *end example*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6057) This subclause makes use of the following exposition-only entities:templateconcept [*completion-signature*](#concept:completion-signature "33.10 Completion signatures [exec.cmplsig]") = *see below*; [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6064) A type Fn satisfies [*completion-signature*](#concept:completion-signature "33.10 Completion signatures [exec.cmplsig]") if and only if it is a function type with one of the following forms: - [(4.1)](#4.1) set_value_t(Vs...), where Vs is a pack of object or reference types[.](#4.1.sentence-1) - [(4.2)](#4.2) set_error_t(Err), where Err is an object or reference type[.](#4.2.sentence-1) - [(4.3)](#4.3) set_stopped_t() [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6078) templatestruct *indirect-meta-apply* {template class T, class... As>using *meta-apply* = T; // *exposition only*}; templateconcept [*always-true*](#concept:always-true "33.10 Completion signatures [exec.cmplsig]") = true; // *exposition only*template synopsis [execution.syn]") Completions, template class Tuple, template class Variant>using *gather-signatures* = *see below*; [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6096) Let Fns be a pack of the arguments of the completion_signatures specialization named by Completions, let TagFns be a pack of the function types in Fns whose return types are Tag, and let Tsn be a pack of the function argument types in the n-th type in TagFns[.](#6.sentence-1) Then, given two variadic templates Tuple and Variant, the type *gather-signatures* names the type*META-APPLY*(Variant, *META-APPLY*(Tuple, Ts0...), *META-APPLY*(Tuple, Ts1...), …, *META-APPLY*(Tuple, Tsm−1...)) where m is the size of the pack TagFns andMETA-APPLY(T, As...) is equivalent to:typename *indirect-meta-apply*<*always-true*>::template *meta-apply* [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6118) [*Note [1](#note-1)*: The purpose of *META-APPLY* is to make it valid to use non-variadic templates as Variant and Tuple arguments to *gather-signatures*[.](#7.sentence-1) — *end note*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6125) [🔗](#lib:execution::completion_signatures) namespace std::execution {template<[*completion-signature*](#concept:completion-signature "33.10 Completion signatures [exec.cmplsig]")... Fns>struct completion_signatures {templatestatic constexpr size_t *count-of*(Tag) { return *see below*; }templatestatic constexpr void *for-each*(Fn&& fn) { // *exposition only*(std::forward(fn)(static_cast(nullptr)), ...); }}; template, template class Tuple = *decayed-tuple*, template class Variant = *variant-or-empty*>requires [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")using value_types_of_t =*gather-signatures*, Tuple, Variant>; template, template class Variant = *variant-or-empty*>requires [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")using error_types_of_t =*gather-signatures*, type_identity_t, Variant>; template>requires [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")constexpr bool sends_stopped =![same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<*type-list*<>, *gather-signatures*, *type-list*, *type-list*>>;} [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L6165) For a subexpression tag, let Tag be the decayed type of tag[.](#9.sentence-1) completion_signatures​::​*count-of*( tag) returns the count of function types in Fns... that are of the form Tag(Ts...) where Ts is a pack of types[.](#9.sentence-2)