GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
std::coroutine_handle,std::noop_coroutine_handle(3) C++ Standard Libary std::coroutine_handle,std::noop_coroutine_handle(3)

std::coroutine_handle,std::noop_coroutine_handle - std::coroutine_handle,std::noop_coroutine_handle


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 = (4) (since C++20)
std::coroutine_handle<std::noop_coroutine_promise>;


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.


constructor constructs a coroutine_handle object
(C++20) (public member function)
operator= assigns the coroutine_handle object
(C++20) (public member function)
Conversion
operator coroutine_handle<> obtains a type-erased coroutine_handle
(C++20) (public member function)


done checks if the coroutine has completed
(C++20) (public member function)
operator bool checks if the handle represents a coroutine
(C++20) (public member function)
Control
operator() resumes execution of the coroutine
resume (public member function)
(C++20)
destroy destroys a coroutine
(C++20) (public member function)
Promise Access
promise access the promise of a coroutine
(C++20) (public member function)
from_promise creates a coroutine_handle from the promise object of a
[static] (C++20) coroutine
(public static member function)
Export/Import
address exports the underlying address, i.e. the pointer backing
(C++20) the coroutine
(public member function)
from_address imports a coroutine from a pointer
[static] (C++20) (public static member function)


operator== compares two coroutine_handle objects
operator<=> (function)
(C++20)


std::hash<std::coroutine_handle> hash support for std::coroutine_handle
(C++20) (class template specialization)


A coroutine_handle may be dangling, in which case the coroutine_handle must be used
carefully in order to avoid undefined behavior.

// Run this code


#include <coroutine>
#include <iostream>
#include <optional>


template<std::movable T>
class Generator {
public:
struct promise_type {
Generator<T> get_return_object() {
return Generator{Handle::from_promise(*this)};
}
static std::suspend_always initial_suspend() noexcept {
return {};
}
static std::suspend_always final_suspend() noexcept {
return {};
}
std::suspend_always yield_value(T value) noexcept {
current_value = std::move(value);
return {};
}
// Disallow co_await in generator coroutines.
void await_transform() = delete;
[[noreturn]]
static void unhandled_exception() {
throw;
}


std::optional<T> current_value;
};


using Handle = std::coroutine_handle<promise_type>;


explicit Generator(const Handle coroutine) :
m_coroutine{coroutine}
{}


Generator() = default;
~Generator() {
if (m_coroutine) {
m_coroutine.destroy();
}
}


Generator(const Generator&) = delete;
Generator& operator=(const Generator&) = delete;


Generator(Generator&& other) noexcept :
m_coroutine{other.m_coroutine}
{
other.m_coroutine = {};
}
Generator& operator=(Generator&& other) noexcept {
if (this != &other) {
if (m_coroutine) {
m_coroutine.destroy();
}
m_coroutine = other.m_coroutine;
other.m_coroutine = {};
}
return *this;
}


// Range-based for loop support.
class Iter {
public:
void operator++() {
m_coroutine.resume();
}
const T& operator*() const {
return *m_coroutine.promise().current_value;
}
bool operator==(std::default_sentinel_t) const {
return !m_coroutine || m_coroutine.done();
}


explicit Iter(const Handle coroutine) :
m_coroutine{coroutine}
{}


private:
Handle m_coroutine;
};


Iter begin() {
if (m_coroutine) {
m_coroutine.resume();
}
return Iter{m_coroutine};
}
std::default_sentinel_t end() {
return {};
}


private:
Handle m_coroutine;
};


template<std::integral T>
Generator<T> range(T first, const T last) {
while (first < last) {
co_yield first++;
}
}


int main() {
for (const char i : range(65, 91)) {
std::cout << i << ' ';
}
std::cout << '\n';
}


A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


Defect reports


The following behavior-changing defect reports were applied retroactively to
previously published C++ standards.


DR Applied to Behavior as published Correct behavior
LWG 3460 C++20 the public base class of coroutine_handle inheritance removed
could leave it in an undesired state

2022.07.31 http://cppreference.com

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.