65#if defined(DEBUG_CIRC_BUF)
66#include DEBUG_CIRC_BUF
80template<
typename Value,
size_t Size,
size_t MaxPacketSize>
87 static_assert(std::popcount(Size) == 1,
"Size needs to be a power of 2");
91 static constexpr size_t sizeBytes =
sizeof(SmallestTypeT<MaxPacketSize>);
93 constexpr size_t capacity()
const {
return Size; }
94 size_t size()
const {
return write - read; }
95 size_t readable()
const {
return notified - read; }
96 size_t unnotified()
const {
return std::max(sizeBytes, write - notified) - sizeBytes; }
97 bool empty()
const {
return size() == 0; }
98 bool full()
const {
return size() == capacity(); }
99 bool dropping()
const {
return dropped; }
104 template<
typename Value_>
106 requires std::same_as<std::remove_cvref_t<Value>, std::remove_cvref_t<Value_>>
109 if (unnotified() >= MaxPacketSize || size() >= capacity())
113 if ((!dropped) && (notified == write))
117 if (unnotified() >= MaxPacketSize || size() >= capacity())
123 buf[write++ % Size] = std::forward<Value_>(v);
140 return buf[read % Size];
147 return buf[read % Size];
174 size_t size = unnotified();
175 for (
size_t i = sizeBytes; i > 0; --i)
177 buf[notified++ % Size] =
static_cast<uint8_t
>(size);
187 using value_type = Value;
188 using difference_type = ptrdiff_t;
191 : parent(parent_), index(index_) {}
192 Iterator & operator++() { ++index;
return *
this; }
193 Iterator operator++(
int) {
const auto tmp = *
this; ++*
this;
return tmp; }
194 const Value & operator*()
const {
return parent->buf[index % Size]; }
195 bool operator!=(
const Iterator & other)
const
197 return parent != other.parent || index != other.index;
199 bool operator==(
const Iterator & other)
const {
return !(*
this != other); }
212 begin_(parent, start),
213 end_(parent, start + len) {}
214 Frame(
const Frame &) =
delete;
215 Frame & operator=(
const Frame &) =
delete;
216 Frame(Frame && o) : begin_(o.begin_), end_(o.end_)
218 std::swap(parent, o.parent);
220 Frame & operator=(Frame && o)
233 parent->read = end_.index;
237 Iterator & begin() {
return begin_; }
258 const auto end = notified;
265 for (
size_t i = sizeBytes; i > 0; --i)
270 size |= buf[start++ % Size];
275 debugf(ERROR
"Truncated next packet size" END);
280 frame.emplace(
this, start, size);
287 return frame.has_value();
300 std::array<Value, Size> buf;
304 bool dropped =
false;
Definition circular_buffer.hpp:185
Definition circular_buffer.hpp:82
void reset_dropped()
Definition circular_buffer.hpp:153
void notify()
Definition circular_buffer.hpp:168
bool get_frame(std::optional< Frame > &frame)
Definition circular_buffer.hpp:247
const Value & front() const
Definition circular_buffer.hpp:145
void push_back(Value_ &&v)
Definition circular_buffer.hpp:107
void reset()
Reset the queue to the initial, empty state.
Definition circular_buffer.hpp:291
void pop_front()
Drop the first element from the queue.
Definition circular_buffer.hpp:128
Value & front()
Definition circular_buffer.hpp:138
uint8_t value_type
Definition circular_buffer.hpp:89
#define debugf(...)
Definition ndebug.hpp:23
#define END
Terminator of log message at the end.
Definition ndebug.hpp:50
#define LOGLEVEL_ARGS
Definition ndebug.hpp:28
#define DEBUG
Debug levels at the start of debugf.
Definition ndebug.hpp:33
Simple type utilities e.g. smallest type for given value.