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

301 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.

[coroutine.handle]
# 17 Language support library [[support]](./#support)
## 17.13 Coroutines [[support.coroutine]](support.coroutine#coroutine.handle)
### 17.13.4 Class template coroutine_handle [coroutine.handle]
#### [17.13.4.1](#general) General [[coroutine.handle.general]](coroutine.handle.general)
[🔗](#lib:coroutine_handle)
namespace std {template<>struct coroutine_handle<void>{// [[coroutine.handle.con]](#con "17.13.4.2Construct/reset"), construct/resetconstexpr coroutine_handle() noexcept; constexpr coroutine_handle(nullptr_t) noexcept;
coroutine_handle& operator=(nullptr_t) noexcept; // [[coroutine.handle.export.import]](#export.import "17.13.4.4Export/import"), export/importconstexpr void* address() const noexcept; static constexpr coroutine_handle from_address(void* addr); // [[coroutine.handle.observers]](#observers "17.13.4.5Observers"), observersconstexpr explicit operator bool() const noexcept; bool done() const; // [[coroutine.handle.resumption]](#resumption "17.13.4.6Resumption"), resumptionvoid operator()() const; void resume() const; void destroy() const; private:void* ptr; // *exposition only*}; template<class Promise>struct coroutine_handle {// [[coroutine.handle.con]](#con "17.13.4.2Construct/reset"), construct/resetconstexpr coroutine_handle() noexcept; constexpr coroutine_handle(nullptr_t) noexcept; static coroutine_handle from_promise(Promise&);
coroutine_handle& operator=(nullptr_t) noexcept; // [[coroutine.handle.export.import]](#export.import "17.13.4.4Export/import"), export/importconstexpr void* address() const noexcept; static constexpr coroutine_handle from_address(void* addr); // [[coroutine.handle.conv]](#conv "17.13.4.3Conversion"), conversionconstexpr operator coroutine_handle<>() const noexcept; // [[coroutine.handle.observers]](#observers "17.13.4.5Observers"), observersconstexpr explicit operator bool() const noexcept; bool done() const; // [[coroutine.handle.resumption]](#resumption "17.13.4.6Resumption"), resumptionvoid operator()() const; void resume() const; void destroy() const; // [[coroutine.handle.promise]](#promise "17.13.4.7Promise access"), promise access Promise& promise() const; private:void* ptr; // *exposition only*};}
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5892)
An object of typecoroutine_handle<T> is called a [*coroutine handle*](#def:coroutine_handle) and can be used to refer to a suspended or executing coroutine[.](#general-1.sentence-1)
A coroutine_handle object whose
member address() returns a null pointer value
does not refer to any
coroutine[.](#general-1.sentence-2)
Two coroutine_handle objects refer to the same coroutine
if and only if their member address() returns the same non-null value[.](#general-1.sentence-3)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5903)
If a program declares an explicit or partial specialization ofcoroutine_handle, the behavior is undefined[.](#general-2.sentence-1)
#### [17.13.4.2](#con) Construct/reset [[coroutine.handle.con]](coroutine.handle.con)
[🔗](#lib:coroutine_handle,constructor)
`constexpr coroutine_handle() noexcept;
constexpr coroutine_handle(nullptr_t) noexcept;
`
[1](#con-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5916)
*Postconditions*: address() == nullptr[.](#con-1.sentence-1)
[🔗](#lib:from_promise,coroutine_handle)
`static coroutine_handle from_promise(Promise& p);
`
[2](#con-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5927)
*Preconditions*: p is a reference to a promise object of a coroutine[.](#con-2.sentence-1)
[3](#con-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5931)
*Postconditions*: addressof(h.promise()) == addressof(p)[.](#con-3.sentence-1)
[4](#con-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5935)
*Returns*: A coroutine handle h referring to the coroutine[.](#con-4.sentence-1)
[🔗](#lib:operator=,coroutine_handle)
`coroutine_handle& operator=(nullptr_t) noexcept;
`
[5](#con-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5946)
*Postconditions*: address() == nullptr[.](#con-5.sentence-1)
[6](#con-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5950)
*Returns*: *this[.](#con-6.sentence-1)
#### [17.13.4.3](#conv) Conversion [[coroutine.handle.conv]](coroutine.handle.conv)
[🔗](#lib:operator_coroutine_handle%3c%3e,coroutine_handle)
`constexpr operator coroutine_handle<>() const noexcept;
`
[1](#conv-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5963)
*Effects*: Equivalent to: return coroutine_handle<>::from_address(address());
#### [17.13.4.4](#export.import) Export/import [[coroutine.handle.export.import]](coroutine.handle.export.import)
[🔗](#lib:address,coroutine_handle)
`constexpr void* address() const noexcept;
`
[1](#export.import-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5976)
*Returns*: ptr[.](#export.import-1.sentence-1)
[🔗](#lib:from_address,coroutine_handle)
`static constexpr coroutine_handle<> coroutine_handle<>::from_address(void* addr);
`
[2](#export.import-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5987)
*Preconditions*: addr was obtained via a prior call to address on an object whose type is a specialization of coroutine_handle[.](#export.import-2.sentence-1)
[3](#export.import-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5992)
*Postconditions*: from_address(address()) == *this[.](#export.import-3.sentence-1)
[🔗](#lib:from_address,coroutine_handle_)
`static constexpr coroutine_handle<Promise> coroutine_handle<Promise>::from_address(void* addr);
`
[4](#export.import-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6003)
*Preconditions*: addr was obtained via a prior call to address on an object of type cv coroutine_handle<Promise>[.](#export.import-4.sentence-1)
[5](#export.import-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6008)
*Postconditions*: from_address(address()) == *this[.](#export.import-5.sentence-1)
#### [17.13.4.5](#observers) Observers [[coroutine.handle.observers]](coroutine.handle.observers)
[🔗](#lib:operator_bool,coroutine_handle)
`constexpr explicit operator bool() const noexcept;
`
[1](#observers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6021)
*Returns*: address() != nullptr[.](#observers-1.sentence-1)
[🔗](#lib:done,coroutine_handle)
`bool done() const;
`
[2](#observers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6032)
*Preconditions*: *this refers to a suspended coroutine[.](#observers-2.sentence-1)
[3](#observers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6036)
*Returns*: true if the coroutine is suspended at its
final suspend point, otherwise false[.](#observers-3.sentence-1)
#### [17.13.4.6](#resumption) Resumption [[coroutine.handle.resumption]](coroutine.handle.resumption)
[1](#resumption-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6044)
Resuming a coroutine via resume, operator(), or destroy on an execution agent other than the one on which it was suspended
has implementation-defined behavior
unless
each execution agent either is
an instance of std::thread or std::jthread,
or is the thread that executes main[.](#resumption-1.sentence-1)
[*Note [1](#resumption-note-1)*:
A coroutine that is resumed on a different execution agent should
avoid relying on consistent thread identity throughout, such as holding
a mutex object across a suspend point[.](#resumption-1.sentence-2)
— *end note*]
[*Note [2](#resumption-note-2)*:
A concurrent resumption of the coroutine can result in a data race[.](#resumption-1.sentence-3)
— *end note*]
[🔗](#lib:operator(),coroutine_handle)
`void operator()() const;
void resume() const;
`
[2](#resumption-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6069)
*Preconditions*: *this refers to a suspended coroutine[.](#resumption-2.sentence-1)
The coroutine is not suspended at its final suspend point[.](#resumption-2.sentence-2)
[3](#resumption-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6074)
*Effects*: Resumes the execution of the coroutine[.](#resumption-3.sentence-1)
[🔗](#lib:destroy,coroutine_handle)
`void destroy() const;
`
[4](#resumption-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6085)
*Preconditions*: *this refers to a suspended coroutine[.](#resumption-4.sentence-1)
[5](#resumption-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6089)
*Effects*: Destroys the coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))[.](#resumption-5.sentence-1)
#### [17.13.4.7](#promise) Promise access [[coroutine.handle.promise]](coroutine.handle.promise)
[🔗](#lib:promise,coroutine_handle)
`Promise& promise() const;
`
[1](#promise-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6102)
*Preconditions*: *this refers to a coroutine[.](#promise-1.sentence-1)
[2](#promise-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6106)
*Returns*: A reference to the promise of the coroutine[.](#promise-2.sentence-1)
#### [17.13.4.8](#compare) Comparison operators [[coroutine.handle.compare]](coroutine.handle.compare)
[🔗](#lib:operator==,coroutine_handle)
`constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
`
[1](#compare-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6120)
*Returns*: x.address() == y.address()[.](#compare-1.sentence-1)
[🔗](#lib:operator%3c=%3e,coroutine_handle)
`constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;
`
[2](#compare-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6131)
*Returns*: compare_three_way()(x.address(), y.address())[.](#compare-2.sentence-1)
#### [17.13.4.9](#hash) Hash support [[coroutine.handle.hash]](coroutine.handle.hash)
[🔗](#lib:hash,coroutine_handle)
`template<class P> struct hash<coroutine_handle<P>>;
`
[1](#hash-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L6144)
The specialization is enabled ([[unord.hash]](unord.hash "22.10.19Class template hash"))[.](#hash-1.sentence-1)