libzed 1.9.9
A general-purpose library for quick and simple data manipulation.
 
Loading...
Searching...
No Matches
circularBuffer.hpp
1#pragma once
2
3#include "arrayLike.hpp"
4#include "sizable.hpp"
5#include <type_traits>
6
7namespace z {
8namespace core {
14template <typename TYPE, unsigned int LEN>
16 const TYPE *ptr;
17 int offset;
18
19public:
25 circularIterator(const TYPE *buffer, int index) noexcept : ptr(buffer), offset(index) {}
26
32 ++offset;
33 return *this;
34 }
35
41 bool operator!=(const circularIterator &other) const noexcept {
42 return offset != other.offset;
43 }
44
50 return ptr[offset % LEN];
51 }
52};
53
59template <typename TYPE, unsigned int LEN>
60class circularBuffer : public sizable, public arrayLike<const TYPE &, circularIterator<TYPE, LEN>> {
61 TYPE data[LEN]; // The data to store
62 int counter = 0; // The current index. This will always be between 0 and LEN.
63 int total = 0; // The total number of items in the buffer. This will never exceed LEN.
64
65 static_assert(LEN > 0, "Buffer must have more than zero elements.");
66
67public:
70
79 template <typename... ARGS>
80 circularBuffer(const ARGS &...args) noexcept {
81 populate(args...);
82 }
83
89 for (int i = 0; i < LEN; ++i) {
90 data[i] = default_value;
91 }
92 }
93
94 size_t size() const noexcept override {
95 return sizeof(TYPE) * LEN;
96 }
97
98 int length() const noexcept override {
99 return LEN;
100 }
101
109 const TYPE &at(const int index) const noexcept override {
110 return data[index % LEN];
111 }
112
113 // Get a reference to an element from the buffer. This is used when we ARE modifying it.
114 // The compiler knows the difference and will use this function only when needed.
115
125 TYPE &at(const int index) noexcept {
126 return data[index % LEN];
127 }
128
133 void append(const TYPE value) noexcept {
134 data[counter] = value;
135 counter = (counter + 1) % LEN;
136 if (total < LEN) {
137 ++total;
138 }
139 }
140
148 return counter;
149 }
150
156 return data[counter];
157 }
158
167 return total;
168 }
169
171 void prev() noexcept {
172 counter = (counter + LEN - 1) % LEN;
173 }
174
176 void next() noexcept {
177 counter = (counter + 1) % LEN;
178 }
179
181 return circularIterator<TYPE, LEN>(data, counter + LEN + LEN - total);
182 }
183
185 return circularIterator<TYPE, LEN>(data, counter + LEN + LEN);
186 }
187
193 template <typename... ARGS>
194 void populate(const TYPE &first, const ARGS &...args) noexcept {
195 append(first);
196 populate(args...);
197 }
198
206 void populate(const TYPE &arg) noexcept {
207 append(arg);
208 }
209
216 static_assert(std::is_arithmetic<TYPE>::value, "circularBuffer::minimum() is only defined for arithmetic types.");
217
218 TYPE value = data[0];
219 for (int i = 1; i < LEN; ++i) {
220 if (data[i] < value) {
221 value = data[i];
222 }
223 }
224 return value;
225 }
226
233 static_assert(std::is_arithmetic<TYPE>::value, "circularBuffer::maximum() is only defined for arithmetic types.");
234
235 TYPE value = data[0];
236 for (int i = 1; i < LEN; ++i) {
237 if (data[i] > value) {
238 value = data[i];
239 }
240 }
241 return value;
242 }
243};
244} // namespace core
245} // namespace z
An interface for all objects that can be both iterated over and directly indexed.
Definition arrayLike.hpp:13
A wrapper for std::vector.
Definition array.hpp:72
A circular buffer of fixed size. Appending can be done indefinitely, as the index will just loop back...
Definition circularBuffer.hpp:60
TYPE minimum() const noexcept
Get the minimum value contained in this buffer.
Definition circularBuffer.hpp:215
TYPE & current() noexcept
Get a reference to the topmost item in the buffer.
Definition circularBuffer.hpp:155
circularIterator< TYPE, LEN > begin() const noexcept override
Get an iterator for the first element in this object.
Definition circularBuffer.hpp:180
void populate(const TYPE &first, const ARGS &...args) noexcept
Append an arbitrary number of elements to the buffer.
Definition circularBuffer.hpp:194
const TYPE & at(const int index) const noexcept override
Get an element from the buffer.
Definition circularBuffer.hpp:109
size_t size() const noexcept override
Get the size of the object in memory.
Definition circularBuffer.hpp:94
int index() const noexcept
Get the index of the current top of the buffer.
Definition circularBuffer.hpp:147
int count() const noexcept
Get the total number of items in the buffer.
Definition circularBuffer.hpp:166
TYPE maximum() const noexcept
Get the maximum value contained in this buffer.
Definition circularBuffer.hpp:232
void next() noexcept
Move current "top" to the next spot in the buffer.
Definition circularBuffer.hpp:176
void populate(const TYPE &arg) noexcept
Append an element to the buffer.
Definition circularBuffer.hpp:206
void prev() noexcept
Move current "top" to the previous spot in the buffer.
Definition circularBuffer.hpp:171
void append(const TYPE value) noexcept
Add a value to the buffer, and increment the current index.
Definition circularBuffer.hpp:133
circularIterator< TYPE, LEN > end() const noexcept override
Get an iterator after the last element of this object.
Definition circularBuffer.hpp:184
circularBuffer(TYPE default_value) noexcept
Initialize all elements with a single value.
Definition circularBuffer.hpp:88
int length() const noexcept override
Get the length of the array.
Definition circularBuffer.hpp:98
circularBuffer() noexcept
Default constructor.
Definition circularBuffer.hpp:69
circularBuffer(const ARGS &...args) noexcept
Initialize the buffer with the contents of an array.
Definition circularBuffer.hpp:80
TYPE & at(const int index) noexcept
Get a modifiable element from the buffer.
Definition circularBuffer.hpp:125
A custom iterator for circular buffers.
Definition circularBuffer.hpp:15
circularIterator operator++() noexcept
Move to the next spot in the buffer.
Definition circularBuffer.hpp:31
circularIterator(const TYPE *buffer, int index) noexcept
Constructor.
Definition circularBuffer.hpp:25
bool operator!=(const circularIterator &other) const noexcept
Inequality operator.
Definition circularBuffer.hpp:41
const TYPE & operator*() const noexcept
Dereference operator.
Definition circularBuffer.hpp:49
An interface for getting an object's size.
Definition sizable.hpp:13