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.

293 lines
6.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: U L I S T . H
  7. //
  8. // Contents: Simple list class
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 1 Nov 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include "array.h"
  17. template <class Type>
  18. class CUList
  19. {
  20. class Node
  21. {
  22. public:
  23. Node() : m_pNext(NULL)
  24. {
  25. }
  26. ~Node()
  27. {
  28. Node * pNode = m_pNext;
  29. while(pNode)
  30. {
  31. Node * pNodeDel = pNode;
  32. pNode = pNodeDel->m_pNext;
  33. pNodeDel->m_pNext = NULL;
  34. delete pNodeDel;
  35. }
  36. m_pNext = NULL;
  37. }
  38. Node * m_pNext;
  39. Type m_type;
  40. private:
  41. Node(const Node &);
  42. Node & operator=(const Node &);
  43. };
  44. public:
  45. CUList() : m_pList(NULL) {}
  46. ~CUList()
  47. {
  48. Clear();
  49. }
  50. class Iterator
  51. {
  52. friend CUList<Type>;
  53. public:
  54. Iterator() : m_ppNode(NULL) {}
  55. HRESULT HrGetItem(Type ** ppItem)
  56. {
  57. if(!m_ppNode || !*m_ppNode)
  58. {
  59. return E_UNEXPECTED;
  60. }
  61. *ppItem = &(*m_ppNode)->m_type;
  62. return S_OK;
  63. }
  64. BOOL FIsItem() const
  65. {
  66. return NULL != m_ppNode && NULL != *m_ppNode;
  67. }
  68. // Return S_FALSE at the end of the list
  69. HRESULT HrNext()
  70. {
  71. if(!m_ppNode || !*m_ppNode)
  72. {
  73. return E_UNEXPECTED;
  74. }
  75. m_ppNode = &(*m_ppNode)->m_pNext;
  76. if(!*m_ppNode)
  77. {
  78. return S_FALSE;
  79. }
  80. return S_OK;
  81. }
  82. HRESULT HrErase()
  83. {
  84. if(!m_ppNode || !*m_ppNode)
  85. {
  86. return E_UNEXPECTED;
  87. }
  88. CUList<Type>::Node * pNode = *m_ppNode;
  89. *m_ppNode = (*m_ppNode)->m_pNext;
  90. pNode->m_pNext = NULL;
  91. delete pNode;
  92. if(!*m_ppNode)
  93. {
  94. return S_FALSE;
  95. }
  96. return S_OK;
  97. }
  98. HRESULT HrRemoveTransfer(Type & type)
  99. {
  100. if(!m_ppNode || !*m_ppNode)
  101. {
  102. return E_UNEXPECTED;
  103. }
  104. CUList<Type>::Node * pNode = *m_ppNode;
  105. *m_ppNode = (*m_ppNode)->m_pNext;
  106. pNode->m_pNext = NULL;
  107. TypeTransfer(type, pNode->m_type);
  108. delete pNode;
  109. if(!*m_ppNode)
  110. {
  111. return S_FALSE;
  112. }
  113. return S_OK;
  114. }
  115. HRESULT HrMoveToList(CUList<Type> & list)
  116. {
  117. if(!m_ppNode || !*m_ppNode)
  118. {
  119. return E_UNEXPECTED;
  120. }
  121. CUList<Type>::Node * pNode = *m_ppNode;
  122. *m_ppNode = (*m_ppNode)->m_pNext;
  123. pNode->m_pNext = list.m_pList;
  124. list.m_pList = pNode;
  125. if(!*m_ppNode)
  126. {
  127. return S_FALSE;
  128. }
  129. return S_OK;
  130. }
  131. private:
  132. Iterator(const Iterator &);
  133. Iterator & operator=(const Iterator &);
  134. void Init(CUList<Type>::Node ** ppNode)
  135. {
  136. m_ppNode = ppNode;
  137. }
  138. CUList<Type>::Node ** m_ppNode;
  139. };
  140. friend class CUList<Type>::Iterator;
  141. HRESULT GetIterator(Iterator & iterator)
  142. {
  143. iterator.Init(&m_pList);
  144. return m_pList ? S_OK : S_FALSE;
  145. }
  146. // Sizing functions
  147. long GetCount() const
  148. {
  149. Node * pNode = m_pList;
  150. for(long n = 0; NULL != pNode; ++n, pNode = pNode->m_pNext);
  151. return n;
  152. }
  153. BOOL IsEmpty() const
  154. {
  155. return NULL == m_pList;
  156. }
  157. void Clear()
  158. {
  159. delete m_pList;
  160. m_pList = NULL;
  161. }
  162. // Insertion function
  163. HRESULT HrPushFrontDefault()
  164. {
  165. HRESULT hr = S_OK;
  166. Node * pNode = new Node;
  167. if(pNode)
  168. {
  169. pNode->m_pNext = m_pList;
  170. m_pList = pNode;
  171. }
  172. else
  173. {
  174. hr = E_OUTOFMEMORY;
  175. }
  176. return hr;
  177. }
  178. HRESULT HrPushFront(const Type & type)
  179. {
  180. HRESULT hr = S_OK;
  181. Node * pNode = new Node;
  182. if(pNode)
  183. {
  184. hr = HrTypeAssign(pNode->m_type, type);
  185. if(SUCCEEDED(hr))
  186. {
  187. pNode->m_pNext = m_pList;
  188. m_pList = pNode;
  189. }
  190. if(FAILED(hr))
  191. {
  192. delete pNode;
  193. }
  194. }
  195. else
  196. {
  197. hr = E_OUTOFMEMORY;
  198. }
  199. return hr;
  200. }
  201. HRESULT HrPushFrontTransfer(Type & type)
  202. {
  203. HRESULT hr = S_OK;
  204. Node * pNode = new Node;
  205. if(pNode)
  206. {
  207. TypeTransfer(pNode->m_type, type);
  208. pNode->m_pNext = m_pList;
  209. m_pList = pNode;
  210. }
  211. else
  212. {
  213. hr = E_OUTOFMEMORY;
  214. }
  215. return hr;
  216. }
  217. Type & Front()
  218. {
  219. Assert(m_pList);
  220. return m_pList->m_type;
  221. }
  222. // Removal
  223. HRESULT HrPopFrontTransfer(Type & type)
  224. {
  225. if(!m_pList)
  226. {
  227. return E_UNEXPECTED;
  228. }
  229. TypeTransfer(type, m_pList->m_type);
  230. Node * pNode = m_pList;
  231. m_pList = pNode->m_pNext;
  232. pNode->m_pNext = NULL;
  233. delete pNode;
  234. return S_OK;
  235. }
  236. void Swap(CUList & ref)
  237. {
  238. Node * pNode = ref.m_pList;
  239. ref.m_pList = m_pList;
  240. m_pList = pNode;
  241. }
  242. // List manipulation
  243. void Append(CUList<Type> & list)
  244. {
  245. // Find end of list
  246. Node ** ppNode = &m_pList;
  247. while(*ppNode != NULL)
  248. {
  249. ppNode = &(*ppNode)->m_pNext;
  250. }
  251. *ppNode = list.m_pList;
  252. list.m_pList = NULL;
  253. }
  254. void Prepend(CUList<Type> & list)
  255. {
  256. // Find end of list
  257. Node ** ppNode = &list.m_pList;
  258. while(*ppNode != NULL)
  259. {
  260. ppNode = &(*ppNode)->m_pNext;
  261. }
  262. *ppNode = m_pList;
  263. m_pList = list.m_pList;
  264. list.m_pList = NULL;
  265. }
  266. private:
  267. CUList(const CUList &);
  268. CUList & operator=(const CUList &);
  269. Node * m_pList;
  270. };