std::coroutine_handle, std::noop_coroutine_handle
From cppreference.com
Defined in header <coroutine>
|
||
template< class Promise = void > struct coroutine_handle; |
(1) | (since C++20) |
template<> struct coroutine_handle<void>; |
(2) | (since C++20) |
template<> struct coroutine_handle<std::noop_coroutine_promise>; |
(3) | (since C++20) |
using noop_coroutine_handle = std::coroutine_handle<std::noop_coroutine_promise>; |
(4) | (since C++20) |
The class template coroutine_handle
can be used to refer to a suspended or executing coroutine. Every specialization of coroutine_handle
is a LiteralType.
1) Primary template, can be created from the promise object of type
Promise
.2) Specialization std::coroutine_handle<void> erases the promise type. It is convertible from other specializations.
3) Specialization std::coroutine_handle<std::noop_coroutine_promise> refers to no-op coroutines. It cannot be created from a promise object.
On typical implementations, every specialization of std::coroutine_handle
is TriviallyCopyable, and holds a pointer to the coroutine state as its only non-static data member.
The behavior of a program that adds specializations for coroutine_handle
is undefined.
Member functions
(C++20) |
constructs a coroutine_handle object (public member function) |
(C++20) |
assigns the coroutine_handle object (public member function) |
[static] (C++20) |
creates a coroutine_handle from the promise object of a coroutine (public static member function) |
Observers | |
(C++20) |
check if the coroutine has completed (public member function) |
(C++20) |
check if the handle represents a coroutine (public member function) |
Control | |
(C++20) |
resumes execution of the coroutine (public member function) |
(C++20) |
destroys a coroutine (public member function) |
Promise Access | |
(C++20) |
access the promise of a coroutine (public member function) |
Export/Import | |
(C++20) |
exports the underlying address, i.e. the pointer backing the coroutine (public member function) |
[static] (C++20) |
import a coroutine from a pointer (public static member function) |
Non-member functions
(C++20) |
compares two coroutine_handle objects (function) |
Helper classes
hash support for std::coroutine_handle (class template specialization) |
Notes
A coroutine_handle
may be dangling, in which case the coroutine_handle
must be used carefully in order to avoid undefined behavior.
Example
Run this code
#include <coroutine> #include <iostream> #include <ranges> template<class T> struct generator { struct promise_type { auto get_return_object() { return generator(std::coroutine_handle<promise_type>::from_promise(*this)); } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void unhandled_exception() { throw; } std::suspend_always yield_value(T value) { current_value = std::move(value); return {}; } void await_transform() = delete; // disallow co_await in generator coroutines T current_value; }; generator(std::coroutine_handle<promise_type> h) : coro(h) {} generator(generator&& other) : coro(other.coro) { other.coro = {}; } ~generator() { if (coro) coro.destroy(); } // range-based for support struct iter { explicit iter(std::coroutine_handle<promise_type> h) : coro(h) {} void operator++() { coro.resume(); } T operator*() const { return coro.promise().current_value; } bool operator==(std::default_sentinel_t) const { return coro.done(); } private: std::coroutine_handle<promise_type> coro; }; iter begin() { coro.resume(); return iter(coro); } std::default_sentinel_t end() { return {}; } private: std::coroutine_handle<promise_type> coro; }; generator<int> ints(int x) { for (int i = 0; i < x; ++i) co_yield i; } int main() { for (auto i : ints(5)) std::cout << i << '\n'; }
Output:
0 1 2 3 4