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.

160 lines
3.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992-1998
  5. //
  6. // File: DYNSTACK.HXX
  7. //
  8. // Contents: Dynamic Stack Template
  9. //
  10. // Classes: CDynStack
  11. //
  12. // History: 20-Jan-92 AmyA Created
  13. // 05-Feb-92 BartoszM Converted to macro
  14. // 19-Jun-92 KyleP Moved to Common
  15. // 06-Jan-93 AmyA Split into CDynArray and CDynStack
  16. // 17-Oct-94 BartoszM Converted to template
  17. //
  18. //----------------------------------------------------------------------------
  19. #pragma once
  20. const unsigned initStackSize = 16;
  21. template<class CItem> class CDynStack
  22. {
  23. public:
  24. CDynStack(unsigned size = initStackSize);
  25. ~CDynStack();
  26. void Clear();
  27. void Push(CItem *newItem);
  28. void DeleteTop();
  29. unsigned Count () const {return _count;}
  30. CItem* Pop();
  31. CItem **AcqStack();
  32. CItem* Get (unsigned position) const;
  33. void Insert(CItem* pNewItem, unsigned position);
  34. void Free( unsigned i )
  35. {
  36. Win4Assert( i < _count );
  37. delete _aItem[i];
  38. _aItem[i] = 0;
  39. }
  40. private:
  41. CItem **_aItem;
  42. unsigned _count;
  43. unsigned _size;
  44. };
  45. #define DECL_DYNSTACK( CMyDynStack, CItem ) \
  46. typedef CDynStack<CItem> CMyDynStack;
  47. template<class CItem> CDynStack<CItem>::CDynStack(unsigned size)
  48. : _size(size), _count(0)
  49. {
  50. if ( 0 != size )
  51. _aItem = new CItem *[_size];
  52. else
  53. _aItem = 0;
  54. }
  55. template<class CItem> CDynStack<CItem>::~CDynStack()
  56. {
  57. Clear();
  58. delete _aItem;
  59. }
  60. template<class CItem> void CDynStack<CItem>::Clear()
  61. {
  62. Win4Assert(_aItem || _count==0);
  63. for (unsigned i=0; i < _count; i++)
  64. delete _aItem[i];
  65. _count = 0;
  66. }
  67. template<class CItem> void CDynStack<CItem>::Push(CItem *newItem)
  68. {
  69. if (_count == _size)
  70. {
  71. unsigned newsize;
  72. if ( _size == 0 )
  73. newsize = initStackSize;
  74. else
  75. newsize = _size * 2;
  76. CItem **aNew = new CItem *[newsize];
  77. memcpy( aNew,
  78. _aItem,
  79. _size * sizeof( CItem *) );
  80. delete _aItem;
  81. _aItem = aNew;
  82. _size = newsize;
  83. }
  84. _aItem[_count] = newItem;
  85. _count++;
  86. }
  87. template<class CItem> void CDynStack<CItem>::DeleteTop()
  88. {
  89. Win4Assert(_count > 0);
  90. _count--;
  91. delete _aItem[_count];
  92. }
  93. template<class CItem> CItem* CDynStack<CItem>::Pop()
  94. {
  95. Win4Assert(_count > 0);
  96. _count--;
  97. return _aItem[_count];
  98. }
  99. template<class CItem> CItem **CDynStack<CItem>::AcqStack()
  100. {
  101. CItem **temp = _aItem;
  102. _aItem = 0;
  103. _count = 0;
  104. _size = 0;
  105. return temp;
  106. }
  107. template<class CItem> CItem* CDynStack<CItem>::Get (unsigned position) const
  108. {
  109. Win4Assert( position < _count );
  110. return _aItem[position];
  111. }
  112. template<class CItem> void CDynStack<CItem>::Insert(CItem *newItem, unsigned pos)
  113. {
  114. Win4Assert(pos <= _count);
  115. Win4Assert(_count <= _size);
  116. if (_count == _size)
  117. {
  118. unsigned newsize;
  119. if ( _size == 0 )
  120. newsize = initStackSize;
  121. else
  122. newsize = _size * 2;
  123. CItem **aNew = new CItem *[newsize];
  124. memcpy( aNew,
  125. _aItem,
  126. pos * sizeof( CItem *) );
  127. memcpy( aNew + pos + 1,
  128. _aItem + pos,
  129. (_count - pos)*sizeof(CItem*));
  130. delete _aItem;
  131. _aItem = aNew;
  132. _size = newsize;
  133. }
  134. else
  135. {
  136. memmove ( _aItem + pos + 1,
  137. _aItem + pos,
  138. (_count - pos)*sizeof(CItem*));
  139. }
  140. _aItem[pos] = newItem;
  141. _count++;
  142. }