20#include "pw_assert/assert.h"
21#include "pw_bytes/span.h"
22#include "pw_containers/dynamic_deque.h"
23#include "pw_multibuf/internal/entry.h"
24#include "pw_preprocessor/compiler.h"
26namespace pw::multibuf {
29template <
typename,
typename>
42template <
typename SizeType,
bool kIsConst>
45 using SpanType = std::conditional_t<kIsConst, ConstByteSpan, ByteSpan>;
46 using ByteType =
typename SpanType::element_type;
47 using Deque = std::conditional_t<kIsConst,
52 using size_type = SizeType;
53 using difference_type = std::ptrdiff_t;
54 using value_type = SpanType;
55 using pointer = value_type*;
56 using const_pointer =
const value_type*;
57 using reference = value_type&;
58 using const_reference =
const value_type&;
59 using iterator_category = std::bidirectional_iterator_tag;
67 return {deque_, depth_, index_};
70 constexpr reference operator*() {
71 PW_ASSERT(is_valid());
75 constexpr const_reference operator*()
const {
76 PW_ASSERT(is_valid());
80 constexpr pointer operator->() {
81 PW_ASSERT(is_valid());
85 constexpr const_pointer operator->()
const {
86 PW_ASSERT(is_valid());
108 return lhs.deque_ == rhs.deque_ && lhs.depth_ == rhs.depth_ &&
109 lhs.index_ == rhs.index_;
114 return !(lhs == rhs);
119 template <
typename,
typename>
123 template <
typename,
bool>
127 template <
typename,
bool>
130 constexpr ChunkIterator(Deque* deque, size_type depth, size_type index)
131 : deque_(deque), depth_(depth), index_(index) {
135 constexpr bool is_valid()
const {
136 return deque_ !=
nullptr && index_ < deque_->size();
139 constexpr ByteType* data(size_type index)
const {
140 return (*deque_)[index].data + (*deque_)[index + depth_ - 1].view.offset;
143 constexpr size_t size(size_type index)
const {
144 return (*deque_)[index + depth_ - 1].view.length;
147 constexpr void ResetCurrent();
149 Deque* deque_ =
nullptr;
150 size_type depth_ = 0;
151 size_type index_ = 0;
157template <
typename SizeType,
bool kIsConst>
160 deque_ = other.deque_;
161 depth_ = other.depth_;
162 index_ = other.index_;
167template <
typename SizeType,
bool kIsConst>
168constexpr ChunkIterator<SizeType, kIsConst>&
169ChunkIterator<SizeType, kIsConst>::operator++() {
170 PW_ASSERT(is_valid());
171 size_t left = current_.size();
173 left -= size(index_);
176 while (index_ < deque_->size() && size(index_) == 0) {
183template <
typename SizeType,
bool kIsConst>
184constexpr ChunkIterator<SizeType, kIsConst>&
185ChunkIterator<SizeType, kIsConst>::operator--() {
186 PW_ASSERT(deque_ !=
nullptr);
187 PW_ASSERT(index_ != 0);
188 current_ = SpanType();
189 while (index_ != 0) {
190 SpanType prev(data(index_ - depth_), size(index_ - depth_));
191 if (!current_.empty() && prev.data() + prev.size() != current_.data()) {
194 current_ = SpanType(prev.data(), prev.size() + current_.size());
200template <
typename SizeType,
bool kIsConst>
201constexpr void ChunkIterator<SizeType, kIsConst>::ResetCurrent() {
203 current_ = SpanType();
206 current_ = SpanType(data(index_), size(index_));
207 for (size_type i = index_; i < deque_->size() - depth_; i += depth_) {
208 SpanType next(data(i + depth_), size(i + depth_));
209 if (current_.empty()) {
214 if (current_.data() + current_.size() != next.data()) {
217 current_ = SpanType(current_.data(), current_.size() + next.size());
Definition: dynamic_deque.h:60
Definition: chunk_iterator.h:30
Definition: byte_iterator.h:44
Definition: chunk_iterator.h:43
Base class for ranges of chunks.
Definition: chunks.h:30