-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path11_mini_project_ring_buffer.cpp
More file actions
79 lines (67 loc) · 1.95 KB
/
Copy path11_mini_project_ring_buffer.cpp
File metadata and controls
79 lines (67 loc) · 1.95 KB
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
#include <array>
#include <cstddef>
#include <iostream>
#include <optional>
template <class T, std::size_t N>
class RingBuffer {
static_assert(N > 0, "N must be > 0");
public:
bool push(const T& value) {
if (full()) return false;
data_[tail_] = value;
tail_ = (tail_ + 1) % N;
++size_;
return true;
}
bool push(T&& value) {
if (full()) return false;
data_[tail_] = std::move(value);
tail_ = (tail_ + 1) % N;
++size_;
return true;
}
std::optional<T> pop() {
if (empty()) return std::nullopt;
T value = std::move(data_[head_]);
head_ = (head_ + 1) % N;
--size_;
return value;
}
[[nodiscard]] std::size_t size() const { return size_; }
[[nodiscard]] bool empty() const { return size_ == 0; }
[[nodiscard]] bool full() const { return size_ == N; }
private:
std::array<T, N> data_{};
std::size_t head_ = 0; // position of the next pop
std::size_t tail_ = 0; // position of the next push
std::size_t size_ = 0; // number of valid elements
};
int main() {
RingBuffer<int, 5> rb;
std::cout << "push 1..5:\n";
for (int i = 1; i <= 5; ++i) {
std::cout << " push(" << i << ") -> " << (rb.push(i) ? "ok" : "full") << "\n";
}
std::cout << "size=" << rb.size() << ", full=" << (rb.full() ? "true" : "false") << "\n";
std::cout << "\npop 3 times:\n";
for (int i = 0; i < 3; ++i) {
auto v = rb.pop();
if (v) {
std::cout << " pop() -> " << *v << "\n";
} else {
std::cout << " pop() -> empty\n";
}
}
std::cout << "size=" << rb.size() << "\n";
std::cout << "\npush 6,7,8 (tests wrap-around):\n";
for (int i = 6; i <= 8; ++i) {
std::cout << " push(" << i << ") -> " << (rb.push(i) ? "ok" : "full") << "\n";
}
std::cout << "size=" << rb.size() << "\n";
std::cout << "\npop until empty:\n";
while (!rb.empty()) {
std::cout << " " << *rb.pop() << "\n";
}
std::cout << "empty=" << (rb.empty() ? "true" : "false") << "\n";
return 0;
}