23 template<
class Allocator = std::allocator<std::u
int8_t>>
24 class DataStorage :
public std::enable_shared_from_this<DataStorage<Allocator>>
26 template<
class It,
class SpanIt>
32 using value_type = std::uint8_t;
35 using difference_type = std::ptrdiff_t;
38 using pointer = std::uint8_t*;
41 using reference = std::uint8_t&;
44 using iterator_category = std::bidirectional_iterator_tag;
48 constexpr Iterator() noexcept =
default;
56 constexpr Iterator(
const It& it,
const It& end_it) noexcept
59 , span_it_(it == end_it_ ? std::nullopt : std::optional<SpanIt>{ (*it_)->begin() })
64 constexpr Iterator(
const Iterator& other) =
default;
67 Iterator& operator=(
const Iterator& other) =
default;
70 constexpr
const std::uint8_t& operator*()
const noexcept {
return **span_it_; }
73 constexpr
const std::uint8_t* operator->()
const noexcept {
return span_it_->operator->(); }
76 constexpr Iterator& operator++() noexcept
78 if (!span_it_.has_value() || ++*span_it_ == (*it_)->end()) {
79 span_it_ = ++it_ == end_it_ ? std::nullopt : std::optional<SpanIt>{ (*it_)->
begin() };
86 constexpr Iterator& operator--() noexcept
88 if (!span_it_.has_value() || --*span_it_ == std::prev((*it_)->begin())) {
89 span_it_ = std::optional<SpanIt>{ std::prev((*--it_)->
end()) };
96 friend constexpr
bool operator==(
const Iterator& lhs,
const Iterator& rhs)
98 return lhs.it_ == rhs.it_ && lhs.span_it_ == rhs.span_it_;
102 friend constexpr
bool operator!=(
const Iterator& lhs,
const Iterator& rhs) {
return !(lhs == rhs); }
107 std::optional<SpanIt> span_it_;
112 using SliceType = std::shared_ptr<std::vector<uint8_t, Allocator>>;
126 : buffer_{ std::move(slice) }
132 static std::shared_ptr<DataStorage>
Create() noexcept
134 return std::shared_ptr<DataStorage>(
new DataStorage());
144 return std::shared_ptr<DataStorage>(
new DataStorage(std::move(slice)));
148 bool Empty() const noexcept {
return buffer_.empty(); }
174 void Push(std::span<const uint8_t> bytes)
176 auto slice = std::make_shared<typename SliceType::element_type>();
177 slice->assign(bytes.begin(), bytes.end());
179 buffer_.push_back(std::move(slice));
203 using iterator = Iterator<typename BufferType::iterator, typename SliceType::element_type::iterator>;
207 Iterator<typename BufferType::const_iterator, typename SliceType::element_type::const_iterator>;
210 std::size_t
size() const noexcept
212 std::size_t value = 0;
213 for (
const auto& buf : buffer_) {
214 value += buf->size();
228 for (
const auto& s : buffer_) {
233 const auto size = s->size();
285 std::size_t start_pos = 0,
286 std::optional<std::size_t> end_pos = std::nullopt)
287 : storage_(std::move(storage))
288 , start_pos_(start_pos)
318 std::optional<std::size_t> end_pos = std::nullopt)
const noexcept
320 if (not end_pos.has_value() || *end_pos > storage_->size()) {
321 end_pos = storage_->size();
329 std::size_t
size() const noexcept {
return (end_pos_.has_value() ? *end_pos_ : storage_->size()) - start_pos_; }
345 std::shared_ptr<DataStorage<>> storage_;
346 std::size_t start_pos_ = 0;
347 std::optional<std::size_t> end_pos_;
Non-owning-position view that shares ownership of a DataStorage<>.
Definition: data_storage.h:274
DataStorageDynView & operator=(DataStorageDynView &&other)=default
Moves the view.
std::size_t size() const noexcept
Definition: data_storage.h:329
DataStorageDynView(DataStorageDynView &&other)=default
Moves the view.
DataStorageDynView Subspan(std::size_t start_pos, std::optional< std::size_t > end_pos=std::nullopt) const noexcept
Creates another absolute view of the same storage.
Definition: data_storage.h:317
DataStorage ::iterator begin() noexcept
Definition: data_storage.h:332
DataStorage ::const_iterator end() const noexcept
Definition: data_storage.h:341
DataStorage ::iterator end() noexcept
Definition: data_storage.h:335
DataStorageDynView(std::shared_ptr< DataStorage<>> storage, std::size_t start_pos=0, std::optional< std::size_t > end_pos=std::nullopt)
Constructs a view over an absolute half-open range.
Definition: data_storage.h:284
DataStorageDynView(const DataStorageDynView &other)=default
Copies the view and shares ownership of its storage.
DataStorage ::const_iterator begin() const noexcept
Definition: data_storage.h:338
DataStorageDynView & operator=(const DataStorageDynView &other)=default
Copies the view and shares ownership of its storage.
Shared, segmented byte storage with a flattened bidirectional iterator.
Definition: data_storage.h:25
static std::shared_ptr< DataStorage > Create(SliceType slice) noexcept
Definition: data_storage.h:142
std::shared_ptr< std::vector< uint8_t, Allocator > > SliceType
Shared ownership of one contiguous byte slice.
Definition: data_storage.h:112
const SliceType GetLast() const noexcept
Definition: data_storage.h:166
std::size_t size() const noexcept
Definition: data_storage.h:210
void Push(SliceType slice)
Appends a shared slice without copying its bytes.
Definition: data_storage.h:187
const_iterator cbegin() const noexcept
Definition: data_storage.h:258
const SliceType & Last() const noexcept
Definition: data_storage.h:160
void Push(std::span< const uint8_t > bytes)
Copies bytes into a new owned slice at the back.
Definition: data_storage.h:174
DataStorage()=default
Constructs empty storage; use Create() from callers.
iterator end() noexcept
Definition: data_storage.h:249
const SliceType & First() const noexcept
Definition: data_storage.h:154
Iterator< typename BufferType::iterator, typename SliceType::element_type::iterator > iterator
Mutable flattened byte iterator type.
Definition: data_storage.h:203
std::deque< SliceType > BufferType
Sequence of shared slices.
Definition: data_storage.h:115
friend DataStorage & operator<<(DataStorage &buffer, std::span< const uint8_t > value)
Appends a copied byte span.
Definition: data_storage.h:195
Iterator< typename BufferType::const_iterator, typename SliceType::element_type::const_iterator > const_iterator
Read-only flattened byte iterator type.
Definition: data_storage.h:207
std::size_t EraseFront(std::size_t len) noexcept
Removes complete slices from the front whose cumulative size does not exceed len.
Definition: data_storage.h:226
const_iterator end() const noexcept
Definition: data_storage.h:255
const_iterator cend() const noexcept
Definition: data_storage.h:261
iterator begin() noexcept
Definition: data_storage.h:246
bool Empty() const noexcept
Definition: data_storage.h:148
const_iterator begin() const noexcept
Definition: data_storage.h:252
static std::shared_ptr< DataStorage > Create() noexcept
Definition: data_storage.h:132
DataStorage(SliceType slice)
Constructs storage containing one shared slice.
Definition: data_storage.h:125
Definition: attributes.h:13