mirror of
https://github.com/boostorg/cobalt.git
synced 2026-01-24 05:42:13 +00:00
70 lines
2.7 KiB
Plaintext
70 lines
2.7 KiB
Plaintext
[#context]
|
|
== cobalt/experimental/context.hpp
|
|
|
|
WARNING: This is (most likely) undefined behaviour, since the violates a precondition in the standard. A paper to address this can be found here (https://isocpp.org/files/papers/P3203R0.html).
|
|
|
|
This header provides `experimental` support for using `boost.fiber` based stackful coroutines
|
|
as if they were C++20 coroutines. That is, they can use `awaitables` by being able to be put into a `coroutine_handle`.
|
|
Likewise the implementation uses a C++20 coroutine promise and runs is as if it was a C++20 coroutine.
|
|
|
|
[source,cpp]
|
|
----
|
|
//
|
|
void delay(experimental::context<promise<void>> h, std::chrono::milliseconds ms)
|
|
{
|
|
asio::steady_timer tim{co_await cobalt::this_coro::executor, ms};
|
|
h.await(tim.async_wait(cobalt::use_op)); // instead of co_await.
|
|
}
|
|
|
|
cobalt::main co_main(int argc, char *argv[])
|
|
{
|
|
cobalt::promise<void> dl = cobalt::experimental::make_context(&delay, 50);
|
|
co_await dl;
|
|
co_return 0;
|
|
}
|
|
----
|
|
|
|
=== Reference
|
|
|
|
[source,cpp]
|
|
----
|
|
// The internal coroutine context.
|
|
/// Args are the function arguments after the handle.
|
|
template<typename Return, typename ... Args>
|
|
struct context
|
|
{
|
|
// Get a handle to the promise
|
|
promise_type & promise();
|
|
const promise_type & promise() const;
|
|
|
|
// Convert it to any context if the underlying promise is the same
|
|
template<typename Return_, typename ... Args_>
|
|
constexpr operator context<Return_, Args_...>() const;
|
|
|
|
// Await something. Uses await_transform automatically.
|
|
template<typename Awaitable>
|
|
auto await(Awaitable && aw);
|
|
// Yield a value, if supported by the promise.
|
|
template<typename Yield>
|
|
auto yield(Yield && value);
|
|
};
|
|
|
|
|
|
// Create a fiber with a custom stack allocator (see boost.fiber for details) and explicit result (e.g. `promise<void>`)
|
|
template<typename Return, typename ... Args, std::invocable<context<Return, Args...>, Args...> Func, typename StackAlloc>
|
|
auto make_context(Func && func, std::allocator_arg_t, StackAlloc && salloc, Args && ... args);
|
|
|
|
// Create a fiber with the default allocator and explicit result (e.g. `promise<void>`)
|
|
template<typename Return, typename ... Args, std::invocable<context<Return, Args...>, Args...> Func>
|
|
auto make_context(Func && func, Args && ... args);
|
|
|
|
// Create a fiber with a custom stack allocator and implicit result (deduced from the first argument to func).
|
|
template<typename ... Args, typename Func, typename StackAlloc>
|
|
auto make_context(Func && func, std::allocator_arg_t, StackAlloc && salloc, Args && ... args);
|
|
|
|
// Create a fiber with the default stack allocator and implicit result (deduced from the first argument to func).
|
|
template<typename ... Args, typename Func>
|
|
auto make_context(Func && func, Args && ... args);
|
|
----
|
|
|