diff --git a/src/nsolid/nsolid_util.h b/src/nsolid/nsolid_util.h index e3f4693b95..09d41d9bf0 100644 --- a/src/nsolid/nsolid_util.h +++ b/src/nsolid/nsolid_util.h @@ -198,44 +198,61 @@ template class RingBuffer { public: NSOLID_DELETE_DEFAULT_CONSTRUCTORS(RingBuffer) - explicit RingBuffer(size_t s) : size_(s) { + explicit RingBuffer(size_t s) + : capacity_(s), + head_(0), + tail_(0), + is_full_(false) { + buffer_ = new T[s]; } - bool empty() const { - return buffer_.empty(); + ~RingBuffer() { + delete[] buffer_; } - const T& front() const { - return buffer_.front(); + bool empty() const { + return (!is_full_ && (head_ == tail_)); } + // Make sure to check empty() first otherwise an invalid value will be + // returned. T& front() { - return buffer_.front(); + return buffer_[head_]; } void pop() { - buffer_.pop(); + if (empty()) + return; + head_ = (head_ + 1) % capacity_; + is_full_ = false; } - void push(const T& value) { - if (buffer_.size() == size_) { - buffer_.pop(); + void push(T& value) { + buffer_[tail_] = value; + tail_ = (tail_ + 1) % capacity_; + + if (is_full_) { + head_ = (head_ + 1) % capacity_; } - buffer_.push(value); + is_full_ = tail_ == head_; } void push(T&& value) { - if (buffer_.size() == size_) { - buffer_.pop(); - } + buffer_[tail_] = value; + tail_ = (tail_ + 1) % capacity_; - buffer_.push(value); + if (is_full_) + head_ = (head_ + 1) % capacity_; + is_full_ = tail_ == head_; } private: - const size_t size_; - std::queue buffer_; + T* buffer_; + size_t capacity_; + size_t head_; + size_t tail_; + bool is_full_; }; } // namespace utils