CircularBuffer

Simple circular-ish buffer for storing items of type T that discards elements when the maximum size is reached. Does not use manual memory allocation.

It can use a static array internally to store elements on the stack, which imposes a hard limit on how many items can be added, or a dynamic heap one with a resizable buffer.

Members

Functions

clear
void clear()

Zeroes out the buffer's elements, getting rid of old contents.

dup
auto dup()

Makes a deep(er) duplicate of the container.

empty
auto empty()

Returns whether or not the container is considered empty.

front
auto ref front()

Returns the front element.

opOpAssign
void opOpAssign(T more)

Implements buf ~= someT (appending) by wrapping put.

popFront
void popFront()

Advances the current position to the next item in the buffer.

put
void put(T item)

Append an item to the buffer.

reset
void reset()

Resets the buffer pointers but doesn't clear the contents.

resize
void resize(size_t size)

Resizes the internal buffer to a specified size.

save
auto save()

Implements Range save.

size
auto size()

Returns the size of the internal buffer.

Variables

buf
T[] buf;

Internal buffer dynamic array.

buf
T[originalSize] buf;

Internal buffer static array.

caughtUp
bool caughtUp;

Whether or not head and tail point to the same position in the context of a circular array.

head
size_t head;

Head position in the internal buffer.

initialised
bool initialised;

Whether or not at least one element has been added.

tail
size_t tail;

Tail position in the internal buffer.

Parameters

T

Buffer item type.

dynamic

Whether to use a dynamic array whose size can be grown at runtime, or to use a static array with a fixed size. Trying to add more elements than there is room for will wrap around and discard elements. Defaults to No.dynamic; a static buffer.

originalSize

How many items to allocate space for in the case of a static array.

Examples

CircularBuffer!(int, Yes.dynamic) buf;
buf.resize(3);
buf.put(1);
buf.put(2);
buf.put(3);
but.put(4);
assert(buf.front == 4);
assert(buf.buf == [ 4, 2, 3 ]);
1 import std.conv : text;
2 
3 {
4     CircularBuffer!(int, Yes.dynamic) buf;
5     buf.resize(3);
6 
7     buf.put(1);
8     assert((buf.front == 1), buf.front.text);
9     buf.put(2);
10     assert((buf.front == 2), buf.front.text);
11     buf.put(3);
12     assert((buf.front == 3), buf.front.text);
13     buf ~= 4;
14     assert((buf.front == 4), buf.front.text);
15     assert((buf.buf[] == [ 4, 2, 3 ]), buf.buf.text);
16     buf ~= 5;
17     assert((buf.front == 5), buf.front.text);
18     buf ~= 6;
19     assert((buf.front == 6), buf.front.text);
20     assert((buf.buf[] == [ 4, 5, 6 ]), buf.buf.text);
21     buf.popFront();
22     buf.popFront();
23     buf.popFront();
24     assert(buf.empty);
25 }
26 {
27     CircularBuffer!(int, No.dynamic, 3) buf;
28     //buf.resize(3);
29 
30     buf.put(1);
31     assert((buf.front == 1), buf.front.text);
32     buf.put(2);
33     assert((buf.front == 2), buf.front.text);
34     buf.put(3);
35     assert((buf.front == 3), buf.front.text);
36     buf ~= 4;
37     assert((buf.front == 4), buf.front.text);
38     assert((buf.buf[] == [ 4, 2, 3 ]), buf.buf.text);
39     buf.popFront();
40     buf.popFront();
41     buf.popFront();
42     assert(buf.empty);
43 }
44 {
45     CircularBuffer!(int, No.dynamic, 2) buf;
46     //buf.resize(2);
47 
48     buf.put(1);
49     assert((buf.front == 1), buf.front.text);
50     buf.put(2);
51     assert((buf.front == 2), buf.front.text);
52     buf.put(3);
53     assert((buf.front == 3), buf.front.text);
54     buf ~= 4;
55     assert((buf.front == 4), buf.front.text);
56     assert((buf.buf[] == [ 3, 4 ]), buf.buf.text);
57     buf.popFront();
58     buf.popFront();
59     assert(buf.empty);
60     //buf.popFront();  // AssertError
61 }
62 {
63     CircularBuffer!(int, No.dynamic, 2) buf;
64     //buf.resize(2);
65 
66     buf.put(1);
67     assert((buf.front == 1), buf.front.text);
68     buf.put(2);
69     assert((buf.front == 2), buf.front.text);
70     buf.put(3);
71     assert((buf.front == 3), buf.front.text);
72     buf ~= 4;
73     assert((buf.front == 4), buf.front.text);
74     assert((buf.buf[] == [ 3, 4 ]), buf.buf.text);
75     auto savedBuf = buf.save();
76     buf.popFront();
77     buf.popFront();
78     assert(buf.empty);
79     assert((savedBuf.front == 4), savedBuf.front.text);
80     savedBuf.popFront();
81     auto savedBuf2 = savedBuf.save();
82     savedBuf.popFront();
83     assert(savedBuf.empty);
84     assert((savedBuf2.front == 3), savedBuf2.front.text);
85     savedBuf2.popFront();
86     assert(savedBuf2.empty);
87 }