#include enum class CircularBufferErrorCode { SUCCESS, BUFFER_FULL, BUFFER_EMPTY, MEMORY_ERROR }; template class CircularBuffer { public: CircularBuffer(size_t _capacity) : _capacity(_capacity) { _buffer = static_cast(malloc(_capacity * sizeof(T))); if (_buffer == nullptr) { // Handle memory allocation error _errorCode = CircularBufferErrorCode::MEMORY_ERROR; } else { _bufferEnd = _buffer + _capacity; _count = 0; _head = _buffer; _tail = _buffer; _errorCode = CircularBufferErrorCode::SUCCESS; } } ~CircularBuffer() { free(_buffer); } CircularBufferErrorCode pushBack(const T& item) { if (isFull()) { return CircularBufferErrorCode::BUFFER_FULL; } *_head = item; _head++; if (_head == _bufferEnd) { _head = _buffer; } _count++; return CircularBufferErrorCode::SUCCESS; } CircularBufferErrorCode popFront(T& item) { if (isEmpty()) { return CircularBufferErrorCode::BUFFER_EMPTY; } item = *_tail; _tail++; if (_tail == _bufferEnd) { _tail = _buffer; } _count--; return CircularBufferErrorCode::SUCCESS; } bool isFull() { return _count == _capacity; } bool isEmpty() { return _count == 0; } private: T *_buffer; // Data _buffer T *_bufferEnd; // End of data buffer size_t _capacity; // Maximum number of items in the buffer size_t _count; // Number of items in the buffer T *_head; // Pointer to head T *_tail; // Pointer to tail CircularBufferErrorCode _errorCode; // Error code };