This is the generic version of the Circular Buffer I have posted before. You can find the non-generic version of the circular buffer here
The header file:
CircularBuffer.hpp
The header file:
CircularBuffer.hpp
#ifndef MCP_CIRCULAR_BUFFER_GENERIC_H_
#define MCP_CIRCULAR_BUFFER_GENERIC_H_
template<class T>
class CircularBuffer {
public:
// Creates a buffer with 'slots' slots.
explicit CircularBuffer(int slots);
// Destructor.
~CircularBuffer();
// Writes 'value' to the next available slot. It may overwrite
// values that were not yet read out of the buffer.
void write(const T & value);
// Returns the next value available for reading, in the order they
// were written, and marks slot as read.
// If the buffer is empty returns -1.
void read(T* val);
// Removes all the elements from the buffer.
void clear();
// returns true if the Circular buffer is empty, false otherwise
bool isEmpty();
private:
//array of integers
T* data_;
// the size of the buffer
int num_of_slots_;
//index to read the next integer from buffer
int read_index_;
//index to write a new integer to buffer
int write_index_;
// Non-copyable, non-assignable.
CircularBuffer(CircularBuffer&);
CircularBuffer& operator=(const CircularBuffer&);
};
template <class T>
CircularBuffer<T>::CircularBuffer(int slots) {
if (slots <= 0) {
num_of_slots_ = 10; /*pre-assigned value */
} else {
num_of_slots_ = slots;
}
clear();
}
template <class T>
CircularBuffer<T>::~CircularBuffer() {
delete[] data_;
}
template <class T>
void CircularBuffer<T>::write(const T & value) {
data_[write_index_] = value;
if (read_index_ == -1) {
//if buffer is empty, set the read index to the
//current write index. because that will be the first
//slot to be read later.
read_index_ = write_index_;
}
write_index_ = (write_index_ + 1) % num_of_slots_;
}
template <class T>
void CircularBuffer<T>::read(T* val) {
if (read_index_ != -1) { // if buffer is not empty
*val = data_[read_index_];
read_index_ = (read_index_ + 1) % num_of_slots_;
if (read_index_ == write_index_) {
/*all available data is read, now buffer is empty*/
read_index_ = -1;
}
}
}
template <class T>
void CircularBuffer<T>::clear() {
read_index_ = -1; /* buffer empty */
write_index_ = 0; /* first time writing to that buffer*/
delete[] data_;
data_ = new T[num_of_slots_]; /* allocate space for buffer */
}
template <class T>
bool CircularBuffer<T>::isEmpty() {
return read_index_ == -1;
}
#endif // MCP_CIRCULAR_BUFFER_GENERIC_H_
Sample main file main.cpp
#include <iostream>
#include "include/CircularBuffer.hpp"
using namespace std;
int main()
{
CircularBuffer<unsigned int> cb(5);
unsigned int val;
for (unsigned int i=1;i<=15;i++)
cb.write(i);
while(!cb.isEmpty())
{
cb.read(&val);
cout << val << endl;
}
return 0;
}