FancySafeBot 0.0.1
A safe robotics library
Loading...
Searching...
No Matches
fsb_circular_buffer.h
1#pragma once
2
3#include <array>
4#include <cstddef>
5#include <cstdint>
6
7namespace fsb
8{
9
18enum class CircularBufferStatus : uint8_t
19{
23 SUCCESS = 0,
27 FULL,
31 EMPTY,
36};
37
42template <typename BufferType, size_t BufferSize> class CircularBuffer
43{
44public:
45 CircularBuffer() = default;
46
53 CircularBufferStatus push(BufferType push_value);
54
61 CircularBufferStatus force_push(BufferType push_value);
62
69 CircularBufferStatus pop(BufferType& popped_value);
70
82 pop_all(std::array<BufferType, BufferSize>& popped_values, size_t& num_popped);
83
88 void reset();
89
95 [[nodiscard]] size_t get_filled() const
96 {
97 size_t filled_size = 0;
98 if (m_full)
99 {
100 filled_size = BufferSize;
101 }
102 else
103 {
104 filled_size = (m_tail > m_head ? (BufferSize - m_tail) + m_head : m_head - m_tail);
105 }
106 return filled_size;
107 }
108
114 [[nodiscard]] size_t get_remaining() const
115 {
116 size_t remaining_size = 0;
117 if (m_full)
118 {
119 remaining_size = 0;
120 }
121 else
122 {
123 remaining_size = (m_tail > m_head ? m_tail - m_head : BufferSize - (m_head - m_tail));
124 }
125 return remaining_size;
126 }
127
133 static size_t get_size()
134 {
135 return BufferSize;
136 }
137
138private:
142 std::array<BufferType, BufferSize> m_buffer = {};
148 size_t m_tail = 0;
154 size_t m_head = 0;
158 bool m_full = false;
159};
160
161// ===============================
162// CircularBuffer Implementation
163// ===============================
164
165template <typename BufferType, size_t BufferSize>
167{
168 auto status = CircularBufferStatus::SUCCESS;
169 if (get_remaining() == 0)
170 {
172 }
173 else
174 {
175 // push to head of queue
176 m_buffer[m_head] = push_value;
177 m_head = (m_head + 1) % BufferSize;
178 m_full = (m_head == m_tail);
179 }
180 return status;
181}
182
183template <typename BufferType, size_t BufferSize>
186{
187 auto status = CircularBufferStatus::SUCCESS;
188 if (get_remaining() == 0)
189 {
190 m_buffer[m_head] = push_value;
191 m_head = (m_head + 1) % BufferSize;
192 m_tail = m_head;
194 }
195 else
196 {
197 // push to head of queue
198 m_buffer[m_head] = push_value;
199 m_head = (m_head + 1) % BufferSize;
200 m_full = (m_head == m_tail);
201 }
202 return status;
203}
204
205template <typename BufferType, size_t BufferSize>
207{
208 auto status = CircularBufferStatus::SUCCESS;
209 if (get_filled() == 0)
210 {
212 }
213 else
214 {
215 // consume at tail of queue
216 popped_value = m_buffer[m_tail];
217 // advance
218 m_tail = (m_tail + 1) % BufferSize;
219 m_full = false;
220 }
221 return status;
222}
223
224template <typename BufferType, size_t BufferSize>
226 std::array<BufferType, BufferSize>& popped_values, size_t& num_popped)
227{
228 num_popped = 0;
229 while (get_filled() > 0)
230 {
231 // consume at tail of queue
232 popped_values[num_popped] = m_buffer[m_tail];
233 num_popped++;
234 // advance
235 m_tail = (m_tail + 1) % BufferSize;
236 m_full = false;
237 }
239}
240
241template <typename BufferType, size_t BufferSize>
243{
244 m_head = 0;
245 m_tail = 0;
246 m_full = false;
247}
248
249} // namespace fsb
Circular Buffer.
Definition fsb_circular_buffer.h:43
CircularBufferStatus
Definition fsb_circular_buffer.h:19
void reset()
Reset buffer to empty state.
Definition fsb_circular_buffer.h:242
size_t get_remaining() const
Get number of remaining buffer positions.
Definition fsb_circular_buffer.h:114
static size_t get_size()
Get total buffer size.
Definition fsb_circular_buffer.h:133
CircularBufferStatus push(BufferType push_value)
Add value to the buffer if there is space available.
Definition fsb_circular_buffer.h:166
CircularBufferStatus pop(BufferType &popped_value)
Get oldest value from buffer.
Definition fsb_circular_buffer.h:206
CircularBufferStatus pop_all(std::array< BufferType, BufferSize > &popped_values, size_t &num_popped)
Pop all values from the buffer into an array.
Definition fsb_circular_buffer.h:225
size_t get_filled() const
Get number of filled buffer positions.
Definition fsb_circular_buffer.h:95
CircularBufferStatus force_push(BufferType push_value)
Add value to buffer and overwrite oldest value if buffer is full.
Definition fsb_circular_buffer.h:185
@ OVERWRITE
Adding to buffer overwrote existing data.
@ EMPTY
Operation failed, buffer is empty.
@ FULL
Operation failed, buffer is full.
@ SUCCESS
Successful operation.