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_traits(3) C++ Standard Libary std::coroutine_traits(3)

std::coroutine_traits - std::coroutine_traits


Defined in header <coroutine>
template< class R, class... Args > (since C++20)
struct coroutine_traits;


Determines the promise type from the return type and parameter types of a coroutine.
The standard library implementation provides a publicly accessible member type
promise_type same as R::promise_type if the qualified-id is valid and denotes a
type. Otherwise, it has no such member.


Program-defined specializations of coroutine_traits shall define a publicly
accessible member type promise_type; otherwise, the behavior is undefined.


R - return type of the coroutine
Args - parameter types of the coroutine, including the implicit object parameter if
the coroutine is a non-static member function


Type Definition
promise_type R::promise_type if it is valid, or provided by program-defined
specializations


template<class, class...>
struct coroutine_traits {};


template<class R, class... Args>
requires requires { typename R::promise_type; }
struct coroutine_traits<R, Args...> {
using promise_type = typename R::promise_type;
};


If the coroutine is a non-static member function, then the first type in Args... is
the type of the implicit object parameter, and the rest are parameter types of the
function (if any).


If std::coroutine_traits<R, Args...>::promise_type does not exist or is not a class
type, the corresponding coroutine definition is ill-formed.


Users may define explicit or partial specializations of coroutine_traits dependent
on program-defined types to avoid modification to return types.

// Run this code


#include <chrono>
#include <coroutine>
#include <exception>
#include <future>
#include <iostream>
#include <thread>
#include <type_traits>


// A program-defined type on which the coroutine_traits specializations below depend
struct as_coroutine {};


// Enable the use of std::future<T> as a coroutine type
// by using a std::promise<T> as the promise type.
template <typename T, typename... Args>
requires(!std::is_void_v<T> && !std::is_reference_v<T>)
struct std::coroutine_traits<std::future<T>, as_coroutine, Args...> {
struct promise_type : std::promise<T> {
std::future<T> get_return_object() noexcept {
return this->get_future();
}


std::suspend_never initial_suspend() const noexcept { return {}; }
std::suspend_never final_suspend() const noexcept { return {}; }


void return_value(const T &value)
noexcept(std::is_nothrow_copy_constructible_v<T>) {
this->set_value(value);
}
void return_value(T &&value)
noexcept(std::is_nothrow_move_constructible_v<T>) {
this->set_value(std::move(value));
}
void unhandled_exception() noexcept {
this->set_exception(std::current_exception());
}
};
};


// Same for std::future<void>.
template <typename... Args>
struct std::coroutine_traits<std::future<void>, as_coroutine, Args...> {
struct promise_type : std::promise<void> {
std::future<void> get_return_object() noexcept {
return this->get_future();
}


std::suspend_never initial_suspend() const noexcept { return {}; }
std::suspend_never final_suspend() const noexcept { return {}; }


void return_void() noexcept {
this->set_value();
}
void unhandled_exception() noexcept {
this->set_exception(std::current_exception());
}
};
};


// Allow co_await'ing std::future<T> and std::future<void>
// by naively spawning a new thread for each co_await.
template <typename T>
auto operator co_await(std::future<T> future) noexcept
requires(!std::is_reference_v<T>) {
struct awaiter : std::future<T> {
bool await_ready() const noexcept {
using namespace std::chrono_literals;
return this->wait_for(0s) != std::future_status::timeout;
}
void await_suspend(std::coroutine_handle<> cont) const {
std::thread([this, cont] {
this->wait();
cont();
}).detach();
}
T await_resume() { return this->get(); }
};
return awaiter{std::move(future)};
}


// Utilize the infrastructure we have established.
std::future<int> compute(as_coroutine) {
int a = co_await std::async([] { return 6; });
int b = co_await std::async([] { return 7; });
co_return a * b;
}


std::future<void> fail(as_coroutine) {
throw std::runtime_error("bleah");
co_return;
}


int main() {
std::cout << compute({}).get() << '\n';


try {
fail({}).get();
} catch (const std::runtime_error &e) {
std::cout << "error: " << e.what() << '\n';
}
}


42
error: bleah

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.