By default the library uses unsigned int indexes, allowing for a maximum of 65536 items, but you'll rarely need such a huge store. Defining the CIRCULAR_BUFFER_XS macro you can reduce the library indexes to unsigned short with no actual impact on the memory used by the library itself, but allowing you to squeeze out those few extra bytes whenever you perform indexed access, if you do any. Obviously the consequence is having a maximum element capacity of 512 items, still plenty in most cases.
The library itself has an implicit memory consumption of about 0.5Kb: 580b (max) of code and 8b of memory, to my calculations. That does not consider the space used to store the items themselves, obviously.
- Declare and initialize
When declaring your buffer you should specify the data type it must handle and the buffer capacity: those two parameters will influence the memory consumed by the buffer.
#include <CircularBuffer.h>
CircularBuffer<short,100> shorts; // uses 538 bytes
CircularBuffer<int,100> ints; // uses 638 bytes
CircularBuffer<long,100> longs; // uses 838 bytes
CircularBuffer<float,100> floats; // uses 988 bytes
CircularBuffer<double,100> doubles; // uses 988 bytes
CircularBuffer<char,100> chars; // uses 538 bytes
CircularBuffer<void*,100> pointers; // uses 638 bytesIf you are close to using all your memory you can try to squeeze out a few bytes by defining CIRCULAR_BUFFER_XS BEFORE including the library:
#define CIRCULAR_BUFFER_XS
#include <CircularBuffer.h>
CircularBuffer<short,100> buffer;Please note the reduced memory usage will not occur unless you were using the array-like access operator AND you start using unsigned int data type for the index access.
- Store data
Let's start making things clear: the library doesn't support inserting data in the middle of the buffer.
You can add data to the buffer either before the first element via a shift() operation or after the last element via a push() operation.
You can keep adding data beyond the buffer maximum capacity, but you'll lose the least significant information:
- since
shift()adds to the head, adding beyond capacity causes the element at tail to be overwritten and lost - since
push()adds to the tail, adding beyond capacity causes the element at head to be overwritten and lost
Both shift() and push() return true if the addition didn't cause any information loss, false if an overwrite occurred:
CircularBuffer<int,5> buffer;
// all of the following return true
buffer.shift(1); // [1]
buffer.shift(2); // [2,1]
buffer.shift(3); // [3,2,1]
buffer.push(0); // [3,2,1,0]
buffer.push(5); // [3,2,1,0,5]
buffer.shift(2); // [2,3,2,1,0] returns false
buffer.shift(10); // [10,2,3,2,1] returns false
buffer.push(-5); // [2,3,2,1,-5] returns false- Retrieve data
Similarly to data addition, data retrieval can be performed at tail via a pop() operation or from head via an unshift() operation: both cause the element being read to be removed from the buffer.
Non-destructive read operations are also available:
first()returns the element at headlast()return the element at tail- an array-like indexed read operation is also available so you can read any element in the buffer using the
[]operator
In all cases reading data beyond the actual buffer size has an undefined behaviour and is user's responsibility to prevent such boundary violations using the additional operations listed in the next section.
CircularBuffer<char, 50> buffer; // ['a','b','c','d','e','f','g']
buffer.first(); // ['a','b','c','d','e','f','g'] returns 'a'
buffer.last(); // ['a','b','c','d','e','f','g'] returns 'g'
buffer.pop(); // ['a','b','c','d','e','f'] returns 'g'
buffer.pop(); // ['a','b','c','d','e'] returns 'f'
buffer.unshift(); // ['b','c','d','e'] returns 'a'
buffer.unshift(); // ['c','d','e'] returns 'b'
buffer[0]; // ['c','d','e'] returns 'c'
buffer[1]; // ['c','d','e'] returns 'd'
buffer[2]; // ['c','d','e'] returns 'e'
buffer[10]; // ['c','d','e'] returned value is undefined- Additional operations
isEmpty()returnstrueonly if no data is stored in the bufferisFull()returnstrueif no data can be further added to the buffer without causing overwrites/data losssize()returns the number of elements currently stored in the buffer; it should be used in conjunction with the[]operator to avoid boundary violations: the first element index is always0(if buffer is not empty), the last element index is alwayssize() - 1available()returns the number of elements that can be added before saturating the bufferclear()resets the whole buffer to its initial state removing all elements