WeakArray.h 7.4 KB

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