You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.2 KiB

  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. inline uint8_t prevPosition(uint8_t position) {
  13. if (position == 0) {
  14. return Size - 1;
  15. }
  16. return position - 1;
  17. }
  18. inline bool enqueue(const T &item) {
  19. static_assert(Size > 1, "RingBuffer size must be > 1");
  20. uint8_t next = nextPosition(head_);
  21. if (next == tail_) {
  22. // Full
  23. return false;
  24. }
  25. buf_[head_] = item;
  26. head_ = next;
  27. return true;
  28. }
  29. inline bool get(T &dest, bool commit = true) {
  30. auto tail = tail_;
  31. if (tail == head_) {
  32. // No more data
  33. return false;
  34. }
  35. dest = buf_[tail];
  36. tail = nextPosition(tail);
  37. if (commit) {
  38. tail_ = tail;
  39. }
  40. return true;
  41. }
  42. inline bool empty() const { return head_ == tail_; }
  43. inline uint8_t size() const {
  44. int diff = head_ - tail_;
  45. if (diff >= 0) {
  46. return diff;
  47. }
  48. return Size + diff;
  49. }
  50. inline T& front() {
  51. return buf_[tail_];
  52. }
  53. inline bool peek(T &item) {
  54. return get(item, false);
  55. }
  56. };