#ifndef __OBJECTLIST_H__ #define __OBJECTLIST_H__ #include "genlib.h" ////////////////////////////////////////////////////////////////////////////// // CObjectList Class // template class CObjectListIter; template class CObjectList { public: friend class CObjectListIter; public: inline CObjectList(); inline ~CObjectList(); inline BOOL Init(); protected: inline VOID Uninit(); inline BOOL Initialized() const; inline BOOL Valid() const; public: // Insertion Functions inline VOID InsertFirst(TLink *pLink); inline VOID InsertLast(TLink *pLink); inline VOID InsertNext(TLink *pLinkBase, TLink *pLink); inline VOID InsertPrev(TLink *pLinkBase, TLink *pLink); protected: inline VOID InsertNext(TLink *pLinkBase, TLink *pLinkFirst, TLink *pLinkLast, UINT_32 uiLength); inline VOID InsertPrev(TLink *pLinkBase, TLink *pLinkFirst, TLink *pLinkLast, UINT_32 uiLength); public: inline VOID Splice(CObjectList *pList); inline VOID SpliceFirst(CObjectList *pList); inline VOID SpliceLast(CObjectList *pList); inline VOID SpliceNext(TLink *pLinkBase, CObjectList *pList); inline VOID SplicePrev(TLink *pLinkBase, CObjectList *pList); public: // Deletion Functions inline VOID Remove(TLink *pLink); inline TLink *RemoveFirst(); inline TLink *RemoveLast(); inline TLink *RemoveNext(TLink *pLink); inline TLink *RemovePrev(TLink *pLink); inline VOID RemoveAll(); // Look up Functions inline TLink *PeekFirst() const; inline TLink *PeekLast() const; inline TLink *PeekNext(TLink *pLink) const; inline TLink *PeekPrev(TLink *pLink) const; // Display Functions inline VOID Display() const; //Inlined Functions public: inline UINT_32 GetLength() const; protected: TLink m_linkSentinel; TLink *m_pHead; TLink *m_pTail; // This is the same Sentinel Node as the Head UINT_32 m_uiLength; }; ////////////////////////////////////////////////// // Inlined Functions // template inline BOOL CObjectList::Initialized() const { return (m_pHead != NULL) && (m_pTail != NULL); } template inline BOOL CObjectList::Valid() const { return Initialized() && (m_pHead == m_pTail); } template inline UINT_32 CObjectList::GetLength() const { return m_uiLength; } ////////////////////////////////////////////////////////////////////////////// // CObjectListIter Class // template class CObjectListIter { public: inline CObjectListIter(); inline ~CObjectListIter(); inline BOOL Init(CObjectList *pCObjectList); protected: inline VOID Uninit(); inline BOOL Valid(); public: // Iteration Functions inline TLink *PeekFirst(); inline TLink *PeekNext(); inline TLink *PeekNextWrap(); inline TLink *PeekLast(); inline TLink *PeekPrev(); inline TLink *PeekPrevWrap(); protected: CObjectList *m_pCObjectList; TLink *m_pCurr; }; ////////////////////////////////////////////////// // Inlined Functions // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Class Implementations // ////////////////////////////////////////////////////////////////////////////// // CObjectList Class // template inline CObjectList::CObjectList() { RemoveAll(); } template inline CObjectList::~CObjectList() { Uninit(); } template inline BOOL CObjectList::Init() { ASSERT( m_pHead == &m_linkSentinel ); ASSERT( m_pTail == &m_linkSentinel ); ASSERT( m_pHead->GetNextLink() == m_pTail ); ASSERT( m_pTail->GetPrevLink() == m_pHead ); ASSERT( m_uiLength == 0 ); ASSERT( Valid() ); return TRUE; } template inline VOID CObjectList::Uninit() { RemoveAll(); } template inline VOID CObjectList::InsertFirst(TLink *pLink) { // Insert the Link at the beginning of the CObjectList InsertNext(m_pHead, pLink); } template inline VOID CObjectList::InsertLast(TLink *pLink) { // Insert the Link at the end of the CObjectList InsertPrev(m_pTail, pLink); } template inline VOID CObjectList::InsertNext(TLink *pLinkBase, TLink *pLink) { ASSERT( pLinkBase != NULL && pLink != NULL ); pLink->SetNextLink(pLinkBase->GetNextLink()); pLink->SetPrevLink(pLinkBase); pLinkBase->GetNextLink()->SetPrevLink(pLink); pLinkBase->SetNextLink(pLink); m_uiLength++; } template inline VOID CObjectList::InsertPrev(TLink *pLinkBase, TLink *pLink) { ASSERT( pLinkBase != NULL && pLink != NULL ); pLink->SetPrevLink(pLinkBase->GetPrevLink()); pLink->SetNextLink(pLinkBase); pLinkBase->GetPrevLink()->SetNextLink(pLink); pLinkBase->SetPrevLink(pLink); m_uiLength++; } template inline VOID CObjectList::InsertNext(TLink *pLinkBase, TLink *pLinkFirst, TLink *pLinkLast, UINT_32 uiLength) { ASSERT( pLinkBase != NULL && pLinkFirst != NULL && pLinkLast != NULL ); ASSERT( uiLength > 0 ); pLinkLast->SetNextLink(pLinkBase->GetNextLink()); pLinkFirst->SetPrevLink(pLinkBase); pLinkBase->GetNextLink()->SetPrevLink(pLinkLast); pLinkBase->SetNextLink(pLinkFirst); m_uiLength += uiLength; } template inline VOID CObjectList::InsertPrev(TLink *pLinkBase, TLink *pLinkFirst, TLink *pLinkLast, UINT_32 uiLength) { ASSERT( pLinkBase != NULL && pLinkFirst != NULL && pLinkLast != NULL ); ASSERT( uiLength > 0 ); pLinkFirst->SetPrevLink(pLinkBase->GetPrevLink()); pLinkLast->SetNextLink(pLinkBase); pLinkBase->GetPrevLink()->SetNextLink(pLinkFirst); pLinkBase->SetPrevLink(pLinkLast); m_uiLength += uiLength; } template inline VOID CObjectList::Splice(CObjectList *pList) { SpliceLast(pList); } template inline VOID CObjectList::SpliceFirst(CObjectList *pList) { SpliceNext(m_pHead, pList); } template inline VOID CObjectList::SpliceLast(CObjectList *pList) { SplicePrev(m_pTail, pList); } template inline VOID CObjectList::SpliceNext(TLink *pLinkBase, CObjectList *pList) { ASSERT( pLinkBase != NULL && pList != NULL ); if ( pList->GetLength() == 0 ) { return; } InsertNext(pLinkBase, pList->PeekFirst(), pList->PeekLast(), pList->GetLength()); pList->RemoveAll(); } template inline VOID CObjectList::SplicePrev(TLink *pLinkBase, CObjectList *pList) { ASSERT( pLinkBase != NULL && pList != NULL ); if ( pList->GetLength() == 0 ) { return; } InsertPrev(pLinkBase, pList->PeekFirst(), pList->PeekLast(), pList->GetLength()); pList->RemoveAll(); } template inline VOID CObjectList::Remove(TLink *pLink) { ASSERT( pLink != NULL ); ASSERT( pLink != m_pHead ); ASSERT( m_uiLength > 0 ); pLink->GetPrevLink()->SetNextLink(pLink->GetNextLink()); pLink->GetNextLink()->SetPrevLink(pLink->GetPrevLink()); pLink->SetPrevLink(NULL); pLink->SetNextLink(NULL); m_uiLength--; } template inline TLink *CObjectList::RemoveFirst() { return RemoveNext(m_pHead); } template inline TLink *CObjectList::RemoveLast() { return RemovePrev(m_pTail); } template inline TLink *CObjectList::RemoveNext(TLink *pLink) { ASSERT( pLink != NULL ); pLink = pLink->GetNextLink(); if ( pLink == m_pTail ) { ASSERT( m_uiLength == 0 ); return NULL; } Remove(pLink); return pLink; } template inline TLink *CObjectList::RemovePrev(TLink *pLink) { ASSERT( pLink != NULL ); pLink = pLink->GetPrevLink(); if ( pLink == m_pHead ) { ASSERT( m_uiLength == 0 ); return NULL; } Remove(pLink); return pLink; } template inline VOID CObjectList::RemoveAll() { m_pHead = &m_linkSentinel; m_pTail = &m_linkSentinel; m_pHead->SetNextLink(m_pTail); m_pTail->SetPrevLink(m_pHead); m_uiLength = 0; } template inline TLink *CObjectList::PeekFirst() const { return PeekNext(m_pHead); } template inline TLink *CObjectList::PeekLast() const { return PeekPrev(m_pTail); } template inline TLink *CObjectList::PeekNext(TLink *pLink) const { ASSERT( pLink != NULL ); pLink = pLink->GetNextLink(); if ( pLink == m_pTail ) { return NULL; } return pLink; } template inline TLink *CObjectList::PeekPrev(TLink *pLink) const { ASSERT( pLink != NULL ); pLink = pLink->GetPrevLink(); if ( pLink == m_pHead ) { return NULL; } return pLink; } template inline VOID CObjectList::Display() const { ASSERT( Valid() ); TLink *pCurr; printf("START: CObjectList %p\n", this); for ( pCurr = m_pHead->GetNextLink(); pCurr != m_pTail; pCurr = pCurr->GetNextLink() ) { pCurr->Display(); } printf("END : CObjectList %p\n", this); } ////////////////////////////////////////////////////////////////////////////// // CObjectListIter Class // template inline CObjectListIter::CObjectListIter() { m_pCObjectList = NULL; m_pCurr = NULL; } template inline CObjectListIter::~CObjectListIter() { Uninit(); } template inline BOOL CObjectListIter::Init(CObjectList *pCObjectList) { ASSERT( pCObjectList != NULL ); Uninit(); m_pCObjectList = pCObjectList; m_pCurr = NULL; return TRUE; } template inline VOID CObjectListIter::Uninit() { m_pCObjectList = NULL; m_pCurr = NULL; } template inline BOOL CObjectListIter::Valid() { return (m_pCObjectList != NULL); } template inline TLink *CObjectListIter::PeekFirst() { ASSERT( Valid() ); m_pCurr = m_pCObjectList->m_pHead->GetNextLink(); if ( m_pCurr == m_pCObjectList->m_pTail ) { m_pCurr = NULL; } return m_pCurr; } template inline TLink *CObjectListIter::PeekNext() { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetNextLink(); if ( m_pCurr == m_pCObjectList->m_pTail ) { m_pCurr = NULL; } return m_pCurr; } template inline TLink *CObjectListIter::PeekNextWrap() { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetNextLink(); if ( m_pCurr == m_pCObjectList->m_pTail ) { m_pCurr = m_pCurr->GetNextLink(); if ( m_pCurr == m_pCObjectList->m_pTail ) { m_pCurr = NULL; } } return m_pCurr; } template inline TLink *CObjectListIter::PeekLast() { ASSERT( Valid() ); m_pCurr = m_pCObjectList->m_pTail->GetPrevLink(); if ( m_pCurr == m_pCObjectList->m_pHead ) { m_pCurr = NULL; } return m_pCurr; } template inline TLink *CObjectListIter::PeekPrev() { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetPrevLink(); if ( m_pCurr == m_pCObjectList->m_pHead ) { m_pCurr = NULL; } return m_pCurr; } template inline TLink *CObjectListIter::PeekPrevWrap() { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetPrevLink(); if ( m_pCurr == m_pCObjectList->m_pHead ) { m_pCurr = m_pCurr->GetPrevLink(); if ( m_pCurr == m_pCObjectList->m_pHead ) { m_pCurr = NULL; } } return m_pCurr; } #endif // __OBJECTLIST_H__