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.

250 lines
7.6 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 - 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: AutoArray.h
  6. * Content: CAutoArray / CAutoPtrArray Declarations
  7. *
  8. * History:
  9. * Date By Reason
  10. * ====== == ======
  11. * 12-12-2001 simonpow Created
  12. ***************************************************************************/
  13. #ifndef __AUTOARRAY_H__
  14. #define __AUTOARRAY_H__
  15. #include "dndbg.h"
  16. /*
  17. * CAutoArray class
  18. * Provides automatic memory management for an array. As elements
  19. * are added to it or moved within it the array will automatically
  20. * grow to hold them.
  21. * The growth policy is dictated by a size multiple value, with the
  22. * array size always being an exact multiple of a pre-defined value.
  23. * e.g. If the size multiple is set to 32 then possible array sizes
  24. * are 32, 64, 96, 128, etc.
  25. * In this scenario setting element 100 on array that is currently
  26. * only 32 elements big will cause the array to grow to 128 elemments.
  27. * i.e. The next largest multiple to hold the required value
  28. *
  29. * For arrays of pointers use the specialisation CAutoPtrArray
  30. * declared below CAutoArray
  31. */
  32. template <class T> class CAutoArray
  33. {
  34. public:
  35. //provide the type of entries stored in array
  36. typedef T Entry;
  37. /*
  38. * Construction and destruction
  39. */
  40. //array is by default zero size, and grows in multiples
  41. //of 16 elements at a time
  42. CAutoArray(DWORD dwSizeMultiple=16)
  43. {
  44. DNASSERT(dwSizeMultiple);
  45. m_dwSize=0;
  46. m_dwSizeMultiple=dwSizeMultiple;
  47. m_pData=(T * ) 0;
  48. };
  49. //delete array and data
  50. ~CAutoArray()
  51. {
  52. if (m_pData)
  53. delete[] m_pData;
  54. };
  55. /*
  56. * Memory management
  57. */
  58. //resets the array (deleting any allocated data)
  59. //ands set a new size multiple value.
  60. //Pass 0 for dwSizeMultiple to leave existing value unchanged
  61. void Reset(DWORD dwSizeMultiple=16)
  62. {
  63. if (dwSizeMultiple)
  64. m_dwSizeMultiple=dwSizeMultiple;
  65. m_dwSize=0;
  66. if (m_pData)
  67. {
  68. delete[] m_pData;
  69. m_pData=(T * ) NULL;
  70. }
  71. };
  72. //ensure the array has space for at least 'numElements'.
  73. //This is useful if you know your about to grow the array, as it
  74. //allows you to minimise the number of memory allocations
  75. //Returns FALSE is a memory allocation fails
  76. BOOL AllocAtLeast(DWORD dwNumElements)
  77. {
  78. if (dwNumElements>m_dwSize)
  79. return GrowToAtLeast(dwNumElements-1);
  80. return TRUE;
  81. }
  82. //returns number of bytes currently allocated to array
  83. //This will always be a multiple of 'dwSizeMultiple' passed to
  84. //constructor or Reset method
  85. DWORD GetCurrentSize()
  86. { return m_dwSize; };
  87. /*
  88. * Moving elements
  89. */
  90. //move the block of 'dwNum' elements starting at 'dwIndex' to the
  91. //'dwNewIndex'. The new location can be either beyond or before
  92. //the current index. The array will be grown automatically if needed
  93. //If 'bCopySemantics' is FALSE then the data in the source block location (dwIndex to
  94. //dwIndex+dwNumElements) will be left undefined. Otherwise it'll be preserved in
  95. //its original form (except where/if its overwritten by the destination block).
  96. //Returns FALSE is a memory allocation fails
  97. BOOL MoveElements(DWORD dwIndex, DWORD dwNumElements, DWORD dwNewIndex, BOOL bCopySemantics);
  98. /*
  99. * Setting elements
  100. */
  101. //set a block of 'dwNumElem' elements starting at 'dwIndex' to the
  102. //values provided in 'pElemData'. If any of the locations set are
  103. //beyond the current array size the array will be automatically
  104. //grown. Returns FALSE is a memory allocation fails
  105. BOOL SetElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem);
  106. //set the single element at 'dwIndex' to value 'data'
  107. //array will automatically grow if necessary
  108. //Returns FALSE is a memory allocation fails
  109. BOOL SetElement(DWORD dwIndex, const T& elem)
  110. {
  111. if (dwIndex>=m_dwSize && GrowToAtLeast(dwIndex)==FALSE)
  112. return FALSE;
  113. m_pData[dwIndex]=elem;
  114. return TRUE;
  115. };
  116. //set the value of an existing element. This doesn't try to
  117. //grow array so its up to the caller to ensure dwIndex is in range
  118. void SetExistingElement(DWORD dwIndex, const T& elem)
  119. { DNASSERT(dwIndex<m_dwSize); m_pData[dwIndex]=elem; };
  120. //set the values of 'dwNumElem' elements to 'pElemData' starting
  121. //from 'dwIndex. This doesn't check if array needs to grow so
  122. //its left to caller to ensure dwIndex and dwNumElem are in range
  123. void SetExistingElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem);
  124. /*
  125. * Getting Elements
  126. * Upto the caller to ensure that index's passed in are in range
  127. * Array isn't grown just so we can return garbage!
  128. * Also note that a pointer/reference into the array can only
  129. * be taken temporarily. Setting/moving elements may cause the
  130. * array to be reallocated and hence invalidate the pointer/references
  131. */
  132. //return value of an element
  133. T GetElementValue(DWORD dwIndex) const
  134. { DNASSERT(dwIndex<m_dwSize); return m_pData[dwIndex]; };
  135. //return a reference to an element
  136. T& GetElementRef(DWORD dwIndex)
  137. { DNASSERT(dwIndex<m_dwSize); return m_pData[dwIndex]; };
  138. //return a constant reference to an element
  139. const T& GetElementRef(DWORD dwIndex) const
  140. { DNASSERT(dwIndex<m_dwSize); return m_pData[dwIndex]; };
  141. //return a pointer to an element
  142. T * GetElementPtr(DWORD dwIndex)
  143. { DNASSERT(dwIndex<m_dwSize); return m_pData+dwIndex; };
  144. //returns pointer to array of all elements
  145. T * GetAllElements()
  146. { return m_pData; };
  147. protected:
  148. //make array large so 'dwIndex' falls within its range
  149. //N.B. Caller must have tested that dwIndex>=m_dwSize already!
  150. BOOL GrowToAtLeast(DWORD dwIndex);
  151. //return the size of array needed to hold index, based on current size multiple
  152. DWORD GetArraySize(DWORD dwIndex)
  153. { return ((dwIndex/m_dwSizeMultiple)+1)*m_dwSizeMultiple; };
  154. //array of data
  155. T * m_pData;
  156. //size of the array of data
  157. DWORD m_dwSize;
  158. //multiple for size
  159. DWORD m_dwSizeMultiple;
  160. };
  161. /*
  162. * Specialisation of CAutoArray designed for handling pointers.
  163. * Whatever the type of pointer stored, this class will always
  164. * use a CAutoArray<void*> underneath, hence ensuring the same
  165. * code is reused between all CAutoPtrArray types
  166. */
  167. template <class T> class CAutoPtrArray : public CAutoArray<void *>
  168. {
  169. public:
  170. typedef T Entry;
  171. typedef CAutoArray<void *> Base;
  172. CAutoPtrArray(DWORD dwSizeMultiple=16) : CAutoArray<void * >(dwSizeMultiple)
  173. {};
  174. BOOL SetElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem)
  175. { return Base::SetElements(dwIndex, (void **) pElemData, dwNumElem); };
  176. BOOL SetElement(DWORD dwIndex, T elem)
  177. { return Base::SetElement(dwIndex, elem); };
  178. void SetExistingElement(DWORD dwIndex, T elem)
  179. { DNASSERT(dwIndex<m_dwSize); m_pData[dwIndex]=(void * ) elem; };
  180. void SetExistingElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem)
  181. { return Base::SetExistingElements(dwIndex, (void **) pElemData, dwNumElem); };
  182. T GetElementValue(DWORD dwIndex) const
  183. { DNASSERT(dwIndex<m_dwSize); return (T) m_pData[dwIndex]; };
  184. T& GetElementRef(DWORD dwIndex)
  185. { DNASSERT(dwIndex<m_dwSize); return (T&) m_pData[dwIndex]; };
  186. const T& GetElementRef(DWORD dwIndex) const
  187. { DNASSERT(dwIndex<m_dwSize); return (const T&) m_pData[dwIndex]; };
  188. T * GetElementPtr(DWORD dwIndex)
  189. { DNASSERT(dwIndex<m_dwSize); return (T* ) m_pData+dwIndex; };
  190. T * GetAllElements()
  191. { return (T* ) m_pData; };
  192. };
  193. /*
  194. * If not building with explicit template instantiation then
  195. * include all methods for CAutoArray
  196. */
  197. #ifndef DPNBUILD_EXPLICIT_TEMPLATES
  198. #include "AutoArray.inl"
  199. #endif
  200. #endif