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.

313 lines
5.5 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. clist.h
  5. Abstract :
  6. Header file for IntrusiveList.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #ifndef __CLIST_H__
  11. #define __CLIST_H__
  12. template<class T> class IntrusiveList
  13. {
  14. public:
  15. struct Link
  16. {
  17. Link * m_left;
  18. Link * m_right;
  19. IntrusiveList * m_list;
  20. Link()
  21. {
  22. m_left = this;
  23. m_right = this;
  24. m_list = NULL;
  25. }
  26. void prepend( Link & val )
  27. {
  28. ASSERT( val.m_left == &val );
  29. ASSERT( val.m_right == &val );
  30. ASSERT( val.m_list == NULL );
  31. ASSERT( m_list != NULL );
  32. val.m_right = this;
  33. val.m_left = m_left;
  34. val.m_list = m_list;
  35. val.m_right->m_left = &val;
  36. val.m_left->m_right = &val;
  37. }
  38. void excise()
  39. {
  40. if (m_list == NULL)
  41. {
  42. ASSERT( m_left == this );
  43. ASSERT( m_right == this );
  44. return;
  45. }
  46. m_right->m_left = m_left;
  47. m_left->m_right = m_right;
  48. m_left = this;
  49. m_right = this;
  50. m_list = NULL;
  51. }
  52. };
  53. class iterator
  54. {
  55. public:
  56. iterator() : m_current(0)
  57. {
  58. }
  59. iterator operator--()
  60. {
  61. m_current = m_current->m_left;
  62. return *this;
  63. }
  64. iterator operator--(int)
  65. {
  66. // postfix operator
  67. iterator temp = *this;
  68. -- *this;
  69. return temp;
  70. }
  71. iterator operator-(int count)
  72. {
  73. iterator temp = *this;
  74. while (count > 0)
  75. {
  76. --temp;
  77. }
  78. return temp;
  79. }
  80. iterator operator+(int count)
  81. {
  82. iterator temp = *this;
  83. while (count > 0)
  84. {
  85. ++temp;
  86. }
  87. return temp;
  88. }
  89. iterator operator++()
  90. {
  91. // prefix operator
  92. m_current = m_current->m_right;
  93. return *this;
  94. }
  95. iterator operator++(int)
  96. {
  97. // postfix operator
  98. iterator temp = *this;
  99. ++ *this;
  100. return temp;
  101. }
  102. T & operator*()
  103. {
  104. return *static_cast<T *> ( m_current );
  105. }
  106. T * operator->()
  107. {
  108. return &(**this);
  109. }
  110. bool operator==(const iterator& _X) const
  111. {
  112. return (m_current == _X.m_current);
  113. }
  114. bool operator!=(const iterator& _X) const
  115. {
  116. return !(*this == _X);
  117. }
  118. iterator( Link * p ) : m_current( p )
  119. {
  120. }
  121. Link * next()
  122. {
  123. return m_current->m_right;
  124. }
  125. Link * prev()
  126. {
  127. return m_current->m_left;
  128. }
  129. void prepend( Link & val )
  130. {
  131. m_current->prepend( val );
  132. }
  133. void excise()
  134. {
  135. m_current->excise();
  136. }
  137. protected:
  138. Link * m_current;
  139. };
  140. //--------------------------------------------------------------------
  141. IntrusiveList() : m_size(0)
  142. {
  143. m_head.m_list = this;
  144. }
  145. iterator begin()
  146. {
  147. return ++iterator( &m_head );
  148. }
  149. iterator end()
  150. {
  151. return iterator( &m_head );
  152. }
  153. iterator push( T& val )
  154. {
  155. return insert( begin(), val );
  156. }
  157. iterator push_back( T& val )
  158. {
  159. return insert( end(), val );
  160. }
  161. iterator insert( iterator pos, T & val)
  162. {
  163. pos.prepend( val );
  164. ++m_size;
  165. return iterator( &val );
  166. }
  167. size_t erase( T & val )
  168. {
  169. if (val.m_list != this)
  170. {
  171. return 0;
  172. }
  173. val.excise();
  174. --m_size;
  175. return 1;
  176. }
  177. void erase( iterator & pos )
  178. {
  179. if (pos == end())
  180. {
  181. return;
  182. }
  183. pos.excise();
  184. --m_size;
  185. }
  186. void erase(iterator pos, iterator term)
  187. {
  188. while (pos != term)
  189. {
  190. erase(pos++);
  191. }
  192. }
  193. iterator find( const T& val )
  194. {
  195. for (iterator iter=begin(); iter != end(); ++iter)
  196. {
  197. if (&(*iter) == &val)
  198. {
  199. return iter;
  200. }
  201. }
  202. return end();
  203. }
  204. void clear()
  205. {
  206. erase( begin(), end() );
  207. }
  208. size_t size()
  209. {
  210. if (m_size == 0)
  211. {
  212. ASSERT( begin() == end() );
  213. }
  214. else
  215. {
  216. ASSERT( begin() != end() );
  217. }
  218. return m_size;
  219. }
  220. bool empty()
  221. {
  222. if (m_size == 0)
  223. {
  224. ASSERT( begin() == end() );
  225. }
  226. else
  227. {
  228. ASSERT( begin() != end() );
  229. }
  230. return (size() == 0);
  231. }
  232. protected:
  233. Link m_head;
  234. size_t m_size;
  235. };
  236. #endif // __CLIST_H__