20#include "pw_bytes/span.h"
21#include "pw_multibuf/v1_adapter/chunk.h"
22#include "pw_multibuf/v1_adapter/internal/traits.h"
23#include "pw_multibuf/v2/chunks.h"
24#include "pw_multibuf/v2/multibuf.h"
25#include "pw_status/status_with_size.h"
27namespace pw::multibuf::v1_adapter {
42 using Mutability = v2::internal::Mutability;
47 template <Mutability kMutability>
50 using size_type = Deque::size_type;
51 using difference_type = Deque::difference_type;
52 using value_type = std::
53 conditional_t<kMutability == Mutability::kConst, const Chunk, Chunk>;
54 using reference = value_type&;
55 using pointer = value_type*;
56 using iterator_category = std::forward_iterator_tag;
58 constexpr Iterator() =
default;
61 operator Iterator<Mutability::kConst>()
const {
62 return mbv2_ ==
nullptr ? Iterator<Mutability::kConst>()
63 : Iterator<Mutability::kConst>(*mbv2_, index_);
66 constexpr reference operator*()
const {
67 PW_ASSERT(chunk_.has_value());
68 return const_cast<reference
>(*chunk_);
70 constexpr pointer operator->()
const {
71 PW_ASSERT(chunk_.has_value());
72 return const_cast<pointer
>(&(*chunk_));
75 constexpr Iterator& operator++() {
81 constexpr Iterator operator++(
int) {
87 constexpr bool operator==(
const Iterator& other)
const {
88 return mbv2_ == other.mbv2_ && index_ == other.index_;
91 constexpr bool operator!=(
const Iterator& other)
const {
92 return !(*
this == other);
98 constexpr Iterator(
const v2::MultiBuf& mbv2, size_type chunk)
99 : mbv2_(&(mbv2.generic())), index_(chunk) {
100 PW_ASSERT(chunk <= mbv2_->num_chunks());
105 constexpr void Update();
109 std::optional<Chunk> chunk_;
113 using iterator = Iterator<Mutability::kMutable>;
114 using const_iterator = Iterator<Mutability::kConst>;
135 return mbv2_.has_value() ? &(**mbv2_) :
nullptr;
138 return mbv2_.has_value() ? &(**mbv2_) :
nullptr;
142 constexpr size_t size()
const;
150 const auto* mbv2 =
v2();
151 last_ = *iterator(*mbv2, mbv2->generic().num_chunks() - 1);
155 iterator begin()
const {
156 const auto* mbv2 =
v2();
157 return mbv2 ==
nullptr ? iterator() : iterator(*mbv2, 0);
159 iterator end()
const {
160 const auto* mbv2 =
v2();
161 return mbv2 ==
nullptr ? iterator()
162 : iterator(*mbv2, mbv2->generic().num_chunks());
165 const_iterator cbegin()
const {
return begin(); }
166 const_iterator cend()
const {
return end(); }
169 constexpr MultiBufChunks() =
default;
178 v2::BasicMultiBuf<kProperties...>&& mb) {
179 mbv2_ = std::move(mb);
183 template <
typename MultiBufType>
185 v2::internal::Instance<MultiBufType>&& mbi) {
186 mbv2_ = std::move(*mbi);
190 void Release() noexcept { mbv2_.reset(); }
193 std::optional<v2::TrackedMultiBuf::Instance> mbv2_;
194 std::optional<Chunk> first_;
195 std::optional<Chunk> last_;
218 using size_type = v2::MultiBuf::size_type;
219 using difference_type = v2::MultiBuf::difference_type;
220 using iterator = v2::MultiBuf::iterator;
222 using pointer = v2::MultiBuf::pointer;
223 using const_pointer = v2::MultiBuf::const_pointer;
224 using reference = v2::MultiBuf::reference;
225 using const_reference = v2::MultiBuf::const_reference;
226 using value_type = v2::MultiBuf::value_type;
244 void Release() noexcept { MultiBufChunks::Release(); }
247 [[nodiscard]]
constexpr size_t size()
const {
248 const auto* mbv2 =
v2();
249 return mbv2 !=
nullptr ? mbv2->size() : 0;
253 [[nodiscard]]
constexpr bool empty()
const {
272 return mbv2 !=
nullptr ? mbv2->begin() : iterator();
274 constexpr const_iterator
begin()
const {
275 const auto* mbv2 =
v2();
276 return mbv2 !=
nullptr ? mbv2->begin() : const_iterator();
278 constexpr const_iterator cbegin()
const {
279 const auto* mbv2 =
v2();
280 return mbv2 !=
nullptr ? mbv2->cbegin() : const_iterator();
284 constexpr iterator
end() {
286 return mbv2 !=
nullptr ? mbv2->end() : iterator();
288 constexpr const_iterator
end()
const {
289 const auto* mbv2 =
v2();
290 return mbv2 !=
nullptr ? mbv2->end() : const_iterator();
292 constexpr const_iterator cend()
const {
293 const auto* mbv2 =
v2();
294 return mbv2 !=
nullptr ? mbv2->end() : const_iterator();
348 MultiBufChunks::iterator
InsertChunk(MultiBufChunks::iterator position,
352 std::tuple<MultiBufChunks::iterator, OwnedChunk>
TakeChunk(
353 MultiBufChunks::iterator position);
370 *
this = std::move(mb);
374 constexpr MultiBuf& operator=(v2::BasicMultiBuf<kProperties...>&& mb) {
375 Assign(std::move(mb));
379 template <
typename MultiBufType>
380 constexpr MultiBuf(v2::internal::Instance<MultiBufType>&& mbi) {
381 *
this = std::move(mbi);
384 template <
typename MultiBufType>
385 constexpr MultiBuf& operator=(v2::internal::Instance<MultiBufType>&& mbi) {
392 PW_ASSERT(mbv2 !=
nullptr);
396 const auto* mbv2 =
v2();
397 PW_ASSERT(mbv2 !=
nullptr);
403 PW_ASSERT(mbv2 !=
nullptr);
407 const auto* mbv2 =
v2();
408 PW_ASSERT(mbv2 !=
nullptr);
414 PW_ASSERT(mbv2 !=
nullptr);
415 return std::move(*mbv2);
418 const auto* mbv2 =
v2();
419 PW_ASSERT(mbv2 !=
nullptr);
420 return std::move(*mbv2);
423 template <
typename OtherMultiBuf,
426 constexpr operator OtherMultiBuf&() & {
428 PW_ASSERT(mbv2 !=
nullptr);
432 template <
typename OtherMultiBuf,
435 constexpr operator const OtherMultiBuf&()
const& {
437 PW_ASSERT(mbv2 !=
nullptr);
441 template <
typename OtherMultiBuf,
444 constexpr operator OtherMultiBuf&&() && {
446 PW_ASSERT(mbv2 !=
nullptr);
447 return std::move(*mbv2);
450 template <
typename OtherMultiBuf,
453 constexpr operator const OtherMultiBuf&&()
const&& {
455 PW_ASSERT(mbv2 !=
nullptr);
456 return std::move(*mbv2);
461 iterator ToByteIterator(
const MultiBufChunks::iterator& position);
464 MultiBufChunks::iterator ToChunksIterator(
const const_iterator& position);
473template <v2::
internal::Mutability kMutability>
474constexpr void MultiBufChunks::Iterator<kMutability>::Update() {
476 if (mbv2_ ==
nullptr || index_ >= mbv2_->num_chunks()) {
477 chunk_ = std::nullopt;
482 auto pos = mbv2_->MakeIterator(index_);
483 if (pos == mbv2_->cend()) {
484 chunk_ = Chunk(mbv2_->get_allocator(), SharedPtr<std::byte[]>());
489 chunk_ = Chunk(mbv2_->get_allocator(), mbv2_->Share(pos));
490 size_type start = mbv2_->GetOffset(index_);
491 size_type end = start + mbv2_->GetLength(index_);
492 chunk_->Slice(start, end);
496 const auto* mbv2 =
v2();
497 if (mbv2 ==
nullptr) {
501 for (Entry::size_type i = 0; i < mbv2->generic().num_chunks(); ++i) {
502 if (mbv2->generic().GetLength(i) != 0) {
Definition: allocator.h:42
Definition: dynamic_deque.h:73
Definition: status_with_size.h:51
Definition: multibuf.h:39
constexpr size_t size() const
Returns the number of Chunks in this MultiBuf, including empty chunks.
Definition: multibuf.h:495
constexpr v2::TrackedMultiBuf * v2()
Definition: multibuf.h:134
Definition: multibuf.h:213
void PushBackChunk(OwnedChunk &&chunk)
void Release() noexcept
Definition: multibuf.h:244
constexpr const MultiBufChunks & ConstChunks() const
Returns a const Chunk-oriented view of this MultiBuf.
Definition: multibuf.h:362
bool ClaimPrefix(size_t bytes_to_claim)
std::optional< ByteSpan > ContiguousSpan()
constexpr MultiBufChunks & Chunks()
Returns a Chunk-oriented view of this MultiBuf.
Definition: multibuf.h:356
void DiscardPrefix(size_t bytes_to_discard)
constexpr const MultiBufChunks & Chunks() const
Returns a Chunk-oriented view of this MultiBuf.
Definition: multibuf.h:359
StatusWithSize CopyTo(ByteSpan dest, size_t position=0) const
std::optional< MultiBuf > TakeSuffix(size_t bytes_to_take)
OwnedChunk TakeFrontChunk()
Definition: multibuf.h:343
constexpr iterator begin()
Returns an iterator pointing to the first byte of this MultiBuf.
Definition: multibuf.h:270
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:253
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:247
void PushSuffix(MultiBuf &&tail)
StatusWithSize CopyFrom(ConstByteSpan source, size_t position=0)
void PushFrontChunk(OwnedChunk &&chunk)
static MultiBuf FromChunk(OwnedChunk &&chunk)
bool ClaimSuffix(size_t bytes_to_claim)
bool IsContiguous() const
Definition: multibuf.h:261
void PushPrefix(MultiBuf &&front)
constexpr iterator end()
Returns an iterator pointing to the end of this MultiBuf.
Definition: multibuf.h:284
internal::Instance< BasicMultiBuf > Instance
Definition: multibuf.h:249
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
Status Assign(InlineString<> &string, std::string_view view)
Definition: util.h:142