Parent directory

ringbuffer.hpp

1259 bytes
 1#pragma once
 2// A simple ringbuffer holding Size elements of type T
 3template <typename T, uint8_t Size>
 4class RingBuffer {
 5 protected:
 6  T buf_[Size];
 7  uint8_t head_{0}, tail_{0};
 8 public:
 9  inline uint8_t nextPosition(uint8_t position) {
10    return (position + 1) % Size;
11  }
12
13  inline uint8_t prevPosition(uint8_t position) {
14    if (position == 0) {
15      return Size - 1;
16    }
17    return position - 1;
18  }
19
20  inline bool enqueue(const T &item) {
21    static_assert(Size > 1, "RingBuffer size must be > 1");
22    uint8_t next = nextPosition(head_);
23    if (next == tail_) {
24      // Full
25      return false;
26    }
27
28    buf_[head_] = item;
29    head_ = next;
30    return true;
31  }
32
33  inline bool get(T &dest, bool commit = true) {
34    auto tail = tail_;
35    if (tail == head_) {
36      // No more data
37      return false;
38    }
39
40    dest = buf_[tail];
41    tail = nextPosition(tail);
42
43    if (commit) {
44      tail_ = tail;
45    }
46    return true;
47  }
48
49  inline bool empty() const { return head_ == tail_; }
50
51  inline uint8_t size() const {
52    int diff = head_ - tail_;
53    if (diff >= 0) {
54      return diff;
55    }
56    return Size + diff;
57  }
58
59  inline T& front() {
60    return buf_[tail_];
61  }
62
63  inline bool peek(T &item) {
64    return get(item, false);
65  }
66};