Leaked source code of windows server 2003
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.

335 lines
11 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 - 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: OrderedArray.h
  6. * Content: COrderedArray / COrderedPtrArray Declarations
  7. *
  8. * History:
  9. * Date By Reason
  10. * ====== == ======
  11. * 12-12-2001 simonpow Created
  12. ***************************************************************************/
  13. #ifndef __ORDEREDARRAY_H__
  14. #define __ORDEREDARRAY_H__
  15. #include "AutoArray.h"
  16. /*
  17. * COrderedArray
  18. * Maintains an array of elements that can be inserted into and removed
  19. * from whilst maintaining element order. i.e. List like semantics
  20. * This class is useful when you want to maintain a list of items in
  21. * order and scan the data far more often than you modify the list.
  22. * If you perform lots of insert/remove operations, then a linked
  23. * list is probably more efficient.
  24. * Memory management is handled through CAutoArray so see comments
  25. * in that header for more information
  26. *
  27. * If you need an array of pointers use the specialisation COrderedPtrArray
  28. * declared below the COrderedArray class.
  29. */
  30. template <class T > class COrderedArray
  31. {
  32. public:
  33. //provides the type of entries held
  34. typedef T Entry;
  35. //array starts 0 zero and by default grows in multiples
  36. //of 16 elements at a time
  37. COrderedArray(DWORD dwSizeMultiple=16) : m_data(dwSizeMultiple), m_dwTopFreeSlot(0)
  38. { };
  39. //standard d'tor
  40. ~COrderedArray()
  41. {};
  42. /*
  43. * Memory Management
  44. */
  45. //Delete existing contents and reset the size multiplier
  46. //Pass 0 for size multiplier to retain the existing value
  47. void Reset(DWORD dwSizeMultiple=16)
  48. { m_data.Reset(dwSizeMultiple); m_dwTopFreeSlot=0; };
  49. //ensure that there is enough space in the array to hold at least
  50. //'numElements' without needing to re-create and copy the data
  51. //returns FALSE if fails due to memory allocation failure
  52. BOOL AllocAtLeast(DWORD dwNumElements)
  53. { return m_data.AllocAtLeast(dwNumElements); };
  54. //ensure there is enough space in the array to hold at least an
  55. //extra 'numElements' without needing to re-create and copy the data
  56. //returns FALSE if fails due to memory allocation failure
  57. BOOL AllocExtra(DWORD dwNumElements)
  58. { return m_data.AllocAtLeast(dwNumElements+m_dwTopFreeSlot); };
  59. /*
  60. * Adding/Modifying Elements
  61. */
  62. //add an entry to end of array
  63. //returns FALSE if fails due to memory allocation failure
  64. BOOL AddElement(const T& elem)
  65. { return m_data.SetElement(m_dwTopFreeSlot++, elem); };
  66. //add a number of elements to the end of the array
  67. //N.B. Don't pass pointers into data in this array as 'pElem'!
  68. //e.g. Don't do array.AddElements(array.GetAllElements, array.GetNumElements());
  69. //returns FALSE if fails due to memory allocation failure
  70. BOOL AddElements(const T * pElem, DWORD dwNumElem);
  71. //add the entries from another ordered array to the end of this one
  72. //N.B. Don't pass array to itself (e.g. Don't do array.AddElements(array); )
  73. //returns FALSE if fails due to memory allocation failure
  74. BOOL AddElements(const COrderedArray<T>& array);
  75. //set the element at 'dwIndex' to 'elem. Upto caller to
  76. //ensure this doesn't create a hole in array (i.e. dwIndex must be<=Num Entries)
  77. //returns FALSE if fails due to memory allocation failure
  78. inline BOOL SetElement(DWORD dwIndex, const T& elem);
  79. //set 'dwNumElem' from 'dwIndex' to values specified by 'pElem'
  80. //Upto caller to ensure this doesn't create a hole in array
  81. //(i.e. dwIndex must be<=Num Entries)
  82. //N.B. Don't pass pointers into data in this array as 'pElem'!
  83. //e.g. Don't do array.SetElements(x, array.GetAllElements, array.GetNumElements());
  84. //returns FALSE if fails due to memory allocation failure
  85. inline BOOL SetElements(DWORD dwIndex, const T * pElem, DWORD dwNumElem);
  86. //insert element 'elem' at index 'dwIndex, shifting up
  87. //elements after 'dwIndex' if necessary
  88. //Upto caller to ensure this doesn't create a hole in the array
  89. //i.e. dwIndex is within the current range
  90. //returns FALSE if fails due to memory allocation failure
  91. BOOL InsertElement(DWORD dwIndex, const T& elem);
  92. //insert 'dwNumElem' elements pointed to be 'pElems' into array
  93. //at index 'dwIndex', shifting up any existing elements if necessary
  94. //Upto caller to ensure this doesn't create a hole in the array
  95. //i.e. dwIndex is within the current range
  96. //N.B. Don't pass pointers into data in this array as 'pElem'!
  97. //e.g. Don't do array.InsertElements(x, array.GetAllElements, array.GetNumElements());
  98. //returns FALSE if fails due to memory allocation failure
  99. BOOL InsertElements(DWORD dwIndex, const T * pElems, DWORD dwNumElem);
  100. /*
  101. * Removing Entries
  102. */
  103. //remove the single entry at 'dwIndex', shifting all the entries
  104. //between 'index'+1 and the last entry down by one.
  105. //Upto caller to ensure dwIndex falls within the current array range
  106. inline void RemoveElementByIndex(DWORD dwIndex);
  107. //remove a block of 'dwNumElem' elements starting at 'dwIndex', moving
  108. //down all entries between 'index'+1 and the last entry by 'dwNumElem'.
  109. //Upto caller to ensure specified block falls within the current array range
  110. inline void RemoveElementsByIndex(DWORD dwIndex, DWORD dwNumElem);
  111. //remove first entry in array that matches 'elem'
  112. //returns TRUE if a match is found and FALSE otherwise
  113. BOOL RemoveElementByValue(const T& elem);
  114. //remove all the current entries in the array
  115. void RemoveAll()
  116. { m_dwTopFreeSlot=0; };
  117. /*
  118. * Accessing the array data
  119. * N.B. Treat any pointers into array contents very carefully.
  120. * Adding new elements to the array or using the Alloc* methods
  121. * can cause them to become invalid
  122. */
  123. //returns the number of entries
  124. DWORD GetNumElements() const
  125. { return m_dwTopFreeSlot; };
  126. //returns TRUE if array is empty
  127. BOOL IsEmpty() const
  128. { return (m_dwTopFreeSlot==0); };
  129. //return value at a specific index
  130. T GetElementValue(DWORD dwIndex) const
  131. { return m_data.GetElementValue(dwIndex); };
  132. //return reference to an element at specific index
  133. T& GetElementRef(DWORD dwIndex)
  134. { return m_data.GetElementRef(dwIndex); };
  135. //return constant reference to an element at specific index
  136. const T& GetElementRef(DWORD dwIndex) const
  137. { return m_data.GetElementRef(dwIndex); };
  138. //return a pointer to an element
  139. T * GetElementPtr(DWORD dwIndex)
  140. { return m_data.GetElementPtr(dwIndex); };
  141. //returns pointer to array of all elements
  142. T * GetAllElements()
  143. { return m_data.GetAllElements(); };
  144. /*
  145. * Searching Array
  146. */
  147. //find an instance of 'elem' in array. If found returns TRUE
  148. //and sets 'pdwIndex' to index of element
  149. BOOL FindElement(const T& elem, DWORD * pdwIndex) const;
  150. //returns TRUE if 'elem' is present in bag
  151. BOOL IsElementPresent(const T& elem) const
  152. { DWORD dwIndex; return (FindElement(elem, &dwIndex)); };
  153. protected:
  154. CAutoArray<T> m_data;
  155. DWORD m_dwTopFreeSlot;
  156. };
  157. /*
  158. * Specialisation of COrderedArray for handling pointers
  159. * If you ever need to declare an ordered array of pointers (e.g. char *)
  160. * declare it as an COrderedPtrArray (e.g. COrderedPtrArray<char *>).
  161. * This specilisation uses a COrderedArray<void *> underneath and hence
  162. * re-uses the same code between all types of COrderedPtrArray.
  163. */
  164. template <class T> class COrderedPtrArray : public COrderedArray<void * >
  165. {
  166. public:
  167. typedef T Entry;
  168. typedef COrderedArray<void * > Base;
  169. COrderedPtrArray(DWORD dwSizeMultiple=16) : COrderedArray<void*>(dwSizeMultiple)
  170. { };
  171. BOOL AddElement(T elem)
  172. { return Base::AddElement((void * ) elem); };
  173. BOOL AddElements(const T * pElem, DWORD dwNumElem)
  174. { return Base::AddElements((void **) pElem, dwNumElem); };
  175. BOOL AddElements(const COrderedArray<T>& array)
  176. { return Base::AddElements((COrderedArray<void*>&) array); };
  177. BOOL SetElement(DWORD dwIndex, T elem)
  178. { return Base::SetElement(dwIndex, (void * ) elem); };
  179. BOOL SetElements(DWORD dwIndex, T * pElem, DWORD dwNumElem)
  180. { return Base::SetElements(dwIndex, (void**) pElem, dwNumElem); };
  181. BOOL InsertElement(DWORD dwIndex, T elem)
  182. { return Base::InsertElement(dwIndex, (void * ) elem); };
  183. BOOL InsertElements(DWORD dwIndex, const T * pElems, DWORD dwNumElem)
  184. { return Base::InsertElements(dwIndex, (void **) pElems, dwNumElem); };
  185. BOOL RemoveElementByValue(T elem)
  186. { return Base::RemoveElementByValue((void *) elem); };
  187. T GetElementValue(DWORD dwIndex) const
  188. { return (T) m_data.GetElementValue(dwIndex); };
  189. T& GetElementRef(DWORD dwIndex)
  190. { return (T&) m_data.GetElementRef(dwIndex); };
  191. const T& GetElementRef(DWORD dwIndex) const
  192. { return (const T&) m_data.GetElementRef(dwIndex); };
  193. T * GetElementPtr(DWORD dwIndex)
  194. { return (T*) m_data.GetElementPtr(dwIndex); };
  195. T * GetAllElements()
  196. { return (T*) m_data.GetAllElements(); };
  197. BOOL FindElement(T elem, DWORD * pdwIndex) const
  198. { return Base::FindElement((void * ) elem, pdwIndex); };
  199. BOOL IsElementPresent(T elem) const
  200. { DWORD dwIndex; return (Base::FindElement((void * ) elem, &dwIndex)); };
  201. };
  202. /*
  203. * COrderedArray inline methods
  204. */
  205. template <class T>
  206. BOOL COrderedArray<T>::AddElements(const T * pElem, DWORD dwNumElem)
  207. {
  208. //ensure pointer passed isn't into this arrays contents
  209. DNASSERT(!(pElem>=m_data.GetAllElements() && pElem<m_data.GetAllElements()+m_data.GetCurrentSize()));
  210. if (!m_data.AllocAtLeast(m_dwTopFreeSlot+dwNumElem))
  211. return FALSE;
  212. m_data.SetExistingElements(m_dwTopFreeSlot, pElem, dwNumElem);
  213. m_dwTopFreeSlot+=dwNumElem;
  214. return TRUE;
  215. }
  216. template <class T>
  217. BOOL COrderedArray<T>::SetElement(DWORD dwIndex, const T& elem)
  218. {
  219. DNASSERT(dwIndex<=m_dwTopFreeSlot);
  220. if (dwIndex==m_dwTopFreeSlot)
  221. return m_data.SetElement(m_dwTopFreeSlot++, elem);
  222. m_data.SetExistingElement(dwIndex, elem);
  223. return TRUE;
  224. }
  225. template <class T>
  226. BOOL COrderedArray<T>::SetElements(DWORD dwIndex, const T * pElem, DWORD dwNumElem)
  227. {
  228. //ensure pointer passed isn't into this arrays contents
  229. DNASSERT(!(pElem>=m_data.GetAllElements() && pElem<m_data.GetAllElements()+m_data.GetCurrentSize()));
  230. //ensure hole isn't created
  231. DNASSERT(dwIndex<=m_dwTopFreeSlot);
  232. if (!m_data.SetElements(dwIndex, pElem, dwNumElem))
  233. return FALSE;
  234. dwIndex+=dwNumElem;
  235. m_dwTopFreeSlot = dwIndex>m_dwTopFreeSlot ? dwIndex : m_dwTopFreeSlot;
  236. return TRUE;
  237. }
  238. template <class T>
  239. void COrderedArray<T>::RemoveElementByIndex(DWORD dwIndex)
  240. {
  241. DNASSERT(dwIndex<m_dwTopFreeSlot);
  242. m_data.MoveElements(dwIndex+1, m_dwTopFreeSlot-dwIndex-1, dwIndex, FALSE);
  243. m_dwTopFreeSlot--;
  244. };
  245. template <class T>
  246. void COrderedArray<T>::RemoveElementsByIndex(DWORD dwIndex, DWORD dwNumElem)
  247. {
  248. DNASSERT(dwIndex+dwNumElem<=m_dwTopFreeSlot);
  249. m_data.MoveElements(dwIndex+dwNumElem, m_dwTopFreeSlot-dwIndex-dwNumElem, dwIndex, FALSE);
  250. m_dwTopFreeSlot-=dwNumElem;
  251. }
  252. /*
  253. * If not building with explicit template instantiation then also
  254. * include all other methods for COrderedArray
  255. */
  256. #ifndef DPNBUILD_EXPLICIT_TEMPLATES
  257. #include "OrderedArray.inl"
  258. #endif
  259. #endif //#ifndef __ORDEREDARRAY_H__