2
0
mirror of https://github.com/boostorg/cobalt.git synced 2026-01-24 17:52:31 +00:00
Files
cobalt/doc/reference/io/ops.adoc
Klemens Morgenstern bc9a00ecb1 [io] ops docs.
2025-06-24 18:15:10 +08:00

118 lines
4.0 KiB
Plaintext

== cobalt/io/ops.hpp
Most functionality in this wrapper is implemented with operations.
They are type-erase, but not by using `virtual`.
This makes devirtualization easier.
The `implementation` function must be provided, where as `try_implementation_t` is optional and will be used in the `ready` function.
Both will be called with `void *this` as the first parameter.
[source,cpp]
----
struct [[nodiscard]] write_op final : op<system::error_code, std::size_t>
{
const_buffer_sequence buffer;
using implementation_t = void(void*, const_buffer_sequence, completion_handler<system::error_code, std::size_t>);
using try_implementation_t = void(void*, const_buffer_sequence, handler<system::error_code, std::size_t>);
write_op(const_buffer_sequence buffer,
void * this_,
implementation_t *implementation,
try_implementation_t * try_implementation = nullptr);
void initiate(completion_handler<system::error_code, std::size_t> handler) final;
void ready(handler<system::error_code, std::size_t> handler) final;
};
struct [[nodiscard]] read_op final : op<system::error_code, std::size_t>
{
mutable_buffer_sequence buffer;
using implementation_t = void(void*, mutable_buffer_sequence, completion_handler<system::error_code, std::size_t>);
using try_implementation_t = void(void*, mutable_buffer_sequence, handler<system::error_code, std::size_t>);
read_op(mutable_buffer_sequence buffer,
void * this_,
implementation_t *implementation,
try_implementation_t * try_implementation = nullptr);
void initiate(completion_handler<system::error_code, std::size_t> handler) final;
void ready(handler<system::error_code, std::size_t> handler) final;
};
struct [[nodiscard]] write_at_op final : op<system::error_code, std::size_t>
{
std::uint64_t offset;
const_buffer_sequence buffer;
using implementation_t = void(void*, std::uint64_t, const_buffer_sequence, completion_handler<system::error_code, std::size_t>);
using try_implementation_t = void(void*, std::uint64_t, const_buffer_sequence, handler<system::error_code, std::size_t>);
write_at_op(std::uint64_t offset,
const_buffer_sequence buffer,
void * this_,
implementation_t *implementation,
try_implementation_t * try_implementation = nullptr);
void initiate(completion_handler<system::error_code, std::size_t> handler) final;
void ready(handler<system::error_code, std::size_t> handler) final;
};
struct [[nodiscard]] read_at_op final : op<system::error_code, std::size_t>
{
std::uint64_t offset;
mutable_buffer_sequence buffer;
using implementation_t = void(void*, std::uint64_t, mutable_buffer_sequence, completion_handler<system::error_code, std::size_t>);
using try_implementation_t = void(void*, std::uint64_t, mutable_buffer_sequence, handler<system::error_code, std::size_t>);
read_at_op(std::uint64_t offset,
mutable_buffer_sequence buffer,
void * this_,
implementation_t *implementation,
try_implementation_t * try_implementation = nullptr);
void initiate(completion_handler<system::error_code, std::size_t> handler) final;
void ready(handler<system::error_code, std::size_t> handler) final;
};
struct [[nodiscard]] wait_op final : op<system::error_code>
{
using implementation_t = void(void*, completion_handler<system::error_code>);
using try_implementation_t = void(void*, handler<system::error_code>);
wait_op(void * this_,
implementation_t *implementation,
try_implementation_t * try_implementation = nullptr);
void initiate(completion_handler<system::error_code> handler) final;
void ready(handler<system::error_code> handler) final;
};
----
The ops can be reused and public members (such as buffer)
can be modified when the op is not awaited. E.g. like this:
[source,cpp]
----
write_op wo = do_w;
auto sz = co_await wo;
while (sz > 0)
{
wo.buffer += sz;
sz = co_await wo;
}
----