#ifndef __lst_h__ #define __lst_h__ #ifndef ASSERT #define ASSERT( x ) #endif // #ifndef ASSERT #include // lst bidirectional linked-list template class // Here are some examples of the usage: // // lst< int > MyList; // // for( int i = 0; i < 10; i++ ) { // MyList . push_front( i ); // } // // // lst< int > TestList; // TestList . insert( TestList . begin(), MyList . begin(), MyList . end() ); // // const lst< int > cList = MyList; // // lst< int >::const_iterator I = cList . begin(); // while( I != cList . end() ) { // int Num = *I; // I++; // } // // // the const_iterator is used to iterate through a const List // // template< class T, class Operator_Eq = std::equal_to > class lst { private: // Data types and typedefs typedef T value_type; typedef value_type* pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef lst< value_type > self; Operator_Eq _FnEq; class node { public: node( node* pP, node* pN, const_reference t ) : pNext( pN ), pPrev( pP ), data( t ) { ; } node( void ) : pNext( NULL ), pPrev( NULL ) { ; } node* pNext; node* pPrev; value_type data; }; public: // iterator class for iterating through the list class iterator { friend lst; private: typedef iterator self; node* pNode; iterator( node* pN ) : pNode( pN ) { ; } public: iterator( void ) : pNode( NULL ) { ; } ~iterator( void ) { ; } iterator( self& r ) { *this = r; } iterator& operator=( iterator& r ) { pNode = r . pNode; return *this; } bool operator==( const self& r ) const { return pNode == r . pNode; } operator!=( const self& r ) const { return pNode != r . pNode; } reference operator*() { return pNode -> data; } self& operator++() { pNode = pNode -> pNext; return *this; } self operator++( int ) { self tmp = *this; ++*this; return tmp; } self& operator--() { pNode = pNode -> pPrev; return *this; } self operator--(int) { self tmp = *this; --*this; return tmp; } }; // const_iterator class for iterating through a const list class const_iterator { friend lst; private: typedef const_iterator self; const node* pNode; const_iterator( const node* pN ) : pNode( pN ) { ; } public: const_iterator( void ) : pNode( NULL ) { ; } ~const_iterator( void ) { ; } const_iterator( const self& r ) { *this = r; } const_iterator& operator=( const const_iterator& r ) { pNode = r . pNode; return *this;} bool operator==( const self& r ) const { return pNode == r . pNode; } operator!=( const self& r ) const { return pNode != r . pNode; } const_reference operator*() const { return pNode -> data; } self& operator++() { pNode = pNode -> pNext; return *this; } self operator++( int ) { self tmp = *this; ++*this; return tmp; } self& operator--() { pNode = pNode -> pPrev; return *this; } self operator--(int) { self tmp = *this; --*this; return tmp; } }; // Data node* m_pNode; size_t m_nItems; public: // construction / destruction lst( void ) { empty_initialize(); }; lst( const self& rList ) { empty_initialize(); *this = rList; } ~lst( void ) { clear(); delete m_pNode; m_pNode = NULL; } bool operator==( const self& rList ) const { if( size() != rList . size() ) { return false; } self::const_iterator IThis = begin(); self::const_iterator IThat = rList . begin(); while( IThis != end() ) { if( !_FnEq( *IThis, *IThat ) ) { return false; } ++IThat; ++IThis; } return true; } // Member Fns self& operator=( const self& rList ) { clear(); insert( begin(), rList . begin(), rList . end() ); return *this; } void empty_initialize( void ) { m_pNode = new node; m_pNode -> pNext = m_pNode; m_pNode -> pPrev = m_pNode; m_nItems = 0; } void clear( void ) { node* pCur = m_pNode -> pNext; while( pCur != m_pNode ) { node* pTmp = pCur; pCur = pCur -> pNext; --m_nItems; delete pTmp; pTmp = NULL; } m_pNode -> pNext = m_pNode; m_pNode -> pPrev = m_pNode; } // Return the size of the list size_t size( void ) const { return m_nItems; } bool empty( void ) const { return 0 == size(); } // Return an iterator to the position after the last element in the list // N.B. ---- Don't dereference end()!!!!!! // N.B. ---- end()++ is undefined!!!!!! iterator end( void ) { return iterator( m_pNode ); } const_iterator end( void ) const { return const_iterator( m_pNode ); } // Return an iterator to the position of the first element of the list // You may dereference begin() iterator begin( void ) { return iterator( m_pNode -> pNext ); } const_iterator begin( void ) const { return const_iterator( m_pNode -> pNext ); } // Returns a reference to the first element in the list reference front( void ) { return *begin(); } const_reference front( void ) const { return *begin(); } // Returns a reference to the last element in the list reference back( void ) { return *(--end()); } const_reference back( void ) const { return *(--end()); } // add an object to the front of the list void push_front( const_reference x ) { insert(begin(), x); } // add an object to the end of the list void push_back( const_reference x ) { insert(end(), x); } // Insert an item before the item that position points to void insert( iterator position, const_reference r ) { node* pTmp = new node( position . pNode -> pPrev, position . pNode, r ); ( position . pNode -> pPrev ) -> pNext = pTmp; position . pNode -> pPrev = pTmp; ++m_nItems; } // Insert items first through last to the list at position position void insert( iterator position, iterator first, iterator last ) { for ( ; first != last; ++first) { insert(position, *first); } } // Insert items first through last to the list at position position void insert( iterator position, const_iterator first, const_iterator last ) { for ( ; first != last; ++first) { insert(position, *first); } } // Pop the first element from the list void pop_front( void ) { erase(begin()); } // Pop the last element from the list void pop_back( void ) { iterator tmp = end(); erase(--tmp); } // erase the item at position pos in the list void erase( iterator pos ) { ASSERT( pos != end() ); ( pos . pNode -> pPrev ) -> pNext = pos . pNode -> pNext; ( pos . pNode -> pNext ) -> pPrev = pos . pNode -> pPrev; --m_nItems; delete pos . pNode; pos . pNode = NULL; } // erase the items in the range first through last void erase( iterator first, iterator last ) { while (first != last) erase(first++); } const_iterator find( const_reference x ) const { return find( begin(), end(), x ); } iterator find( const_reference x ) { return find( begin(), end(), x ); } iterator find( iterator first, iterator last, const_reference x ) { while( first != last ) { if( _FnEq(*first, x) ) { return first; } first++; } return end(); } const_iterator find( const_iterator first, const_iterator last, const_reference x ) const { while( first != last ) { if( _FnEq(*first, x) ) { return first; } first++; } return end(); } }; template< class T, class F > lst< T >::iterator find( lst< T >& rLst, F& f ) { lst< T >::iterator I = rLst . begin(); while( rLst . end() != I ) { if( f( *I ) ) { return I; } ++I; } return I; } template< class T, class F > void for_each( lst< T >& rLst, F& f ) { lst< T >::iterator I = rLst . begin(); while( rLst . end() != I ) { f( *I ); ++I; } } #endif //__lst_h__