Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
4.1 KiB

  1. /**
  2. ** File : array.h
  3. ** Description: Array template declaration
  4. **/
  5. #ifndef Array_h
  6. #define Array_h
  7. #define ForIndex(i,n) for(int i=0; i<(n); ++i)
  8. #define EndFor
  9. // for PArray<T>, like Array<T>, T must have a public operator=()
  10. template<class T, int psize>
  11. class PArray {
  12. private:
  13. int size; // must come before a
  14. T* a;
  15. int n;
  16. T pa[psize];
  17. private:
  18. void resize(int nsize);
  19. void resize_aux(int ne);
  20. public:
  21. inline PArray(int ne=0)
  22. {
  23. if (ne <= psize)
  24. {
  25. size = psize;
  26. a = pa;
  27. }
  28. else
  29. {
  30. size = ne;
  31. a = new T[ne];
  32. }
  33. n=ne;
  34. }
  35. PArray<T,psize>& operator=(const PArray<T,psize>& ar);
  36. PArray(const PArray<T,psize>& ar);
  37. inline ~PArray() { if (size!=psize) delete[] a; }
  38. inline int num() const { return n; }
  39. inline void clearcompletely()
  40. {
  41. if (size != psize)
  42. {
  43. delete[] a;
  44. size = psize;
  45. a = pa;
  46. }
  47. n=0;
  48. }
  49. /*
  50. * allocate ne, CLEAR if too small
  51. */
  52. inline void init(int ne)
  53. {
  54. if (ne > size)
  55. {
  56. if (size!=psize) delete[] a;
  57. size=ne;
  58. a=new T[ne];
  59. }
  60. n=ne;
  61. }
  62. /*
  63. * allocate at least e+1, COPY if too small
  64. */
  65. inline void access(int e)
  66. {
  67. int ne=e+1;
  68. if (ne>size) resize_aux(ne);
  69. if (ne>n) n=ne;
  70. }
  71. /*
  72. * allocate ne, COPY if too small
  73. */
  74. inline void need(int ne)
  75. {
  76. if (ne>size) resize_aux(ne);
  77. n=ne;
  78. }
  79. /*
  80. * ret: previous num()
  81. */
  82. inline int add(int ne)
  83. {
  84. int cn=n; need(n+ne); return cn;
  85. }
  86. inline void sub(int ne)
  87. {
  88. n-=ne;
  89. }
  90. /*
  91. * do not use a+=a[..]!!
  92. * add() may allocate a[]!!
  93. */
  94. inline PArray<T,psize>& operator+=(const T& e)
  95. {
  96. int i=add(1);
  97. a[i]=e;
  98. return *this;
  99. }
  100. inline void squeeze() { if (n<size) resize(n); }
  101. inline operator const T*() const { return a; }
  102. inline operator T*() { return a; }
  103. inline const T& operator[](int i) const { ok(i); return a[i]; }
  104. inline T& operator[](int i) { ok(i); return a[i]; }
  105. inline const T& last() const { return operator[](n-1); }
  106. inline T& last() { return operator[](n-1); }
  107. #if 0
  108. inline void reverse()
  109. {
  110. for(int i=0; i<n/2; ++i)
  111. {
  112. swap(&a[i],&a[n-1-i]);
  113. }
  114. }
  115. #endif
  116. #ifdef __TIGHTER_ASSERTS
  117. inline void ok(int i) const { assertx(i>=0 && i<n); }
  118. #else
  119. inline void ok(int) const { }
  120. #endif
  121. int contains(const T& e) const;
  122. int index(const T& e) const;
  123. };
  124. // was 'const T&', but with 'Cut*', expanded to 'const Cut*&' (bad)
  125. #define ForPArray(A,T,V) ForIndex(zzz,(A).num()) T const& V=(A)[zzz];
  126. template<class T, int psize>
  127. PArray<T,psize>& PArray<T,psize>::operator=(const PArray<T,psize>& ar)
  128. {
  129. if (&ar==this) return *this;
  130. init(ar.num());
  131. ForIndex(i,n) { a[i]=ar[i]; } EndFor;
  132. return *this;
  133. }
  134. template<class T, int psize>
  135. PARRAY_INLINE
  136. PArray<T,psize>::PArray(const PArray<T,psize>& ar) : size(psize), a(pa), n(0)
  137. {
  138. *this=ar;
  139. }
  140. template<class T, int psize>
  141. void PArray<T,psize>::resize(int nsize)
  142. {
  143. T* na;
  144. if (nsize<=psize) {
  145. if (size==psize) return;
  146. na=pa;
  147. } else {
  148. na=new T[nsize];
  149. }
  150. ForIndex(i,n) { na[i]=a[i]; } EndFor;
  151. if (size!=psize) delete[] a;
  152. a=na;
  153. size=nsize<=psize?psize:nsize;
  154. }
  155. template<class T, int psize>
  156. void PArray<T,psize>::resize_aux(int ne)
  157. {
  158. resize(max(int(n*1.5f)+3,ne));
  159. }
  160. template<class T, int psize>
  161. PARRAY_INLINE
  162. int PArray<T,psize>::contains(const T& e) const
  163. {
  164. ForIndex(i,n) { if (a[i]==e) return 1; } EndFor;
  165. return 0;
  166. }
  167. template<class T, int psize>
  168. PARRAY_INLINE
  169. int PArray<T,psize>::index(const T& e) const
  170. {
  171. ForIndex(i,n) { if (a[i]==e) return i; } EndFor;
  172. assertnever(""); return 0;
  173. }
  174. #endif //Array_h