qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

ringbuffer.hpp (1259B)


      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 };