boost::capy::io_awaitable_promise_base

CRTP mixin that adds I/O awaitable support to a promise type.

Synopsis

template<typename Derived>
class io_awaitable_promise_base;

Description

Inherit from this class to enable these capabilities in your coroutine:

1. Frame allocation — The mixin provides operator new/delete that use the thread‐local frame allocator set by run_async.

2. Environment storage — The mixin stores a pointer to the io_env containing the executor, stop token, and allocator for this coroutine.

3. Environment access — Coroutine code can retrieve the environment via co_await this_coro::environment, or individual fields via co_await this_coro::executor, co_await this_coro::stop_token, and co_await this_coro::allocator.

Basic Usage

For coroutines that need to access their execution environment:

struct my_task
{
    struct promise_type : io_awaitable_promise_base<promise_type>
    {
        my_task get_return_object();
        std::suspend_always initial_suspend() noexcept;
        std::suspend_always final_suspend() noexcept;
        void return_void();
        void unhandled_exception();
    };

    // ... awaitable interface ...
};

my_task example()
{
    auto env = co_await this_coro::environment;
    // Access env->executor, env->stop_token, env->allocator

    // Or use fine-grained accessors:
    auto ex = co_await this_coro::executor;
    auto token = co_await this_coro::stop_token;
    auto* alloc = co_await this_coro::allocator;
}

Custom Awaitable Transformation

If your promise needs to transform awaitables (e.g., for affinity or logging), override transform_awaitable instead of await_transform:

struct promise_type : io_awaitable_promise_base<promise_type>
{
    template<typename A>
    auto transform_awaitable(A&& a)
    {
        // Your custom transformation logic
        return std::forward<A>(a);
    }
};

The mixin's await_transform intercepts this_coro::environment_tag and the fine‐grained tag types (this_coro::executor_tag, this_coro::stop_token_tag, this_coro::allocator_tag), then delegates all other awaitables to your transform_awaitable.

Making Your Coroutine an IoAwaitable

The mixin handles the "inside the coroutine" part—accessing the environment. To receive the environment when your coroutine is awaited (satisfying IoAwaitable), implement the await_suspend overload on your coroutine return type:

struct my_task
{
    struct promise_type : io_awaitable_promise_base<promise_type> { ... };

    std::coroutine_handle<promise_type> h_;

    // IoAwaitable await_suspend receives and stores the environment
    std::coroutine_handle<> await_suspend(std::coroutine_handle<> cont, io_env const* env)
    {
        h_.promise().set_environment(env);
        // ... rest of suspend logic ...
    }
};

Thread Safety

The environment is stored during await_suspend and read during co_await this_coro::environment. These occur on the same logical thread of execution, so no synchronization is required.

Member Functions

Name

Description

~io_awaitable_promise_base [destructor]

Destructor

await_transform

Intercept co_await expressions.

continuation

Return and consume the stored continuation handle.

environment

Return the stored execution environment.

set_continuation

Store the continuation to resume on completion.

set_environment

Store a pointer to the execution environment.

transform_awaitable

Transform an awaitable before co_await.

Static Member Functions

Name

Description

operator delete

Deallocate a coroutine frame.

operator new

Allocate a coroutine frame.

Derived Classes

Name Description

promise_type

Template Parameters

Name Description

Derived

The derived promise type (CRTP pattern).

See Also

this_coro::environment, this_coro::executor, this_coro::stop_token, this_coro::allocator

io_env

IoAwaitable

Created with MrDocs