1 #ifndef VTESTBED_CORE_CIRCULAR_BUFFER_HH 2 #define VTESTBED_CORE_CIRCULAR_BUFFER_HH 8 #include <vtestbed/base/multiple_array_iterator.hh> 24 using pointer = value_type*;
25 using const_pointer =
const value_type*;
28 using reference = value_type&;
29 using const_reference =
const value_type&;
35 pointer _first =
nullptr, _last =
nullptr, _current =
nullptr;
49 std::fill_n(this->data(), this->max_size(), value);
64 _current{rhs._current} {
70 _data{
new T[rhs.max_size()]},
72 _last{_data.get() + rhs.max_size()},
73 _current{_data.get() + (rhs._current - rhs._first)} {
74 std::copy(rhs._first, rhs._last, _first);
91 data()
const noexcept {
92 return this->_data.get();
97 return this->_data.get();
101 max_size()
const noexcept {
102 return this->_last - this->_first;
106 size()
const noexcept {
107 return (this->middle()-this->current()) +
108 (this->current() - this->_first);
113 return this->size() == 0;
117 counter()
const noexcept {
118 return this->_counter;
122 cbegin()
const noexcept {
124 std::make_pair(this->_current,this->middle()),
125 std::make_pair(this->_first,this->_current)
130 begin()
const noexcept {
131 return this->cbegin();
137 std::make_pair(this->_current,this->middle()),
138 std::make_pair(this->_first,this->_current)
143 cend()
const noexcept {
145 std::make_pair(this->_current,this->middle()),
146 std::make_pair(this->_first,this->_current)
151 end()
const noexcept {
158 std::make_pair(this->_current,this->middle()),
159 std::make_pair(this->_first,this->_current)
164 current()
const noexcept {
165 return this->_current;
170 return this->_current;
175 return (this->_counter == this->max_size())
176 ? this->_last : this->_current;
181 return (this->_counter == this->max_size())
182 ? this->_last : this->_current;
187 return *((this->_counter == this->max_size())
188 ? this->_current : this->_first);
191 inline const value_type&
192 front()
const noexcept {
193 return *((this->_counter == this->max_size())
194 ? this->_current : this->_first);
199 return *((this->_current == this->_first)
200 ? (this->_last-1) : (this->_current-1));
203 inline const value_type&
204 back()
const noexcept {
205 return *((this->_current == this->_first)
206 ? (this->_last-1) : (this->_current-1));
209 inline const value_type&
211 return this->_first[i];
215 record(
const T& value) {
216 if (this->_counter < this->max_size()) {
219 if (_current == _last) {
228 if (this->_counter < this->max_size()) {
231 if (_current == _last) {
234 *_current = std::forward<T>(value);
243 auto first = this->_first;
244 auto last = first + std::min(new_size, this->max_size());
245 auto result = new_data.get();
246 offset = this->_current - this->_first;
247 while (first != last) {
248 *result = std::move(*first);
253 this->_data = std::move(new_data);
254 this->_first = this->_data.get();
255 this->_last = this->_first + new_size;
256 this->_current = this->_first + std::min(offset, new_size);
257 this->_counter = std::min(this->_counter, new_size);
263 swap(this->_data, rhs._data);
264 swap(this->_first, rhs._first);
265 swap(this->_last, rhs._last);
266 swap(this->_current, rhs._current);
267 swap(this->_counter, rhs._counter);
273 std::fill_n(this->data(), n, value_type{});
274 this->_first = this->_data.get();
275 this->_last = this->_first + n;
276 this->_current = this->_first;
292 #endif // vim:filetype=cpp
Fixed-size circular buffer. Used as time series storage.