A C++23 coroutine library.
This is effort, much inspired by Lewis Baker's cppcoro library, is an ab-initio set of C++ classes designed to implement coroutines with great efficiency and flexibility. This implementation is intended to work only on compilers with the latest and greatest features, especially symmetric transfer and "deduced this".
The coroutines defined by C++20 are -awesome-, but there are some non-straightforward
results from it that this library attempts to solve. Most especially, deriving
new task / promise types from an existing library is extremely difficult. The
coroutine_handle<T>::from_promise
method requires the precise type of the
promise object; using a derived class is disallowed. This library attempts
to solve that problem by documenting inheritance points and requirements.
There are other non-trivial consequences of using coroutines naively that result in low-performance applications. For example, ordinary implementations of mutexes result in degradation of parallelization; this library provides primitive operations to support maintaining parallelism.
This is a header-only library by design.
This library does not provide platform-specific IO primitives. It provides only those primitives that are implementable only using the C++ standard and common extensions.
This library include Visual Studio Natvis visualizers for many of the embedded types.
By and large, this library aims to be source-level compatible with cppcoro. Cppcoro namespaces, includes, and type aliases are provided.
The library also aims to support different behavior axes that are convenient for certain use cases. It does so via policies.h.
The #1 goal of the library is high performance. Most defaults are oriented towards high performance operation.
Put the include/Phantom.Coroutines
directory in your include path. Then,
#include
the header that you desire:
#include <Phantom.Coroutines/task.h>
The library is so far only tested on the lastest versions of Microsoft Visual C++.
It requires the /std:c++latest
flag to enable C++ 23 features.
The contents of the Phantom::Coroutines
namespace are available for use as documented. Everything
in Phantom::Coroutines::detail
is undocumented. At some point, this will be
enforced through C++ modules.
Many classes make use of policies to customize behavior, while providing default high-performance policies for typical uses.
Library contents:
Auto reset event that releases one waiter upon being signalled.
Async generator.
Manual reset event that releases all waiters upon being signalled.
Mutual exclusion inside coroutines.
Delayed acquisition of published values.
Start background tasks asynchronously and wait for them to complete.
Wrap awaitable objects with an awaiter implementation.
Coroutines that terminate execution when termination conditions are encountered.
This or task<>
are expected to be the most
heavily used classes.
Write promise types that can be extended or do extend other promise types. Most promise types in the Phantom.Coroutines library are built using these types.
Non-async generator.
Provides policy parameters to other classes, such as async_mutex.h.
Support custom allocators for promise objects.
Schedule coroutines to resume on other threads.
Wait for a number to be published.
A task<>
-like object that can be co_await
'ed
multiple times, moved, and copied.
Discover whether a co_await operation suspended or not.
Create std::future
objects from awaitable objects, and synchronously
wait for the results.
An extremely high performance lightweight awaitable operation. This is expected to be one of the most commonly used classes for most code.
Metaprogramming tools for introspection of asynchronous code.