-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeneric_circular_buffer.cpp
More file actions
97 lines (81 loc) · 2.88 KB
/
generic_circular_buffer.cpp
File metadata and controls
97 lines (81 loc) · 2.88 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <vector>
#include <iostream>
#include <optional>
#include <iomanip>
/**
definition: generic circular buffer
TODOs:
it is not thread-safe now
print_data function prints only printable data, type which has insertion operator overload.
godbolt link: https://godbolt.org/z/TPqdn5fn7
*/
template<typename T>
struct circular_buffer{
private:
int head_position = 0;
int tail_position = 0;
int capacity = 0;
std::vector<T> buffer;
public:
circular_buffer(int capacity){
buffer.reserve(capacity+1);
this->capacity = capacity;
}
bool is_full(){
if(tail_position == capacity){
return head_position == 0;
}
return tail_position+1 == head_position;
}
bool is_empty(){
int diff = tail_position - head_position;
return diff == 0;
}
bool push(T data){
if(!is_full()){
buffer[tail_position%capacity] = data;
tail_position = tail_position == capacity ? 0 : tail_position+1;
return true;
}
return false;
}
std::optional<T> pop(){
std::optional<T> data;
if(!is_empty()){
data = buffer[head_position%capacity];
++head_position;
if(is_empty()) {
head_position = tail_position = 0;
}
}
return data;
}
void print_data(){
std::cout << "\n*********** print data *********** \n";
std::cout << "head: " << head_position << "\n";
std::cout << "tail: " << tail_position << "\n";
std::cout << "size: " << buffer.size() << "\n";
std::cout << "capacity: " << capacity << "\n";
for(auto index = 0; index < capacity; ++index){
std::cout << buffer[index] << " ";
}
std::cout << "\n*********** print data *********** \n";
}
};
int main() {
circular_buffer<int> buffer{2};
std::cout << "is empty: " << std::boolalpha << buffer.is_empty() << "\n\n";
///////////////////////////////////////////////////////////////////////////////////////
std::cout << "push " << std::boolalpha << buffer.push(100) << "\n";
std::cout << "push " << std::boolalpha << buffer.push(200) << "\n";
std::cout << "push " << std::boolalpha << buffer.push(300) << "\n";
std::cout << "pop " << std::boolalpha << buffer.pop().value_or(-1) << "\n";
std::cout << "pop " << std::boolalpha << buffer.pop().value_or(-1) << "\n";
std::cout << "push " << std::boolalpha << buffer.push(300) << "\n";
std::cout << "push " << std::boolalpha << buffer.push(400) << "\n";
std::cout << "is full: " << std::boolalpha << buffer.is_full() << "\n";
std::cout << "is empty: " << std::boolalpha << buffer.is_empty() << "\n\n";
///////////////////////////////////////////////////////////////////////////////////////
buffer.print_data();
return 0;
}