summaryrefslogtreecommitdiff
path: root/app/platform/stm32f0-gcc/ring_buffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'app/platform/stm32f0-gcc/ring_buffer.h')
-rw-r--r--app/platform/stm32f0-gcc/ring_buffer.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/app/platform/stm32f0-gcc/ring_buffer.h b/app/platform/stm32f0-gcc/ring_buffer.h
new file mode 100644
index 0000000..1a065ef
--- /dev/null
+++ b/app/platform/stm32f0-gcc/ring_buffer.h
@@ -0,0 +1,50 @@
+#pragma once
+#include <cassert>
+#include <cstring>
+
+template <typename T>
+class RingBuffer
+{
+public:
+ using UnitType = T;
+ constexpr explicit RingBuffer(UnitType* buffer, size_t buffer_size)
+ : _buffer_size(buffer_size), _buffer(buffer)
+ {
+ assert(buffer_size);
+ assert(buffer);
+ }
+ constexpr void Push(UnitType item)
+ {
+ _buffer[_head] = item;
+ _head = (_head + 1) % _buffer_size;
+ }
+ constexpr void Push(const UnitType *items, size_t nitems)
+ {
+ if (items) for (; nitems; items++, nitems--) Push(*items);
+ }
+ constexpr UnitType Pop()
+ {
+ const auto item = _buffer[_tail];
+ _tail = (_tail + 1) % _buffer_size;
+ return item;
+ }
+ constexpr void Pop(UnitType* buf, size_t nitems)
+ {
+ if (buf) for (; nitems; nitems--, buf++) *buf = Pop();
+ }
+ constexpr size_t Free()
+ {
+ return Size() - Occupied();
+ }
+ constexpr size_t Occupied()
+ {
+ return _head - _tail + (_head >= _tail) ? 0 : _buffer_size;
+ }
+ constexpr bool IsEmpty() { return _head == _tail; }
+ constexpr bool IsFull() { return _tail + 1 == _head; }
+ constexpr size_t Size() { return _buffer_size - 1; }
+private:
+ size_t _buffer_size{};
+ UnitType *_buffer{};
+ size_t _head{}, _tail{};
+};