/* {{copyright}} */ /* {{version}} */ /* {{license}} */ #pragma once #include #include #include namespace sdi_toolBox::generic { //-------------------------------------------------------------- template class CircularBuffer final { public: CircularBuffer() = default; // Constructor ~CircularBuffer() = default; // Destructor CircularBuffer(const CircularBuffer &other) = delete; // Copy constructor CircularBuffer(CircularBuffer &&other) noexcept = delete; // Move constructor CircularBuffer &operator=(const CircularBuffer &other) = delete; // Copy assignment CircularBuffer &operator=(CircularBuffer &&other) noexcept = delete; // Move assignment bool push(const T &item); // Add an element to the buffer std::optional pop(); // Retrieve an element from the buffer bool isEmpty() const; // Check if the buffer is empty bool isFull() const; // Check if the buffer is full size_t size() const; // Get the current number of elements protected: std::array m_buffer; volatile size_t m_head = 0; // Index for the next write (push) volatile size_t m_tail = 0; // Index for the next read (pop) volatile size_t m_size = 0; // Current number of elements stored }; //-------------------------------------------------------------- //-------------------------------------------------------------- /* Add an element to the buffer */ template inline bool CircularBuffer::push(const T &item) { if (isFull()) return false; // Buffer is full // Write the item at the current head position m_buffer[m_head] = item; // Move head pointer, wrapping around using modulo m_head = (m_head + 1) % BUFFER_SIZE; // Increase the current size of the data in the buffer m_size = m_size + 1; return true; } //-------------------------------------------------------------- /* Retrieve an element from the buffer */ template inline std::optional CircularBuffer::pop() { if (isEmpty()) return {}; // Buffer is empty, cannot pop // Read (copy) the item at the current tail position T item = m_buffer[m_tail]; // Move tail pointer, wrapping around using modulo m_tail = (m_tail + 1) % BUFFER_SIZE; // Decrease the current size of the data in the buffer m_size = m_size - 1; return item; } //-------------------------------------------------------------- /* Check if the buffer is empty */ template inline bool CircularBuffer::isEmpty() const { return m_size == 0; } //-------------------------------------------------------------- /* Check if the buffer is full */ template inline bool CircularBuffer::isFull() const { return m_size == BUFFER_SIZE; } //-------------------------------------------------------------- /* Get the current number of elements */ template inline size_t CircularBuffer::size() const { return m_size; } //-------------------------------------------------------------- } // namespace sdi_toolBox::generic