MiniQueue.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : a small memory overhead, fixed size, efficient, iterable
  9. // queue class used for CContextView SObjectClone
  10. #ifndef CRYINCLUDE_CRYCOMMON_MINIQUEUE_H
  11. #define CRYINCLUDE_CRYCOMMON_MINIQUEUE_H
  12. #pragma once
  13. // this class implements a very small queue of plain-old-data
  14. template <typename T, uint8 N>
  15. struct MiniQueue
  16. {
  17. public:
  18. MiniQueue()
  19. : m_nValues(0)
  20. , m_nOffset(0) {}
  21. MiniQueue(const MiniQueue& mq)
  22. {
  23. m_nValues = mq.m_nValues;
  24. m_nOffset = 0;
  25. for (int i = 0; i < m_nValues; i++)
  26. {
  27. m_vValues[i] = mq[i];
  28. }
  29. }
  30. bool Empty() const
  31. {
  32. return m_nValues == 0;
  33. }
  34. bool Full() const
  35. {
  36. return m_nValues == N;
  37. }
  38. uint8 Size() const
  39. {
  40. return m_nValues;
  41. }
  42. uint8 Capacity() const
  43. {
  44. return N;
  45. }
  46. ILINE void Push(T nValue)
  47. {
  48. assert(!Full());
  49. m_vValues[(m_nOffset + m_nValues) % N] = nValue;
  50. m_nValues++;
  51. }
  52. // push, but if the queue is full, then pop first
  53. void CyclePush(T nValue)
  54. {
  55. if (Full())
  56. {
  57. Pop();
  58. }
  59. Push(nValue);
  60. }
  61. void PushFront(T nValue)
  62. {
  63. assert(!Full());
  64. m_nOffset = (m_nOffset + (N - 1)) % N;
  65. m_vValues[m_nOffset] = nValue;
  66. m_nValues++;
  67. }
  68. T Front() const
  69. {
  70. assert(!Empty());
  71. return m_vValues[m_nOffset];
  72. }
  73. T& Front()
  74. {
  75. assert(!Empty());
  76. return m_vValues[m_nOffset];
  77. }
  78. T& operator[](int i)
  79. {
  80. return m_vValues[(m_nOffset + i) % N];
  81. }
  82. T operator[](int i) const
  83. {
  84. return m_vValues[(m_nOffset + i) % N];
  85. }
  86. T Back() const
  87. {
  88. assert(!Empty());
  89. return m_vValues[(m_nOffset + m_nValues - 1) % N];
  90. }
  91. T& Back()
  92. {
  93. assert(!Empty());
  94. return m_vValues[(m_nOffset + m_nValues - 1) % N];
  95. }
  96. void Pop()
  97. {
  98. assert(!Empty());
  99. m_nOffset = (m_nOffset + 1) % N;
  100. m_nValues--;
  101. }
  102. void PopBack()
  103. {
  104. assert(!Empty());
  105. m_nValues--;
  106. }
  107. void Clear()
  108. {
  109. m_nOffset = m_nValues = 0;
  110. }
  111. struct SIterator
  112. {
  113. public:
  114. SIterator() {}
  115. SIterator(T* pValues, uint8 nOffset)
  116. : m_pValues(pValues)
  117. , m_nOffset(nOffset) {}
  118. T& operator*()
  119. {
  120. return m_pValues[m_nOffset % N];
  121. }
  122. T* operator->()
  123. {
  124. return &m_pValues[m_nOffset % N];
  125. }
  126. SIterator& operator++()
  127. {
  128. m_nOffset++;
  129. return *this;
  130. }
  131. SIterator operator++(int)
  132. {
  133. SIterator itor = *this;
  134. ++m_nOffset;
  135. return itor;
  136. }
  137. SIterator& operator--()
  138. {
  139. m_nOffset--;
  140. return *this;
  141. }
  142. SIterator& operator+=(uint8 delta)
  143. {
  144. m_nOffset += delta;
  145. return *this;
  146. }
  147. SIterator& operator-=(uint8 delta)
  148. {
  149. m_nOffset -= delta;
  150. return *this;
  151. }
  152. friend bool operator!=(const SIterator& a, const SIterator& b)
  153. {
  154. assert(a.m_pValues == b.m_pValues);
  155. return a.m_nOffset != b.m_nOffset;
  156. }
  157. friend bool operator==(const SIterator& a, const SIterator& b)
  158. {
  159. assert(a.m_pValues == b.m_pValues);
  160. return a.m_nOffset == b.m_nOffset;
  161. }
  162. friend int operator-(const SIterator& a, const SIterator& b)
  163. {
  164. assert(a.m_pValues == b.m_pValues);
  165. int diff = int(a.m_nOffset) - int(b.m_nOffset);
  166. return diff;
  167. }
  168. uint8 Offset() { return m_nOffset; }
  169. private:
  170. T* m_pValues;
  171. uint8 m_nOffset;
  172. };
  173. SIterator Begin() { return SIterator(m_vValues, m_nOffset); }
  174. SIterator End() { return SIterator(m_vValues, m_nOffset + m_nValues); }
  175. SIterator RBegin() { return SIterator(m_vValues, m_nOffset + m_nValues - 1); }
  176. SIterator REnd() { return SIterator(m_vValues, m_nOffset - 1); }
  177. struct SConstIterator
  178. {
  179. public:
  180. SConstIterator() {}
  181. SConstIterator(const T* pValues, uint8 nOffset)
  182. : m_pValues(pValues)
  183. , m_nOffset(nOffset) {}
  184. const T& operator*()
  185. {
  186. return m_pValues[m_nOffset % N];
  187. }
  188. const T* operator->()
  189. {
  190. return &m_pValues[m_nOffset % N];
  191. }
  192. SConstIterator& operator++()
  193. {
  194. m_nOffset++;
  195. return *this;
  196. }
  197. SConstIterator& operator--()
  198. {
  199. m_nOffset--;
  200. return *this;
  201. }
  202. SConstIterator& operator+=(uint8 delta)
  203. {
  204. m_nOffset += delta;
  205. return *this;
  206. }
  207. SConstIterator& operator-=(uint8 delta)
  208. {
  209. m_nOffset -= delta;
  210. return *this;
  211. }
  212. friend bool operator!=(const SConstIterator& a, const SConstIterator& b)
  213. {
  214. assert(a.m_pValues == b.m_pValues);
  215. return a.m_nOffset != b.m_nOffset;
  216. }
  217. friend bool operator==(const SConstIterator& a, const SConstIterator& b)
  218. {
  219. assert(a.m_pValues == b.m_pValues);
  220. return a.m_nOffset == b.m_nOffset;
  221. }
  222. friend int operator-(const SConstIterator& a, const SConstIterator& b)
  223. {
  224. assert(a.m_pValues == b.m_pValues);
  225. int diff = int(a.m_nOffset) - int(b.m_nOffset);
  226. return diff;
  227. }
  228. uint8 Offset() { return m_nOffset; }
  229. private:
  230. const T* m_pValues;
  231. uint8 m_nOffset;
  232. };
  233. SConstIterator Begin() const { return SConstIterator(m_vValues, m_nOffset); }
  234. SConstIterator End() const { return SConstIterator(m_vValues, m_nOffset + m_nValues); }
  235. SConstIterator RBegin() const { return SConstIterator(m_vValues, m_nOffset + m_nValues - 1); }
  236. SConstIterator REnd() const { return SConstIterator(m_vValues, m_nOffset - 1); }
  237. void Erase(SIterator where)
  238. {
  239. assert(where.Offset() >= m_nOffset);
  240. assert(where.Offset() < m_nOffset + m_nValues);
  241. for (size_t offset = where.Offset(); offset < (size_t)(m_nOffset + m_nValues - 1); offset++)
  242. {
  243. m_vValues[offset % N] = m_vValues[(offset + 1) % N];
  244. }
  245. m_nValues--;
  246. }
  247. void Erase(SIterator first, SIterator last)
  248. {
  249. int num = last - first;
  250. if (num == 0)
  251. {
  252. return;
  253. }
  254. assert(num > 0);
  255. assert(num <= Size());
  256. assert(first.Offset() >= m_nOffset);
  257. assert(first.Offset() < m_nOffset + m_nValues);
  258. assert(last.Offset() >= m_nOffset);
  259. assert(last.Offset() <= m_nOffset + m_nValues);
  260. for (int offset = (int)first.Offset(); offset < m_nOffset + m_nValues - 1; offset++)
  261. {
  262. m_vValues[offset % N] = m_vValues[(offset + num) % N];
  263. }
  264. m_nValues -= num;
  265. }
  266. private:
  267. uint8 m_nValues;
  268. uint8 m_nOffset;
  269. T m_vValues[N];
  270. };
  271. #endif // CRYINCLUDE_CRYCOMMON_MINIQUEUE_H