#pragma once #include template class RingBuffer { public: RingBuffer(); bool Push(const T& v); template typename std::enable_if< !std::is_array::value, Q >::type Pop() { std::unique_lock lock(m_mutex); if (m_readPointer == m_writePointer) { return T(); } const T& tmp = m_data[m_readPointer]; m_readPointer = (m_readPointer + 1) % elements; return tmp; } T& GetSlot(); T& GetSlotAndAdvance(); void Advance(); void Clear(); P GetReadPointer(); P GetWritePointer(); bool HasData(); private: T m_data[elements]; P m_readPointer; P m_writePointer; std::mutex m_mutex; }; template RingBuffer::RingBuffer() : m_readPointer(0), m_writePointer(0) { } template bool RingBuffer::Push(const T& v) { std::unique_lock lock(m_mutex); if (m_readPointer == ((m_writePointer + 1) % elements)) { debugBreakpoint(); // buffer is full return false; } m_data[m_writePointer] = v; m_writePointer = (m_writePointer + 1) % elements; return true; } template T& RingBuffer::GetSlot() { std::unique_lock lock(m_mutex); T& result = m_data[m_writePointer]; m_writePointer = (m_writePointer + 1) % elements; return result; } template T& RingBuffer::GetSlotAndAdvance() { std::unique_lock lock(m_mutex); T& result = m_data[m_writePointer]; m_writePointer = (m_writePointer + 1) % elements; m_readPointer = (m_readPointer + 1) % elements; return result; } template void RingBuffer::Advance() { std::unique_lock lock(m_mutex); if (m_readPointer != m_writePointer) { m_readPointer = (m_readPointer + 1) % elements; } } template void RingBuffer::Clear() { std::unique_lock lock(m_mutex); m_readPointer = 0; m_writePointer = 0; } template P RingBuffer::GetReadPointer() { std::unique_lock lock(m_mutex); P tmp = m_readPointer; return tmp; } template P RingBuffer::GetWritePointer() { std::unique_lock lock(m_mutex); P tmp = m_writePointer; return tmp; } template bool RingBuffer::HasData() { std::unique_lock lock(m_mutex); return m_readPointer != m_writePointer; }