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.

186 lines
3.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // File: dynarray.hxx
  4. //
  5. // Contents: Simple dynamic array class.
  6. //
  7. // Classes: CDynamicArray (macro defined)
  8. //
  9. // History: 20-Aug-95 MarkBl Created
  10. //
  11. //----------------------------------------------------------------------------
  12. #ifndef _DYNARRAY_HXX_
  13. #define _DYNARRAY_HXX_
  14. template<class CItem> class CDynamicArray
  15. {
  16. public:
  17. //
  18. // No allocation on construction.
  19. //
  20. CDynamicArray(WORD Size = 1)
  21. : _Size(Size), _Count(0), _Array(NULL) { ; }
  22. //
  23. // Array element individual destruction.
  24. //
  25. ~CDynamicArray();
  26. //
  27. // Allocate on demand.
  28. //
  29. HRESULT Add(const CItem & Item);
  30. //
  31. // No reallocation.
  32. //
  33. void Remove(WORD Index);
  34. //
  35. // Onus upon caller to specify valid index.
  36. //
  37. CItem & operator[](WORD Index) const {
  38. // BUGBUG : schAssert(_IsWithinRange(Index));
  39. return(_Array[Index]);
  40. }
  41. WORD GetSize(void) const { return(_Size); }
  42. //
  43. // Set *only* when the size is zero.
  44. //
  45. void SetSize(WORD Size) {
  46. if (!_Size) _Size = Size;
  47. }
  48. WORD GetCount(void) const { return(_Count); }
  49. //
  50. // Careful with these members!
  51. //
  52. CItem * GetArray(void) const { return(_Array); }
  53. void SetArray(WORD Count, CItem * Array) {
  54. _Count = _Size = Count;
  55. _Array = Array;
  56. schAssert(LocalSize(Array) >= Count * sizeof(CItem));
  57. }
  58. void FreeArray(void) {
  59. LocalFree(_Array);
  60. _Count = _Size = 0;
  61. _Array = NULL;
  62. }
  63. //
  64. // Allocate and copy from supplied data.
  65. //
  66. HRESULT AllocAndCopy(WORD Count, const void * Data);
  67. private:
  68. BOOL _IsWithinRange(WORD Index) const {
  69. return(Index < _Count ? 1 : 0);
  70. }
  71. CItem * _Array;
  72. WORD _Count;
  73. WORD _Size;
  74. };
  75. template<class CItem> CDynamicArray<CItem>::~CDynamicArray()
  76. {
  77. this->FreeArray();
  78. }
  79. template<class CItem> HRESULT CDynamicArray<CItem>::Add(const CItem & Item)
  80. {
  81. HLOCAL hMem;
  82. if (_Array == NULL)
  83. {
  84. //
  85. // Allocate initial array.
  86. //
  87. if (!_Size) _Size = 1;
  88. _Array = (CItem *)LocalAlloc(LMEM_FIXED, _Size*sizeof(CItem));
  89. if (_Array == NULL)
  90. return(HRESULT_FROM_WIN32(GetLastError()));
  91. }
  92. else if (_Count == _Size)
  93. {
  94. //
  95. // Realloc array.
  96. //
  97. WORD NewSize = _Size ? _Size * 2 : 1;
  98. CItem * Array = (CItem *)LocalReAlloc(_Array,
  99. NewSize*sizeof(CItem),
  100. LMEM_MOVEABLE);
  101. if (Array == NULL) {
  102. return(HRESULT_FROM_WIN32(GetLastError()));
  103. }
  104. _Array = Array;
  105. _Size = NewSize;
  106. }
  107. //
  108. // Copy element.
  109. //
  110. CopyMemory(&_Array[_Count], &Item, sizeof(CItem));
  111. _Count++;
  112. return(S_OK);
  113. }
  114. template<class CItem> HRESULT CDynamicArray<CItem>::AllocAndCopy(
  115. WORD Count, const void * Data)
  116. {
  117. if (_Array == NULL || _Size < Count)
  118. {
  119. LocalFree(_Array);
  120. _Size = Count;
  121. _Array = (CItem *)LocalAlloc(LMEM_FIXED, _Size*sizeof(CItem));
  122. if (_Array == NULL)
  123. return(HRESULT_FROM_WIN32(GetLastError()));
  124. }
  125. //
  126. // Copy elements.
  127. //
  128. CopyMemory(_Array, Data, Count * sizeof(CItem));
  129. _Count = Count;
  130. return(S_OK);
  131. }
  132. template<class CItem> void CDynamicArray<CItem>::Remove(WORD Index)
  133. {
  134. // BUGBUG : schAssert(this->_IsWithinRange(Index));
  135. //
  136. // Overwrite it.
  137. //
  138. --_Count;
  139. if (!(Index == _Count))
  140. {
  141. MoveMemory(_Array + Index,
  142. _Array + Index + 1,
  143. (_Count - Index)*sizeof(CItem));
  144. }
  145. }
  146. #endif // _DYNARRAY_HXX_