diff options
Diffstat (limited to 'app/platform/stm32f0-gcc/ring_buffer.h')
-rw-r--r-- | app/platform/stm32f0-gcc/ring_buffer.h | 50 |
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{}; +}; |