ringbuffer.hpp (1259B)
1 #pragma once 2 // A simple ringbuffer holding Size elements of type T 3 template <typename T, uint8_t Size> 4 class RingBuffer { 5 protected: 6 T buf_[Size]; 7 uint8_t head_{0}, tail_{0}; 8 public: 9 inline uint8_t nextPosition(uint8_t position) { 10 return (position + 1) % Size; 11 } 12 13 inline uint8_t prevPosition(uint8_t position) { 14 if (position == 0) { 15 return Size - 1; 16 } 17 return position - 1; 18 } 19 20 inline bool enqueue(const T &item) { 21 static_assert(Size > 1, "RingBuffer size must be > 1"); 22 uint8_t next = nextPosition(head_); 23 if (next == tail_) { 24 // Full 25 return false; 26 } 27 28 buf_[head_] = item; 29 head_ = next; 30 return true; 31 } 32 33 inline bool get(T &dest, bool commit = true) { 34 auto tail = tail_; 35 if (tail == head_) { 36 // No more data 37 return false; 38 } 39 40 dest = buf_[tail]; 41 tail = nextPosition(tail); 42 43 if (commit) { 44 tail_ = tail; 45 } 46 return true; 47 } 48 49 inline bool empty() const { return head_ == tail_; } 50 51 inline uint8_t size() const { 52 int diff = head_ - tail_; 53 if (diff >= 0) { 54 return diff; 55 } 56 return Size + diff; 57 } 58 59 inline T& front() { 60 return buf_[tail_]; 61 } 62 63 inline bool peek(T &item) { 64 return get(item, false); 65 } 66 };