| Index: cc/debug/ring_buffer.h
|
| diff --git a/cc/debug/ring_buffer.h b/cc/debug/ring_buffer.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f9a6749e11622b0cd5a29ff92f69a962c5b762e0
|
| --- /dev/null
|
| +++ b/cc/debug/ring_buffer.h
|
| @@ -0,0 +1,120 @@
|
| +// Copyright 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CC_DEBUG_RING_BUFFER_H_
|
| +#define CC_DEBUG_RING_BUFFER_H_
|
| +
|
| +#include "base/logging.h"
|
| +
|
| +namespace cc {
|
| +
|
| +template<typename T, size_t kSize>
|
| +class RingBuffer {
|
| + public:
|
| + RingBuffer() : current_index_(0) {}
|
| +
|
| + size_t BufferSize() const {
|
| + return kSize;
|
| + }
|
| +
|
| + size_t CurrentIndex() const {
|
| + return current_index_;
|
| + }
|
| +
|
| + // tests if a value was saved to this index
|
| + bool IsFilledIndex(size_t n) const {
|
| + return BufferIndex(n) < current_index_;
|
| + }
|
| +
|
| + // n = 0 returns the oldest value and
|
| + // n = bufferSize() - 1 returns the most recent value.
|
| + const T& ReadBuffer(size_t n) const {
|
| + DCHECK(IsFilledIndex(n));
|
| + return buffer_[BufferIndex(n)];
|
| + }
|
| +
|
| + T* MutableReadBuffer(size_t n) {
|
| + DCHECK(IsFilledIndex(n));
|
| + return &buffer_[BufferIndex(n)];
|
| + }
|
| +
|
| + void SaveToBuffer(const T& value) {
|
| + buffer_[BufferIndex(0)] = value;
|
| + current_index_++;
|
| + }
|
| +
|
| + void Clear() {
|
| + current_index_ = 0;
|
| + }
|
| +
|
| + // Iterator has const access to the RingBuffer it got retrieved from.
|
| + class Iterator {
|
| + public:
|
| + size_t index() const { return index_; }
|
| +
|
| + const T* operator->() const { return &buffer_.ReadBuffer(index_); }
|
| + const T* operator*() const { return &buffer_.ReadBuffer(index_); }
|
| +
|
| + Iterator& operator++() {
|
| + index_++;
|
| + if (index_ == kSize)
|
| + out_of_range_ = true;
|
| + return *this;
|
| + }
|
| +
|
| + Iterator& operator--() {
|
| + if (index_ == 0)
|
| + out_of_range_ = true;
|
| + index_--;
|
| + return *this;
|
| + }
|
| +
|
| + operator bool() const {
|
| + return buffer_.IsFilledIndex(index_) && !out_of_range_;
|
| + }
|
| +
|
| + private:
|
| + Iterator(const RingBuffer<T, kSize>& buffer, size_t index)
|
| + : buffer_(buffer),
|
| + index_(index),
|
| + out_of_range_(false) {
|
| + }
|
| +
|
| + const RingBuffer<T, kSize>& buffer_;
|
| + size_t index_;
|
| + bool out_of_range_;
|
| +
|
| + friend class RingBuffer<T, kSize>;
|
| + };
|
| +
|
| + // Returns an Iterator pointing to the oldest value in the buffer.
|
| + // Example usage (iterate from oldest to newest value):
|
| + // for (RingBuffer<T, kSize>::Iterator it = ring_buffer.Begin(); it; ++it) {}
|
| + Iterator Begin() const {
|
| + if (current_index_ < kSize)
|
| + return Iterator(*this, kSize - current_index_);
|
| + return Iterator(*this, 0);
|
| + }
|
| +
|
| + // Returns an Iterator pointing to the newest value in the buffer.
|
| + // Example usage (iterate backwards from newest to oldest value):
|
| + // for (RingBuffer<T, kSize>::Iterator it = ring_buffer.End(); it; --it) {}
|
| + Iterator End() const {
|
| + return Iterator(*this, kSize - 1);
|
| + }
|
| +
|
| + private:
|
| + inline size_t BufferIndex(size_t n) const {
|
| + return (current_index_ + n) % kSize;
|
| + }
|
| +
|
| + T buffer_[kSize];
|
| + size_t current_index_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RingBuffer);
|
| +};
|
| +
|
| +} // namespace cc
|
| +
|
| +#endif // CC_DEBUG_RING_BUFFER_H_
|
|
|