Skip to content

Instantly share code, notes, and snippets.

@onlined
Created November 3, 2018 01:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onlined/e164a0bb29956f9778967d5669aa304a to your computer and use it in GitHub Desktop.
Save onlined/e164a0bb29956f9778967d5669aa304a to your computer and use it in GitHub Desktop.
A simple circular buffer implementation
#include <exception>
#include <algorithm>
#include <utility>
#include <cstdlib>
template <typename T>
class CircularBuffer {
private:
const size_t capacity;
size_t size;
size_t start;
T *data;
public:
class FullCapacity: public std::exception {
public:
const char* what() const noexcept override {
return "Buffer capacity is full";
}
};
class Empty: public std::exception {
public:
const char* what() const noexcept override {
return "No element in buffer";
}
};
CircularBuffer(size_t capacity) :
capacity(capacity),
size(0),
start(0),
data(new T[capacity]) {}
CircularBuffer(CircularBuffer& cb) :
capacity(cb.capacity),
size(cb.size),
start(cb.start),
data(new T[cb.capacity])
{
std::copy(cb.data, cb.data + cb.capacity, data);
}
CircularBuffer(CircularBuffer&& cb) :
capacity(cb.capacity),
size(cb.size),
start(cb.start),
data(nullptr)
{
std::swap(data, cb.data);
}
CircularBuffer& operator=(CircularBuffer& cb) {
if (this == &cb)
return *this;
capacity = cb.capacity;
size = cb.size;
start = cb.start;
delete[] data;
data = new T[cb.capacity];
std::copy(cb.data, cb.data + cb.capacity, data);
return *this;
}
CircularBuffer& operator=(CircularBuffer&& cb) {
if (this == &cb)
return *this;
capacity = cb.capacity;
size = cb.size;
start = cb.start;
std::swap(data, cb.data);
return *this;
}
~CircularBuffer() { delete[] data; }
void push(T& item) {
if (size == capacity)
throw FullCapacity();
data[(start + size) % capacity] = item;
size++;
}
void push(T&& item) {
if (size == capacity)
throw FullCapacity();
data[(start + size) % capacity] = item;
size++;
}
T pop() {
if (!size)
throw Empty();
T res{std::move(data[start])};
start = (start + 1) % capacity;
size--;
return res;
}
T& front() { return data[start]; }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment