Skip to content

Instantly share code, notes, and snippets.

@HookedBehemoth
Created October 11, 2020 02:49
Show Gist options
  • Save HookedBehemoth/ca746bbadb684fd47e730803514e3bec to your computer and use it in GitHub Desktop.
Save HookedBehemoth/ca746bbadb684fd47e730803514e3bec to your computer and use it in GitHub Desktop.
#pragma once
#include <array>
#include <cstdint>
enum class order {
Ascending, Descending
};
template <typename DataType, size_t MaxSize, order Order = order::Descending>
class CircularBuffer {
public:
using Type = CircularBuffer<DataType, MaxSize, Order>;
using Impl = std::array<DataType, MaxSize>;
private:
Impl impl;
bool full = false;
size_t off = 0;
class Iterator {
private:
const Type *parent;
size_t size, i;
public:
Iterator() = default;
Iterator(const Type *_impl, size_t _size)
: parent(_impl)
, size(_size)
, i() { }
const DataType &operator*() const {
return parent->operator[](i);
}
bool operator!=(const Iterator &) const {
return i < size;
}
void operator++() {
i++;
}
};
public:
void Push(const DataType &data) {
impl[off++] = data;
if (off >= MaxSize) {
full = true;
off = 0;
}
}
const DataType &operator[](const size_t idx) const {
if constexpr (Order == order::Descending) {
if (full) {
return impl[((off + MaxSize) - 1 - idx) % MaxSize];
} else {
return impl[off - 1 - idx];
}
} else {
if (full) {
return impl[(off + idx) % MaxSize];
} else {
return impl[idx];
}
}
}
size_t size() const {
return full ? MaxSize : off;
}
auto begin() const {
return Iterator(this, size());
}
auto end() const {
return Iterator();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment