clist.h
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 7k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //+-------------------------------------------------------------------------
  2. //
  3. //  Microsoft Windows
  4. //
  5. //  Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. //  File:       clist.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef _INC_CSCVIEW_CLIST_H
  11. #define _INC_CSCVIEW_CLIST_H
  12. ///////////////////////////////////////////////////////////////////////////////
  13. /*  File: clist.h
  14.     Description: A simple doubly-linked list template class.
  15.         classes:  CList<T>          - Generic list.
  16.                   CQueueAsList<T>   - Queue implemented as a list.
  17.                   CStackAsList<T>   - Stack implemented as a list.
  18.                   CListIterator<T>  - Iterator for walking a list.
  19.             
  20.     Revision History:
  21.     Date        Description                                          Programmer
  22.     --------    ---------------------------------------------------  ----------
  23.     10/16/97    Initial creation.                                    BrianAu
  24. */
  25. ///////////////////////////////////////////////////////////////////////////////
  26. template <class T> class CListIterator; // fwd decl.
  27. template <class T>
  28. class CListEntry
  29. {
  30.     public:
  31.         CListEntry(void)
  32.             : m_pNext(NULL),
  33.               m_pPrev(NULL) { }
  34.         CListEntry(const T& item)
  35.             : m_pNext(NULL),
  36.               m_pPrev(NULL),
  37.               m_item(item) { }
  38.         CListEntry<T> *m_pNext;
  39.         CListEntry<T> *m_pPrev;
  40.         T              m_item;
  41.     private:
  42.         CListEntry(const CListEntry<T>& rhs);
  43.         CListEntry<T>& operator = (const CListEntry<T>& rhs);
  44. };
  45. template <class T>
  46. class CList 
  47. {
  48.     public:
  49.         CList(void) throw();
  50.         virtual ~CList(void) throw();
  51.         bool Append(const T& item);
  52.         bool Insert(const T& item);
  53.         bool RetrieveHead(T *pItem, bool bRemove = false) throw();
  54.         bool RetrieveTail(T *pItem, bool bRemove = false) throw();
  55.         bool RemoveHead(T *pItem) throw();
  56.         bool RemoveTail(T *pItem) throw();
  57.         int Count(void) const throw()
  58.             { return m_cItems; }
  59.         void Clear(void) throw();
  60.     private:
  61.         CListEntry<T> m_ZNode;
  62.         int   m_cItems;
  63.         bool Retrieve(T *pItem, CListEntry<T> *pEntry, bool bRemove) throw();
  64.         CListEntry<T> *FindEntry(const T& key) throw();
  65.         void Unlink(CListEntry<T> *pEntry) throw();
  66.         void Link(CListEntry<T> *pEntry, CListEntry<T> *pPrev) throw();
  67.         friend class CListIterator<T>;
  68. };
  69. template <class T>
  70. CList<T>::CList(
  71.     void
  72.     ) throw()
  73.       : m_cItems(0)
  74. {
  75.     m_ZNode.m_pNext = m_ZNode.m_pPrev = &m_ZNode;
  76. }
  77. template <class T>
  78. CList<T>::~CList(
  79.     void
  80.     ) throw()
  81. {
  82.     Clear();
  83. }
  84. template <class T>
  85. void
  86. CList<T>::Unlink(
  87.     CListEntry<T> *pEntry
  88.     ) throw()
  89. {
  90.     pEntry->m_pNext->m_pPrev = pEntry->m_pPrev;
  91.     pEntry->m_pPrev->m_pNext = pEntry->m_pNext;
  92.     pEntry->m_pPrev = pEntry->m_pNext = NULL;
  93.     m_cItems--;
  94. }
  95. template <class T>
  96. void
  97. CList<T>::Link(
  98.     CListEntry<T> *pEntry,
  99.     CListEntry<T> *pPrev
  100.     ) throw()
  101. {
  102.     pEntry->m_pPrev = pPrev;
  103.     pEntry->m_pNext = pPrev->m_pNext;
  104.     pPrev->m_pNext = pPrev->m_pNext->m_pPrev = pEntry;
  105.     m_cItems++;
  106. }
  107. template <class T>
  108. void
  109. CList<T>::Clear(
  110.     void
  111.     ) throw()
  112. {
  113.     CListEntry<T> *pDelThis = m_ZNode.m_pNext;
  114.     while(&m_ZNode != pDelThis)
  115.     {
  116.         Unlink(pDelThis);
  117.         delete pDelThis;
  118.         pDelThis = m_ZNode.m_pNext;
  119.     }
  120. }
  121. //
  122. // Add item before ZNode.
  123. //
  124. template <class T>
  125. bool
  126. CList<T>::Append(
  127.     const T& item
  128.     )
  129. {
  130.     CListEntry<T> *pEntry = new CListEntry<T>(item);
  131.     if (NULL != pEntry)
  132.     {
  133.         Link(pEntry, m_ZNode->m_pPrev);
  134.         return true;
  135.     }
  136.     return false;
  137. }
  138. //
  139. // Add item after ZNode.
  140. //
  141. template <class T>
  142. bool
  143. CList<T>::Insert(
  144.     const T& item
  145.     )
  146. {
  147.     CListEntry<T> *pEntry = new CListEntry<T>(item);
  148.     if (NULL != pEntry)
  149.     {
  150.         Link(pEntry, &m_ZNode);
  151.         return true;
  152.     }
  153.     return false;
  154. }
  155. template <class T>
  156. CListEntry<T> *
  157. CList<T>::FindEntry(
  158.     const T& key
  159.     ) throw()
  160. {
  161.     for (CListEntry<T> *pEntry = m_ZNode.m_pNext; &m_ZNode != pEntry; pEntry = pEntry->m_pNext)
  162.     {
  163.         if (pEntry->m_item == key)
  164.             return pEntry;
  165.     }
  166.     return NULL;
  167. }
  168. template <class T>
  169. bool
  170. CList<T>::RetrieveHead(
  171.     T *pItem,
  172.     bool bRemove
  173.     ) throw()
  174. {
  175.     return Retrieve(pItem, m_ZNode.m_pNext, bRemove);
  176. }
  177. template <class T>
  178. bool
  179. CList<T>::RetrieveTail(
  180.     T *pItem,
  181.     bool bRemove
  182.     ) throw()
  183. {
  184.     return Retrieve(pItem, m_ZNode.m_pPrev, bRemove);
  185. }
  186. template <class T>
  187. bool
  188. CList<T>::Retrieve(
  189.     T *pItem,
  190.     CListEntry<T> *pEntry,
  191.     bool bRemove
  192.     ) throw()
  193. {
  194.     DBGASSERT((NULL != pItem));
  195.     if (pEntry != &m_ZNode)
  196.     {
  197.         *pItem = pEntry->m_item;
  198.         if (bRemove)
  199.         {
  200.             Unlink(pEntry);
  201.             delete pEntry;
  202.         }
  203.         return true;
  204.     }
  205.     return false;
  206. }
  207. template <class T>
  208. bool
  209. CList<T>::RemoveHead(
  210.     T *pItem
  211.     ) throw()
  212. {
  213.     return RetrieveHead(pItem, true);
  214. }
  215. template <class T>
  216. bool
  217. CList<T>::RemoveTail(
  218.     T *pItem
  219.     ) throw()
  220. {
  221.     return RetrieveTail(pItem, true);
  222. }
  223. template <class T>
  224. class CQueueAsList : public CList<T>
  225. {
  226.     public:
  227.         CQueueAsList(void) { }
  228.         ~CQueueAsList(void) { }
  229.         bool Add(const T& item)
  230.             { return Insert(item); }
  231.         bool Remove(T *pItem)
  232.             { return RemoveTail(pItem); }
  233.         bool Retrieve(T *pItem)
  234.             { return RetrieveTail(pItem); }
  235. };
  236. template <class T>
  237. class CStackAsList : public CList<T>
  238. {
  239.     public:
  240.         CStackAsList(void) { }
  241.         ~CStackAsList(void) { }
  242.         bool Push(const T& item)
  243.             { return Insert(item); }
  244.         bool Pop(T *pItem)
  245.             { return RemoveHead(pItem); }
  246.         bool Peek(T *pItem)
  247.             { return RetrieveHead(pItem); }
  248. };
  249. template <class T>
  250. class CListIterator
  251. {
  252.     public:
  253.         CListIterator(const CList<T>& list)
  254.             : m_list(list),
  255.               m_pEntry(NULL) { Reset(); }
  256.         void Reset(void)
  257.             { m_pEntry = m_list.m_ZNode.m_pNext; }
  258.         bool Next(T **ppItem);
  259.     private:
  260.         const CList<T>& m_list;
  261.         CListEntry<T> *m_pEntry;
  262. };
  263.               
  264. template <class T>
  265. bool
  266. CListIterator<T>::Next(
  267.     T **ppItem
  268.     )
  269. {
  270.     DBGASSERT((NULL != ppItem));
  271.     if (m_pEntry != &m_list.m_ZNode)
  272.     {
  273.         *ppItem = &(m_pEntry->m_item);
  274.         m_pEntry = m_pEntry->m_pNext;
  275.         return true;
  276.     }
  277.     return false;
  278. }
  279. #endif // _INC_CSCVIEW_CLIST_H