StaticArray.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #ifndef SE_INCL_STATICARRAY_CPP
  13. #define SE_INCL_STATICARRAY_CPP
  14. #ifdef PRAGMA_ONCE
  15. #pragma once
  16. #endif
  17. #define FOREACHINSTATICARRAY(array, type, iter) \
  18. for(CStaticArrayIterator<type> iter(array); !iter.IsPastEnd(); iter.MoveToNext() )
  19. #include <Engine/Base/Console.h>
  20. #include <Engine/Templates/StaticArray.h>
  21. /*
  22. * Default constructor.
  23. */
  24. template<class Type>
  25. inline CStaticArray<Type>::CStaticArray(void) {
  26. sa_Count=0;
  27. sa_Array=NULL;
  28. }
  29. /*
  30. * Destructor.
  31. */
  32. template<class Type>
  33. inline CStaticArray<Type>::~CStaticArray(void) {
  34. // if some objects were allocated
  35. if (sa_Count!=0) {
  36. // destroy them
  37. Delete();
  38. }
  39. };
  40. /* Random access operator. */
  41. template<class Type>
  42. inline void CStaticArray<Type>::operator=(const CStaticArray<Type> &arOriginal) {
  43. CopyArray(arOriginal);
  44. }
  45. template<class Type>
  46. /* Destroy all objects, and reset the array to initial (empty) state. */
  47. inline void CStaticArray<Type>::Clear(void) {
  48. if (sa_Count!=0) Delete();
  49. }
  50. /*
  51. * Create a given number of objects.
  52. */
  53. template<class Type>
  54. inline void CStaticArray<Type>::New(INDEX iCount) {
  55. ASSERT(this!=NULL && iCount>=0);
  56. // if no new members are needed in fact
  57. if (iCount==0) {
  58. // do nothing
  59. return;
  60. }
  61. //ASSERT(sa_Count==0 && sa_Array==NULL);
  62. #ifndef NDEBUG
  63. if(!(sa_Count==0 && sa_Array==NULL)) {
  64. if(sa_Array == NULL) {
  65. CPrintF("CStaticArray array not set!\n");
  66. } else {
  67. CPrintF("CStaticArray new(%d) called while already holding %d elements!\n", iCount, sa_Count);
  68. }
  69. }
  70. #endif
  71. sa_Count = iCount;
  72. sa_Array = new Type[iCount+1]; //(+1 for cache-prefetch opt)
  73. };
  74. /* Expand stack size but keep old objects. */
  75. template<class Type>
  76. inline void CStaticArray<Type>::Expand(INDEX iNewCount)
  77. {
  78. ASSERT(this!=NULL && iNewCount>sa_Count);
  79. // if not already allocated
  80. if (sa_Count==0) {
  81. // just allocate
  82. New(iNewCount);
  83. return;
  84. // if already allocated
  85. } else {
  86. ASSERT(sa_Count!=0 && sa_Array!=NULL);
  87. // allocate new array with more space
  88. Type *ptNewArray = new Type[iNewCount+1]; //(+1 for cache-prefetch opt)
  89. // copy old objects
  90. for (INDEX iOld=0; iOld<sa_Count; iOld++) {
  91. ptNewArray[iOld] = sa_Array[iOld];
  92. }
  93. // free old array
  94. delete[] sa_Array;
  95. // remember the new array
  96. sa_Count = iNewCount;
  97. sa_Array = ptNewArray;
  98. }
  99. }
  100. /*
  101. * Destroy all objects.
  102. */
  103. template<class Type>
  104. inline void CStaticArray<Type>::Delete(void) {
  105. ASSERT(this!=NULL);
  106. ASSERT(sa_Count!=0 && sa_Array!=NULL);
  107. delete[] sa_Array;
  108. sa_Count = 0;
  109. sa_Array = NULL;
  110. }
  111. /*
  112. * Random access operator.
  113. */
  114. template<class Type>
  115. inline Type &CStaticArray<Type>::operator[](INDEX i) {
  116. ASSERT(this!=NULL);
  117. ASSERT(i>=0 && i<sa_Count); // check bounds
  118. return sa_Array[i];
  119. }
  120. template<class Type>
  121. inline const Type &CStaticArray<Type>::operator[](INDEX i) const {
  122. ASSERT(this!=NULL);
  123. ASSERT(i>=0 && i<sa_Count); // check bounds
  124. return sa_Array[i];
  125. }
  126. /*
  127. * Get number of elements in array.
  128. */
  129. template<class Type>
  130. INDEX CStaticArray<Type>::Count(void) const {
  131. ASSERT(this!=NULL);
  132. return sa_Count;
  133. }
  134. /*
  135. * Get index of a member from it's pointer
  136. */
  137. template<class Type>
  138. INDEX CStaticArray<Type>::Index(Type *ptMember) {
  139. ASSERT(this!=NULL);
  140. INDEX i = ptMember-sa_Array;
  141. ASSERT(i>=0 && i<sa_Count);
  142. return i;
  143. }
  144. /*
  145. * Assignment operator.
  146. */
  147. template<class Type>
  148. /* Copy all elements of another array into this one. */
  149. void CStaticArray<Type>::CopyArray(const CStaticArray<Type> &arOriginal)
  150. {
  151. ASSERT(this!=NULL);
  152. ASSERT(&arOriginal!=NULL);
  153. ASSERT(this!=&arOriginal);
  154. // clear previous contents
  155. Clear();
  156. // get count of elements in original array
  157. INDEX ctOriginal = arOriginal.Count();
  158. // if the other array has no elements
  159. if (ctOriginal ==0) {
  160. return;
  161. }
  162. // create that much elements
  163. New(ctOriginal);
  164. // copy them all
  165. for (INDEX iNew=0; iNew<ctOriginal; iNew++) {
  166. sa_Array[iNew] = arOriginal[iNew];
  167. }
  168. }
  169. /* Move all elements of another array into this one. */
  170. template<class Type>
  171. void CStaticArray<Type>::MoveArray(CStaticArray<Type> &arOther)
  172. {
  173. ASSERT(this!=NULL);
  174. ASSERT(&arOther!=NULL);
  175. ASSERT(this!=&arOther);
  176. // clear previous contents
  177. Clear();
  178. // if the other array has no elements
  179. if (arOther.Count()==0) {
  180. // no assignment
  181. return;
  182. }
  183. // move data from the other array into this one and clear the other one
  184. sa_Count = arOther.sa_Count;
  185. sa_Array = arOther.sa_Array;
  186. arOther.sa_Count = 0;
  187. arOther.sa_Array = NULL;
  188. }
  189. /////////////////////////////////////////////////////////////////////
  190. // CStaticArrayIterator
  191. /*
  192. * Template class for iterating static array.
  193. */
  194. template<class Type>
  195. class CStaticArrayIterator {
  196. private:
  197. INDEX sai_Index; // index of current element
  198. CStaticArray<Type> &sai_Array; // reference to array
  199. public:
  200. /* Constructor for given array. */
  201. inline CStaticArrayIterator(CStaticArray<Type> &sa);
  202. /* Destructor. */
  203. inline ~CStaticArrayIterator(void);
  204. /* Move to next object. */
  205. inline void MoveToNext(void);
  206. /* Check if finished. */
  207. inline BOOL IsPastEnd(void);
  208. /* Get current element. */
  209. Type &Current(void) { return sai_Array[sai_Index]; }
  210. Type &operator*(void) { return sai_Array[sai_Index]; }
  211. operator Type *(void) { return &sai_Array[sai_Index]; }
  212. Type *operator->(void) { return &sai_Array[sai_Index]; }
  213. };
  214. /*
  215. * Constructor for given array.
  216. */
  217. template<class Type>
  218. inline CStaticArrayIterator<Type>::CStaticArrayIterator(CStaticArray<Type> &sa) : sai_Array(sa) {
  219. sai_Index = 0;
  220. }
  221. /*
  222. * Destructor.
  223. */
  224. template<class Type>
  225. inline CStaticArrayIterator<Type>::~CStaticArrayIterator(void) {
  226. sai_Index = -1;
  227. }
  228. /*
  229. * Move to next object.
  230. */
  231. template<class Type>
  232. inline void CStaticArrayIterator<Type>::MoveToNext(void) {
  233. ASSERT(this!=NULL);
  234. sai_Index++;
  235. }
  236. /*
  237. * Check if finished.
  238. */
  239. template<class Type>
  240. inline BOOL CStaticArrayIterator<Type>::IsPastEnd(void) {
  241. ASSERT(this!=NULL);
  242. return sai_Index>=sai_Array.sa_Count;
  243. }
  244. #endif /* include-once check. */