12 #ifndef hifi_RingBufferHistory_h
13 #define hifi_RingBufferHistory_h
21 class RingBufferHistory {
25 RingBufferHistory(
int capacity = 10)
26 : _size(capacity + 1),
28 _newestEntryAtIndex(0),
38 void setCapacity(
int capacity) {
41 _newestEntryAtIndex = 0;
43 _buffer.resize(_size);
46 void insert(
const T& entry) {
48 _newestEntryAtIndex = (_newestEntryAtIndex + 1) % _size;
51 _buffer[_newestEntryAtIndex] = entry;
52 if (_numEntries < _capacity) {
58 void insert(T&& entry) {
60 _newestEntryAtIndex = (_newestEntryAtIndex + 1) % _size;
63 _buffer[_newestEntryAtIndex] = std::move(entry);
64 if (_numEntries < _capacity) {
71 const T* get(
int entryAge)
const {
72 if (!(entryAge >= 0 && entryAge < _numEntries)) {
75 int entryAt = _newestEntryAtIndex - entryAge;
79 return &_buffer[entryAt];
82 T* get(
int entryAge) {
83 return const_cast<T*
>((
static_cast<const RingBufferHistory*
>(
this))->get(entryAge));
86 const T* getNewestEntry()
const {
87 return _numEntries == 0 ? NULL : &_buffer[_newestEntryAtIndex];
91 return _numEntries == 0 ? NULL : &_buffer[_newestEntryAtIndex];
94 int getCapacity()
const {
return _capacity; }
95 int getNumEntries()
const {
return _numEntries; }
96 bool isFilled()
const {
return _numEntries == _capacity; }
101 int _newestEntryAtIndex;
103 std::vector<T> _buffer;
106 class Iterator :
public std::iterator < std::random_access_iterator_tag, T > {
108 Iterator(T* bufferFirst, T* bufferLast, T* newestAt, T* at)
109 : _bufferFirst(bufferFirst),
110 _bufferLast(bufferLast),
111 _bufferLength(bufferLast - bufferFirst + 1),
115 bool operator==(
const Iterator& rhs) {
return _at == rhs._at; }
116 bool operator!=(
const Iterator& rhs) {
return _at != rhs._at; }
117 T& operator*() {
return *_at; }
118 T* operator->() {
return _at; }
120 Iterator& operator++() {
121 _at = (_at == _bufferFirst) ? _bufferLast : _at - 1;
125 Iterator operator++(
int) {
131 Iterator& operator--() {
132 _at = (_at == _bufferLast) ? _bufferFirst : _at + 1;
136 Iterator operator--(
int) {
142 Iterator operator+(
int add) {
144 sum._at = atShiftedBy(add);
148 Iterator operator-(
int sub) {
150 sum._at = atShiftedBy(-sub);
154 Iterator& operator+=(
int add) {
155 _at = atShiftedBy(add);
159 Iterator& operator-=(
int sub) {
160 _at = atShiftedBy(-sub);
164 T& operator[](
int i) {
165 return *(atShiftedBy(i));
168 bool operator<(
const Iterator& rhs) {
169 return age() < rhs.age();
172 bool operator>(
const Iterator& rhs) {
173 return age() > rhs.age();
176 bool operator<=(
const Iterator& rhs) {
177 return age() <= rhs.age();
180 bool operator>=(
const Iterator& rhs) {
181 return age() >= rhs.age();
184 int operator-(
const Iterator& rhs) {
185 return age() - rhs.age();
189 T* atShiftedBy(
int i) {
190 i = (_at - _bufferFirst - i) % _bufferLength;
194 return _bufferFirst + i;
198 int age = _newestAt - _at;
200 age += _bufferLength;
212 Iterator begin() {
return Iterator(&_buffer.front(), &_buffer.back(), &_buffer[_newestEntryAtIndex], &_buffer[_newestEntryAtIndex]); }
215 int endAtIndex = _newestEntryAtIndex - _numEntries;
216 if (endAtIndex < 0) {
219 return Iterator(&_buffer.front(), &_buffer.back(), &_buffer[_newestEntryAtIndex], &_buffer[endAtIndex]);