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.

336 lines
8.9 KiB

  1. #ifndef __lst_h__
  2. #define __lst_h__
  3. #ifndef ASSERT
  4. #define ASSERT( x )
  5. #endif // #ifndef ASSERT
  6. #include <functional>
  7. // lst bidirectional linked-list template class
  8. // Here are some examples of the usage:
  9. //
  10. // lst< int > MyList;
  11. //
  12. // for( int i = 0; i < 10; i++ ) {
  13. // MyList . push_front( i );
  14. // }
  15. //
  16. //
  17. // lst< int > TestList;
  18. // TestList . insert( TestList . begin(), MyList . begin(), MyList . end() );
  19. //
  20. // const lst< int > cList = MyList;
  21. //
  22. // lst< int >::const_iterator I = cList . begin();
  23. // while( I != cList . end() ) {
  24. // int Num = *I;
  25. // I++;
  26. // }
  27. //
  28. //
  29. // the const_iterator is used to iterate through a const List
  30. //
  31. //
  32. template< class T, class Operator_Eq = std::equal_to<T> >
  33. class lst {
  34. private: // Data types and typedefs
  35. typedef T value_type;
  36. typedef value_type* pointer;
  37. typedef value_type& reference;
  38. typedef const value_type& const_reference;
  39. typedef lst< value_type > self;
  40. Operator_Eq _FnEq;
  41. class node {
  42. public:
  43. node( node* pP, node* pN, const_reference t ) : pNext( pN ), pPrev( pP ), data( t ) { ; }
  44. node( void ) : pNext( NULL ), pPrev( NULL ) { ; }
  45. node* pNext;
  46. node* pPrev;
  47. value_type data;
  48. };
  49. public:
  50. // iterator class for iterating through the list
  51. class iterator {
  52. friend lst;
  53. private:
  54. typedef iterator self;
  55. node* pNode;
  56. iterator( node* pN ) : pNode( pN ) { ; }
  57. public:
  58. iterator( void ) : pNode( NULL ) { ; }
  59. ~iterator( void ) { ; }
  60. iterator( self& r ) { *this = r; }
  61. iterator& operator=( iterator& r ) { pNode = r . pNode; return *this; }
  62. bool operator==( const self& r ) const { return pNode == r . pNode; }
  63. operator!=( const self& r ) const { return pNode != r . pNode; }
  64. reference operator*() { return pNode -> data; }
  65. self& operator++() {
  66. pNode = pNode -> pNext;
  67. return *this;
  68. }
  69. self operator++( int ) {
  70. self tmp = *this;
  71. ++*this;
  72. return tmp;
  73. }
  74. self& operator--() {
  75. pNode = pNode -> pPrev;
  76. return *this;
  77. }
  78. self operator--(int) {
  79. self tmp = *this;
  80. --*this;
  81. return tmp;
  82. }
  83. };
  84. // const_iterator class for iterating through a const list
  85. class const_iterator {
  86. friend lst;
  87. private:
  88. typedef const_iterator self;
  89. const node* pNode;
  90. const_iterator( const node* pN ) : pNode( pN ) { ; }
  91. public:
  92. const_iterator( void ) : pNode( NULL ) { ; }
  93. ~const_iterator( void ) { ; }
  94. const_iterator( const self& r ) { *this = r; }
  95. const_iterator& operator=( const const_iterator& r ) { pNode = r . pNode; return *this;}
  96. bool operator==( const self& r ) const { return pNode == r . pNode; }
  97. operator!=( const self& r ) const { return pNode != r . pNode; }
  98. const_reference operator*() const { return pNode -> data; }
  99. self& operator++() {
  100. pNode = pNode -> pNext;
  101. return *this;
  102. }
  103. self operator++( int ) {
  104. self tmp = *this;
  105. ++*this;
  106. return tmp;
  107. }
  108. self& operator--() {
  109. pNode = pNode -> pPrev;
  110. return *this;
  111. }
  112. self operator--(int) {
  113. self tmp = *this;
  114. --*this;
  115. return tmp;
  116. }
  117. };
  118. // Data
  119. node* m_pNode;
  120. size_t m_nItems;
  121. public:
  122. // construction / destruction
  123. lst( void ) {
  124. empty_initialize();
  125. };
  126. lst( const self& rList ) { empty_initialize(); *this = rList; }
  127. ~lst( void ) { clear(); delete m_pNode; m_pNode = NULL; }
  128. bool operator==( const self& rList ) const {
  129. if( size() != rList . size() ) { return false; }
  130. self::const_iterator IThis = begin();
  131. self::const_iterator IThat = rList . begin();
  132. while( IThis != end() ) {
  133. if( !_FnEq( *IThis, *IThat ) ) {
  134. return false;
  135. }
  136. ++IThat;
  137. ++IThis;
  138. }
  139. return true;
  140. }
  141. // Member Fns
  142. self& operator=( const self& rList ) {
  143. clear();
  144. insert( begin(), rList . begin(), rList . end() );
  145. return *this;
  146. }
  147. void empty_initialize( void ) {
  148. m_pNode = new node;
  149. m_pNode -> pNext = m_pNode;
  150. m_pNode -> pPrev = m_pNode;
  151. m_nItems = 0;
  152. }
  153. void clear( void ) {
  154. node* pCur = m_pNode -> pNext;
  155. while( pCur != m_pNode ) {
  156. node* pTmp = pCur;
  157. pCur = pCur -> pNext;
  158. --m_nItems;
  159. delete pTmp;
  160. pTmp = NULL;
  161. }
  162. m_pNode -> pNext = m_pNode;
  163. m_pNode -> pPrev = m_pNode;
  164. }
  165. // Return the size of the list
  166. size_t size( void ) const { return m_nItems; }
  167. bool empty( void ) const { return 0 == size(); }
  168. // Return an iterator to the position after the last element in the list
  169. // N.B. ---- Don't dereference end()!!!!!!
  170. // N.B. ---- end()++ is undefined!!!!!!
  171. iterator end( void ) { return iterator( m_pNode ); }
  172. const_iterator end( void ) const { return const_iterator( m_pNode ); }
  173. // Return an iterator to the position of the first element of the list
  174. // You may dereference begin()
  175. iterator begin( void ) { return iterator( m_pNode -> pNext ); }
  176. const_iterator begin( void ) const { return const_iterator( m_pNode -> pNext ); }
  177. // Returns a reference to the first element in the list
  178. reference front( void ) { return *begin(); }
  179. const_reference front( void ) const { return *begin(); }
  180. // Returns a reference to the last element in the list
  181. reference back( void ) { return *(--end()); }
  182. const_reference back( void ) const { return *(--end()); }
  183. // add an object to the front of the list
  184. void push_front( const_reference x ) { insert(begin(), x); }
  185. // add an object to the end of the list
  186. void push_back( const_reference x ) { insert(end(), x); }
  187. // Insert an item before the item that position points to
  188. void insert( iterator position, const_reference r ) {
  189. node* pTmp = new node( position . pNode -> pPrev, position . pNode, r );
  190. ( position . pNode -> pPrev ) -> pNext = pTmp;
  191. position . pNode -> pPrev = pTmp;
  192. ++m_nItems;
  193. }
  194. // Insert items first through last to the list at position position
  195. void insert( iterator position, iterator first, iterator last ) {
  196. for ( ; first != last; ++first) {
  197. insert(position, *first);
  198. }
  199. }
  200. // Insert items first through last to the list at position position
  201. void insert( iterator position, const_iterator first, const_iterator last ) {
  202. for ( ; first != last; ++first) {
  203. insert(position, *first);
  204. }
  205. }
  206. // Pop the first element from the list
  207. void pop_front( void ) { erase(begin()); }
  208. // Pop the last element from the list
  209. void pop_back( void ) {
  210. iterator tmp = end();
  211. erase(--tmp);
  212. }
  213. // erase the item at position pos in the list
  214. void erase( iterator pos ) {
  215. ASSERT( pos != end() );
  216. ( pos . pNode -> pPrev ) -> pNext = pos . pNode -> pNext;
  217. ( pos . pNode -> pNext ) -> pPrev = pos . pNode -> pPrev;
  218. --m_nItems;
  219. delete pos . pNode;
  220. pos . pNode = NULL;
  221. }
  222. // erase the items in the range first through last
  223. void erase( iterator first, iterator last ) {
  224. while (first != last) erase(first++);
  225. }
  226. const_iterator find( const_reference x ) const {
  227. return find( begin(), end(), x );
  228. }
  229. iterator find( const_reference x ) {
  230. return find( begin(), end(), x );
  231. }
  232. iterator find( iterator first, iterator last, const_reference x ) {
  233. while( first != last ) {
  234. if( _FnEq(*first, x) ) {
  235. return first;
  236. }
  237. first++;
  238. }
  239. return end();
  240. }
  241. const_iterator find( const_iterator first, const_iterator last, const_reference x ) const {
  242. while( first != last ) {
  243. if( _FnEq(*first, x) ) {
  244. return first;
  245. }
  246. first++;
  247. }
  248. return end();
  249. }
  250. };
  251. template< class T, class F >
  252. lst< T >::iterator find( lst< T >& rLst, F& f ) {
  253. lst< T >::iterator I = rLst . begin();
  254. while( rLst . end() != I ) {
  255. if( f( *I ) ) {
  256. return I;
  257. }
  258. ++I;
  259. }
  260. return I;
  261. }
  262. template< class T, class F >
  263. void for_each( lst< T >& rLst, F& f ) {
  264. lst< T >::iterator I = rLst . begin();
  265. while( rLst . end() != I ) {
  266. f( *I );
  267. ++I;
  268. }
  269. }
  270. #endif //__lst_h__