boost::capy::BufferSink
Concept for types that consume buffer data using callee‐owned buffers.
Synopsis
template<typename T>
concept BufferSink = requires(T& sink, std::span<mutable_buffer> dest, std::size_t n)
{
// Synchronous: get writable buffers from sink's internal storage
{ sink.prepare(dest) } ‐> std::same_as<std::span<mutable_buffer>>;
// Async: commit n bytes written
{ sink.commit(n) } ‐> IoAwaitable;
requires awaitable_decomposes_to<
decltype(sink.commit(n)),
std::error_code>;
// Async: commit n final bytes and signal end of data
{ sink.commit_eof(n) } ‐> IoAwaitable;
requires awaitable_decomposes_to<
decltype(sink.commit_eof(n)),
std::error_code>;
};
Description
A type satisfies BufferSink if it provides a synchronous prepare member function that fills a caller‐provided span with mutable buffer descriptors pointing to the sink's internal storage, and asynchronous commit and commit_eof member functions to finalize written data.
This concept models the "callee owns buffers" pattern where the sink provides writable memory and the caller writes directly into it, enabling zero‐copy data transfer. Compare with WriteSink which uses the "caller owns buffers" pattern.
Syntactic Requirements
-
`T` must provide a synchronous `prepare` member function accepting a `std::span<mutable_buffer>` and returning a span of filled buffers
-
`T` must provide `commit(n)` returning an
IoAwaitablethat decomposes to `(error_code)` -
`T` must provide `commit_eof(n)` returning an
IoAwaitablethat decomposes to `(error_code)`
Semantic Requirements
The prepare operation provides writable buffer space:
-
Returns a span of buffer descriptors that were filled
-
The returned buffers point to the sink's internal storage
-
If the returned span is empty, the sink has no available space; caller should call `commit` to flush data and try again
The commit operation finalizes written data:
-
Commits `n` bytes written to the most recent `prepare` buffers
-
May trigger underlying I/O (flush to socket, compression, etc.)
-
On success: `ec` is `false`
-
On error: `ec` is `true`
The commit_eof operation commits final data and signals end‐of‐stream:
-
Commits `n` bytes written to the most recent `prepare` buffers and finalizes the sink
-
After success, no further operations are permitted
-
On success: `ec` is `false`, sink is finalized
-
On error: `ec` is `true`
Buffer Lifetime
Buffers returned by prepare remain valid until the next call to prepare, commit, commit_eof, or until the sink is destroyed.
Conforming Signatures
std::span<mutable_buffer> prepare( std::span<mutable_buffer> dest );
IoAwaitable auto commit( std::size_t n );
IoAwaitable auto commit_eof( std::size_t n );
Example
template<BufferSource Source, BufferSink Sink>
io_task<std::size_t> transfer( Source& source, Sink& sink )
{
const_buffer src_arr[16];
mutable_buffer dst_arr[16];
std::size_t total = 0;
for(;;)
{
auto [ec1, src_bufs] = co_await source.pull( src_arr );
if( ec1 == cond::eof )
{
auto [eof_ec] = co_await sink.commit_eof( 0 );
co_return {eof_ec, total};
}
if( ec1 )
co_return {ec1, total};
auto dst_bufs = sink.prepare( dst_arr );
std::size_t n = buffer_copy( dst_bufs, src_bufs );
auto [ec2] = co_await sink.commit( n );
if( ec2 )
co_return {ec2, total};
total += n;
}
}
See Also
BufferSource, WriteSink, IoAwaitable, awaitable_decomposes_to
Created with MrDocs