Advertisement
Guest User

Untitled

a guest
Mar 18th, 2019
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.63 KB | None | 0 0
  1. #pragma once
  2. #include <vector>
  3. #include <stdint.h>
  4. #include <assert.h>
  5.  
  6. using u32 = uint32_t;
  7. constexpr u32 u32_invalid_id{ 0xffffffff };
  8.  
  9. template <typename T>
  10. class free_list_vector
  11. {
  12. static_assert(sizeof(T) >= sizeof(u32));
  13. public:
  14. explicit free_list_vector() = default;
  15. explicit free_list_vector(size_t n)
  16. {
  17. _array.reserve(n);
  18. _next_free_index = u32_invalid_id;
  19. }
  20. ~free_list_vector() { clear(); }
  21.  
  22. template<class... params>
  23. u32 add(params&&... p)
  24. {
  25. u32 id{ u32_invalid_id };
  26. if (_next_free_index == u32_invalid_id)
  27. {
  28. id = (u32)_array.size();
  29. _array.emplace_back(std::forward<params>(p)...);
  30. }
  31. else
  32. {
  33. id = _next_free_index;
  34. assert(id < _array.size() && already_removed(id));
  35. _next_free_index = read_index(id);
  36. new (&_array[id]) T(std::forward<params>(p)...);
  37. }
  38. return id;
  39. }
  40.  
  41. constexpr void remove(u32 id)
  42. {
  43. assert(id < _array.size() && !already_removed(id));
  44. T& item{ _array[id] };
  45. item.~T();
  46. write_index(id, _next_free_index);
  47. _next_free_index = id;
  48. }
  49.  
  50. constexpr void clear()
  51. {
  52. clear_removed_items();
  53. _array.clear();
  54. }
  55. constexpr decltype(auto) size() const { return _array.size(); }
  56.  
  57. [[nodiscard]] T& operator[](u32 id)
  58. {
  59. assert(id < _array.size());
  60. return _array[id];
  61. }
  62.  
  63. [[nodiscard]] const T& operator[](u32 id) const
  64. {
  65. assert(id < _array.size());
  66. return _array[id];
  67. }
  68.  
  69. constexpr operator const std::vector<T>&() const
  70. {
  71. return _array;
  72. }
  73. private:
  74. constexpr void write_index(u32 id, u32 next_free_id)
  75. {
  76. debug_op(memset(&_array[id], 0xcc, sizeof(T)));
  77. u32 *const p{ reinterpret_cast<u32 *const>(&_array[id]) };
  78. *p = next_free_id;
  79. }
  80.  
  81. constexpr u32 read_index(u32 id) const
  82. {
  83. return *reinterpret_cast<const u32 *const>(&_array[id]);
  84. }
  85.  
  86. constexpr void clear_removed_items()
  87. {
  88. while (_next_free_index != u32_invalid_id)
  89. {
  90. const u32 id{ _next_free_index };
  91. _next_free_index = read_index(id);
  92. new (&_array[id]) T{};
  93. }
  94. }
  95.  
  96. #ifdef _DEBUG
  97. constexpr bool already_removed(u32 id) const
  98. {
  99. u32 i{ sizeof(u32) }; // skip the first 4 bytes
  100. const u8 *const p{ reinterpret_cast<const u8 *const>(&_array[id]) };
  101. while ((p[i] == 0xcc) && (i < sizeof(T))) ++i;
  102. return i == sizeof(T);
  103. }
  104. #endif
  105.  
  106. std::vector<T> _array;
  107. u32 _next_free_index{ u32_invalid_id };
  108. };
  109.  
  110. struct _1 {
  111. explicit _1() = default;
  112. explicit _1(ID3DBlob* b, u32 size)
  113. :res1{ b }, blah{ size }
  114. {
  115.  
  116. }
  117. DISABLE_COPY(_1); // deletes copy constructor and copy assignment operator
  118. explicit _1(_1&& o)
  119. {
  120. *this = std::move(o);
  121. }
  122. ~_1() { reset(); }
  123. _1& operator=(_1&& o)
  124. {
  125. reset();
  126. res1 = o.res1;
  127. blah = o.blah;
  128. new (&o) _1{}; // we don't want to release the COM-object after a move
  129. return *this;
  130. }
  131.  
  132. ID3DBlob *const blob() { return res1; }
  133. private:
  134. void reset()
  135. {
  136. if (res1)
  137. {
  138. res1->Release();
  139. res1 = nullptr;
  140. }
  141. }
  142. ID3DBlob* res1{ nullptr };
  143. u32 blah{ u32_invalid_id };
  144. };
  145.  
  146. void free_list_test()
  147. {
  148. free_list_vector<_1> list;
  149. for (u32 i = 0; i < 10; ++i)
  150. {
  151. ID3DBlob* b;
  152. D3DCreateBlob(4096, &b);
  153. list.add(b, 4096);
  154. }
  155.  
  156. {
  157. u32 indices[]{ 3, 5, 8, 1, 6 };
  158. for (u32 i = 0; i < _countof(indices); ++i)
  159. {
  160. list.remove(indices[i]);
  161. }
  162. }
  163.  
  164. for (u32 i = 0; i < 40; ++i)
  165. {
  166. ID3DBlob* b;
  167. D3DCreateBlob(4096, &b);
  168. list.add(b, 4096);
  169. }
  170.  
  171. size_t sizes{ 0 };
  172. for (u32 i = 0; i < 45; ++i)
  173. {
  174. sizes += list[i].blob()->GetBufferSize();
  175. }
  176. assert(sizes == 45 * 4096);
  177.  
  178. {
  179. u32 indices[]{ 23, 35, 18, 11, 26 };
  180. for (u32 i = 0; i < _countof(indices); ++i)
  181. {
  182. list.remove(indices[i]);
  183. }
  184. }
  185. }
  186.  
  187. int main(){
  188. free_list_test();
  189. return 0;
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement