#pragma once #include template struct Ringbuf { Ringbuf() : m_head(0), m_tail(0) {} void clear() { m_head = 0; m_tail = 0; } T peek(int offset) const { const int nextHead = (m_head + offset) % Size; return m_items[nextHead]; } bool take(T& dest) { if (m_head == m_tail) { return false; } const int cur = m_head; const int nextHead = (m_head + 1) % Size; m_head = nextHead; dest = m_items[cur]; return true; } void insert(const T& src) { const int cur = m_tail; const int nextTail = (m_tail + 1) % Size; if (nextTail == m_head) { return; } else { m_tail = nextTail; } m_items[cur] = src; } size_t write(T(&dest)[Size]) { int i = 0; size_t ret = 0; while(take(dest[i])) { i++; ret += sizeof(T); } return ret; } size_t write(Print& stream) { T val; size_t ret = 0; while(take(val)) { stream.write(val); } return ret; } size_t size() { if (m_tail > m_head) { return m_tail - m_head; } return m_tail + (Size - m_head); } private: int m_head = 0; int m_tail = 0; std::array m_items; };