windows-nt/Source/XPSP1/NT/enduser/netmeeting/h/lst.h
2020-09-26 16:20:57 +08:00

337 lines
8.9 KiB
C++

#ifndef __lst_h__
#define __lst_h__
#ifndef ASSERT
#define ASSERT( x )
#endif // #ifndef ASSERT
#include <functional>
// 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<T> >
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__