20#include "pw_bytes/span.h"
21#include "pw_multibuf/v1_adapter/chunk.h"
22#include "pw_multibuf/v2/chunks.h"
23#include "pw_multibuf/v2/multibuf.h"
24#include "pw_status/status_with_size.h"
26namespace pw::multibuf::v1_adapter {
41 using Mutability = v2::internal::Mutability;
46 template <Mutability kMutability>
49 using size_type = Deque::size_type;
50 using difference_type = Deque::difference_type;
51 using value_type = std::
52 conditional_t<kMutability == Mutability::kConst, const Chunk, Chunk>;
53 using reference = value_type&;
54 using pointer = value_type*;
55 using iterator_category = std::forward_iterator_tag;
57 constexpr Iterator() =
default;
60 operator Iterator<Mutability::kConst>()
const {
61 return mbv2_ ==
nullptr ? Iterator<Mutability::kConst>()
62 : Iterator<Mutability::kConst>(*mbv2_, index_);
65 constexpr reference operator*()
const {
66 PW_ASSERT(chunk_.has_value());
67 return const_cast<reference
>(*chunk_);
69 constexpr pointer operator->()
const {
70 PW_ASSERT(chunk_.has_value());
71 return const_cast<pointer
>(&(*chunk_));
74 constexpr Iterator& operator++() {
80 constexpr Iterator operator++(
int) {
86 constexpr bool operator==(
const Iterator& other)
const {
87 return mbv2_ == other.mbv2_ && index_ == other.index_;
90 constexpr bool operator!=(
const Iterator& other)
const {
91 return !(*
this == other);
97 constexpr Iterator(
const v2::MultiBuf& mbv2, size_type chunk)
98 : mbv2_(&(mbv2.generic())),
99 index_(std::min(chunk, mbv2.generic().num_chunks())) {
103 constexpr void Update() {
105 if (mbv2_ ==
nullptr || index_ >= mbv2_->num_chunks()) {
106 chunk_ = std::nullopt;
111 auto pos = mbv2_->MakeIterator(index_);
112 if (pos == mbv2_->cend()) {
118 chunk_ =
Chunk(mbv2_->get_allocator(), mbv2_->Share(pos));
119 size_type start = mbv2_->GetOffset(index_);
120 size_type end = start + mbv2_->GetLength(index_);
121 chunk_->Slice(start, end);
126 std::optional<Chunk> chunk_;
130 using iterator = Iterator<Mutability::kMutable>;
131 using const_iterator = Iterator<Mutability::kConst>;
134 constexpr size_t size()
const {
135 const auto& mbv2 = mbv2_->generic();
136 if (mbv2_ ==
nullptr) {
140 for (Entry::size_type i = 0; i < mbv2.num_chunks(); ++i) {
141 if (mbv2.GetLength(i) != 0) {
148 iterator begin()
const {
149 return mbv2_ ==
nullptr ? iterator() : iterator(*mbv2_, 0);
151 iterator end()
const {
152 return mbv2_ ==
nullptr
155 std::numeric_limits<iterator::size_type>::max());
158 const_iterator cbegin()
const {
return begin(); }
159 const_iterator cend()
const {
return end(); }
189 using size_type = v2::MultiBuf::size_type;
190 using difference_type = v2::MultiBuf::difference_type;
191 using iterator = v2::MultiBuf::iterator;
193 using pointer = v2::MultiBuf::pointer;
194 using const_pointer = v2::MultiBuf::const_pointer;
195 using reference = v2::MultiBuf::reference;
196 using const_reference = v2::MultiBuf::const_reference;
197 using value_type = v2::MultiBuf::value_type;
221 return mbv2_.has_value() ? &(**mbv2_) :
nullptr;
224 return mbv2_.has_value() ? &(**mbv2_) :
nullptr;
238 [[nodiscard]] constexpr
size_t size()
const {
239 return mbv2_.has_value() ? (*mbv2_)->size() : 0;
243 [[nodiscard]]
constexpr bool empty()
const {
261 return mbv2_.has_value() ? (*mbv2_)->begin() : iterator();
263 constexpr const_iterator
begin()
const {
264 return mbv2_.has_value() ? (*mbv2_)->begin() : const_iterator();
266 constexpr const_iterator cbegin()
const {
267 return mbv2_.has_value() ? (*mbv2_)->cbegin() : const_iterator();
271 constexpr iterator
end() {
272 return mbv2_.has_value() ? (*mbv2_)->end() : iterator();
274 constexpr const_iterator
end()
const {
275 return mbv2_.has_value() ? (*mbv2_)->end() : const_iterator();
277 constexpr const_iterator cend()
const {
278 return mbv2_.has_value() ? (*mbv2_)->end() : const_iterator();
332 MultiBufChunks::iterator
InsertChunk(MultiBufChunks::iterator position,
336 std::tuple<MultiBufChunks::iterator, OwnedChunk>
TakeChunk(
337 MultiBufChunks::iterator position);
354 : mbv2_(std::in_place, allocator) {}
358 *
this = std::move(mb);
362 constexpr MultiBuf& operator=(v2::BasicMultiBuf<kProperties...>&& mb) {
363 mbv2_ = std::move(mb);
367 template <
typename MultiBufType>
368 constexpr MultiBuf(v2::internal::Instance<MultiBufType>&& mbi) {
369 *
this = std::move(mbi);
372 template <
typename MultiBufType>
373 constexpr MultiBuf& operator=(v2::internal::Instance<MultiBufType>&& mbi) {
374 mbv2_ = std::move(*mbi);
379 PW_ASSERT(mbv2_.has_value());
383 PW_ASSERT(mbv2_.has_value());
388 PW_ASSERT(mbv2_.has_value());
392 PW_ASSERT(mbv2_.has_value());
397 PW_ASSERT(mbv2_.has_value());
398 return std::move(**mbv2_);
401 PW_ASSERT(mbv2_.has_value());
402 return std::move(**mbv2_);
405 template <
typename MultiBufType>
406 constexpr operator MultiBufType&() & {
407 PW_ASSERT(mbv2_.has_value());
410 template <
typename MultiBufType>
411 constexpr operator const MultiBufType&()
const& {
412 PW_ASSERT(mbv2_.has_value());
416 template <
typename MultiBufType>
417 constexpr operator MultiBufType&&() && {
418 PW_ASSERT(mbv2_.has_value());
419 return std::move(**mbv2_);
421 template <
typename MultiBufType>
422 constexpr operator const MultiBufType&&()
const&& {
423 PW_ASSERT(mbv2_.has_value());
424 return std::move(**mbv2_);
429 iterator ToByteIterator(
const MultiBufChunks::iterator& position);
432 MultiBufChunks::iterator ToChunksIterator(
const const_iterator& position);
434 std::optional<v2::TrackedMultiBuf::Instance> mbv2_;
Definition: allocator.h:45
Definition: dynamic_deque.h:60
Definition: shared_ptr.h:68
Definition: status_with_size.h:51
Definition: multibuf.h:38
Definition: multibuf.h:184
void PushBackChunk(OwnedChunk &&chunk)
bool ClaimPrefix(size_t bytes_to_claim)
std::optional< ByteSpan > ContiguousSpan()
void DiscardPrefix(size_t bytes_to_discard)
constexpr MultiBufChunks Chunks()
Returns a Chunk-oriented view of this MultiBuf.
Definition: multibuf.h:340
StatusWithSize CopyTo(ByteSpan dest, size_t position=0) const
std::optional< MultiBuf > TakeSuffix(size_t bytes_to_take)
OwnedChunk TakeFrontChunk()
Definition: multibuf.h:327
constexpr iterator begin()
Returns an iterator pointing to the first byte of this MultiBuf.
Definition: multibuf.h:260
void Truncate(size_t len)
StatusWithSize CopyFromAndTruncate(ConstByteSpan source, size_t position=0)
void TruncateAfter(iterator pos)
MultiBufChunks::iterator InsertChunk(MultiBufChunks::iterator position, OwnedChunk &&chunk)
void Slice(size_t begin, size_t end)
constexpr bool empty() const
Definition: multibuf.h:243
constexpr v2::TrackedMultiBuf * v2()
Definition: multibuf.h:220
std::tuple< MultiBufChunks::iterator, OwnedChunk > TakeChunk(MultiBufChunks::iterator position)
std::optional< MultiBuf > TakePrefix(size_t bytes_to_take)
constexpr size_t size() const
Definition: multibuf.h:238
void PushSuffix(MultiBuf &&tail)
StatusWithSize CopyFrom(ConstByteSpan source, size_t position=0)
constexpr const MultiBufChunks ConstChunks() const
Returns a const Chunk-oriented view of this MultiBuf.
Definition: multibuf.h:347
void PushFrontChunk(OwnedChunk &&chunk)
static MultiBuf FromChunk(OwnedChunk &&chunk)
bool ClaimSuffix(size_t bytes_to_claim)
bool IsContiguous() const
Definition: multibuf.h:251
void PushPrefix(MultiBuf &&front)
constexpr iterator end()
Returns an iterator pointing to the end of this MultiBuf.
Definition: multibuf.h:271
Byte iterator templated on the const-ness of the bytes it references.
Definition: byte_iterator.h:85
Definition: multibuf.h:1057
Property
Basic properties of a MultiBuf.
Definition: properties.h:24
BasicMultiBuf< Property::kLayerable, Property::kObservable > TrackedMultiBuf
Definition: multibuf.h:80