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.

190 lines
5.0 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation. All Rights Reserved.
  2. #ifndef _INC_ARRAY_TEMPLATE
  3. //If the Version 3 catalog standard library has been included then use its
  4. //memory allocation definations as these types include the correct error
  5. //handling.
  6. #define LOCALMALLOC(size) V3_calloc(1, size)
  7. #define LOCALREALLOC(memblock, size) V3_realloc(memblock, size)
  8. #define LOCALFREE(p) V3_free(p)
  9. /*
  10. * Variable Array Template
  11. *
  12. * This header defines a variable element array. This allows run time arrays
  13. * of any size to be used with having to worry about managing the internal
  14. * memory.
  15. *
  16. * For example:
  17. *
  18. * To use an array of longs declair Varray<long> x;
  19. *
  20. * You can then say x[50] = 5L; and the array will size itself to provide space for at least
  21. * 50 longs.
  22. *
  23. * You can also specify an initial size in the constructor. So to create a variable array of
  24. * class type Cfoo with an initial size of 50 you would declair Varray<Cfoo> x(50);
  25. *
  26. * To access the array simply use the array symbols in the first example you would write
  27. * long ll = x[5]; to get the sixth element.
  28. *
  29. * Note: The array is 0 based.
  30. *
  31. * Also when memory for the template's internal storage is allocted it is not initialize in
  32. * any manner. This means that a classes constructor is not called. It is the responsibility
  33. * of the caller to have any classes that are placed into the array to already be initialized.
  34. *
  35. */
  36. template <class TYPE> class Varray
  37. {
  38. public:
  39. Varray(int iInitialSize = 1);
  40. ~Varray<TYPE>();
  41. inline TYPE &operator[]( int index );
  42. inline TYPE &Insert(int insertAt, int iElements);
  43. inline int SIZEOF(void);
  44. inline int LastUsed(void);
  45. //inline TYPE *operator &(); Note: To pass a pointer to the beginning
  46. //of the array simply use &array[0].
  47. private:
  48. TYPE *m_pArray;
  49. int m_iMaxArray;
  50. int m_iMinAllocSize;
  51. int m_iLastUsedArray;
  52. };
  53. /*
  54. * Varray class constructor
  55. *
  56. * Constructs a dynamic size class array of the specified type.
  57. *
  58. * The array is initialized to have space for 1 element.
  59. *
  60. */
  61. template <class TYPE> Varray<TYPE>::Varray(int iInitialSize)
  62. {
  63. if ( iInitialSize <= 0 )
  64. iInitialSize = 1;
  65. m_pArray = (TYPE *)LOCALMALLOC(iInitialSize * sizeof(TYPE));
  66. m_iMaxArray = 1;
  67. m_iMinAllocSize = 1;
  68. m_iLastUsedArray = -1;
  69. }
  70. /*
  71. * Varray class destructor
  72. *
  73. * frees up the space used by a Varray
  74. *
  75. */
  76. template <class TYPE>Varray<TYPE>::~Varray()
  77. {
  78. if ( m_pArray )
  79. LOCALFREE( m_pArray );
  80. m_iMaxArray = 0;
  81. m_iMinAllocSize = 1;
  82. }
  83. /*
  84. * Varray operator [] handler
  85. *
  86. * Allows one to access the elements of a Varray. The array is resized
  87. * as necessary to accomidate the number of elements needed.
  88. *
  89. *
  90. * There are three cases that need to be handled by the allocation scheme.
  91. * Sequential allocation this is where the caller is initializing an array
  92. * in a sequential manner. We want to keep new requests to the memory
  93. * allocator to a mimimum. Two is where the client asks for an array element
  94. * far outside the currently allocated block size. Three when the client is
  95. * using an element that is allready allocated.
  96. *
  97. * This class's solution is to keep a block size count and double it. This
  98. * keeps going up to a fixed size limit. The allocation occurs every time
  99. * a new array allocation is required.
  100. */
  101. template <class TYPE> inline TYPE &Varray<TYPE>::operator[]( int index )
  102. {
  103. int iCurrentSize;
  104. int nextAllocSize;
  105. if ( index >= m_iMaxArray )
  106. {
  107. nextAllocSize = m_iMinAllocSize;
  108. if ( nextAllocSize < 512 )
  109. nextAllocSize = m_iMinAllocSize * 2;
  110. iCurrentSize = m_iMaxArray;
  111. if ( index - m_iMaxArray >= nextAllocSize )
  112. m_iMaxArray = index + 1;
  113. else
  114. {
  115. m_iMaxArray = m_iMaxArray + nextAllocSize;
  116. m_iMinAllocSize = nextAllocSize;
  117. }
  118. m_pArray = (TYPE *)LOCALREALLOC(m_pArray, m_iMaxArray * sizeof(TYPE));
  119. //clear out new cells
  120. memset(m_pArray+iCurrentSize, 0, (m_iMaxArray-iCurrentSize) * sizeof(TYPE));
  121. }
  122. if ( index > m_iLastUsedArray )
  123. m_iLastUsedArray = index;
  124. return (*((TYPE*) &m_pArray[index]));
  125. }
  126. template <class TYPE> inline TYPE &Varray<TYPE>::Insert(int insertAt, int iElements)
  127. {
  128. int i;
  129. int iCurrentSize;
  130. iCurrentSize = m_iMaxArray;
  131. m_iMaxArray += iElements+1;
  132. m_pArray = (TYPE *)LOCALREALLOC(m_pArray, m_iMaxArray * sizeof(TYPE));
  133. for(i=iCurrentSize; i>=insertAt; i--)
  134. memcpy(&m_pArray[i+iElements], &m_pArray[i], sizeof(TYPE));
  135. //clear out new cells
  136. memset(m_pArray+insertAt, 0, iElements * sizeof(TYPE));
  137. return (*((TYPE*) &m_pArray[insertAt]));
  138. }
  139. /*
  140. * Varray SIZEOF method
  141. *
  142. * The SIZEOF method returns the currently allocated size of the
  143. * internal array.
  144. */
  145. template <class TYPE> inline int Varray<TYPE>::SIZEOF(void)
  146. {
  147. return m_iMaxArray;
  148. }
  149. //Note: This method will be invalid after elements are inserted into the
  150. //varray. So use with caution.
  151. template <class TYPE> inline int Varray<TYPE>::LastUsed(void)
  152. {
  153. return m_iLastUsedArray;
  154. }
  155. #define _INC_ARRAY_TEMPLATE
  156. #endif