blob: 8e6c6be5e12d97ce77f8d48f05f9f27c598ef4f1 (
plain)
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
|
#pragma once
#include <cassert>
#include <cstring>
template <typename T>
class RingBuffer
{
public:
using UnitType = T;
constexpr explicit RingBuffer(UnitType* buffer, size_t buffer_size)
: _buffer_size(buffer_size), _buffer(buffer)
{
assert(buffer_size);
assert(buffer);
}
constexpr void Push(UnitType item)
{
_buffer[_head] = item;
_head = (_head + 1) % _buffer_size;
}
constexpr void Push(const UnitType *items, size_t nitems)
{
if (items) {
for (size_t i = 0; i < nitems; i++) {
Push(items[i]);
}
}
}
constexpr UnitType Pop()
{
const auto item = _buffer[_tail];
_tail = (_tail + 1) % _buffer_size;
return item;
}
constexpr void Pop(UnitType* buf, size_t nitems)
{
if (buf) {
for (size_t i = 0; i < nitems; i++) {
buf[i] = Pop();
}
}
}
constexpr size_t Free()
{
return Size() - Occupied();
}
constexpr size_t Occupied()
{
return _head - _tail + ((_head >= _tail) ? 0 : _buffer_size);
}
constexpr bool IsEmpty() { return _head == _tail; }
constexpr bool IsFull() { return _tail + 1 == _head; }
constexpr size_t Size() { return _buffer_size - 1; }
private:
size_t _buffer_size{};
UnitType *_buffer{};
size_t _head{}, _tail{};
};
|