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.

238 lines
4.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: C L I S T . H
  7. //
  8. // Contents: Very simple templatized CList. Yes, we could import and use
  9. // the STL stuff, but that's a real pain for this one class.
  10. //
  11. // Notes:
  12. //
  13. // Author: jeffspr 9 Dec 1999
  14. //
  15. //----------------------------------------------------------------------------
  16. #ifndef _CLIST_H_
  17. #define _CLIST_H_
  18. #pragma once
  19. // T is the type stored in the list
  20. // K is a type used to search for elements of type T
  21. template<class T, class K> class CList
  22. {
  23. struct TNode
  24. {
  25. TNode * pNext;
  26. TNode * pPrev;
  27. T Data;
  28. };
  29. public:
  30. inline CList() { m_pRootNode = NULL; m_pCurrentNode = NULL; m_pLastNode = NULL; m_iElements = 0; };
  31. inline ~CList();
  32. inline BOOL FAdd(T pNew);
  33. inline BOOL FDelete(K keyDelete);
  34. inline BOOL FFirst(T * pItem);
  35. inline BOOL FNext(T * pItem);
  36. inline VOID Flush();
  37. inline int GetCount() { return m_iElements; };
  38. inline BOOL FFind(K key, T * pItem);
  39. protected:
  40. inline BOOL FInternalDelete(TNode * pItem);
  41. virtual BOOL FCompare(T pNode, K key) = 0;
  42. inline BOOL FInternalFind(K key, TNode ** ppItem);
  43. protected:
  44. TNode * m_pRootNode;
  45. TNode * m_pCurrentNode;
  46. TNode * m_pLastNode;
  47. int m_iElements;
  48. };
  49. template <class T, class K> BOOL CList< T, K >::FInternalDelete(TNode * pItem)
  50. {
  51. Assert(pItem);
  52. if (pItem->pPrev)
  53. {
  54. pItem->pPrev->pNext = pItem->pNext;
  55. }
  56. if (pItem->pNext)
  57. {
  58. pItem->pNext->pPrev = pItem->pPrev;
  59. }
  60. if (m_pRootNode == pItem)
  61. {
  62. m_pRootNode = pItem->pNext;
  63. }
  64. if (m_pLastNode == pItem)
  65. {
  66. m_pLastNode = pItem->pPrev;
  67. }
  68. if (m_pCurrentNode == pItem)
  69. {
  70. m_pCurrentNode = pItem->pNext;
  71. }
  72. delete pItem->Data;
  73. delete pItem;
  74. m_iElements--;
  75. return TRUE;
  76. }
  77. template <class T, class K> CList< T, K >::~CList()
  78. {
  79. m_pCurrentNode = m_pRootNode;
  80. while (m_pCurrentNode)
  81. {
  82. TNode *pNextNode = m_pCurrentNode->pNext;
  83. delete m_pCurrentNode;
  84. m_pCurrentNode = pNextNode;
  85. m_iElements--;
  86. }
  87. }
  88. template <class T, class K> BOOL CList< T, K >::FFirst( T * pItem )
  89. {
  90. m_pCurrentNode = m_pRootNode;
  91. return FNext(pItem);
  92. }
  93. template <class T, class K> BOOL CList< T, K >::FNext( T * pItem )
  94. {
  95. BOOL fReturn = FALSE;
  96. if (m_pCurrentNode)
  97. {
  98. *pItem = m_pCurrentNode->Data;
  99. m_pCurrentNode = m_pCurrentNode->pNext;
  100. fReturn = TRUE;
  101. }
  102. return fReturn;
  103. }
  104. template <class T, class K> BOOL CList< T, K >::FAdd( T ItemToAdd )
  105. {
  106. TNode * pNewNode = new TNode;
  107. if (!pNewNode)
  108. {
  109. return FALSE;
  110. }
  111. else
  112. {
  113. pNewNode->Data = ItemToAdd;
  114. pNewNode->pNext = NULL;
  115. if (m_pLastNode)
  116. {
  117. m_pLastNode->pNext = pNewNode;
  118. pNewNode->pPrev = m_pLastNode;
  119. }
  120. else
  121. {
  122. pNewNode->pPrev = NULL;
  123. }
  124. m_pLastNode = pNewNode;
  125. if (!m_pRootNode)
  126. m_pRootNode = m_pLastNode;
  127. m_iElements++;
  128. }
  129. return TRUE;
  130. }
  131. template <class T, class K> VOID CList< T, K >::Flush()
  132. {
  133. TNode * pLast = m_pLastNode;
  134. while (pLast)
  135. {
  136. FInternalDelete(pLast);
  137. pLast = m_pLastNode;
  138. }
  139. Assert(m_iElements == 0);
  140. }
  141. template <class T, class K> BOOL CList< T, K >::FDelete(K key)
  142. {
  143. BOOL fReturn = FALSE;
  144. BOOL fFound = FALSE;
  145. TNode * pNode = NULL;
  146. fFound = FInternalFind(key, &pNode);
  147. if (fFound)
  148. {
  149. fReturn = FInternalDelete(pNode);
  150. }
  151. return fReturn;
  152. }
  153. template <class T, class K> BOOL CList< T, K >::FFind(K key, T * pItem)
  154. {
  155. BOOL fReturn = FALSE;
  156. TNode * pSearch = NULL;
  157. fReturn = FInternalFind(key, &pSearch);
  158. if (fReturn)
  159. {
  160. Assert(pSearch);
  161. if (pItem)
  162. {
  163. *pItem = pSearch->Data;
  164. }
  165. }
  166. return fReturn;
  167. }
  168. template <class T, class K> BOOL CList< T, K >::FInternalFind(K Key, TNode ** ppNode)
  169. {
  170. BOOL fReturn = FALSE;
  171. BOOL fFound = FALSE;
  172. TNode * pSearch = NULL;
  173. pSearch = m_pRootNode;
  174. while (!fFound && pSearch)
  175. {
  176. if (FCompare(pSearch->Data, Key))
  177. {
  178. fFound = TRUE;
  179. }
  180. else
  181. {
  182. pSearch = pSearch->pNext;
  183. }
  184. }
  185. if (fFound)
  186. {
  187. fReturn = TRUE;
  188. if (ppNode)
  189. {
  190. *ppNode = pSearch;
  191. }
  192. }
  193. return fReturn;
  194. }
  195. #endif // _CLIST_H_