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.

208 lines
5.6 KiB

  1. /**************************************************************************++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module name:
  4. cfgarray.h
  5. $Header: $
  6. Abstract:
  7. Author:
  8. marcelv 5/9/2001 12:28:08 Initial Release
  9. Revision History:
  10. --**************************************************************************/
  11. #ifndef __CFGARRAY_H__
  12. #define __CFGARRAY_H__
  13. #pragma once
  14. template <class T>
  15. class CCfgArray
  16. {
  17. public:
  18. CCfgArray () : m_aData(0), m_cElements(0), m_cSize(0) {}
  19. ~CCfgArray ()
  20. {
  21. delete [] m_aData;
  22. m_aData = 0;
  23. }
  24. ULONG Count () const
  25. {
  26. return m_cElements;
  27. }
  28. ULONG AllocSize () const
  29. {
  30. return m_cSize;
  31. }
  32. HRESULT SetAllocSize (ULONG i_iNewSize)
  33. {
  34. return AllocNewSize (i_NewSize);
  35. }
  36. HRESULT Append (const T& i_NewElement)
  37. {
  38. return InsertAt (i_NewElement, m_cElements);
  39. }
  40. HRESULT Prepend (const T& i_NewElement)
  41. {
  42. return InsertAt (i_NewElement, 0);
  43. }
  44. HRESULT InsertAt (const T& i_NewElement, ULONG i_idx)
  45. {
  46. HRESULT hr = S_OK;
  47. if (m_cElements==m_cSize)
  48. {
  49. hr = AllocNewSize (m_cSize==0?1:2*m_cSize);
  50. if (FAILED (hr))
  51. {
  52. return hr;
  53. }
  54. }
  55. // move the data in the array. Note that you cannot use
  56. // memmove, because when you have an array of objects that are
  57. // refcounted, you have to call the copy constructor, else you
  58. // get very weird behavior (program crash, etc).
  59. for (ULONG jdx = m_cElements; jdx > i_idx; --jdx)
  60. {
  61. m_aData[jdx] = m_aData[jdx-1];
  62. }
  63. m_aData[i_idx] = i_NewElement;
  64. m_cElements++;
  65. return hr;
  66. }
  67. T& operator[] (ULONG idx) const
  68. {
  69. return m_aData[idx];
  70. };
  71. //=================================================================================
  72. // The Iterator class is used to navigate through the elements in the linked list. Call
  73. // List::Begin to get an iterator pointing to the first element in the list, and call
  74. // Next to get the next element in the list. List::End can be used if we are at the end
  75. // of the list
  76. //=================================================================================
  77. class Iterator
  78. {
  79. private:
  80. void operator =(const Iterator&);
  81. friend class CCfgArray<T>;
  82. public:
  83. //=================================================================================
  84. // Function: Next
  85. //
  86. // Synopsis: get iterator to next element in the list
  87. //=================================================================================
  88. void Next () { m_curIdx++;}
  89. //=================================================================================
  90. // Function: Value
  91. //
  92. // Synopsis: Returns value of element that iterator points to
  93. //=================================================================================
  94. T& Value () const
  95. {
  96. return m_aData[m_curIdx];
  97. }
  98. bool operator== (const Iterator& rhs) const {return m_curIdx == rhs.m_curIdx;}
  99. bool operator!= (const Iterator& rhs) const {return m_curIdx != rhs.m_curIdx;}
  100. private:
  101. Iterator (const CCfgArray<T> * i_paData, ULONG iStart) : m_aData(*i_paData), m_curIdx (iStart) {} // only list can create these
  102. ULONG m_curIdx;
  103. const CCfgArray<T>& m_aData;
  104. };
  105. //=================================================================================
  106. // Function: Begin
  107. //
  108. // Synopsis: Returns an iterator to the beginning of the list
  109. //=================================================================================
  110. const Iterator Begin () const
  111. {
  112. return Iterator (this, 0);
  113. }
  114. //=================================================================================
  115. // Function: End
  116. //
  117. // Synopsis: Returns an iterator one past the end of the list (like STL does)
  118. //=================================================================================
  119. const Iterator End () const
  120. {
  121. return Iterator (this, m_cElements);
  122. }
  123. // returns index of place to insert element in sorted array
  124. ULONG BinarySearch (const T& i_ElemToSearch) const
  125. {
  126. ULONG iLow = 0;
  127. ULONG iHigh = m_cElements;
  128. while (iLow < iHigh)
  129. {
  130. // (low + high) / 2 might overflow
  131. ULONG iMid = iLow + (iHigh - iLow) / 2;
  132. if (m_aData[iMid] > i_ElemToSearch)
  133. {
  134. iHigh = iMid;
  135. }
  136. else
  137. {
  138. iLow = iMid + 1;
  139. }
  140. }
  141. return iLow;
  142. }
  143. private:
  144. HRESULT AllocNewSize (ULONG i_NewSize)
  145. {
  146. T * aNewData = new T [i_NewSize];
  147. if (aNewData == 0)
  148. {
  149. return E_OUTOFMEMORY;
  150. }
  151. // copy the data from the old array in the new array.
  152. // you have to use the copy constructor (and not memcpy), to avoid
  153. // all kind of weird errors. When you use memcpy, you are not updating
  154. // possible refcounts that are part of type T, and thus you get possible
  155. // crashes
  156. for (ULONG idx=0; idx < m_cSize; ++idx)
  157. {
  158. aNewData[idx] = m_aData[idx];
  159. }
  160. delete[] m_aData;
  161. m_aData = aNewData;
  162. m_cSize = i_NewSize;
  163. return S_OK;
  164. }
  165. // we don't allow copies
  166. CCfgArray (const CCfgArray<T>& );
  167. CCfgArray<T>& operator=(const CCfgArray<T>& );
  168. T * m_aData;
  169. ULONG m_cSize;
  170. ULONG m_cElements;
  171. };
  172. #endif