Files
2025-10-25 03:02:53 +03:00

297 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.4Await")) 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.4Await")) 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.4Await")) 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.3Sender 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.2Concept 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.2The 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)