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.

80 lines
1.6KB

  1. #pragma once
  2. #include <assert.h>
  3. /**
  4. * A simple ring buffer.
  5. * Template arguments are for numeric type stored, and for size.
  6. * Not thread safe.
  7. * Guaranteed to be non-blocking. Adding or removing items will never
  8. * allocate or free memory.
  9. * Objects in RingBuffer are not owned by RingBuffer - they will not be destroyed.
  10. */
  11. template <typename T, int SIZE>
  12. class RingBuffer
  13. {
  14. public:
  15. RingBuffer()
  16. {
  17. for (int i = 0; i < SIZE; ++i) {
  18. memory[i] = 0;
  19. }
  20. }
  21. void push(T);
  22. T pop();
  23. bool full() const;
  24. bool empty() const;
  25. private:
  26. T memory[SIZE];
  27. bool couldBeFull = false; // full and empty are ambiguous, both are in--out
  28. int inIndex = 0;
  29. int outIndex = 0;
  30. /** Move up 'p' (a buffer index), wrap around if we hit the end
  31. * (this is the core of the circular ring buffer).
  32. */
  33. void advance(int &p);
  34. };
  35. template <typename T, int SIZE>
  36. inline void RingBuffer<T, SIZE>::push(T value)
  37. {
  38. assert(!full());
  39. memory[inIndex] = value;
  40. advance(inIndex);
  41. couldBeFull = true;
  42. }
  43. template <typename T, int SIZE>
  44. inline T RingBuffer<T, SIZE>::pop()
  45. {
  46. assert(!empty());
  47. T value = memory[outIndex];
  48. advance(outIndex);
  49. couldBeFull = false;
  50. return value;
  51. }
  52. template <typename T, int SIZE>
  53. inline bool RingBuffer<T, SIZE>::full() const
  54. {
  55. return (inIndex == outIndex) && couldBeFull;
  56. }
  57. template <typename T, int SIZE>
  58. inline bool RingBuffer<T, SIZE>::empty() const
  59. {
  60. return (inIndex == outIndex) && !couldBeFull;
  61. }
  62. template <typename T, int SIZE>
  63. inline void RingBuffer<T, SIZE>::advance(int &p)
  64. {
  65. if (++p >= SIZE) p = 0;
  66. }