libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
queue.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstdio>
5#include <cstring>
6
7#include "libxr_def.hpp"
8
9namespace LibXR
10{
20{
21 public:
28 BaseQueue(uint16_t element_size, size_t length, uint8_t *buffer)
29 : queue_array_(buffer),
30 ELEMENT_SIZE(element_size),
31 length_(length),
32 own_buffer_(false)
33 {
34 }
35
41 BaseQueue(uint16_t element_size, size_t length)
42 : queue_array_(new uint8_t[length * element_size]),
43 ELEMENT_SIZE(element_size),
44 length_(length),
45 own_buffer_(true)
46 {
47 }
48
53 {
54 if (own_buffer_)
55 {
56 delete[] queue_array_;
57 }
58 }
59
65 [[nodiscard]] void *operator[](uint32_t index)
66 {
67 return &queue_array_[static_cast<size_t>(index * ELEMENT_SIZE)];
68 }
69
76 ErrorCode Push(const void *data)
77 {
78 ASSERT(data != nullptr);
79
80 if (is_full_)
81 {
82 return ErrorCode::FULL;
83 }
84
86
87 tail_ = (tail_ + 1) % length_;
88 if (head_ == tail_)
89 {
90 is_full_ = true;
91 }
92
93 return ErrorCode::OK;
94 }
95
102 ErrorCode Peek(void *data)
103 {
104 ASSERT(data != nullptr);
105
106 if (Size() > 0)
107 {
108 memcpy(data, &queue_array_[head_ * ELEMENT_SIZE], ELEMENT_SIZE);
109 return ErrorCode::OK;
110 }
111 else
112 {
113 return ErrorCode::EMPTY;
114 }
115 }
116
124 ErrorCode Pop(void *data = nullptr)
125 {
126 if (Size() == 0)
127 {
128 return ErrorCode::EMPTY;
129 }
130
131 if (data != nullptr)
132 {
133 memcpy(data, &queue_array_[head_ * ELEMENT_SIZE], ELEMENT_SIZE);
134 }
135 head_ = (head_ + 1) % length_;
136 is_full_ = false;
137 return ErrorCode::OK;
138 }
139
147 {
148 if (Size() == 0)
149 {
150 return -1;
151 }
152 return static_cast<int>((tail_ + length_ - 1) % length_);
153 }
154
162 {
163 if (Size() == 0)
164 {
165 return -1;
166 }
167 return static_cast<int>(head_);
168 }
169
177 ErrorCode PushBatch(const void *data, size_t size)
178 {
179 ASSERT(data != nullptr);
180
181 auto avail = EmptySize();
182 if (avail < size)
183 {
184 return ErrorCode::FULL;
185 }
186
187 auto tmp = reinterpret_cast<const uint8_t *>(data);
188
189 size_t first_part = LibXR::min(size, length_ - tail_);
190 memcpy(&queue_array_[tail_ * ELEMENT_SIZE], tmp, first_part * ELEMENT_SIZE);
191
192 if (size > first_part)
193 {
194 memcpy(queue_array_, &tmp[first_part * ELEMENT_SIZE],
195 (size - first_part) * ELEMENT_SIZE);
196 }
197
198 tail_ = (tail_ + size) % length_;
199 if (head_ == tail_)
200 {
201 is_full_ = true;
202 }
203 return ErrorCode::OK;
204 }
205
214 ErrorCode PopBatch(void *data, size_t size)
215 {
216 if (Size() < size)
217 {
218 return ErrorCode::EMPTY;
219 }
220
221 if (size == 0)
222 {
223 return ErrorCode::OK;
224 }
225 is_full_ = false;
226
227 size_t first_part = LibXR::min(size, length_ - head_);
228 if (data != nullptr)
229 {
230 auto tmp = reinterpret_cast<uint8_t *>(data);
231 memcpy(tmp, &queue_array_[head_ * ELEMENT_SIZE], first_part * ELEMENT_SIZE);
232 if (size > first_part)
233 {
234 memcpy(&tmp[first_part * ELEMENT_SIZE], queue_array_,
235 (size - first_part) * ELEMENT_SIZE);
236 }
237 }
238
239 head_ = (head_ + size) % length_;
240 return ErrorCode::OK;
241 }
242
250 ErrorCode PeekBatch(void *data, size_t size)
251 {
252 ASSERT(data != nullptr);
253
254 if (Size() < size)
255 {
256 return ErrorCode::EMPTY;
257 }
258
259 auto index = head_;
260
261 auto tmp = reinterpret_cast<uint8_t *>(data);
262
263 size_t first_part = LibXR::min(size, length_ - index);
264 memcpy(tmp, &queue_array_[index * ELEMENT_SIZE], first_part * ELEMENT_SIZE);
265
266 if (first_part < size)
267 {
268 memcpy(&tmp[first_part * ELEMENT_SIZE], queue_array_,
269 (size - first_part) * ELEMENT_SIZE);
270 }
271
272 return ErrorCode::OK;
273 }
274
281 ErrorCode Overwrite(const void *data)
282 {
283 ASSERT(data != nullptr);
284
285 head_ = tail_ = 0;
286 is_full_ = false;
287
288 memcpy(queue_array_, data, ELEMENT_SIZE * length_);
289
290 tail_ = (tail_ + 1) % length_;
291 if (head_ == tail_)
292 {
293 is_full_ = true;
294 }
295
296 return ErrorCode::OK;
297 }
298
302 void Reset()
303 {
304 head_ = tail_ = 0;
305 is_full_ = false;
306 }
307
312 [[nodiscard]] size_t Size() const
313 {
314 if (is_full_)
315 {
316 return length_;
317 }
318 else if (tail_ >= head_)
319 {
320 return tail_ - head_;
321 }
322 else
323 {
324 return length_ + tail_ - head_;
325 }
326 }
327
332 [[nodiscard]] size_t EmptySize() const { return length_ - Size(); }
333
334 BaseQueue(const BaseQueue &) = delete;
335 BaseQueue &operator=(const BaseQueue &) = delete;
336 BaseQueue &operator=(BaseQueue &) = delete;
337 BaseQueue &operator=(const BaseQueue &&) = delete;
338 BaseQueue &operator=(BaseQueue &&) = delete;
339
340 uint8_t *queue_array_;
341 const uint16_t ELEMENT_SIZE;
342 size_t head_ = 0;
343 size_t tail_ = 0;
344 bool is_full_ = false;
345 size_t length_;
346 bool own_buffer_ = false;
347};
348
360template <typename Data>
361class Queue : public BaseQueue
362{
363 public:
369 Queue(size_t length) : BaseQueue(sizeof(Data), length) {}
370
377 Queue(size_t length, uint8_t *buffer) : BaseQueue(sizeof(Data), length, buffer) {}
378
393 Data &operator[](int32_t index)
394 {
395 if (index >= 0)
396 {
397 index = (head_ + index) % length_;
398 }
399 else
400 {
401 index = (tail_ + index + length_) % length_;
402 }
403
404 return *reinterpret_cast<Data *>(&queue_array_[index * ELEMENT_SIZE]);
405 }
406
415 ErrorCode Push(const Data &data) { return BaseQueue::Push(&data); }
416
425 ErrorCode Pop(Data &data) { return BaseQueue::Pop(&data); }
426
434 ErrorCode Pop() { return BaseQueue::Pop(); }
435
444 ErrorCode Peek(Data &data) { return BaseQueue::Peek(&data); }
445
455 ErrorCode PushBatch(const Data *data, size_t size)
456 {
457 return BaseQueue::PushBatch(data, size);
458 }
459
470 ErrorCode PopBatch(Data *data, size_t size) { return BaseQueue::PopBatch(data, size); }
471
482 ErrorCode PeekBatch(Data *data, size_t size)
483 {
484 return BaseQueue::PeekBatch(data, size);
485 }
486
494 ErrorCode Overwrite(const Data &data) { return BaseQueue::Overwrite(&data); }
495};
496
497} // namespace LibXR
基础队列类,提供固定大小的循环缓冲区 (Base queue class providing a fixed-size circular buffer).
Definition queue.hpp:20
ErrorCode Pop(void *data=nullptr)
移除队列头部的元素 (Pop the front element from the queue).
Definition queue.hpp:124
bool is_full_
队列是否已满 (Indicates if the queue is full).
Definition queue.hpp:344
size_t tail_
尾部索引 (Tail index).
Definition queue.hpp:343
ErrorCode Overwrite(const void *data)
覆盖队列中的数据 (Overwrite the queue with new data).
Definition queue.hpp:281
ErrorCode Push(const void *data)
向队列中添加一个元素 (Push an element into the queue).
Definition queue.hpp:76
size_t head_
头部索引 (Head index).
Definition queue.hpp:342
size_t length_
队列最大容量 (Maximum queue capacity).
Definition queue.hpp:345
int GetLastElementIndex() const
获取队列中最后一个元素的索引 (Get the index of the last element in the queue).
Definition queue.hpp:146
size_t EmptySize() const
获取队列的空闲空间 (Get the available space in the queue).
Definition queue.hpp:332
ErrorCode PopBatch(void *data, size_t size)
批量移除多个元素 (Pop multiple elements from the queue).
Definition queue.hpp:214
BaseQueue(uint16_t element_size, size_t length, uint8_t *buffer)
构造函数,初始化队列 (Constructor to initialize the queue).
Definition queue.hpp:28
void Reset()
重置队列,清空所有数据 (Reset the queue and clear all data).
Definition queue.hpp:302
ErrorCode PeekBatch(void *data, size_t size)
批量获取多个元素但不移除 (Peek at multiple elements without removing them).
Definition queue.hpp:250
void * operator[](uint32_t index)
访问指定索引的元素 (Access an element at a specified index).
Definition queue.hpp:65
size_t Size() const
获取队列中的元素个数 (Get the number of elements in the queue).
Definition queue.hpp:312
bool own_buffer_
是否由队列自己管理缓冲区 (Owns buffer memory).
Definition queue.hpp:346
ErrorCode Peek(void *data)
获取队列头部的元素但不移除 (Peek at the front element without removing it).
Definition queue.hpp:102
BaseQueue(uint16_t element_size, size_t length)
构造函数,初始化队列 (Constructor to initialize the queue).
Definition queue.hpp:41
~BaseQueue()
析构函数,释放队列内存 (Destructor to free queue memory).
Definition queue.hpp:52
int GetFirstElementIndex() const
获取队列中第一个元素的索引 (Get the index of the first element in the queue).
Definition queue.hpp:161
uint8_t * queue_array_
存储队列数据的数组 (Array storing queue data).
Definition queue.hpp:340
ErrorCode PushBatch(const void *data, size_t size)
批量推入多个元素 (Push multiple elements into the queue).
Definition queue.hpp:177
const uint16_t ELEMENT_SIZE
每个元素的大小 (Size of each element).
Definition queue.hpp:341
基于 BaseQueue 的泛型队列模板类 (Generic queue template class based on BaseQueue).
Definition queue.hpp:362
ErrorCode PopBatch(Data *data, size_t size)
批量移除多个元素,并获取数据 (Pop multiple elements from the queue and retrieve data).
Definition queue.hpp:470
Queue(size_t length, uint8_t *buffer)
构造函数,初始化队列 (Constructor to initialize the queue).
Definition queue.hpp:377
ErrorCode PeekBatch(Data *data, size_t size)
批量查看多个元素但不移除 (Peek at multiple elements without removing them).
Definition queue.hpp:482
ErrorCode PushBatch(const Data *data, size_t size)
批量推入多个元素 (Push multiple elements into the queue).
Definition queue.hpp:455
ErrorCode Peek(Data &data)
查看队列头部的元素但不移除 (Peek at the front element without removing it).
Definition queue.hpp:444
ErrorCode Overwrite(const Data &data)
覆盖队列中的数据 (Overwrite the queue with new data).
Definition queue.hpp:494
ErrorCode Pop()
仅从队列中移除头部元素,不获取数据 (Remove the front element from the queue without retrieving data).
Definition queue.hpp:434
Queue(size_t length)
构造函数,初始化队列 (Constructor to initialize the queue).
Definition queue.hpp:369
ErrorCode Pop(Data &data)
从队列中移除头部元素,并获取该元素的数据 (Remove the front element from the queue and retrieve its data).
Definition queue.hpp:425
Data & operator[](int32_t index)
访问队列中的元素 (Access an element in the queue).
Definition queue.hpp:393
ErrorCode Push(const Data &data)
向队列中添加一个元素 (Push an element into the queue).
Definition queue.hpp:415
LibXR 命名空间
Definition ch32_gpio.hpp:9
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值