Files
IR-protocol/RingBuffer.h

54 lines
1.4 KiB
C++

#pragma once
#include "IrInterruptGuard.h"
template <typename T, unsigned int BufferSize>
class RingBuffer {
public:
RingBuffer() : start(0), end(0) {}
bool isFull() const {
return ((end + 1) % BufferSize) == start;
}
bool isEmpty() const {
return start == end;
}
bool push(T element) {
bool pushed = false;
IrInterruptGuard guard;
if (!isFull()) {
data[end] = element;
end = (end + 1) % BufferSize;
pushed = true;
}
return pushed;
}
T* pop() {
IrInterruptGuard guard;
T* value = nullptr;
if (!isEmpty()) {
value = &data[start];
start = (start + 1) % BufferSize;
}
return value;
}
// B5: безопасный pop — копирует элемент под ОДНОЙ критсекцией и отдаёт по значению.
// (T* pop() отдаёт указатель во внутренний слот; после выхода слот снова может быть перезаписан.)
bool pop(T &out) {
bool popped = false;
IrInterruptGuard guard;
if (!isEmpty()) {
out = data[start];
start = (start + 1) % BufferSize;
popped = true;
}
return popped;
}
private:
T data[BufferSize];
unsigned int start, end;
};