You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.6 KiB
C++

// vim: set noet ts=4 sw=4:
/*! \file
* \brief Contains a \ref BBuffer "bounded buffer"
*/
#pragma once
#include "../types.h"
/*! \brief The class BBuffer implements a bounded buffer, that is a circular
* buffer with a fixed capacity.
*
* \tparam T the type of data to be stored
* \tparam CAP the buffers capacity (must be greater than 1)
*/
template <typename T, unsigned CAP>
class BBuffer {
static_assert(CAP > 1, "BBuffer of size 1 is unsupported.");
// Prevent copies and assignments
BBuffer(const BBuffer&) = delete;
BBuffer& operator=(const BBuffer&) = delete;
private:
T data[CAP];
volatile unsigned in;
volatile unsigned out;
public:
/*! \brief Constructor that initialized an empty buffer.
*/
BBuffer() : in(0), out(0) {}
/*! \brief Add an element to the buffer.
* \param val The element to be added.
* \return `false` if the buffer is full and no element can be added; `true`
* otherwise.
*/
bool produce(T val) {
unsigned nextin = (in + 1) % CAP;
if (nextin != out) {
data[in] = val;
in = nextin;
return true;
}
return false;
}
/*! \brief Remove an element from the buffer.
* \param val Output parameter that receives the next element. If there is
* (currently) no next element, `val` will not be modified.
* \return `false` if the buffer was empty; `true` if the buffer was
* not empty and an element was written to val.
*/
bool consume(T& val) {
if (in != out) {
val = data[out];
out = (out + 1) % CAP;
return true;
}
return false;
}
};