Boost.Capy
Boost.Capy is a lightweight C++20 coroutine framework that provides lazy tasks with automatic executor affinity propagation, along with buffer management, compression, and cryptographic utilities.
What This Library Does
Capy solves a specific problem: when you co_await a child coroutine, where
does it resume? Without affinity tracking, completions can arrive on arbitrary
threads, forcing you to add synchronization everywhere.
Capy provides:
-
Lazy tasks that do not start until awaited or explicitly launched
-
Automatic affinity propagation through coroutine call chains
-
Zero-overhead dispatcher protocol for custom awaitables
-
Frame allocation recycling to minimize allocation overhead
-
Thread pool execution context with service management
-
Buffer types for efficient memory handling (
const_buffer,mutable_buffer, sequences) -
Compression support (Brotli and ZLib)
-
BCrypt password hashing for secure credential storage
What This Library Does Not Do
Capy is not a general-purpose I/O framework. It does not include:
-
Event loops or I/O polling (use io_uring wrappers, etc.)
-
Networking primitives (sockets, HTTP, etc.)
-
The sender/receiver execution model (P2300)
Capy integrates with existing I/O frameworks by wrapping their completion mechanisms in affine-aware awaitables.
Design Philosophy
Lazy by default. Tasks suspend immediately on creation. This enables
structured composition where parent coroutines naturally await their children.
Eager execution is available through async_run.
Affinity through the protocol. The dispatcher propagates through
await_suspend parameters, not through thread-local storage or global state.
This makes the data flow explicit and testable.
Type erasure at boundaries. Tasks use type-erased dispatchers (any_dispatcher)
internally, paying the indirection cost once rather than templating everything.
For I/O-bound code, this cost is negligible.
Quick Example
#include <boost/capy/task.hpp>
#include <boost/capy/ex/async_run.hpp>
#include <boost/capy/ex/thread_pool.hpp>
#include <iostream>
using boost::capy::task;
using boost::capy::async_run;
using boost::capy::thread_pool;
task<int> compute()
{
co_return 42;
}
task<void> run()
{
int result = co_await compute();
std::cout << "Result: " << result << "\n";
}
int main()
{
thread_pool pool(1);
async_run(pool.get_executor())(run());
// Pool destructor waits for completion
}
Next Steps
-
Quick Start — Get a working program in 5 minutes
-
Tasks — Understand lazy coroutines
-
Execution Contexts — Thread pools and services