WeakArray.h 6.9 KB

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