boost::capy::DynamicBuffer

Concept for resizable buffer types with prepare/commit semantics.

Synopsis

template<class T>
concept DynamicBuffer = requires(T& t, T const& ct, std::size_t n)
    {
        typename T::const_buffers_type;
        typename T::mutable_buffers_type;
        { ct.size() } ‐> std::convertible_to<std::size_t>;
        { ct.max_size() } ‐> std::convertible_to<std::size_t>;
        { ct.capacity() } ‐> std::convertible_to<std::size_t>;
        { ct.data() } ‐> std::same_as<typename T::const_buffers_type>;
        { t.prepare(n) } ‐> std::same_as<typename T::mutable_buffers_type>;
        t.commit(n);
        t.consume(n);
    } &&
    ConstBufferSequence<typename T::const_buffers_type> &&
    MutableBufferSequence<typename T::mutable_buffers_type>;

Description

Types satisfying this concept provide a two‐phase write model: call prepare(n) to get writable space, write data, then call commit(n) to make those bytes readable via data().

Semantic Requirements

data() returns buffer sequence valid until next mutating operation ‐ prepare(n) returns buffer sequence valid until commit() or next prepare() ‐ Types may reference external storage; caller manages lifetime

Value Types vs Wrapper Adapters

Dynamic buffer types fall into two categories:

Value types (e.g., flat_dynamic_buffer) store bookkeeping internally. Passing as rvalue to a coroutine loses state on suspend.

Wrapper adapters (e.g., string_buffers) reference external storage and are safe as rvalues since the external object persists.

Conforming Signatures

For non‐coroutine functions, use DynamicBuffer auto&:

void fill( DynamicBuffer auto& buffers );

For coroutine functions, use DynamicBufferParam auto&& instead. This concept enforces lifetime safety: it accepts lvalues of any DynamicBuffer, but restricts rvalues to adapter types only. Using plain DynamicBuffer in coroutines allows dangerous rvalue passing that compiles but silently loses data on suspend.

io_task<std::size_t>
read( ReadSource auto& src, DynamicBufferParam auto&& buffers );

Example

flat_dynamic_buffer fb( storage, sizeof( storage ) );
auto mb = fb.prepare( 100 );    // get writable region
std::size_t n = read( sock, mb );
fb.commit( n );                 // make n bytes readable
process( fb.data() );           // access committed data
fb.consume( fb.size() );        // discard processed data

See Also

DynamicBufferParam

Created with MrDocs