1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CC_DEBUG_RING_BUFFER_H_
6 #define CC_DEBUG_RING_BUFFER_H_
8 #include "base/logging.h"
12 template<typename T
, size_t kSize
>
15 RingBuffer() : current_index_(0) {}
17 size_t BufferSize() const {
21 size_t CurrentIndex() const {
22 return current_index_
;
25 // tests if a value was saved to this index
26 bool IsFilledIndex(size_t n
) const {
27 return BufferIndex(n
) < current_index_
;
30 // n = 0 returns the oldest value and
31 // n = bufferSize() - 1 returns the most recent value.
32 const T
& ReadBuffer(size_t n
) const {
33 DCHECK(IsFilledIndex(n
));
34 return buffer_
[BufferIndex(n
)];
37 T
* MutableReadBuffer(size_t n
) {
38 DCHECK(IsFilledIndex(n
));
39 return &buffer_
[BufferIndex(n
)];
42 void SaveToBuffer(const T
& value
) {
43 buffer_
[BufferIndex(0)] = value
;
51 // Iterator has const access to the RingBuffer it got retrieved from.
54 size_t index() const { return index_
; }
56 const T
* operator->() const { return &buffer_
.ReadBuffer(index_
); }
57 const T
* operator*() const { return &buffer_
.ReadBuffer(index_
); }
59 Iterator
& operator++() {
66 Iterator
& operator--() {
73 operator bool() const {
74 return buffer_
.IsFilledIndex(index_
) && !out_of_range_
;
78 Iterator(const RingBuffer
<T
, kSize
>& buffer
, size_t index
)
81 out_of_range_(false) {
84 const RingBuffer
<T
, kSize
>& buffer_
;
88 friend class RingBuffer
<T
, kSize
>;
91 // Returns an Iterator pointing to the oldest value in the buffer.
92 // Example usage (iterate from oldest to newest value):
93 // for (RingBuffer<T, kSize>::Iterator it = ring_buffer.Begin(); it; ++it) {}
94 Iterator
Begin() const {
95 if (current_index_
< kSize
)
96 return Iterator(*this, kSize
- current_index_
);
97 return Iterator(*this, 0);
100 // Returns an Iterator pointing to the newest value in the buffer.
101 // Example usage (iterate backwards from newest to oldest value):
102 // for (RingBuffer<T, kSize>::Iterator it = ring_buffer.End(); it; --it) {}
103 Iterator
End() const {
104 return Iterator(*this, kSize
- 1);
108 inline size_t BufferIndex(size_t n
) const {
109 return (current_index_
+ n
) % kSize
;
113 size_t current_index_
;
115 DISALLOW_COPY_AND_ASSIGN(RingBuffer
);
120 #endif // CC_DEBUG_RING_BUFFER_H_