MutableBufferSequence
A MutableBufferSequence represents zero or more contiguous writable memory
regions as a bidirectional range whose value type is convertible to
mutable_buffer, or as an object which is convertible to mutable_buffer.
All mutable buffer sequences are also constant buffer sequences, since writable memory can always be read.
Concept Definition
template<typename T>
concept mutable_buffer_sequence =
std::is_convertible_v<T, mutable_buffer> || (
std::ranges::bidirectional_range<T> &&
std::is_convertible_v<std::ranges::range_value_t<T>, mutable_buffer>);
Requirements
-
Tdenotes a type meeting the MutableBufferSequence requirements. -
tdenotes a value of typeT. -
udenotes a value of typeT.
| Expression | Type | Semantics, Pre/Post-conditions |
|---|---|---|
|
|
|
|
Iterator |
Returns a bidirectional iterator to the first buffer, or |
|
Iterator |
Returns a bidirectional iterator one past the last buffer. |
|
Convertible to |
Where |
|
Copy construction. |
Iteration
While std::ranges::begin and std::ranges::end work on bidirectional ranges,
they do not handle objects merely convertible to mutable_buffer. Use
and buffers::begin for uniform handling:buffers::end
template<class MutableBufferSequence>
std::size_t fill_with_zeros(MutableBufferSequence const& bs)
{
std::size_t total = 0;
for(auto it = buffers::begin(bs); it != buffers::end(bs); ++it)
{
mutable_buffer b = *it;
std::memset(b.data(), 0, b.size());
total += b.size();
}
return total;
}
// Works with ranges
std::vector<mutable_buffer> v = /* ... */;
fill_with_zeros(v);
// Also works with single buffers
char data[100];
mutable_buffer mb(data, sizeof(data));
fill_with_zeros(mb);
Copy Semantics
Copies of a buffer sequence must reference the same underlying memory:
T t(u);
static_assert(mutable_buffer_sequence<T>);
assert(std::equal(
buffers::begin(t), buffers::end(t),
buffers::begin(u), buffers::end(u),
[](mutable_buffer const& b1, mutable_buffer const& b2)
{
return b1.data() == b2.data() && b1.size() == b2.size();
}));
This property enables efficient pass-by-value semantics. Copying a buffer sequence is cheap because only the handle is copied, not the underlying data.
Relationship to ConstBufferSequence
Every MutableBufferSequence is also a ConstBufferSequence. This allows mutable buffer sequences to be used wherever constant buffer sequences are expected:
template<class ConstBufferSequence>
std::size_t count_bytes(ConstBufferSequence const& bs);
char data[100];
mutable_buffer mb(data, sizeof(data));
// mutable_buffer works with ConstBufferSequence algorithms
std::size_t n = count_bytes(mb);
Models
The following types model MutableBufferSequence:
-
slice_of(when wrapping a mutable sequence) -
std::array<mutable_buffer, N> -
std::vector<mutable_buffer>
See Also
-
ConstBufferSequence - Read-only buffer sequences
-
Introduction - Buffer sequence concepts explained
-
Algorithms - Functions operating on buffer sequences