#include <iostream>
#include <vector>
#include <stdexcept>
template<typename T>
class CircularBuffer {
private:
std::vector<T> buffer;
size_t head = 0; // Points to the first element
size_t tail = 0; // Points to the next free position
size_t max_size;
bool full = false;
public:
CircularBuffer(size_t size) : buffer(size), max_size(size) {}
void push(T item) {
if (full) {
head = (head + 1) % max_size; // Overwrite oldest element
}
buffer[tail] = item;
tail = (tail + 1) % max_size;
full = head == tail;
}
T pop() {
if (empty()) {
throw std::runtime_error("Buffer is empty");
}
T item = buffer[head];
head = (head + 1) % max_size;
full = false;
return item;
}
T& front() {
if (empty()) {
throw std::runtime_error("Buffer is empty");
}
return buffer[head];
}
void reset() {
head = tail = 0;
full = false;
}
bool empty() const {
return (!full && (head == tail));
}
bool full_buffer() const {
return full;
}
size_t size() const {
if (full) return max_size;
if (tail >= head) return tail - head;
return max_size + tail - head;
}
size_t capacity() const {
return max_size;
}
};
int main() {
CircularBuffer<int> cb(5);
// Fill the buffer
for (int i = 1; i <= 5; ++i) {
cb.push(i);
std::cout << "Pushed: " << i << ", Size: " << cb.size() << std::endl;
}
std::cout << "Buffer full: " << (cb.full_buffer() ? "Yes" : "No") << std::endl;
// Overfill the buffer
cb.push(6);
std::cout << "Pushed: 6, Size: " << cb.size() << std::endl;
// Pop and print elements
while (!cb.empty()) {
std::cout << "Popped: " << cb.pop() << ", Size: " << cb.size() << std::endl;
}
// Try to pop from empty buffer
try {
cb.pop();
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
return 0;
}