#pragma once #include #include #include template class RingBuffer { public: explicit RingBuffer(size_t capacity); size_t capacity() const; size_t size() const; bool is_empty() const; bool is_full() const; void enqueue(const T&); T dequeue(); private: size_t capacity_; size_t start_; size_t size_; std::unique_ptr data_; }; template RingBuffer::RingBuffer(size_t capacity) { capacity_ = capacity; start_ = 0; size_ = 0; data_ = new T[capacity]; } template size_t RingBuffer::capacity() const { return capacity_; } template size_t RingBuffer::size() const { return size_; } template bool RingBuffer::is_empty() const { return size() == 0; } template bool RingBuffer::is_full() const { return size() == capacity(); } template void RingBuffer::enqueue(const T& element) { if (is_full()) throw std::runtime_error("RingBuffer::enqueue: full"); data_[(start_ + size_) % capacity_] = element; ++size_; } template T RingBuffer::dequeue() { if (is_empty()) throw std::runtime_error("RingBuffer::dequeue: empty"); T result = data_[start_]; data_[start_] = T(); --size_; start_ = (start_ + 1) % capacity_; return result; }