WeakArray.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Util/Array.h>
  7. #include <AnKi/Util/DynamicArray.h>
  8. namespace anki {
  9. /// @addtogroup util_containers
  10. /// @{
  11. /// Array that doesn't own the memory.
  12. template<typename T, typename TSize = U32>
  13. class WeakArray
  14. {
  15. public:
  16. using Value = T;
  17. using Iterator = Value*;
  18. using ConstIterator = const Value*;
  19. using Reference = Value&;
  20. using ConstReference = const Value&;
  21. using Size = TSize;
  22. WeakArray(T* mem, Size size)
  23. : m_data(mem)
  24. , m_size(size)
  25. {
  26. if(size)
  27. {
  28. ANKI_ASSERT(mem);
  29. }
  30. }
  31. WeakArray()
  32. : WeakArray(nullptr, 0)
  33. {
  34. }
  35. template<PtrSize TSIZE>
  36. WeakArray(Array<T, TSIZE>& arr)
  37. : WeakArray(&arr[0], arr.getSize())
  38. {
  39. }
  40. explicit WeakArray(DynamicArray<T, TSize>& arr)
  41. : WeakArray()
  42. {
  43. if(arr.getSize())
  44. {
  45. m_data = &arr[0];
  46. m_size = arr.getSize();
  47. }
  48. }
  49. explicit WeakArray(DynamicArrayAuto<T, TSize>& arr)
  50. : WeakArray()
  51. {
  52. if(arr.getSize())
  53. {
  54. m_data = &arr[0];
  55. m_size = arr.getSize();
  56. }
  57. }
  58. /// Copy.
  59. WeakArray(const WeakArray& b)
  60. : WeakArray(b.m_data, b.m_size)
  61. {
  62. }
  63. /// Move.
  64. WeakArray(WeakArray&& b)
  65. : WeakArray()
  66. {
  67. *this = std::move(b);
  68. }
  69. /// Copy.
  70. WeakArray& operator=(const WeakArray& b)
  71. {
  72. m_data = b.m_data;
  73. m_size = b.m_size;
  74. return *this;
  75. }
  76. /// Move.
  77. WeakArray& operator=(WeakArray&& b)
  78. {
  79. m_data = b.m_data;
  80. b.m_data = nullptr;
  81. m_size = b.m_size;
  82. b.m_size = 0;
  83. return *this;
  84. }
  85. template<PtrSize TSIZE>
  86. WeakArray& operator=(Array<T, TSIZE>& arr)
  87. {
  88. m_data = &arr[0];
  89. m_size = arr.getSize();
  90. return *this;
  91. }
  92. WeakArray& operator=(DynamicArray<T, TSize>& arr)
  93. {
  94. m_data = (arr.getSize()) ? &arr[0] : nullptr;
  95. m_size = arr.getSize();
  96. return *this;
  97. }
  98. WeakArray& operator=(DynamicArrayAuto<T, TSize>& arr)
  99. {
  100. m_data = (arr.getSize()) ? &arr[0] : nullptr;
  101. m_size = arr.getSize();
  102. return *this;
  103. }
  104. Reference operator[](const Size n)
  105. {
  106. ANKI_ASSERT(n < m_size);
  107. return m_data[n];
  108. }
  109. ConstReference operator[](const Size n) const
  110. {
  111. ANKI_ASSERT(n < m_size);
  112. return m_data[n];
  113. }
  114. Iterator getBegin()
  115. {
  116. return m_data;
  117. }
  118. ConstIterator getBegin() const
  119. {
  120. return m_data;
  121. }
  122. Iterator getEnd()
  123. {
  124. return m_data + m_size;
  125. }
  126. ConstIterator getEnd() const
  127. {
  128. return m_data + m_size;
  129. }
  130. /// Make it compatible with the C++11 range based for loop.
  131. Iterator begin()
  132. {
  133. return getBegin();
  134. }
  135. /// Make it compatible with the C++11 range based for loop.
  136. ConstIterator begin() const
  137. {
  138. return getBegin();
  139. }
  140. /// Make it compatible with the C++11 range based for loop.
  141. Iterator end()
  142. {
  143. return getEnd();
  144. }
  145. /// Make it compatible with the C++11 range based for loop.
  146. ConstIterator end() const
  147. {
  148. return getEnd();
  149. }
  150. /// Get first element.
  151. Reference getFront()
  152. {
  153. ANKI_ASSERT(!isEmpty());
  154. return m_data[0];
  155. }
  156. /// Get first element.
  157. ConstReference getFront() const
  158. {
  159. ANKI_ASSERT(!isEmpty());
  160. return m_data[0];
  161. }
  162. /// Get last element.
  163. Reference getBack()
  164. {
  165. ANKI_ASSERT(!isEmpty());
  166. return m_data[m_size - 1];
  167. }
  168. /// Get last element.
  169. ConstReference getBack() const
  170. {
  171. ANKI_ASSERT(!isEmpty());
  172. return m_data[m_size - 1];
  173. }
  174. /// Set the array pointer and its size.
  175. void setArray(Value* array, Size size)
  176. {
  177. ANKI_ASSERT((array && size > 0) || (array == nullptr && size == 0));
  178. m_data = array;
  179. m_size = size;
  180. }
  181. Size getSize() const
  182. {
  183. return m_size;
  184. }
  185. Bool isEmpty() const
  186. {
  187. return m_size == 0;
  188. }
  189. PtrSize getSizeInBytes() const
  190. {
  191. return m_size * sizeof(Value);
  192. }
  193. private:
  194. Value* m_data;
  195. Size m_size;
  196. };
  197. /// Array that doesn't own the memory.
  198. template<typename T, typename TSize = U32>
  199. class ConstWeakArray
  200. {
  201. public:
  202. using Value = T;
  203. using ConstIterator = const Value*;
  204. using ConstReference = const Value&;
  205. using Size = TSize;
  206. ConstWeakArray(const T* mem, Size size)
  207. : m_data(mem)
  208. , m_size(size)
  209. {
  210. if(size)
  211. {
  212. ANKI_ASSERT(mem);
  213. }
  214. }
  215. ConstWeakArray()
  216. : ConstWeakArray(nullptr, 0)
  217. {
  218. }
  219. /// Construct from WeakArray.
  220. ConstWeakArray(const WeakArray<T, TSize>& arr)
  221. : ConstWeakArray((arr.getSize()) ? &arr[0] : nullptr, arr.getSize())
  222. {
  223. }
  224. /// Construct from Array.
  225. template<PtrSize TSIZE>
  226. ConstWeakArray(const Array<T, TSIZE>& arr)
  227. : ConstWeakArray(&arr[0], arr.getSize())
  228. {
  229. }
  230. /// Construct from DynamicArray.
  231. ConstWeakArray(const DynamicArray<T, TSize>& arr)
  232. : ConstWeakArray()
  233. {
  234. if(arr.getSize())
  235. {
  236. m_data = &arr[0];
  237. m_size = arr.getSize();
  238. }
  239. }
  240. /// Construct from DynamicArrayAuto.
  241. ConstWeakArray(const DynamicArrayAuto<T, TSize>& arr)
  242. : ConstWeakArray()
  243. {
  244. if(arr.getSize())
  245. {
  246. m_data = &arr[0];
  247. m_size = arr.getSize();
  248. }
  249. }
  250. /// Copy.
  251. ConstWeakArray(const ConstWeakArray& b)
  252. : ConstWeakArray(b.m_data, b.m_size)
  253. {
  254. }
  255. /// Move.
  256. ConstWeakArray(ConstWeakArray&& b)
  257. : ConstWeakArray()
  258. {
  259. *this = std::move(b);
  260. }
  261. /// Copy.
  262. ConstWeakArray& operator=(const ConstWeakArray& b)
  263. {
  264. m_data = b.m_data;
  265. m_size = b.m_size;
  266. return *this;
  267. }
  268. /// Copy from a WeakArray.
  269. template<typename Y>
  270. ConstWeakArray& operator=(const WeakArray<Y, TSize>& b)
  271. {
  272. m_data = (b.getSize()) ? b.getBegin() : nullptr;
  273. m_size = b.getSize();
  274. return *this;
  275. }
  276. /// Move.
  277. ConstWeakArray& operator=(ConstWeakArray&& b)
  278. {
  279. m_data = b.m_data;
  280. b.m_data = nullptr;
  281. m_size = b.m_size;
  282. b.m_size = 0;
  283. return *this;
  284. }
  285. template<PtrSize TSIZE>
  286. ConstWeakArray& operator=(const Array<T, TSIZE>& arr)
  287. {
  288. m_data = &arr[0];
  289. m_size = arr.getSize();
  290. return *this;
  291. }
  292. ConstWeakArray& operator=(const DynamicArray<T, TSize>& arr)
  293. {
  294. m_data = (arr.getSize()) ? &arr[0] : nullptr;
  295. m_size = arr.getSize();
  296. return *this;
  297. }
  298. ConstWeakArray& operator=(const DynamicArrayAuto<T, TSize>& arr)
  299. {
  300. m_data = (arr.getSize()) ? &arr[0] : nullptr;
  301. m_size = arr.getSize();
  302. return *this;
  303. }
  304. ConstReference operator[](const Size n) const
  305. {
  306. ANKI_ASSERT(n < m_size);
  307. return m_data[n];
  308. }
  309. ConstIterator getBegin() const
  310. {
  311. return m_data;
  312. }
  313. ConstIterator getEnd() const
  314. {
  315. return m_data + m_size;
  316. }
  317. /// Make it compatible with the C++11 range based for loop.
  318. ConstIterator begin() const
  319. {
  320. return getBegin();
  321. }
  322. /// Make it compatible with the C++11 range based for loop.
  323. ConstIterator end() const
  324. {
  325. return getEnd();
  326. }
  327. /// Get first element.
  328. ConstReference getFront() const
  329. {
  330. ANKI_ASSERT(!isEmpty());
  331. return m_data[0];
  332. }
  333. /// Get last element.
  334. ConstReference getBack() const
  335. {
  336. ANKI_ASSERT(!isEmpty());
  337. return m_data[m_size - 1];
  338. }
  339. /// Set the array pointer and its size.
  340. void setArray(Value* array, Size size)
  341. {
  342. ANKI_ASSERT((array && size > 0) || (array == nullptr && size == 0));
  343. m_data = array;
  344. m_size = size;
  345. }
  346. Size getSize() const
  347. {
  348. return m_size;
  349. }
  350. Bool isEmpty() const
  351. {
  352. return m_size == 0;
  353. }
  354. PtrSize getSizeInBytes() const
  355. {
  356. return m_size * sizeof(Value);
  357. }
  358. private:
  359. const Value* m_data;
  360. Size m_size;
  361. };
  362. /// @}
  363. } // end namespace anki