[wpiutil] Improve wpi::circular_buffer iterators (#3410)

The implementation of wpi::circular_buffer has been effectively replaced
with a dynamically sized copy of wpi::static_circular_buffer with a
resize() member function.
This commit is contained in:
Tyler Veness
2021-06-05 21:08:12 -07:00
committed by GitHub
parent 8aecda03ed
commit 82856cf816
8 changed files with 393 additions and 297 deletions

View File

@@ -4,134 +4,10 @@
#pragma once
#include <algorithm>
#include "wpi/circular_buffer.h"
namespace wpi {
template <class T>
circular_buffer<T>::circular_buffer(size_t size) : m_data(size, T{}) {}
/**
* Returns number of elements in buffer
*/
template <class T>
typename circular_buffer<T>::size_type circular_buffer<T>::size() const {
return m_length;
}
/**
* Returns value at front of buffer
*/
template <class T>
T& circular_buffer<T>::front() {
return (*this)[0];
}
/**
* Returns value at front of buffer
*/
template <class T>
const T& circular_buffer<T>::front() const {
return (*this)[0];
}
/**
* Returns value at back of buffer
*/
template <class T>
T& circular_buffer<T>::back() {
// If there are no elements in the buffer, do nothing
if (m_length == 0) {
return zero_val;
}
return m_data[(m_front + m_length - 1) % m_data.size()];
}
/**
* Returns value at back of buffer
*/
template <class T>
const T& circular_buffer<T>::back() const {
// If there are no elements in the buffer, do nothing
if (m_length == 0) {
return zero_val;
}
return m_data[(m_front + m_length - 1) % m_data.size()];
}
/**
* Push new value onto front of the buffer. The value at the back is overwritten
* if the buffer is full.
*/
template <class T>
void circular_buffer<T>::push_front(T value) {
if (m_data.size() == 0) {
return;
}
m_front = ModuloDec(m_front);
m_data[m_front] = value;
if (m_length < m_data.size()) {
m_length++;
}
}
/**
* Push new value onto back of the buffer. The value at the front is overwritten
* if the buffer is full.
*/
template <class T>
void circular_buffer<T>::push_back(T value) {
if (m_data.size() == 0) {
return;
}
m_data[(m_front + m_length) % m_data.size()] = value;
if (m_length < m_data.size()) {
m_length++;
} else {
// Increment front if buffer is full to maintain size
m_front = ModuloInc(m_front);
}
}
/**
* Pop value at front of buffer.
*/
template <class T>
T circular_buffer<T>::pop_front() {
// If there are no elements in the buffer, do nothing
if (m_length == 0) {
return T{0};
}
T& temp = m_data[m_front];
m_front = ModuloInc(m_front);
m_length--;
return temp;
}
/**
* Pop value at back of buffer.
*/
template <class T>
T circular_buffer<T>::pop_back() {
// If there are no elements in the buffer, do nothing
if (m_length == 0) {
return T{0};
}
m_length--;
return m_data[(m_front + m_length) % m_data.size()];
}
/**
* Resizes internal buffer to given size.
*/
@@ -185,54 +61,4 @@ void circular_buffer<T>::resize(size_t size) {
}
}
/**
* Sets internal buffer contents to zero.
*/
template <class T>
void circular_buffer<T>::reset() {
std::fill(m_data.begin(), m_data.end(), T{0});
m_front = 0;
m_length = 0;
}
/**
* @return Element at index starting from front of buffer.
*/
template <class T>
T& circular_buffer<T>::operator[](size_t index) {
return m_data[(m_front + index) % m_data.size()];
}
/**
* @return Element at index starting from front of buffer.
*/
template <class T>
const T& circular_buffer<T>::operator[](size_t index) const {
return m_data[(m_front + index) % m_data.size()];
}
/**
* Increment an index modulo the length of the buffer.
*
* @return The result of the modulo operation.
*/
template <class T>
size_t circular_buffer<T>::ModuloInc(size_t index) {
return (index + 1) % m_data.size();
}
/**
* Decrement an index modulo the length of the buffer.
*
* @return The result of the modulo operation.
*/
template <class T>
size_t circular_buffer<T>::ModuloDec(size_t index) {
if (index == 0) {
return m_data.size() - 1;
} else {
return index - 1;
}
}
} // namespace wpi