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.

436 lines
9.2 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: SIMLIST.H
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 2/25/1999
  12. *
  13. * DESCRIPTION: Simple singly linked list template class.
  14. *
  15. *******************************************************************************/
  16. #ifndef __SIMLIST_H_INCLUDED
  17. #define __SIMLIST_H_INCLUDED
  18. template <class T>
  19. class CSimpleLinkedList
  20. {
  21. private:
  22. class CLinkedListNode
  23. {
  24. private:
  25. CLinkedListNode *m_pNext;
  26. T m_Data;
  27. public:
  28. CLinkedListNode( const T &data )
  29. : m_pNext(NULL), m_Data(data)
  30. {
  31. }
  32. const CLinkedListNode *Next(void) const
  33. {
  34. return (m_pNext);
  35. }
  36. CLinkedListNode *Next(void)
  37. {
  38. return (m_pNext);
  39. }
  40. void Next( CLinkedListNode *pNext )
  41. {
  42. m_pNext = pNext;
  43. }
  44. const T &Data(void) const
  45. {
  46. return (m_Data);
  47. }
  48. T &Data(void)
  49. {
  50. return (m_Data);
  51. }
  52. };
  53. private:
  54. CLinkedListNode *m_pHead;
  55. CLinkedListNode *m_pTail;
  56. int m_nItemCount;
  57. public:
  58. CSimpleLinkedList( const CSimpleLinkedList &other )
  59. : m_pHead(NULL),
  60. m_pTail(NULL),
  61. m_nItemCount(0)
  62. {
  63. for (Iterator i(other);i != other.End();i++)
  64. {
  65. Append(*i);
  66. }
  67. }
  68. CSimpleLinkedList(void)
  69. : m_pHead(NULL),
  70. m_pTail(NULL),
  71. m_nItemCount(0)
  72. {
  73. }
  74. CSimpleLinkedList &operator=( const CSimpleLinkedList &other )
  75. {
  76. //
  77. // Make sure we aren't the same object
  78. //
  79. if (this != &other)
  80. {
  81. //
  82. // Free our list
  83. //
  84. Destroy();
  85. //
  86. // Loop through the other list, copying nodes to our list
  87. //
  88. for (Iterator i(other);i != other.End();i++)
  89. {
  90. Append(*i);
  91. }
  92. }
  93. return *this;
  94. }
  95. virtual ~CSimpleLinkedList(void)
  96. {
  97. Destroy();
  98. }
  99. void Destroy(void)
  100. {
  101. //
  102. // Loop through each item, deleting it
  103. //
  104. while (m_pHead)
  105. {
  106. //
  107. // Save the head pointer
  108. //
  109. CLinkedListNode *pCurr = m_pHead;
  110. //
  111. // Point the head to the next item
  112. //
  113. m_pHead = m_pHead->Next();
  114. //
  115. // Delete this item
  116. //
  117. delete pCurr;
  118. }
  119. //
  120. // Reinitialize all the variables to their empty state
  121. //
  122. m_pHead = m_pTail = NULL;
  123. m_nItemCount = 0;
  124. }
  125. void Remove( const T &data )
  126. {
  127. //
  128. // Loop until we find this item, and save the previous item before incrementing
  129. //
  130. CLinkedListNode *pPrev = NULL, *pCurr = m_pHead;
  131. while (pCurr && pCurr->Data() != data)
  132. {
  133. pPrev = pCurr;
  134. pCurr = pCurr->Next();
  135. }
  136. //
  137. // If we didn't find the item, return
  138. //
  139. if (!pCurr)
  140. {
  141. return;
  142. }
  143. //
  144. // If this is the last item, point the tail pointer at the previous item (which could be NULL)
  145. //
  146. if (pCurr == m_pTail)
  147. {
  148. m_pTail = pPrev;
  149. }
  150. //
  151. // If this is the first item, point the head at the next item
  152. //
  153. if (pCurr == m_pHead)
  154. {
  155. m_pHead = pCurr->Next();
  156. }
  157. //
  158. // Point the previous item's next pointer at our next pointer
  159. //
  160. if (pPrev)
  161. {
  162. pPrev->Next(pCurr->Next());
  163. }
  164. //
  165. // Delete this item
  166. //
  167. delete pCurr;
  168. //
  169. // Decrement the item count
  170. //
  171. m_nItemCount--;
  172. }
  173. void Append( const CSimpleLinkedList &other )
  174. {
  175. //
  176. // Loop through the other list, copying nodes to our list
  177. //
  178. for (Iterator i(other);i != other.End();i++)
  179. {
  180. Append(*i);
  181. }
  182. }
  183. int Count(void) const
  184. {
  185. return m_nItemCount;
  186. }
  187. class Iterator;
  188. friend class Iterator;
  189. class Iterator
  190. {
  191. private:
  192. CLinkedListNode *m_pCurr;
  193. public:
  194. Iterator( CLinkedListNode *pNode )
  195. : m_pCurr(pNode)
  196. {
  197. }
  198. Iterator( const CSimpleLinkedList &list )
  199. : m_pCurr(list.m_pHead)
  200. {
  201. }
  202. Iterator(void)
  203. : m_pCurr(NULL)
  204. {
  205. }
  206. Iterator &Next(void)
  207. {
  208. if (m_pCurr)
  209. {
  210. m_pCurr = m_pCurr->Next();
  211. }
  212. return (*this);
  213. }
  214. Iterator &Begin(const CSimpleLinkedList &list)
  215. {
  216. m_pCurr = list.m_pHead;
  217. return (*this);
  218. }
  219. Iterator &operator=( const Iterator &other )
  220. {
  221. m_pCurr = other.m_pCurr;
  222. return (*this);
  223. }
  224. bool End(void) const
  225. {
  226. return(m_pCurr == NULL);
  227. }
  228. T &operator*(void)
  229. {
  230. return (m_pCurr->Data());
  231. }
  232. const T &operator*(void) const
  233. {
  234. return (m_pCurr->Data());
  235. }
  236. Iterator &operator++(void)
  237. {
  238. Next();
  239. return (*this);
  240. }
  241. Iterator operator++(int)
  242. {
  243. Iterator tmp(*this);
  244. Next();
  245. return (tmp);
  246. }
  247. bool operator!=( const Iterator &other ) const
  248. {
  249. return (m_pCurr != other.m_pCurr);
  250. }
  251. bool operator==( const Iterator &other ) const
  252. {
  253. return (m_pCurr == other.m_pCurr);
  254. }
  255. };
  256. Iterator Begin(void) const
  257. {
  258. return Iterator(*this);
  259. }
  260. Iterator End(void) const
  261. {
  262. return Iterator();
  263. }
  264. Iterator Begin(void)
  265. {
  266. return Iterator(*this);
  267. }
  268. Iterator End(void)
  269. {
  270. return Iterator();
  271. }
  272. Iterator Find( const T &data )
  273. {
  274. for (Iterator i=Begin();i != End();++i)
  275. {
  276. if (*i == data)
  277. {
  278. return i;
  279. }
  280. }
  281. return End();
  282. }
  283. Iterator Prepend( const T &data )
  284. {
  285. //
  286. // Allocate a new item to hold this data
  287. //
  288. CLinkedListNode *pNewItem = new CLinkedListNode(data);
  289. if (pNewItem)
  290. {
  291. //
  292. // If the list is empty, point everything at this item
  293. //
  294. if (Empty())
  295. {
  296. m_pHead = m_pTail = pNewItem;
  297. }
  298. //
  299. // Point our next pointer to the current, then point the head at us
  300. //
  301. else
  302. {
  303. pNewItem->Next(m_pHead);
  304. m_pHead = pNewItem;
  305. }
  306. //
  307. // Increment the item count
  308. //
  309. m_nItemCount++;
  310. }
  311. //
  312. // Return an iterator that points to the new item
  313. //
  314. return Iterator(pNewItem);
  315. }
  316. Iterator Append( const T &data )
  317. {
  318. //
  319. // Allocate a new item to hold this data
  320. //
  321. CLinkedListNode *pNewItem = new CLinkedListNode(data);
  322. if (pNewItem)
  323. {
  324. //
  325. // If the list is empty, point everything at this item
  326. //
  327. if (Empty())
  328. {
  329. m_pHead = m_pTail = pNewItem;
  330. }
  331. //
  332. // Point the tail's next pointer to us, then point the tail at us
  333. //
  334. else
  335. {
  336. m_pTail->Next(pNewItem);
  337. m_pTail = pNewItem;
  338. }
  339. //
  340. // Increment the item count
  341. //
  342. m_nItemCount++;
  343. }
  344. //
  345. // Return an iterator that points to the new item
  346. //
  347. return Iterator(pNewItem);
  348. }
  349. bool Empty(void) const
  350. {
  351. return (m_pHead == NULL);
  352. }
  353. };
  354. template <class T>
  355. class CSimpleStack : public CSimpleLinkedList<T>
  356. {
  357. private:
  358. CSimpleStack( const CSimpleStack &other );
  359. CSimpleStack &operator=( const CSimpleStack &other );
  360. public:
  361. CSimpleStack(void)
  362. {
  363. }
  364. virtual ~CSimpleStack(void)
  365. {
  366. }
  367. void Push( const T &data )
  368. {
  369. Prepend(data);
  370. }
  371. bool Pop( T &data )
  372. {
  373. if (Empty())
  374. return false;
  375. Iterator iter(*this);
  376. data = *iter;
  377. Remove(*iter);
  378. return true;
  379. }
  380. };
  381. template <class T>
  382. class CSimpleQueue : public CSimpleLinkedList<T>
  383. {
  384. private:
  385. CSimpleQueue( const CSimpleQueue &other );
  386. CSimpleQueue &operator=( const CSimpleQueue &other );
  387. public:
  388. CSimpleQueue(void)
  389. {
  390. }
  391. virtual ~CSimpleQueue(void)
  392. {
  393. }
  394. void Enqueue( const T &data )
  395. {
  396. Append(data);
  397. }
  398. bool Dequeue( T &data )
  399. {
  400. if (Empty())
  401. return false;
  402. Iterator iter(*this);
  403. data = *iter;
  404. Remove(*iter);
  405. return true;
  406. }
  407. };
  408. #endif __SIMLIST_H_INCLUDED