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;
108 using iterator_category = std::random_access_iterator_tag;
109 using value_type = T;
110 using difference_type = ptrdiff_t;
112 using reference = T&;
114 Iterator(T* bufferFirst, T* bufferLast, T* newestAt, T* at)
115 : _bufferFirst(bufferFirst),
116 _bufferLast(bufferLast),
117 _bufferLength(bufferLast - bufferFirst + 1),
121 bool operator==(
const Iterator& rhs) {
return _at == rhs._at; }
122 bool operator!=(
const Iterator& rhs) {
return _at != rhs._at; }
123 T& operator*() {
return *_at; }
124 T* operator->() {
return _at; }
126 Iterator& operator++() {
127 _at = (_at == _bufferFirst) ? _bufferLast : _at - 1;
131 Iterator operator++(
int) {
137 Iterator& operator--() {
138 _at = (_at == _bufferLast) ? _bufferFirst : _at + 1;
142 Iterator operator--(
int) {
148 Iterator operator+(
int add) {
150 sum._at = atShiftedBy(add);
154 Iterator operator-(
int sub) {
156 sum._at = atShiftedBy(-sub);
160 Iterator& operator+=(
int add) {
161 _at = atShiftedBy(add);
165 Iterator& operator-=(
int sub) {
166 _at = atShiftedBy(-sub);
170 T& operator[](
int i) {
171 return *(atShiftedBy(i));
174 bool operator<(
const Iterator& rhs) {
175 return age() < rhs.age();
178 bool operator>(
const Iterator& rhs) {
179 return age() > rhs.age();
182 bool operator<=(
const Iterator& rhs) {
183 return age() <= rhs.age();
186 bool operator>=(
const Iterator& rhs) {
187 return age() >= rhs.age();
190 int operator-(
const Iterator& rhs) {
191 return age() - rhs.age();
195 T* atShiftedBy(
int i) {
196 i = (_at - _bufferFirst - i) % _bufferLength;
200 return _bufferFirst + i;
204 int age = _newestAt - _at;
206 age += _bufferLength;
218 Iterator begin() {
return Iterator(&_buffer.front(), &_buffer.back(), &_buffer[_newestEntryAtIndex], &_buffer[_newestEntryAtIndex]); }
221 int endAtIndex = _newestEntryAtIndex - _numEntries;
222 if (endAtIndex < 0) {
225 return Iterator(&_buffer.front(), &_buffer.back(), &_buffer[_newestEntryAtIndex], &_buffer[endAtIndex]);