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.

266 lines
7.4 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CList.h
  7. //
  8. // Description:
  9. // Header file for CList template class.
  10. //
  11. // CList is a template class the provides the functionality of a linked
  12. // list. It has an CIterator that allows both forward and reverse
  13. // traversal.
  14. //
  15. // This class is intended to be used instead of std::list since the
  16. // use of STL is prohibited in our project.
  17. //
  18. // Maintained By:
  19. // Vij Vasu (Vvasu) 24-APR-2000
  20. //
  21. //////////////////////////////////////////////////////////////////////////////
  22. // Make sure that this file is included only once per compile path.
  23. #pragma once
  24. //////////////////////////////////////////////////////////////////////////////
  25. // Include files
  26. //////////////////////////////////////////////////////////////////////////////
  27. // For the CException class
  28. #include "CException.h"
  29. //////////////////////////////////////////////////////////////////////////////
  30. //++
  31. //
  32. // template< class t_Ty >
  33. // class CList
  34. //
  35. // Description:
  36. // CList is a template class the provides the functionality of a linked
  37. // list. It has an CIterator that allows both forward and reverse
  38. // traversal.
  39. //
  40. // This class is implemented as a circular doubly linked list.
  41. //--
  42. //////////////////////////////////////////////////////////////////////////////
  43. template< class t_Ty >
  44. class CList
  45. {
  46. private:
  47. //////////////////////////////////////////////////////////////////////////
  48. // Private types
  49. //////////////////////////////////////////////////////////////////////////
  50. class CNode
  51. {
  52. public:
  53. // Constructor
  54. CNode( const t_Ty & rtyDataIn, CNode * pNextIn, CNode *pPrevIn )
  55. : m_tyData( rtyDataIn )
  56. , m_pNext( pNextIn )
  57. , m_pPrev( pPrevIn )
  58. {
  59. } //*** CNode()
  60. // Member data
  61. t_Ty m_tyData;
  62. CNode * m_pNext;
  63. CNode * m_pPrev;
  64. }; //*** class CNode
  65. public:
  66. //////////////////////////////////////////////////////////////////////////
  67. // Public types
  68. //////////////////////////////////////////////////////////////////////////
  69. class CIterator;
  70. friend class CIterator;
  71. // The iterator for this list
  72. class CIterator
  73. {
  74. public:
  75. CIterator( CNode * pNodeIn = NULL ) throw()
  76. : m_pNode( pNodeIn )
  77. {} //*** CIterator()
  78. t_Ty & operator*() const throw()
  79. {
  80. return m_pNode->m_tyData;
  81. } //*** operator*()
  82. t_Ty * operator->() const throw()
  83. {
  84. return &( m_pNode->m_tyData );
  85. } //*** operator->()
  86. CIterator & operator++()
  87. {
  88. m_pNode = m_pNode->m_pNext;
  89. return *this;
  90. } //*** operator++()
  91. CIterator & operator--()
  92. {
  93. m_pNode = m_pNode->m_pPrev;
  94. return *this;
  95. } //*** operator--()
  96. bool operator==( const CIterator & rRHSIn ) const throw()
  97. {
  98. return ( m_pNode == rRHSIn.m_pNode );
  99. } //*** operator==()
  100. bool operator!=( const CIterator & rRHSIn ) const throw()
  101. {
  102. return ( m_pNode != rRHSIn.m_pNode );
  103. } //*** operator!=()
  104. CNode * PGetNodePtr() const throw()
  105. {
  106. return m_pNode;
  107. } //*** PGetNodePtr()
  108. private:
  109. class CList;
  110. friend class CList;
  111. CNode * m_pNode;
  112. }; //*** class CIterator
  113. public:
  114. //////////////////////////////////////////////////////////////////////////
  115. // Constructors and destructors
  116. //////////////////////////////////////////////////////////////////////////
  117. // Default constructor
  118. CList()
  119. : m_cSize( 0 )
  120. {
  121. // The list is never empty. It always has the special "head" node.
  122. // The reinterpret_cast is required to prevent the constructor of t_Ty
  123. // from being called when the head node is created.
  124. m_pHead = reinterpret_cast< CNode * >( new char[ sizeof( *m_pHead ) ] );
  125. if ( m_pHead == NULL )
  126. {
  127. THROW_EXCEPTION( E_OUTOFMEMORY );
  128. } // if: memory allocation failed
  129. m_pHead->m_pNext = m_pHead;
  130. m_pHead->m_pPrev = m_pHead;
  131. } //*** CList()
  132. // Default destructor
  133. ~CList()
  134. {
  135. Empty();
  136. // Cast to void * to prevent destructor call
  137. delete reinterpret_cast< void * >( m_pHead );
  138. } //*** ~CList()
  139. //////////////////////////////////////////////////////////////////////////
  140. // Member functions
  141. //////////////////////////////////////////////////////////////////////////
  142. // Add to the end of the list
  143. void Append( const t_Ty & rctyNewDataIn )
  144. {
  145. InsertAfter( m_pHead->m_pPrev, rctyNewDataIn );
  146. } //*** Append()
  147. // Add a new node after the input node
  148. void InsertAfter( const CIterator & rciNodeIn, const t_Ty & rctyDataIn )
  149. {
  150. CNode * pNode = rciNodeIn.PGetNodePtr();
  151. CNode * pNewNode = new CNode( rctyDataIn, pNode->m_pNext, pNode );
  152. if ( pNewNode == NULL )
  153. {
  154. THROW_EXCEPTION( E_OUTOFMEMORY );
  155. } // if: memory allocation failed
  156. pNode->m_pNext->m_pPrev = pNewNode;
  157. pNode->m_pNext = pNewNode;
  158. ++m_cSize;
  159. } //*** InsertAfter()
  160. // Delete a node. After this operation the input iterator points to the next node.
  161. void DeleteAndMoveToNext( CIterator & riNodeIn )
  162. {
  163. CNode * pNode = riNodeIn.PGetNodePtr();
  164. // Move to the next node.
  165. ++riNodeIn;
  166. pNode->m_pNext->m_pPrev = pNode->m_pPrev;
  167. pNode->m_pPrev->m_pNext = pNode->m_pNext;
  168. delete pNode;
  169. --m_cSize;
  170. } //*** Delete()
  171. // Delete all the elements in this list.
  172. void Empty()
  173. {
  174. CIterator ciCurNode( m_pHead->m_pNext );
  175. while( m_cSize != 0 )
  176. {
  177. DeleteAndMoveToNext( ciCurNode );
  178. } // while: the list is not empty
  179. } //*** Empty()
  180. // Return an iterator pointing to the first element in the list
  181. CIterator CiBegin() const throw()
  182. {
  183. return CIterator( m_pHead->m_pNext );
  184. } //*** CiBegin()
  185. // Return an iterator pointing past the last element in the list.
  186. CIterator CiEnd() const throw()
  187. {
  188. return CIterator( m_pHead );
  189. } //*** CiEnd()
  190. // Get a count of the number of elements in the list.
  191. int CGetSize() const throw()
  192. {
  193. return m_cSize;
  194. } //*** CGetSize()
  195. private:
  196. //////////////////////////////////////////////////////////////////////////
  197. // Private member functions
  198. //////////////////////////////////////////////////////////////////////////
  199. // Copy constructor
  200. CList( const CList & );
  201. // Assignment operator
  202. const CList & operator=( const CList & );
  203. //////////////////////////////////////////////////////////////////////////
  204. // Private data
  205. //////////////////////////////////////////////////////////////////////////
  206. // Pointer to the head of the list
  207. CNode * m_pHead;
  208. // Count of the number of elements in the list
  209. int m_cSize;
  210. }; //*** class CList