]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/ringbuffer.hpp
fixed two typos
[qmk_firmware.git] / tmk_core / protocol / lufa / ringbuffer.hpp
1 #pragma once
2 // A simple ringbuffer holding Size elements of type T
3 template <typename T, uint8_t Size>
4 class 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 };