#ifndef RINGBUFFER_H #define RINGBUFFER_H #include #include #include #include #include #include #include template class RingBuffer { public: explicit RingBuffer(size_t capacity, T initValue = T{}) : m_capacity(capacity) , m_data(capacity, initValue) {} inline void push(const T& v) { const uint64_t w = m_write.fetch_add(1, std::memory_order_relaxed); m_data[w % m_capacity] = v; const uint64_t newSize = std::min(w + 1, m_capacity); m_size.store(newSize, std::memory_order_release); } inline uint64_t size() const { return m_size.load(std::memory_order_acquire); } inline uint64_t capacity() const { return m_capacity; } inline uint64_t oldestGlobalIndex() const { const uint64_t w = m_write.load(std::memory_order_acquire); const uint64_t s = size(); return (w >= s) ? (w - s) : 0; } inline uint64_t newestGlobalIndex() const { const uint64_t w = m_write.load(std::memory_order_acquire); return (w > 0) ? (w - 1) : 0; } inline bool readByGlobalIndex(uint64_t gidx, T& out) const { const uint64_t oldest = oldestGlobalIndex(); const uint64_t newest = newestGlobalIndex(); if (gidx < oldest || gidx > newest) return false; out = m_data[gidx % m_capacity]; return true; } inline void reset() { m_write.store(0, std::memory_order_release); m_size.store(0, std::memory_order_release); } inline void readRange(uint64_t gidx, uint64_t count, std::vector& out) const { out.clear(); out.reserve(count); for (size_t i = 0; i < count; i++) { T v{}; if (readByGlobalIndex(gidx, v)) { out.push_back(v); } else { } } } private: uint64_t m_capacity; std::vector m_data; std::atomic m_write{0}; std::atomic m_size{0}; }; #endif