Skip to content

Instantly share code, notes, and snippets.

@GaryLee
Created March 8, 2025 15:06
Show Gist options
  • Save GaryLee/af178302f9a62e99f1581366d68baa0b to your computer and use it in GitHub Desktop.
Save GaryLee/af178302f9a62e99f1581366d68baa0b to your computer and use it in GitHub Desktop.
The circular buffer class in c++.
/**
* @file circular_buffer.h The circular buffer.
*/
#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H
/**
* @brief The circular buffer class.
*/
template <typename T> class CircularBuffer {
private:
T* buffer; ///< The buffer.
int bufferSize; ///< The size of buffer.
int bufferReadPos; ///< The read position of buffer.
int bufferWritePos; ///< The write position of buffer.
public:
/**
* @brief Construct a new Circular Buffer object
*
* @param size The size of buffer.
*/
explicit CircularBuffer(int size)
: bufferSize(size)
, bufferReadPos(0)
, bufferWritePos(0)
{
assert(size > 0); // The buffer size must be greater than 0.
buffer = new T[bufferSize];
}
/**
* @brief Destroy the Circular Buffer object
*/
~CircularBuffer()
{
delete[] buffer;
}
/**
* @brief Check if the buffer is full.
*
* @return true If the buffer is full.
* @return false If the buffer is not full.
*/
bool isFull(void) const
{
return (bufferWritePos + 1) % bufferSize == bufferReadPos;
}
/**
* @brief Get the data count.
*
* @return int The available data in buffer.
*/
int count(void) const
{
// return (bufferReadPos - bufferWritePos) % bufferSize;
return (bufferWritePos - bufferReadPos + bufferSize) % bufferSize;
}
int available(void) const
{
return bufferSize - count();
}
/**
* @brief Push data into the buffer.
*
* @param len The length of data.
* @param data The data array.
* @return int The number of data pushed into the buffer. Return 0 if the buffer is full.
*/
int push(int len, T* data)
{
int dataCount = count();
// Buffer full! Cannot push data.
if (isFull()) {
return 0;
}
int dst;
int src;
for (dst = bufferWritePos + 1, src = 0; src < dataCount && src < len; dst = (dst + 1) % bufferSize, src++) {
buffer[dst] = data[src];
}
bufferWritePos = dst;
return src;
}
/**
* @brief Pop data from the buffer.
*
* @param len The length of data.
* @param data The data array.
* @param drop The number of data to drop. drop must be smaller or equal to len.
* @return int The number of data popped from the buffer.
*/
int pop(int len, T* data, int drop = 0)
{
int dataCount = count();
assert(drop >= 0 && drop <= len);
if (dataCount == 0) {
return 0;
}
int dst;
int src;
for (dst = 0, src = bufferReadPos; dst < dataCount && dst < len; src = (src + 1) % bufferSize, dst++) {
data[dst] = buffer[src];
}
bufferReadPos = (drop <= 0) ? src : ((src + drop) % bufferSize);
return dst;
}
};
#endif // CIRCULAR_BUFFER_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment