// 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 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 = 0; volatile unsigned out = 0; public: /*! \brief Constructor that initialized an empty buffer. */ constexpr BBuffer() {} /*! \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; } };