Dynamic Buffers
This page explains growable buffer containers that manage their own storage.
Code snippets assume using namespace boost::capy; is in effect.
|
What is a Dynamic Buffer?
A dynamic buffer is a container that provides both readable and writable regions. Data flows through a dynamic buffer:
-
Prepare writable space
-
Write data into that space
-
Commit the written bytes to make them readable
-
Read the data
-
Consume the read bytes
This model enables efficient streaming without copying.
Common Interface
All dynamic buffers provide these operations:
| Operation | Description |
|---|---|
|
Number of readable bytes |
|
Maximum capacity |
|
Current writable space available |
|
Buffer sequence of readable bytes |
|
Buffer sequence of |
|
Move |
|
Remove |
flat_buffer
A flat_buffer uses a single contiguous memory region:
// Fixed storage (stack or pre-allocated)
char storage[1024];
flat_buffer buf(storage, sizeof(storage));
// Prepare space for writing
mutable_buffer out = buf.prepare(100);
// Write data
std::memcpy(out.data(), "Hello", 5);
// Commit written bytes
buf.commit(5);
// Read data
const_buffer in = buf.data();
// in.data() points to "Hello", in.size() == 5
// Consume read bytes
buf.consume(5);
// buf.size() == 0
circular_buffer
A circular_buffer uses a ring buffer that wraps around:
char storage[1024];
circular_buffer buf(storage, sizeof(storage));
// Same interface as flat_buffer
auto out = buf.prepare(100); // May return two-element sequence
buf.commit(50);
auto in = buf.data(); // May return two-element sequence
buf.consume(25);
string_buffer
A string_buffer adapts a std::string as a dynamic buffer:
std::string str;
string_buffer buf(&str);
// Write data
auto out = buf.prepare(100);
std::memcpy(out.data(), "Hello", 5);
buf.commit(5);
// str now contains "Hello"
Characteristics
-
Owns no storage - wraps an existing string
-
String grows as needed (up to max_size)
-
Destructor resizes string to final size
-
Move-only (cannot be copied)
Choosing a Buffer Type
| Type | Best For | Trade-off |
|---|---|---|
|
Simple linear data flow |
May waste space after consume |
|
Continuous streaming |
Two-element sequences add complexity |
|
Building strings incrementally |
Requires external string ownership |
Example: Reading Chunked Data
char storage[4096];
circular_buffer buf(storage, sizeof(storage));
while (!done)
{
// Prepare space
auto writable = buf.prepare(1024);
// Read into buffer
std::size_t n = read_some(writable);
buf.commit(n);
// Process available data
auto readable = buf.data();
std::size_t processed = process(readable);
buf.consume(processed);
}
Summary
| Type | Description |
|---|---|
|
Single contiguous region, simple sequences |
|
Ring buffer, two-element sequences, no fragmentation |
|
Adapts |
Next Steps
-
Buffer Sequences — Buffer sequence concepts
-
Buffer Types — Basic buffer types