/**************************************************************************** * * Copyright (C) 2000-2001 RealNetworks, Inc. All rights reserved. * * This program is free software. It may be distributed under the terms * in the file LICENSE, found in the top level of the source distribution. * */ #ifndef _TLIST_H #define _TLIST_H #include template class TSingleList { private: // Unimplemented TSingleList( const TSingleList& ); TSingleList& operator=( const TSingleList& ); protected: class TSingleNode { public: TSingleNode( TSingleNode* pNext, const T& Data ) : m_pNext(pNext), m_Data(Data) { // Empty } T& GetData( void ) { return m_Data; } const T& GetData( void ) const { return m_Data; } TSingleNode* m_pNext; T m_Data; }; class IteratorBase { friend class TSingleList; public: IteratorBase( void ) : m_pList(NULL), m_pNode(NULL) { // Empty } bool operator++( void ) { assert( m_pList && m_pNode ); m_pNode = m_pNode->m_pNext; return ( m_pNode != NULL ); } bool operator++( int ) { assert( m_pList && m_pNode ); m_pNode = m_pNode->m_pNext; return ( m_pNode != NULL ); } operator bool( void ) const { return ( m_pList != NULL && m_pNode != NULL ); } bool operator==( const IteratorBase& itr ) const { return ( itr.m_pList == m_pList && itr.m_pNode == m_pNode ); } bool operator!=( const IteratorBase& itr ) const { return ( itr.m_pList != m_pList || itr.m_pNode != m_pNode ); } protected: IteratorBase( const TSingleList* pList, TSingleNode* pNode ) : m_pList(pList), m_pNode(pNode) { // Empty } protected: const TSingleList* m_pList; TSingleNode* m_pNode; }; public: class Iterator : public IteratorBase { friend class TSingleList; public: Iterator( void ) : IteratorBase() { // Empty } T& operator*( void ) { assert( TSingleList::m_pList && TSingleList::m_pNode ); return TSingleList::m_pNode->GetData(); } protected: Iterator( TSingleList* pList, TSingleNode* pNode ) : IteratorBase( pList, pNode ) { // Empty } }; class ConstIterator : public IteratorBase { friend class TSingleList; public: ConstIterator( void ) : IteratorBase() { // Empty } const T& operator*( void ) const { assert(TSingleList::m_pList && TSingleList::m_pNode ); return TSingleList::m_pNode->GetData(); } protected: ConstIterator( const TSingleList* pList, TSingleNode* pNode ) : IteratorBase( pList, pNode ) { // Empty } }; TSingleList( void ) : m_pHead(NULL), m_pTail(NULL), m_nCount(0) {} ~TSingleList( void ) { while( ! IsEmpty() ) { RemoveHead(); } } bool IsEmpty( void ) const { return m_pHead == NULL; } unsigned int GetCount( void ) const { return m_nCount; } void InsertHead( const T& Data ) { TSingleNode* pNode = new TSingleNode( m_pHead, Data ); assert( pNode ); m_pHead = pNode; if( ! m_pTail ) { m_pTail = pNode; } m_nCount++; } void InsertTail( const T& Data ) { TSingleNode* pNode = new TSingleNode( NULL, Data ); assert( pNode ); if( m_pTail ) { m_pTail->m_pNext = pNode; } m_pTail = pNode; if( ! m_pHead ) { m_pHead = pNode; } m_nCount++; } T RemoveHead( void ) { TSingleNode* pNode = m_pHead; m_pHead = pNode->m_pNext; if( ! m_pHead ) { m_pTail = NULL; } T Data = pNode->GetData(); delete pNode; m_nCount--; return Data; } Iterator Begin( void ) { return Iterator( this, m_pHead ); } ConstIterator Begin( void ) const { return ConstIterator( this, m_pHead ); } Iterator End( void ) { return Iterator( this, NULL ); } ConstIterator End( void ) const { return ConstIterator( this, NULL ); } protected: TSingleNode* m_pHead; TSingleNode* m_pTail; unsigned int m_nCount; }; template class TDoubleList { private: // Unimplemented TDoubleList( const TDoubleList& ); TDoubleList& operator=( const TDoubleList& ); protected: class TDoubleNode { public: TDoubleNode( TDoubleNode* pPrev, TDoubleNode* pNext, const T& Data ) : m_pPrev(pPrev), m_pNext(pNext), m_Data(Data) { // Empty } T& GetData( void ) { return m_Data; } const T& GetData( void ) const { return m_Data; } TDoubleNode* m_pPrev; TDoubleNode* m_pNext; T m_Data; }; class IteratorBase { friend class TDoubleList; public: IteratorBase( void ) : m_pList(NULL), m_pNode(NULL) { // Empty } bool operator++( void ) { assert( m_pList && m_pNode ); m_pNode = m_pNode->m_pNext; return ( m_pNode != NULL ); } bool operator++( int ) { assert( m_pList && m_pNode ); m_pNode = m_pNode->m_pNext; return ( m_pNode != NULL ); } bool operator--( void ) { assert( m_pList && m_pNode ); m_pNode = m_pNode->m_pPrev; return ( m_pNode != NULL ); } bool operator--( int ) { assert( m_pList && m_pNode ); m_pNode = m_pNode->m_pNext; return ( m_pNode != NULL ); } operator bool( void ) const { return ( m_pList != NULL && m_pNode != NULL ); } bool operator==( const IteratorBase& itr ) const { return ( itr.m_pList == m_pList && itr.m_pNode == m_pNode ); } bool operator!=( const IteratorBase& itr ) const { return ( itr.m_pList != m_pList || itr.m_pNode != m_pNode ); } protected: IteratorBase( const TDoubleList* pList, TDoubleNode* pNode ) : m_pList(pList), m_pNode(pNode) { // Empty } protected: const TDoubleList* m_pList; TDoubleNode* m_pNode; }; public: class Iterator : public IteratorBase { friend class TDoubleList; public: Iterator( void ) : IteratorBase() { // Empty } T& operator*( void ) { assert(TDoubleList::IteratorBase::m_pList && TDoubleList::IteratorBase::m_pNode ); return TDoubleList::IteratorBase::m_pNode->GetData(); } protected: Iterator( const TDoubleList* pList, TDoubleNode* pNode ) : IteratorBase( pList, pNode ) { // Empty } }; class ConstIterator : public IteratorBase { friend class TDoubleList; public: ConstIterator( void ) : IteratorBase() { // Empty } const T& operator*( void ) const { assert(TDoubleList::IteratorBase::m_pList && TDoubleList::IteratorBase::m_pNode); return TDoubleList::IteratorBase::m_pNode->GetData(); } protected: ConstIterator( const TDoubleList* pList, TDoubleNode* pNode ) : IteratorBase( pList, pNode ) { // Empty } }; TDoubleList( void ) : m_pHead(NULL), m_pTail(NULL), m_nCount(0) {} ~TDoubleList( void ) { while( ! IsEmpty() ) { RemoveHead(); } } bool IsEmpty( void ) const { return m_pHead == NULL; } unsigned int GetCount( void ) const { return m_nCount; } void InsertHead( const T& Data ) { TDoubleNode* pNode = new TDoubleNode( NULL, m_pHead, Data ); assert( pNode ); if( m_pHead ) { m_pHead->m_pPrev = pNode; } m_pHead = pNode; if( ! m_pTail ) { m_pTail = pNode; } m_nCount++; } void InsertTail( const T& Data ) { TDoubleNode* pNode = new TDoubleNode( m_pTail, NULL, Data ); assert( pNode ); if( m_pTail ) { m_pTail->m_pNext = pNode; } m_pTail = pNode; if( ! m_pHead ) { m_pHead = pNode; } m_nCount++; } void InsertBefore( const Iterator& itr, const T& Data ) { assert( this == itr.m_pList && NULL != itr.m_pNode ); assert( m_pHead && m_pTail && m_nCount ); TDoubleNode* pNode = new TDoubleNode( NULL, itr.m_pNode, Data ); assert( pNode ); if( itr.m_pNode->m_pPrev ) { itr.m_pNode->m_pPrev->m_pNext = pNode; pNode->m_pPrev = itr.m_pNode->m_pPrev; } else { assert( m_pHead == itr.m_pNode ); m_pHead = pNode; } itr.m_pNode->m_pPrev = pNode; m_nCount++; } void InsertAfter( const Iterator& itr, const T& Data ) { assert( this == itr.m_pList && NULL != itr.m_pNode ); assert( m_pHead && m_pTail && m_nCount ); TDoubleNode* pNode = new TDoubleNode( itr.m_pNode, NULL, Data ); assert( pNode ); if( itr.m_pNode->m_pNext ) { itr.m_pNode->m_pNext->m_pPrev = pNode; pNode->m_pNext = itr.m_pNode->m_pNext; } else { assert( m_pTail == itr.m_pNode ); m_pTail = pNode; } itr.m_pNode->m_pNext = pNode; m_nCount++; } T Remove( Iterator& itr ) { assert( this == itr.m_pList && NULL != itr.m_pNode ); assert( m_pHead && m_pTail && m_nCount ); TDoubleNode* pNode = itr.m_pNode; itr.m_pNode = NULL; if( pNode->m_pPrev ) { pNode->m_pPrev->m_pNext = pNode->m_pNext; } else { assert( m_pHead == pNode ); m_pHead = pNode->m_pNext; } if( pNode->m_pNext ) { pNode->m_pNext->m_pPrev = pNode->m_pPrev; } else { assert( m_pTail == pNode ); m_pTail = pNode->m_pPrev; } T Data = pNode->GetData(); delete pNode; m_nCount--; return Data; } T RemoveHead( void ) { assert( m_pHead && m_pTail && m_nCount ); TDoubleNode* pNode = m_pHead; m_pHead = pNode->m_pNext; if( ! m_pHead ) { m_pTail = NULL; } T Data = pNode->GetData(); delete pNode; m_nCount--; return Data; } T RemoveTail( void ) { assert( m_pHead && m_pTail && m_nCount ); TDoubleNode* pNode = m_pTail; m_pTail = pNode->m_pPrev; if( ! m_pTail ) { m_pHead = NULL; } T Data = pNode->GetData(); delete pNode; m_nCount--; return Data; } Iterator Begin( void ) { return Iterator( this, m_pHead ); } ConstIterator Begin( void ) const { return ConstIterator( this, m_pHead ); } Iterator End( void ) { return Iterator( this, NULL ); } ConstIterator End( void ) const { return ConstIterator( this, NULL ); } protected: TDoubleNode* m_pHead; TDoubleNode* m_pTail; unsigned int m_nCount; }; #endif // _TLIST_H