BumpList.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #pragma once
  2. #include "BeefySysLib/Common.h"
  3. #include "BeefySysLib/util/BumpAllocator.h"
  4. NS_BF_BEGIN
  5. template <typename T>
  6. class BumpList
  7. {
  8. public:
  9. struct Node
  10. {
  11. T mValue;
  12. Node* mNext;
  13. };
  14. struct Iterator
  15. {
  16. public:
  17. Node* mNode;
  18. public:
  19. Iterator(Node* node)
  20. {
  21. mNode = node;
  22. }
  23. Iterator& operator++()
  24. {
  25. mNode = mNode->mNext;
  26. return *this;
  27. }
  28. bool operator!=(const Iterator& itr) const
  29. {
  30. return mNode != itr.mNode;
  31. }
  32. bool operator==(const Iterator& itr) const
  33. {
  34. return mNode == itr.mNode;
  35. }
  36. T operator*()
  37. {
  38. return mNode->mValue;
  39. }
  40. };
  41. struct RemovableIterator
  42. {
  43. public:
  44. Node** mPrevNextPtr;
  45. public:
  46. RemovableIterator(Node** headPtr)
  47. {
  48. mPrevNextPtr = headPtr;
  49. }
  50. RemovableIterator& operator++()
  51. {
  52. Node* newNode = *mPrevNextPtr;
  53. if (newNode != NULL)
  54. mPrevNextPtr = &newNode->mNext;
  55. return *this;
  56. }
  57. bool operator!=(const RemovableIterator& itr) const
  58. {
  59. if (itr.mPrevNextPtr == NULL)
  60. return *mPrevNextPtr != NULL;
  61. return *itr.mPrevNextPtr != *mPrevNextPtr;
  62. }
  63. bool operator==(const RemovableIterator& itr) const
  64. {
  65. if (itr.mPrevNextPtr == NULL)
  66. return *mPrevNextPtr == NULL;
  67. return *itr.mPrevNextPtr == *mPrevNextPtr;
  68. }
  69. T operator*()
  70. {
  71. return (*mPrevNextPtr)->mValue;
  72. }
  73. };
  74. public:
  75. Node* mHead;
  76. BumpList()
  77. {
  78. mHead = NULL;
  79. }
  80. void PushFront(T value, BumpAllocator* bumpAllocator)
  81. {
  82. auto newHead = bumpAllocator->Alloc<Node>();
  83. newHead->mValue = value;
  84. newHead->mNext = mHead;
  85. mHead = newHead;
  86. }
  87. bool IsEmpty()
  88. {
  89. return mHead == NULL;
  90. }
  91. T front()
  92. {
  93. return mHead->mValue;
  94. }
  95. RemovableIterator begin()
  96. {
  97. return RemovableIterator(&mHead);
  98. }
  99. RemovableIterator end()
  100. {
  101. return RemovableIterator(NULL);
  102. }
  103. RemovableIterator erase(RemovableIterator itr)
  104. {
  105. T removedVal = *itr;
  106. (*itr.mPrevNextPtr) = (*itr.mPrevNextPtr)->mNext;
  107. return itr;
  108. }
  109. };
  110. // This is a simple construct that acts as a push-only stack.
  111. // The 'NodeBlock' is designed to take advantage of being exactly 16-byte aligned when storing
  112. // Ts of 32-bit pointers.
  113. template <typename T>
  114. class BlockBumpList
  115. {
  116. public:
  117. struct NodeBlock
  118. {
  119. static const int NodeCount = 3;
  120. T mVals[NodeCount];
  121. NodeBlock* mNextBlock;
  122. NodeBlock()
  123. {
  124. mVals[0] = NULL;
  125. mVals[1] = NULL;
  126. mVals[2] = NULL;
  127. mNextBlock = NULL;
  128. }
  129. };
  130. struct Iterator
  131. {
  132. public:
  133. NodeBlock* mNodeBlock;
  134. int mMemberIdx;
  135. public:
  136. Iterator(NodeBlock* nodeBlock)
  137. {
  138. SetNodeBlock(nodeBlock);
  139. }
  140. void SetNodeBlock(NodeBlock* nodeBlock)
  141. {
  142. mNodeBlock = nodeBlock;
  143. if (mNodeBlock != NULL)
  144. {
  145. mMemberIdx = NodeBlock::NodeCount - 1;
  146. while ((mMemberIdx >= 0) && (!mNodeBlock->mVals[mMemberIdx]))
  147. mMemberIdx--;
  148. }
  149. else
  150. mMemberIdx = -1;
  151. }
  152. Iterator& operator++()
  153. {
  154. mMemberIdx--;
  155. if (mMemberIdx < 0)
  156. SetNodeBlock(mNodeBlock->mNextBlock);
  157. return *this;
  158. }
  159. bool operator!=(const Iterator& itr) const
  160. {
  161. return (mNodeBlock != itr.mNodeBlock) || (mMemberIdx != itr.mMemberIdx);
  162. }
  163. bool operator==(const Iterator& itr) const
  164. {
  165. return (mNodeBlock == itr.mNodeBlock) && (mMemberIdx == itr.mMemberIdx);
  166. }
  167. T operator*()
  168. {
  169. return mNodeBlock->mVals[mMemberIdx];
  170. }
  171. };
  172. public:
  173. NodeBlock* mHeadBlock;
  174. BlockBumpList()
  175. {
  176. mHeadBlock = NULL;
  177. }
  178. void Add(T value, BumpAllocator* bumpAllocator)
  179. {
  180. if (mHeadBlock == NULL)
  181. mHeadBlock = bumpAllocator->Alloc<NodeBlock>();
  182. else if (mHeadBlock->mVals[NodeBlock::NodeCount - 1])
  183. {
  184. auto newHeadBlock = bumpAllocator->Alloc<NodeBlock>();
  185. newHeadBlock->mNextBlock = mHeadBlock;
  186. mHeadBlock = newHeadBlock;
  187. }
  188. for (int i = 0; i < NodeBlock::NodeCount; i++)
  189. {
  190. if (!mHeadBlock->mVals[i])
  191. {
  192. mHeadBlock->mVals[i] = value;
  193. break;
  194. }
  195. }
  196. }
  197. Iterator begin()
  198. {
  199. return Iterator(mHeadBlock);
  200. }
  201. Iterator end()
  202. {
  203. return Iterator(NULL);
  204. }
  205. };
  206. NS_BF_END