[task.promise]

# 33 Execution control library [[exec]](./#exec)

## 33.13 Coroutine utilities [[exec.coro.util]](exec.coro.util#task.promise)

### 33.13.6 execution​::​task [[exec.task]](exec.task#task.promise)

#### 33.13.6.5 Class task​::​promise_type [task.promise]

namespace std::execution {template<class T, class Environment>class task<T, Environment>::promise_type {public:template<class... Args> promise_type(const Args&... args);

 task get_return_object() noexcept; auto initial_suspend() noexcept; auto final_suspend() noexcept; void uncaught_exception();
 coroutine_handle<> unhandled_stopped(); void return_void(); // present only if is_void_v<T> is truetemplate<class V>void return_value(V&& value); // present only if is_void_v<T> is falsetemplate<class E>*unspecified* yield_value(with_error<E> error); template<class A>auto await_transform(A&& a); template<class Sch>auto await_transform(change_coroutine_scheduler<Sch> sch); *unspecified* get_env() const noexcept; template<class... Args>void* operator new(size_t size, Args&&... args); void operator delete(void* pointer, size_t size) noexcept; private:using *error-variant* = *see below*; // *exposition only* allocator_type *alloc*; // *exposition only* stop_source_type *source*; // *exposition only* stop_token_type *token*; // *exposition only* optional<T> *result*; // *exposition only*; present only if is_void_v<T> is false*error-variant* *errors*; // *exposition only*};}

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7466)

Let *prom* be an object of promise_type and let *tsk* be the task object
created by *prom*.get_return_object()[.](#1.sentence-1)

The description below
refers to objects *STATE*(*prom*),*RCVR*(*prom*),
and *SCHED*(*prom*) associated with *tsk* during evaluation of task​::​*state*<Rcvr>​::​start for some receiver Rcvr[.](#1.sentence-2)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7478)

*error-variant* is a variant<monostate,
remove_cvref_t<E>...>, with duplicate types removed, where E... are the parameter types of the template arguments of the specialization ofexecution​::​completion_signatures denoted byerror_types[.](#2.sentence-1)

[ð](#lib:task::promise_type,constructor)

`template<class... Args>
  promise_type(const Args&... args);
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7491)

*Mandates*: The first parameter of type allocator_arg_t (if any) is not
the last parameter[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7496)

*Effects*: If Args contains an element of type allocator_arg_t then *alloc* is initialized with the corresponding next
element of args[.](#4.sentence-1)

Otherwise, *alloc* is initialized with allocator_type()[.](#4.sentence-2)

[ð](#lib:get_return_object,task::promise_type)

`task get_return_object() noexcept;
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7509)

*Returns*: A task object whose member *handle* iscoroutine_handle<promise_type>​::​​from_promise​(*this)[.](#5.sentence-1)

[ð](#lib:initial_suspend,task::promise_type)

`auto initial_suspend() noexcept;
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7520)

*Returns*: An awaitable object of unspecified type ([[expr.await]](expr.await "7.6.2.4 Await")) whose
member functions arrange for

- [(6.1)](#6.1)

the calling coroutine to be suspended,

- [(6.2)](#6.2)

the coroutine to be resumed on an execution agent of the
execution resource associated with *SCHED*(*this)[.](#6.sentence-1)

[ð](#lib:final_suspend,task::promise_type)

`auto final_suspend() noexcept;
`

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7536)

*Returns*: An awaitable object of unspecified type ([[expr.await]](expr.await "7.6.2.4 Await")) whose
member functions arrange for the completion of the asynchronous
operation associated with *STATE*(*this) by invoking:

- [(7.1)](#7.1)

set_error(std​::​move(*RCVR*(*this)), std​::​move(e)) if *errors*.index() is greater than zero ande is the value held by *errors*, otherwise

- [(7.2)](#7.2)

set_value(std​::​move(*RCVR*(*this))) if is_void<T> is true,
and otherwise

- [(7.3)](#7.3)

set_value(std​::​move(*RCVR*(*this)), **result*)[.](#7.sentence-1)

[ð](#lib:yield_value,task::promise_type)

`template<class Err>
  auto yield_value(with_error<Err> err);
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7560)

*Mandates*: std​::​move(err.error) is convertible to exactly one of theset_error_t argument types of error_types[.](#8.sentence-1)

Let *Cerr* be that type[.](#8.sentence-2)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7566)

*Returns*: An awaitable object of unspecified type ([[expr.await]](expr.await "7.6.2.4 Await")) whose
member functions arrange for the calling coroutine to be suspended
and then completes the asynchronous operation associated with*STATE*(*this) by invoking set_error(std​::​move(*RCVR*(*this)),*Cerr*(std​::​move(err.error)))[.](#9.sentence-1)

[ð](#lib:await_transform,task::promise_type)

`template<[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") Sender>
  auto await_transform(Sender&& sndr) noexcept;
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7581)

*Returns*: If [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<inline_scheduler, scheduler_type> is true returns as_awaitable(​std​::​​forward<Sender>(sndr), *this);
otherwise returnsas_awaitable(affine_on(​std​::​​forward<Sender>(sndr), *SCHED*(*this)), *this)[.](#10.sentence-1)

[ð](#lib:await_transform,task::promise_type_)

`template<class Sch>
  auto await_transform(change_coroutine_scheduler<Sch> sch) noexcept;
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7595)

*Effects*: Equivalent to:return await_transform(just(exchange(*SCHED*(*this), scheduler_type(sch.scheduler))), *this);

[ð](#lib:uncaught_exception,task::promise_type)

`void uncaught_exception();
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7608)

*Effects*: If the signature set_error_t(exception_ptr) is not an element
of error_types, calls terminate() ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#12.sentence-1)

Otherwise, stores current_exception() into *errors*[.](#12.sentence-2)

[ð](#lib:unhandled_stopped,task::promise_type)

`coroutine_handle<> unhandled_stopped();
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7620)

*Effects*: Completes the asynchronous operation associated with *STATE*(*this) by invoking set_stopped(std​::​move(*RCVR*(*this)))[.](#13.sentence-1)

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7626)

*Returns*: noop_coroutine()[.](#14.sentence-1)

[ð](#lib:get_env,task::promise_type)

`unspecified get_env() const noexcept;
`

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7636)

*Returns*: An object env such that queries are forwarded as follows:

- [(15.1)](#15.1)

  env.query(get_scheduler) returns scheduler_type(*SCHED*(*this))[.](#15.1.sentence-1)

- [(15.2)](#15.2)

  env.query(get_allocator) returns *alloc*[.](#15.2.sentence-1)

- [(15.3)](#15.3)

  env.query(get_stop_token) returns *token*[.](#15.3.sentence-1)

- [(15.4)](#15.4)

  For any other query q and arguments a... a
call to env.query(q, a...) returns*STATE*(*this)[.](#15.4.sentence-1)
  environment.query(q, a...) if this expression
is well-formed and forwarding_query(q) is well-formed and is true[.](#15.4.sentence-2)
  Otherwise env.query(q, a...) is ill-formed[.](#15.4.sentence-3)

[ð](#lib:operator_new,task::promise_type)

`template<class... Args>
  void* operator new(size_t size, const Args&... args);
`

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7657)

If there is no parameter with type allocator_arg_t then letalloc be allocator_type()[.](#16.sentence-1)

Otherwise, let arg_next be the parameter
following the first allocator_arg_t parameter,
and let alloc be allocator_type(arg_next)[.](#16.sentence-2)

Let PAlloc be allocator_traits<allocator_type>​::​template rebind_alloc<U>, where U is an unspecified type
whose size and alignment are both __STDCPP_DEFAULT_NEW_ALIGNMENT__[.](#16.sentence-3)

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7667)

*Mandates*: 

- [(17.1)](#17.1)

  The first parameter of type allocator_arg_t (if any) is not the last parameter[.](#17.1.sentence-1)

- [(17.2)](#17.2)

  allocator_type(arg_next) is a valid expression if there is a parameter
of type allocator_arg_t[.](#17.2.sentence-1)

- [(17.3)](#17.3)

  allocator_traits<PAlloc>​::​pointer is a pointer type[.](#17.3.sentence-1)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7676)

*Effects*: Initializes an allocator palloc of type PAlloc withalloc[.](#18.sentence-1)

Uses palloc to allocate storage for the
smallest array of U sufficient to provide storage for a
coroutine state of size size, and unspecified additional
state necessary to ensure that operator delete can later
deallocate this memory block with an allocator equal to palloc[.](#18.sentence-2)

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7686)

*Returns*: A pointer to the allocated storage[.](#19.sentence-1)

[ð](#lib:operator_delete,task::promise_type)

`void operator delete(void* pointer, size_t size) noexcept;
`

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7696)

*Preconditions*: pointer was returned from an invocation of the above overload
of operator new with a size argument equal to size[.](#20.sentence-1)

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7701)

*Effects*: Deallocates the storage pointed to by pointer using an
allocator equal to that used to allocate it[.](#21.sentence-1)
