example1_implementation.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#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;
}
Back to circular_buffer