queue.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #pragma once
  2. //simple circular ring buffer
  3. #include <nall/range.hpp>
  4. #include <nall/serializer.hpp>
  5. namespace nall {
  6. template<typename T>
  7. struct queue {
  8. queue() = default;
  9. queue(const queue& source) { operator=(source); }
  10. queue(queue&& source) { operator=(move(source)); }
  11. ~queue() { reset(); }
  12. auto operator=(const queue& source) -> queue& {
  13. if(this == &source) return *this;
  14. delete[] _data;
  15. _data = new T[source._capacity];
  16. _capacity = source._capacity;
  17. _size = source._size;
  18. _read = source._read;
  19. _write = source._write;
  20. for(uint n : range(_capacity)) _data[n] = source._data[n];
  21. return *this;
  22. }
  23. auto operator=(queue&& source) -> queue& {
  24. if(this == &source) return *this;
  25. _data = source._data;
  26. _capacity = source._capacity;
  27. _size = source._size;
  28. _read = source._read;
  29. _write = source._write;
  30. source._data = nullptr;
  31. source.reset();
  32. return *this;
  33. }
  34. template<typename U = T> auto capacity() const -> uint { return _capacity * sizeof(T) / sizeof(U); }
  35. template<typename U = T> auto size() const -> uint { return _size * sizeof(T) / sizeof(U); }
  36. auto empty() const -> bool { return _size == 0; }
  37. auto pending() const -> bool { return _size > 0; }
  38. auto full() const -> bool { return _size >= (int)_capacity; }
  39. auto underflow() const -> bool { return _size < 0; }
  40. auto overflow() const -> bool { return _size > (int)_capacity; }
  41. auto data() -> T* { return _data; }
  42. auto data() const -> const T* { return _data; }
  43. auto reset() {
  44. delete[] _data;
  45. _data = nullptr;
  46. _capacity = 0;
  47. _size = 0;
  48. _read = 0;
  49. _write = 0;
  50. }
  51. auto resize(uint capacity, const T& value = {}) -> void {
  52. delete[] _data;
  53. _data = new T[capacity];
  54. _capacity = capacity;
  55. _size = 0;
  56. _read = 0;
  57. _write = 0;
  58. for(uint n : range(_capacity)) _data[n] = value;
  59. }
  60. auto flush() -> void {
  61. _size = 0;
  62. _read = 0;
  63. _write = 0;
  64. }
  65. auto fill(const T& value = {}) -> void {
  66. _size = 0;
  67. _read = 0;
  68. _write = 0;
  69. for(uint n : range(_capacity)) _data[n] = value;
  70. }
  71. auto peek(uint index) const -> T {
  72. return _data[(_read + index) % _size];
  73. }
  74. auto read() -> T {
  75. T value = _data[_read++];
  76. if(_read >= _capacity) _read = 0;
  77. _size--;
  78. return value;
  79. }
  80. auto write(const T& value) -> void {
  81. _data[_write++] = value;
  82. if(_write >= _capacity) _write = 0;
  83. _size++;
  84. }
  85. auto serialize(serializer& s) -> void {
  86. s.array(_data, _capacity);
  87. s.integer(_capacity);
  88. s.integer(_size);
  89. s.integer(_read);
  90. s.integer(_write);
  91. }
  92. private:
  93. T* _data = nullptr;
  94. uint _capacity = 0;
  95. int _size = 0;
  96. uint _read = 0;
  97. uint _write = 0;
  98. };
  99. }