RingBuffer.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #ifndef CORE_RINGBUFFER_HPP
  2. #define CORE_RINGBUFFER_HPP
  3. #include <assert.h>
  4. #include "core/utils/AlignedData.hpp"
  5. #include "core/utils/ArrayString.hpp"
  6. namespace Core {
  7. template<typename T, size_t N>
  8. class RingBuffer final {
  9. AlignedType<T> data[N];
  10. size_t writeIndex = 0;
  11. size_t readIndex = 0;
  12. size_t values = 0;
  13. public:
  14. RingBuffer() = default;
  15. RingBuffer(const RingBuffer& other) {
  16. copy(other);
  17. }
  18. RingBuffer(RingBuffer&& other) {
  19. move(Core::move(other));
  20. other.clear();
  21. }
  22. ~RingBuffer() {
  23. clear();
  24. }
  25. RingBuffer& operator=(const RingBuffer& other) {
  26. if(&other != this) {
  27. clear();
  28. copy(other);
  29. }
  30. return *this;
  31. }
  32. RingBuffer& operator=(RingBuffer&& other) {
  33. if(&other != this) {
  34. clear();
  35. move(Core::move(other));
  36. other.clear();
  37. }
  38. return *this;
  39. }
  40. template<typename... Args>
  41. T* put(Args&&... args) {
  42. if(getLength() >= N) {
  43. return nullptr;
  44. }
  45. T* t = new(data + writeIndex) T(Core::forward<Args>(args)...);
  46. writeIndex = (writeIndex + 1) % N;
  47. values++;
  48. return t;
  49. }
  50. template<typename... Args>
  51. RingBuffer& add(Args&&... args) {
  52. put(Core::forward<Args>(args)...);
  53. return *this;
  54. }
  55. T& operator[](size_t index) {
  56. return reinterpret_cast<T*>(data)[(index + readIndex) % N];
  57. }
  58. const T& operator[](size_t index) const {
  59. return reinterpret_cast<const T*>(data)[(index + readIndex) % N];
  60. }
  61. size_t getLength() const {
  62. return values;
  63. }
  64. bool canRemove() const {
  65. return getLength() > 0;
  66. }
  67. void clear() {
  68. for(size_t i = 0; i < getLength(); i++) {
  69. (*this)[i].~T();
  70. }
  71. writeIndex = 0;
  72. readIndex = 0;
  73. values = 0;
  74. }
  75. void remove() {
  76. assert(canRemove());
  77. values--;
  78. (*this)[0].~T();
  79. readIndex = (readIndex + 1) % N;
  80. }
  81. void toString(BufferString& s) const {
  82. s.append("[");
  83. size_t end = getLength();
  84. if(end > 0) {
  85. end--;
  86. for(size_t i = 0; i < end; i++) {
  87. s.append((*this)[i]).append(", ");
  88. }
  89. s.append((*this)[end]);
  90. }
  91. s.append("]");
  92. }
  93. private:
  94. void copy(const RingBuffer& other) {
  95. for(size_t i = 0; i < other.getLength(); i++) {
  96. add(other[i]);
  97. }
  98. }
  99. void move(RingBuffer&& other) {
  100. for(size_t i = 0; i < other.getLength(); i++) {
  101. add(Core::move(other[i]));
  102. }
  103. }
  104. };
  105. }
  106. #endif