75 std::size_t
size_bytes()
const {
return impl().size_bytes_impl(); }
93 return position >= begin && position <= end &&
94 count_bytes <= end - position;
99 requires requires(const Impl& value) { value.as_bytes_impl(); }
101 return impl().as_bytes_impl();
110 requires requires(Impl& value) {
113 } -> std::same_as<SplitSpan<std::byte>>;
138 requires requires(Impl& value) {
141 } -> std::same_as<SplitSpan<std::byte>>;
144 if constexpr (
requires(Impl& value) {
147 impl().prepare_segments_impl(position, count_bytes);
149 validate_range(position, count_bytes);
150 return impl().segments_impl(position, count_bytes);
160 std::size_t count_bytes)
const {
161 validate_range(position, count_bytes);
162 return impl().segments_impl(position, count_bytes);
171 requires requires(const Impl& value) { value.as_bytes_impl(); }
173 return as_words<std::uint16_t>();
182 requires requires(const Impl& value) { value.as_bytes_impl(); }
184 return as_words<std::uint64_t>();
189 requires requires(const Impl& value) {
190 value.view_impl(std::size_t{}, std::size_t{});
202 auto view(std::size_t offset_bytes, std::size_t count_bytes)
const
203 requires requires(
const Impl& value) {
204 value.view_impl(std::size_t{}, std::size_t{});
207 return impl().view_impl(offset_bytes, count_bytes);
215 for (
const std::span<const std::byte> segment :
segments()) {
222 requires requires(Impl& value) { value.resize_impl(
size_bits); }
229 requires requires(Impl& value) { value.writable_bytes_impl(); }
231 return impl().writable_bytes_impl();
236 requires requires(Impl& value) { value.writable_words16_impl(); }
238 return impl().writable_words16_impl();
243 requires requires(Impl& value) { value.writable_words64_impl(); }
245 return impl().writable_words64_impl();
250 requires requires(const Impl& value) { value.allocated_bytes_impl(); }
252 return impl().allocated_bytes_impl();
257 requires requires(Impl& value) { value.shrink_to_fit_impl(); }
259 impl().shrink_to_fit_impl();
264 void validate_range(
position_type position, std::size_t count_bytes)
const {
265 if (!
contains(position, count_bytes)) {
266 throw std::out_of_range(
"Storage range is outside the working window");
271 const Impl& impl()
const {
return static_cast<const Impl&
>(*this); }
274 Impl& impl() {
return static_cast<Impl&
>(*this); }
276 template <
class Word>
277 std::span<const Word> as_words()
const {
279 if (bytes.size() %
sizeof(Word) != 0 ||
280 reinterpret_cast<std::uintptr_t
>(bytes.data()) %
alignof(Word) != 0) {
281 throw std::invalid_argument(
"Storage is not aligned to the word type");
283 return {
reinterpret_cast<const Word*
>(bytes.data()),
284 bytes.size() /
sizeof(Word)};
289template <
class Storage>
291 std::derived_from<Storage, StorageBase<Storage>>;
Bounded-buffer writer for canonical little-endian binary data.
Definition serialization.h:198
void write_bytes(std::span< const std::byte > bytes)
Append bytes without interpretation.
Definition serialization.h:297
void write_size(std::size_t value)
Write a platform size as an unsigned 64-bit integer.
Definition serialization.h:287
CRTP facade for optional binary serialization and deserialization.
Definition serialization.h:693
A logical contiguous sequence stored in at most two physical spans.
Definition split_span.h:25
CRTP facade for byte-addressable storage.
Definition storage.h:65
SplitSpan< std::byte > segments(position_type position, std::size_t count_bytes)
Return a checked writable logical byte range as one or two spans.
Definition storage.h:137
auto view() const
Return a non-owning read-only view of all exposed bytes.
Definition storage.h:188
std::span< const std::byte > as_bytes() const
Return a contiguous read-only view of all logical exposed bytes.
Definition storage.h:98
SplitSpan< const std::byte > segments() const
Return all logical bytes as one or two physical spans.
Definition storage.h:124
SplitSpan< std::byte > segments()
Return all logical bytes as one or two writable physical spans.
Definition storage.h:109
bool contains(position_type position, std::size_t count_bytes) const
Return whether a complete logical range is currently exposed.
Definition storage.h:90
auto writable_words64()
Return writable storage as 64-bit words.
Definition storage.h:242
void shrink_to_fit()
Request release of unused reserved storage.
Definition storage.h:256
std::span< const std::uint16_t > as_words16() const
Return a read-only view as 16-bit words.
Definition storage.h:170
std::span< const std::uint64_t > as_words64() const
Return a read-only view as 64-bit words.
Definition storage.h:181
position_type begin_position() const
Return the first logical byte position currently exposed.
Definition storage.h:84
void serialize_impl(BinaryWriter &writer) const
Serialize the exposed bytes with a 64-bit little-endian size prefix.
Definition storage.h:213
auto view(std::size_t offset_bytes, std::size_t count_bytes) const
Return a non-owning read-only byte subrange.
Definition storage.h:202
std::size_t size_bits() const
Return the exposed storage size in bits.
Definition storage.h:78
std::uint64_t position_type
Monotonic logical byte position used to address storage ranges.
Definition storage.h:68
auto writable_words16()
Return writable storage as 16-bit words.
Definition storage.h:235
std::size_t size_bytes() const
Return the logical exposed storage size in bytes.
Definition storage.h:75
SplitSpan< const std::byte > segments(position_type position, std::size_t count_bytes) const
Return a checked logical byte range as one or two physical spans.
Definition storage.h:159
position_type end_position() const
Return the position one past the last logical byte exposed.
Definition storage.h:87
auto writable_bytes()
Return writable storage bytes.
Definition storage.h:228
std::size_t allocated_bytes() const
Return bytes reserved by an owning storage implementation.
Definition storage.h:249
void resize(std::size_t size_bits)
Resize mutable storage to hold at least size_bits bits.
Definition storage.h:221
bool empty() const
Check whether the storage is empty.
Definition storage.h:81
A concrete CRTP implementation of StorageBase.
Definition storage.h:290
Checked byte-oriented binary serialization primitives.
Allocation-free logical ranges split across at most two spans.