[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:template<class Fn>concept [*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)

template<bool>struct *indirect-meta-apply* {template<template<class...> class T, class... As>using *meta-apply* = T<As...>; // *exposition only*};

template<class...>concept [*always-true*](#concept:always-true "33.10 Completion signatures [exec.cmplsig]") = true; // *exposition only*template<class Tag, [*valid-completion-signatures*](execution.syn#concept:valid-completion-signatures "33.4 Header <execution> synopsis [execution.syn]") Completions, template<class...> class Tuple, template<class...> 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*<Tag, Completions, Tuple, Variant> 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*<As...>>::template *meta-apply*<T, As...>

[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 {template<class Tag>static constexpr size_t *count-of*(Tag) { return *see below*; }template<class Fn>static constexpr void *for-each*(Fn&& fn) { // *exposition only*(std::forward<Fn>(fn)(static_cast<Fns*>(nullptr)), ...); }}; template<class Sndr, class Env = env<>, template<class...> class Tuple = *decayed-tuple*, template<class...> class Variant = *variant-or-empty*>requires [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")<Sndr, Env>using value_types_of_t =*gather-signatures*<set_value_t, completion_signatures_of_t<Sndr, Env>, Tuple, Variant>; template<class Sndr, class Env = env<>, template<class...> class Variant = *variant-or-empty*>requires [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")<Sndr, Env>using error_types_of_t =*gather-signatures*<set_error_t, completion_signatures_of_t<Sndr, Env>,
 type_identity_t, Variant>; template<class Sndr, class Env = env<>>requires [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")<Sndr, Env>constexpr bool sends_stopped =![same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<*type-list*<>, *gather-signatures*<set_stopped_t, completion_signatures_of_t<Sndr, Env>, *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<Fns...>​::​*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)
