20#ifndef __circular_queue_h
21#define __circular_queue_h
27#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
37#if !defined(ESP32) && !defined(ESP8266)
46template<
typename T,
typename ForEachArg =
void >
144 inline T& IRAM_ATTR
pushpeek() __attribute__((always_inline))
156 inline bool IRAM_ATTR
push() __attribute__((always_inline))
159 const size_t next = (inPos + 1) %
m_bufSize;
175 inline bool IRAM_ATTR
push(T&& val) __attribute__((always_inline))
178 const size_t next = (inPos + 1) %
m_bufSize;
198 inline bool IRAM_ATTR
push(
const T& val) __attribute__((always_inline))
204#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
211 size_t push_n(
const T* buffer,
size_t size);
221#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
228 size_t pop_n(T* buffer,
size_t size);
235#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
247#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
256#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
265template<
typename T,
typename ForEachArg >
268 if (cap + 1 == m_bufSize)
return true;
269 else if (available() > cap)
return false;
271 const auto available = pop_n(buffer, cap);
272 m_buffer.reset(buffer);
280#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
281template<
typename T,
typename ForEachArg >
287 size_t blockSize = (outPos > inPos) ? outPos - 1 - inPos : (outPos == 0) ? m_bufSize - 1 - inPos : m_bufSize - inPos;
288 blockSize = min(size, blockSize);
289 if (!blockSize)
return 0;
290 int next = (inPos + blockSize) % m_bufSize;
294 auto dest = m_buffer.get() + inPos;
295 std::copy_n(std::make_move_iterator(buffer), blockSize, dest);
296 size = min(size - blockSize, outPos > 1 ?
static_cast<size_t>(outPos - next - 1) : 0);
298 dest = m_buffer.get();
299 std::copy_n(std::make_move_iterator(buffer + blockSize), size, dest);
304 return blockSize + size;
308template<
typename T,
typename ForEachArg >
324#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
325template<
typename T,
typename ForEachArg >
327 size_t avail = size = min(size, available());
328 if (!avail)
return 0;
330 size_t n = min(avail,
static_cast<size_t>(m_bufSize - outPos));
335 buffer = std::copy_n(std::make_move_iterator(m_buffer.get() + outPos), n, buffer);
337 std::copy_n(std::make_move_iterator(m_buffer.get()), avail, buffer);
347template<
typename T,
typename ForEachArg >
348#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
357 while (outPos != inPos)
361 outPos = (outPos + 1) % m_bufSize;
366template<
typename T,
typename ForEachArg >
367#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
376 if (outPos == inPos0)
return false;
378 auto outPos1 = inPos0;
388 }
while (pos != outPos);
Definition Delegate.h:2049
Instance class for a single-producer, single-consumer circular queue / ring buffer (FIFO)....
Definition circular_queue.h:48
size_t push_n(const T *buffer, size_t size)
Push copies of multiple elements from a buffer into the queue, in order, beginning at buffer's head.
Definition circular_queue.h:282
circular_queue & operator=(circular_queue &&cq)
Definition circular_queue.h:74
void for_each(const Delegate< void(T &&), ForEachArg > &fun)
Iterate over and remove each available element from queue, calling back fun with an rvalue reference ...
circular_queue & operator=(const circular_queue &)=delete
void for_each(Delegate< void(T &&), ForEachArg > fun)
~circular_queue()
Definition circular_queue.h:69
bool for_each_rev_requeue(Delegate< bool(T &), ForEachArg > fun)
T pop()
Pop the next available element from the queue.
Definition circular_queue.h:309
bool capacity(const size_t cap)
Resize the queue. The available elements in the queue are preserved. This is not lock-free and concur...
Definition circular_queue.h:266
const T defaultValue
Definition circular_queue.h:254
size_t available() const
Get a snapshot number of elements that can be retrieved by pop.
Definition circular_queue.h:111
circular_queue(const size_t capacity)
Constructs a queue of the given maximum capacity.
Definition circular_queue.h:61
bool IRAM_ATTR push(const T &val) __attribute__((always_inline))
Push a copy of the parameter into the queue.
Definition circular_queue.h:198
std::unique_ptr< T > m_buffer
Definition circular_queue.h:259
void flush()
Discard all data in the queue.
Definition circular_queue.h:103
circular_queue(circular_queue &&cq)
Definition circular_queue.h:66
std::unique_ptr< T[]> m_buffer
Definition circular_queue.h:257
size_t pop_n(T *buffer, size_t size)
Pop multiple elements in ordered sequence from the queue to a buffer. If buffer is nullptr,...
Definition circular_queue.h:326
size_t capacity() const
Get the numer of elements the queue can hold at most.
Definition circular_queue.h:86
std::atomic< size_t > m_inPos
Definition circular_queue.h:261
circular_queue()
Constructs a valid, but zero-capacity dummy queue.
Definition circular_queue.h:53
T peek() const
Peek at the next element pop will return without removing it from the queue.
Definition circular_queue.h:133
bool IRAM_ATTR push(T &&val) __attribute__((always_inline))
Move the rvalue parameter into the queue.
Definition circular_queue.h:175
size_t available_for_push() const
Get the remaining free elementes for pushing.
Definition circular_queue.h:121
size_t m_bufSize
Definition circular_queue.h:255
bool for_each_rev_requeue(const Delegate< bool(T &), ForEachArg > &fun)
In reverse order, iterate over, pop and optionally requeue each available element from the queue,...
circular_queue(const circular_queue &)=delete
T &IRAM_ATTR pushpeek() __attribute__((always_inline))
Peek at the next pending input value.
Definition circular_queue.h:144
bool IRAM_ATTR push() __attribute__((always_inline))
Release the next pending input value, accessible by pushpeek(), into the queue.
Definition circular_queue.h:156
std::atomic< size_t > m_outPos
Definition circular_queue.h:262
T load(std::memory_order=std::memory_order_seq_cst) const volatile noexcept
Definition ghostl.h:47
void store(T desired, std::memory_order=std::memory_order_seq_cst) volatile noexcept
Definition ghostl.h:46
void reset(pointer p=pointer()) noexcept
Definition ghostl.h:69
void atomic_thread_fence(std::memory_order order) noexcept
Definition ghostl.h:49
T && move(T &t) noexcept
Definition ghostl.h:50
@ memory_order_relaxed
Definition ghostl.h:35
@ memory_order_release
Definition ghostl.h:37
@ memory_order_acquire
Definition ghostl.h:36