DynamicStackArray.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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_DYNAMICSTACKARRAY_CPP
  13. #define SE_INCL_DYNAMICSTACKARRAY_CPP
  14. #ifdef PRAGMA_ONCE
  15. #pragma once
  16. #endif
  17. #include <Engine/Templates/DynamicStackArray.h>
  18. #include <Engine/Templates/DynamicArray.cpp>
  19. /*
  20. * Default constructor.
  21. */
  22. template<class Type>
  23. inline CDynamicStackArray<Type>::CDynamicStackArray(void) : CDynamicArray<Type>() {
  24. da_ctUsed=0;
  25. da_ctAllocationStep = 256;
  26. // lock the array on construction
  27. CDynamicArray<Type>::Lock();
  28. }
  29. /*
  30. * Destructor.
  31. */
  32. template<class Type>
  33. inline CDynamicStackArray<Type>::~CDynamicStackArray(void) {
  34. // lock the array on destruction
  35. CDynamicArray<Type>::Unlock();
  36. };
  37. /* Destroy all objects, and reset the array to initial (empty) state. */
  38. template<class Type>
  39. inline void CDynamicStackArray<Type>::Clear(void) {
  40. CDynamicArray<Type>::Clear(); da_ctUsed = 0;
  41. }
  42. /*
  43. * Set how many elements to allocate when stack overflows.
  44. */
  45. template<class Type>
  46. inline void CDynamicStackArray<Type>::SetAllocationStep(INDEX ctStep)
  47. {
  48. ASSERT(ctStep>0);
  49. da_ctAllocationStep = ctStep;
  50. };
  51. /*
  52. * Add new object(s) on top of stack.
  53. */
  54. template<class Type>
  55. inline Type &CDynamicStackArray<Type>::Push(void) {
  56. // if there are no free elements in the array
  57. if (CDynamicArray<Type>::Count()-da_ctUsed<1) {
  58. // alocate a new block
  59. CDynamicArray<Type>::New(da_ctAllocationStep);
  60. }
  61. // get the new element
  62. da_ctUsed++;
  63. ASSERT(da_ctUsed <= CDynamicArray<Type>::Count());
  64. return CDynamicArray<Type>::operator[](da_ctUsed-1);
  65. }
  66. template<class Type>
  67. inline Type *CDynamicStackArray<Type>::Push(INDEX ct) {
  68. // if there are no free elements in the array
  69. while(CDynamicArray<Type>::Count()-da_ctUsed<ct) {
  70. // alocate a new block
  71. CDynamicArray<Type>::New(da_ctAllocationStep);
  72. }
  73. // get new elements
  74. da_ctUsed+=ct;
  75. ASSERT(da_ctUsed <= CDynamicArray<Type>::Count());
  76. return &CDynamicArray<Type>::operator[](da_ctUsed-ct);
  77. }
  78. /*
  79. * Remove all objects from stack, but keep stack space.
  80. */
  81. template<class Type>
  82. inline void CDynamicStackArray<Type>::PopAll(void) {
  83. // if there is only one block allocated
  84. if ( da_BlocksList.IsEmpty()
  85. || &da_BlocksList.Head()==&da_BlocksList.Tail()) {
  86. // just clear the counter
  87. da_ctUsed = 0;
  88. // if there is more than one block allocated
  89. } else {
  90. // remember how much was allocated, rounded up to allocation step
  91. INDEX ctUsedBefore = CDynamicArray<Type>::Count();
  92. // free all memory
  93. CDynamicArray<Type>::Clear();
  94. // allocate one big block
  95. CDynamicArray<Type>::New(ctUsedBefore);
  96. da_ctUsed = 0;
  97. }
  98. }
  99. /*
  100. * Random access operator.
  101. */
  102. template<class Type>
  103. inline Type &CDynamicStackArray<Type>::operator[](INDEX i) {
  104. ASSERT(this!=NULL);
  105. ASSERT(i<da_ctUsed); // check bounds
  106. return CDynamicArray<Type>::operator[](i);
  107. }
  108. template<class Type>
  109. inline const Type &CDynamicStackArray<Type>::operator[](INDEX i) const {
  110. ASSERT(this!=NULL);
  111. ASSERT(i<da_ctUsed); // check bounds
  112. return CDynamicArray<Type>::operator[](i);
  113. }
  114. /*
  115. * Get number of elements in array.
  116. */
  117. template<class Type>
  118. INDEX CDynamicStackArray<Type>::Count(void) const {
  119. ASSERT(this!=NULL);
  120. return da_ctUsed;
  121. }
  122. /*
  123. * Get index of a member from it's pointer
  124. */
  125. template<class Type>
  126. INDEX CDynamicStackArray<Type>::Index(Type *ptMember) {
  127. ASSERT(this!=NULL);
  128. INDEX i = CDynamicArray<Type>::Index(ptMember);
  129. ASSERTMSG(i<da_ctUsed, "CDynamicStackArray<>::Index(): Not a member of this array!");
  130. return i;
  131. }
  132. /*
  133. * Get array of pointers to elements (used for sorting elements by sorting pointers).
  134. */
  135. template<class Type>
  136. Type **CDynamicStackArray<Type>::GetArrayOfPointers(void)
  137. {
  138. return da_Pointers;
  139. }
  140. /*
  141. * Assignment operator.
  142. */
  143. template<class Type>
  144. CDynamicStackArray<Type> &CDynamicStackArray<Type>::operator=(CDynamicStackArray<Type> &arOriginal)
  145. {
  146. ASSERT(this!=NULL);
  147. ASSERT(&arOriginal!=NULL);
  148. ASSERT(this!=&arOriginal);
  149. // copy stack arrays
  150. CDynamicArray<Type>::operator=(arOriginal);
  151. // copy used count
  152. da_ctUsed = arOriginal.da_ctUsed;
  153. return *this;
  154. }
  155. #endif /* include-once check. */