#ifndef __LIST_H__ #define __LIST_H__ #include "genlib.h" ////////////////////////////////////////////////////////////////////////////// // CLink Class // template class CLink { public: inline CLink(); inline ~CLink(); inline BOOL Init(TKey key, TPData pData); protected: inline VOID Uninit(); public: inline VOID Display(); // Inlined Functions public: inline CLink *GetNext(); inline VOID SetNext(CLink *pNext); inline CLink *GetPrev(); inline VOID SetPrev(CLink *pPrev); inline TKey GetKey(); inline TPData GetData(TKey *pTKey = NULL); protected: CLink *m_pNext; CLink *m_pPrev; TKey m_key; TPData m_pData; }; ////////////////////// // Inlined Functions // template inline CLink *CLink::GetNext() { return m_pNext; } template inline VOID CLink::SetNext(CLink *pNext) { m_pNext = pNext; } template inline CLink *CLink::GetPrev() { return m_pPrev; } template inline VOID CLink::SetPrev(CLink *pPrev) { m_pPrev = pPrev; } template inline TKey CLink::GetKey() { return m_key; } template inline TPData CLink::GetData(TKey *pTKey/* = NULL*/) { if ( pTKey != NULL ) { *pTKey = m_key; } return m_pData; } #define CLINKBUFFER #ifdef CLINKBUFFER ////////////////////////////////////////////////////////////////////////////// // CLinkBuffer Class // template class CLinkBuffer { public: inline CLinkBuffer(); inline ~CLinkBuffer(); inline BOOL Init(UINT_32 uiSize = 20); protected: inline VOID Uninit(); // Inlined Functions public: inline CLinkBuffer *GetNext(); inline VOID SetNext(CLinkBuffer *pNext); inline CLink *GetBuffer(); protected: CLinkBuffer *m_pNext; UINT_32 m_uiCLinks; CLink *m_pCLinks; }; ////////////////////////////////////////////////// // Inlined Functions // template inline CLinkBuffer *CLinkBuffer::GetNext() { return m_pNext; } template inline VOID CLinkBuffer::SetNext(CLinkBuffer *pNext) { m_pNext = pNext; } template inline CLink *CLinkBuffer::GetBuffer() { return m_pCLinks; } #endif // CLINKBUFFER ////////////////////////////////////////////////////////////////////////////// // CList Class // template class CListIter; template class CList { public: friend class CListIter; public: inline CList(); inline ~CList(); inline BOOL Init(UINT_32 uiSize = 20); protected: inline VOID Uninit(); inline BOOL Initialized() const; inline BOOL Valid() const; public: // Insertion Functions inline TPData Insert(TPData pData, TKey key); inline TPData InsertForward(TPData pData, TKey key); inline TPData InsertBackward(TPData pData, TKey key); inline TPData InsertFirst(TPData pData, TKey key); inline TPData InsertLast(TPData pData, TKey key); inline VOID InsertArray(TPData pDataArray, size_t sizeItem, UINT_32 uiNumItems); // Deletion Functions inline TPData Remove(TKey key); inline TPData Remove(TPData pData); inline TPData RemoveForward(TKey key); inline TPData RemoveBackward(TKey key); inline TPData RemoveFirst(TKey *pTKey = NULL); inline TPData RemoveLast(TKey *pTKey = NULL); inline VOID RemoveAll(); // Look up Functions inline TPData Peek(TKey key) const; inline TPData PeekForward(TKey key) const; inline TPData PeekBackward(TKey key) const; inline TPData PeekFirst(TKey *pTKey = NULL) const; inline TPData PeekLast(TKey *pTKey = NULL) const; #define SORT_ENABLED #ifdef SORT_ENABLED // Sorting Functions inline BOOL Sort(); // This preforms a Merge Sort #endif // SORT_ENABLED // Display Functions inline VOID Display(); public: inline UINT_32 GetLength(); protected: // CLink Allocation inline CLink *AllocateLink(); inline VOID FreeLink(CLink *pCLink); // Insertion and Deletion inline VOID InsertNext(CLink *pCurr, CLink *pCLink); inline CLink *RemoveNext(CLink *pCurr); inline VOID InsertPrev(CLink *pCurr, CLink *pCLink); inline CLink *RemovePrev(CLink *pCurr); #ifdef SORT_ENABLED // Merge Sort Functions inline CLink *Divide(CLink *pCLink, UINT_32 uiLength); inline CLink *Merge(CLink *pLeft, CLink *pRight); inline VOID MergeAdd(CLink** ppTail, CLink** ppCLink); #endif // SORT_ENABLED protected: CLink *m_pHead; CLink *m_pTail; // This is the same Sentinal Node as the Head UINT_32 m_uiAllocations; UINT_32 m_uiLength; #ifdef CLINKBUFFER CLink *m_pFree; CLinkBuffer *m_pCLinkBuffer; #endif // CLINKBUFFER }; ////////////////////////////////////////////////// // Inlined Functions // template inline BOOL CList::Initialized() const { return (m_pHead != NULL) && (m_pTail != NULL) && (m_uiLength >= 1) && (m_uiAllocations >= 1); } template inline BOOL CList::Valid() const { return Initialized() && (m_pHead == m_pTail) && (m_uiAllocations == m_uiLength); } template inline TPData CList::Insert(TPData pData, TKey key) { return InsertForward(pData, key); } template VOID CList::InsertArray(TPData pDataArray, size_t sizeItem, UINT_32 uiNumItems) { UINT_32 i; for (i = 0; i < uiNumItems; i++) { InsertLast(pDataArray, 0); pDataArray++; } } template inline TPData CList::Remove(TKey key) { return RemoveForward(key); } template inline TPData CList::Peek(TKey key) const { return PeekForward(key); } template inline UINT_32 CList::GetLength() { if (m_uiLength == 0) return 0; else return m_uiLength - 1; } ////////////////////////////////////////////////////////////////////////////// // CListIter Class // template class CListIter { public: inline CListIter(); inline ~CListIter(); inline BOOL Init(CList *pCList); protected: inline VOID Uninit(); inline BOOL Valid(); public: // Iteration Functions inline TPData Peek(TKey key); inline TPData PeekForward(TKey key); inline TPData PeekBackward(TKey key); inline TPData PeekFirst(TKey *pTKey = NULL); inline TPData PeekNext(TKey *pTKey = NULL); inline TPData PeekLast(TKey *pTKey = NULL); inline TPData PeekPrev(TKey *pTKey = NULL); protected: const CList *m_pCList; CLink *m_pCurr; }; ////////////////////////////////////////////////// // Inlined Functions // template inline TPData CListIter::Peek(TKey key) { return PeekForward(key); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Class Implementations // ////////////////////////////////////////////////////////////////////////////// // CLink Class // template inline CLink::CLink() { m_pNext = NULL; m_pPrev = NULL; SetNull(&m_key); m_pData = NULL; } template inline CLink::~CLink() { Uninit(); } template inline BOOL CLink::Init(TKey key, TPData pData) { m_pNext = NULL; m_pPrev = NULL; m_key = key; m_pData = pData; return TRUE; } template inline VOID CLink::Uninit() { m_pNext = NULL; SetNull(&m_key); m_pData = NULL; } template inline VOID CLink::Display() { printf("( k = "); Print(&m_key); printf(", d = %p)", m_pData); } ////////////////////////////////////////////////////////////////////////////// // CLinkBuffer Class // template inline CLinkBuffer::CLinkBuffer() { m_pNext = NULL; m_uiCLinks = 0; m_pCLinks = NULL; } template inline CLinkBuffer::~CLinkBuffer() { Uninit(); } template inline BOOL CLinkBuffer::Init(UINT_32 uiSize/* = 20*/) { UINT_32 i; ASSERT( uiSize != 0 ); m_pNext = NULL; m_uiCLinks = uiSize; m_pCLinks = new CLink[m_uiCLinks]; ASSERT( m_pCLinks != NULL ); for ( i = 1; i < m_uiCLinks; i++ ) { m_pCLinks[i-1].SetNext(&(m_pCLinks[i])); } return TRUE; } template inline VOID CLinkBuffer::Uninit() { m_pNext = NULL; m_uiCLinks = 0; if ( m_pCLinks != NULL ) { delete []m_pCLinks; m_pCLinks = NULL; } } ////////////////////////////////////////////////////////////////////////////// // CList Class // template inline CList::CList() { m_pHead = NULL; m_pTail = NULL; m_uiAllocations = 0; m_uiLength = 0; #ifdef CLINKBUFFER m_pFree = NULL; m_pCLinkBuffer = NULL; #endif // CLINKBUFFER } template inline CList::~CList() { Uninit(); } template inline BOOL CList::Init(UINT_32 uiSize/* = 20*/) { ASSERT( m_pHead == NULL && m_pTail == NULL && m_uiLength == 0 ); #ifdef CLINKBUFFER if ( m_pFree == NULL ) { //printf("*** Allocating a new link Buffer ***\n"); // The free list is empty so // dynamically allocate a new buffer CLinkBuffer *pCLinkBuffer; pCLinkBuffer = new CLinkBuffer; ASSERT( pCLinkBuffer != NULL ); pCLinkBuffer->Init(uiSize); // Insert the new buffer at the beginning of the buffer list // so that we can deallocate it later pCLinkBuffer->SetNext(m_pCLinkBuffer); m_pCLinkBuffer = pCLinkBuffer; // Set the free list to be the list contained in the buffer m_pFree = m_pCLinkBuffer->GetBuffer(); ASSERT( m_pFree != NULL ); } ASSERT( m_pFree != NULL ); #endif // CLINKBUFFER m_pHead = AllocateLink(); ASSERT( m_pHead != NULL ); m_pHead->SetNext(m_pHead); m_pHead->SetPrev(m_pHead); m_pTail = m_pHead; m_uiLength = 1; ASSERT( Valid() ); return TRUE; } template inline VOID CList::Uninit() { if ( m_pHead != NULL ) { RemoveAll(); ASSERT( m_pHead != NULL && m_pHead == m_pTail && m_uiLength == 1 ); m_uiLength = 0; FreeLink(m_pHead); ASSERT( m_uiAllocations == 0 ); } m_pHead = NULL; m_pTail = NULL; m_uiAllocations = 0; m_uiLength = 0; #ifdef CLINKBUFFER while ( m_pCLinkBuffer != NULL ) { CLinkBuffer *pCLinkBuffer; pCLinkBuffer = m_pCLinkBuffer; m_pCLinkBuffer = m_pCLinkBuffer->GetNext(); delete pCLinkBuffer; } m_pFree = NULL; #endif // CLINKBUFFER } template inline TPData CList::InsertForward(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Find the correct position in the CList for the CLink for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetNext()->GetKey() > key ) { break; } } // Insert the CLink at the current position in the CList InsertNext(pCurr, pCLink); return pData; } template inline TPData CList::InsertBackward(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Find the correct position in the CList for the CLink for ( pCurr = m_pTail; pCurr->GetPrev() != m_pHead; pCurr = pCurr->GetPrev() ) { if ( pCurr->GetPrev()->GetKey() < key ) { break; } } // Insert the CLink at the current position in the CList InsertPrev(pCurr, pCLink); return pData; } template inline TPData CList::InsertFirst(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Insert the CLink at the beginning of the CList InsertNext(m_pHead, pCLink); return pData; } template inline TPData CList::InsertLast(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Insert the CLink at the end of the CList InsertPrev(m_pTail, pCLink); return pData; } template inline TPData CList::Remove(TPData pData) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; TPData pDataFound; pDataFound = NULL; // Find the correct position in the CList for the CLink for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetNext()->GetData() == pData ) { // Remove this next CLink pCLink = RemoveNext(pCurr); ASSERT( pCLink != NULL ); // Pull out the Data from the CLink pDataFound = pCLink->GetData(NULL); // Deallocate the CLink FreeLink(pCLink); break; } } return pDataFound; } template inline TPData CList::RemoveForward(TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; TPData pData; pData = NULL; // Find the correct position in the CList for the CLink for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetNext()->GetKey() < key ) { // Not there yet continue; } else if ( pCurr->GetNext()->GetKey() == key ) { // We found it // Remove this next CLink pCLink = RemoveNext(pCurr); ASSERT( pCLink != NULL ); // Pull out the Data from the CLink pData = pCLink->GetData(NULL); // Deallocate the CLink FreeLink(pCLink); break; } else { // We passed it break; } } return pData; } template inline TPData CList::RemoveBackward(TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; TPData pData; pData = NULL; // Find the correct position in the CList for the CLink for ( pCurr = m_pTail; pCurr->GetPrev() != m_pHead; pCurr = pCurr->GetPrev() ) { if ( pCurr->GetPrev()->GetKey() > key ) { // Not there yet continue; } else if ( pCurr->GetPrev()->GetKey() == key ) { // We found it // Remove this prev CLink pCLink = RemovePrev(pCurr); ASSERT( pCLink != NULL ); // Pull out the Data from the CLink pData = pCLink->GetData(NULL); // Deallocate the CLink FreeLink(pCLink); break; } else { // We passed it break; } } return pData; } template inline TPData CList::RemoveFirst(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); CLink *pCLink; TPData pData; // Remove the CLink at the beginning of the CList pCLink = RemoveNext(m_pHead); if ( pCLink == NULL ) { return NULL; } // Pull out the Data from the CLink pData = pCLink->GetData(pTKey); // Deallocate the CLink FreeLink(pCLink); return pData; } template inline TPData CList::RemoveLast(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); CLink *pCLink; TPData pData; // Remove the CLink at the end of the CList pCLink = RemovePrev(m_pTail); if ( pCLink == NULL ) { return NULL; } // Pull out the Data from the CLink pData = pCLink->GetData(pTKey); // Deallocate the CLink FreeLink(pCLink); return pData; } template inline VOID CList::RemoveAll() { ASSERT( Valid() ); CLink *pCLink; pCLink = RemoveNext(m_pHead); while ( pCLink != NULL ) { FreeLink(pCLink); pCLink = RemoveNext(m_pHead); } } template inline TPData CList::PeekForward(TKey key) const { ASSERT( Valid() ); CLink *pCurr; TPData pData; pData = NULL; // Find the correct position in the CList for the CLink for ( pCurr = m_pHead->GetNext(); pCurr != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetKey() < key ) { // Not there yet continue; } else if ( pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CList::PeekBackward(TKey key) const { ASSERT( Valid() ); CLink *pCurr; TPData pData; pData = NULL; // Find the correct position in the CList for the CLink for ( pCurr = m_pTail->GetPrev(); pCurr != m_pHead; pCurr = pCurr->GetPrev() ) { if ( pCurr->GetKey() > key ) { // Not there yet continue; } else if ( pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CList::PeekFirst(TKey *pTKey/* = NULL */) const { CLink *pCurr; ASSERT( Valid() ); pCurr = m_pHead->GetNext(); if ( pCurr == m_pTail ) { pCurr = NULL; return NULL; } return pCurr->GetData(pTKey); } template inline TPData CList::PeekLast(TKey *pTKey/* = NULL */) const { CLink *pCurr; ASSERT( Valid() ); pCurr = m_pTail->GetPrev(); if ( pCurr == m_pHead ) { pCurr = NULL; return NULL; } return pCurr->GetData(pTKey); } template inline VOID CList::Display() { ASSERT( Valid() ); CLink *pCurr; for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr == m_pHead ) { printf("(HEAD)->"); } pCurr->GetNext()->Display(); printf("->"); if ( m_pTail == pCurr->GetNext() ) { printf("<-(TAIL)"); } } printf("\n"); } #ifdef CLINKBUFFER template inline CLink *CList::AllocateLink() { CLink *pCLink; ASSERT( m_uiAllocations == m_uiLength ); if ( m_pFree == NULL ) { //printf("*** Allocating a new link Buffer ***\n"); // The free list is empty so // dynamically allocate a new buffer CLinkBuffer *pCLinkBuffer; pCLinkBuffer = new CLinkBuffer; ASSERT( pCLinkBuffer != NULL ); pCLinkBuffer->Init(); // Insert the new buffer at the beginning of the buffer list // so that we can deallocate it later pCLinkBuffer->SetNext(m_pCLinkBuffer); m_pCLinkBuffer = pCLinkBuffer; // Set the free list to be the list contained in the buffer m_pFree = m_pCLinkBuffer->GetBuffer(); ASSERT( m_pFree != NULL ); } ASSERT( m_pFree != NULL ); // Take the first free link off the free list pCLink = m_pFree; m_pFree = m_pFree->GetNext(); pCLink->SetNext(NULL); m_uiAllocations++; return pCLink; } template inline VOID CList::FreeLink(CLink *pCLink) { ASSERT( pCLink != NULL ); // Insert the newly freed link at the beginning of the free list to be reused pCLink->SetNext(m_pFree); m_pFree = pCLink; m_uiAllocations--; ASSERT( m_uiAllocations == m_uiLength ); } #else // CLINKBUFFER template inline CLink *CList::AllocateLink() { CLink *pCLink; ASSERT( Valid() ); pCLink = new CLink; ASSERT( pCLink != NULL ); m_uiAllocations++; return pCLink; } template inline VOID CList::FreeLink(CLink *pCLink) { ASSERT( Initialized() ); ASSERT( pCLink != NULL ); delete pCLink; m_uiAllocations--; ASSERT( Valid() ); } #endif // CLINKBUFFER template inline VOID CList::InsertNext(CLink *pCurr, CLink *pCLink) { ASSERT( Initialized() ); ASSERT( pCurr != NULL && pCLink != NULL ); pCLink->SetNext(pCurr->GetNext()); pCLink->SetPrev(pCurr); pCurr->GetNext()->SetPrev(pCLink); pCurr->SetNext(pCLink); m_uiLength++; ASSERT( Valid() ); } template inline CLink *CList::RemoveNext(CLink *pCurr) { ASSERT( Valid() ); ASSERT( pCurr != NULL ); CLink *pCLink; pCLink = pCurr->GetNext(); if ( pCLink == m_pTail ) { return NULL; } pCurr->SetNext(pCLink->GetNext()); pCurr->GetNext()->SetPrev(pCurr); m_uiLength--; return pCLink; } template inline VOID CList::InsertPrev(CLink *pCurr, CLink *pCLink) { ASSERT( Initialized() ); ASSERT( pCurr != NULL && pCLink != NULL ); pCLink->SetPrev(pCurr->GetPrev()); pCLink->SetNext(pCurr); pCurr->GetPrev()->SetNext(pCLink); pCurr->SetPrev(pCLink); m_uiLength++; ASSERT( Valid() ); } template inline CLink *CList::RemovePrev(CLink *pCurr) { ASSERT( Valid() ); ASSERT( pCurr != NULL ); CLink *pCLink; pCLink = pCurr->GetPrev(); if ( pCLink == m_pTail ) { return NULL; } pCurr->SetPrev(pCLink->GetPrev()); pCurr->GetPrev()->SetNext(pCurr); m_uiLength--; return pCLink; } #ifdef SORT_ENABLED template inline BOOL CList::Sort() { ASSERT( Valid() ); UINT_32 i; CLink *pCLink; if ( GetLength() == 0 ) { return TRUE; } pCLink = Divide(m_pHead->GetNext(), GetLength()); ASSERT( pCLink != NULL ); m_pHead->SetNext(pCLink); i = 0; for ( pCLink = m_pHead; pCLink->GetNext() != NULL; pCLink = pCLink->GetNext() ) { pCLink->GetNext()->SetPrev(pCLink); i++; } ASSERT( i == GetLength() ); pCLink->SetNext(m_pTail); m_pTail->SetPrev(pCLink); return TRUE; } template inline CLink *CList::Divide(CLink *pCLink, UINT_32 uiLength) { ASSERT( m_pHead != NULL && m_pTail != NULL ); ASSERT( uiLength > 0 && pCLink != NULL ); CLink *pCurr, *pLeft, *pRight; UINT_32 uiLeft, uiRight; UINT_32 i; if ( uiLength == 1 ) { pCLink->SetNext(NULL); return pCLink; } uiLeft = uiLength/2; uiRight = uiLength - uiLeft; pCurr = pCLink; for ( i = 1; i < uiLeft; i++ ) { ASSERT( pCurr != NULL ); pCurr = pCurr->GetNext(); } pLeft = pCLink; pRight = pCurr->GetNext(); ASSERT( pRight != NULL ); pCurr->SetNext(NULL); return Merge(Divide(pLeft, uiLeft), Divide(pRight, uiRight)); } template inline CLink *CList::Merge(CLink *pLeft, CLink *pRight) { ASSERT( m_pHead != NULL && m_pTail != NULL ); ASSERT( pLeft != NULL && pRight != NULL ); CLink *pHead, *pTail; // if ( pLeft->KeyCompare(pRight->GetKeyInteger()) < 0 ) if ( pLeft->GetKey() < pRight->GetKey() ) { pHead = pLeft; pLeft = pLeft->GetNext(); } else { pHead = pRight; pRight = pRight->GetNext(); } pTail = pHead; while ( pLeft != NULL && pRight != NULL ) { if ( pLeft->GetKey() < pRight->GetKey() ) { MergeAdd(&pTail, &pLeft); } else { MergeAdd(&pTail, &pRight); } } if ( pLeft != NULL ) { ASSERT( pRight == NULL ); MergeAdd(&pTail, &pLeft); } if ( pRight != NULL ) { ASSERT( pLeft == NULL ); MergeAdd(&pTail, &pRight); } return pHead; } template inline VOID CList::MergeAdd(CLink** ppTail, CLink** ppCLink) { ASSERT( m_pHead != NULL && m_pTail != NULL ); ASSERT( ppTail != NULL && ppCLink != NULL ); ASSERT( *ppTail != NULL && *ppCLink != NULL ); (*ppTail)->SetNext(*ppCLink); *ppTail = (*ppTail)->GetNext(); *ppCLink = (*ppCLink)->GetNext(); } #endif // SORT_ENABLED ////////////////////////////////////////////////////////////////////////////// // CListIter Class // template inline CListIter::CListIter() { m_pCList = NULL; m_pCurr = NULL; } template inline CListIter::~CListIter() { Uninit(); } template inline BOOL CListIter::Init(CList *pCList) { ASSERT( pCList != NULL ); Uninit(); m_pCList = pCList; m_pCurr = NULL; return TRUE; } template inline VOID CListIter::Uninit() { m_pCList = NULL; m_pCurr = NULL; } template inline BOOL CListIter::Valid() { return (m_pCList != NULL); } template inline TPData CListIter::PeekForward(TKey key) { ASSERT( Valid() ); TPData pData; pData = NULL; // Find the correct position in the CList for the CLink for ( m_pCurr = m_pCList->m_pHead->GetNext(); m_pCurr != m_pCList->m_pTail; m_pCurr = m_pCurr->GetNext() ) { if ( m_pCurr->GetKey() < key ) { // Not there yet continue; } else if ( m_pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = m_pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CListIter::PeekBackward(TKey key) { ASSERT( Valid() ); TPData pData; pData = NULL; // Find the correct position in the CList for the CLink for ( m_pCurr = m_pCList->m_pTail->GetPrev(); m_pCurr != m_pCList->m_pHead; m_pCurr = m_pCurr->GetPrev() ) { if ( m_pCurr->GetKey() > key ) { // Not there yet continue; } else if ( m_pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = m_pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CListIter::PeekFirst(TKey *pTKey/* = NULL */) { ASSERT( Valid() ); m_pCurr = m_pCList->m_pHead->GetNext(); if ( m_pCurr == m_pCList->m_pTail ) { m_pCurr = NULL; return NULL; } return m_pCurr->GetData(pTKey); } template inline TPData CListIter::PeekNext(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetNext(); if ( m_pCurr == m_pCList->m_pTail ) { m_pCurr = NULL; return NULL; } return m_pCurr->GetData(pTKey); } template inline TPData CListIter::PeekLast(TKey *pTKey/* = NULL */) { ASSERT( Valid() ); m_pCurr = m_pCList->m_pTail->GetPrev(); if ( m_pCurr == m_pCList->m_pHead ) { m_pCurr = NULL; return NULL; } return m_pCurr->GetData(pTKey); } template inline TPData CListIter::PeekPrev(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetPrev(); if ( m_pCurr == m_pCList->m_pTail ) { m_pCurr = NULL; return NULL; } return m_pCurr->GetData(pTKey); } /******************/ ////////////////////////////////////////////////////////////////////////////// // CCircularList Class // template class CCircularListIter; template class CCircularList { public: friend class CCircularListIter; public: inline CCircularList(); inline ~CCircularList(); inline BOOL Init(); protected: inline VOID Uninit(); inline BOOL Initialized() const; inline BOOL Valid() const; public: // Insertion Functions inline TPData Insert(TPData pData, TKey key); inline TPData InsertForward(TPData pData, TKey key); inline TPData InsertBackward(TPData pData, TKey key); inline TPData InsertFirst(TPData pData, TKey key); inline TPData InsertLast(TPData pData, TKey key); // Deletion Functions inline TPData Remove(TKey key); inline TPData RemoveForward(TKey key); inline TPData RemoveBackward(TKey key); inline TPData RemoveFirst(TKey *pTKey = NULL); inline TPData RemoveLast(TKey *pTKey = NULL); inline VOID RemoveAll(); // Look up Functions inline TPData Peek(TKey key) const; inline TPData PeekForward(TKey key) const; inline TPData PeekBackward(TKey key) const; inline TPData PeekFirst(TKey *pTKey = NULL) const; inline TPData PeekLast(TKey *pTKey = NULL) const; inline CLink *PeekFirstLink(TKey *pTKey = NULL) const; inline CLink *PeekLastLink(TKey *pTKey = NULL) const; // Display Functions inline VOID Display(); // Inlined Functions public: // UINT_32 GetLength(); // Functions for really getting down and dirty with the list inline CLink *GetHead() {return m_pHead;}; inline CLink *GetTail() {return m_pTail;}; inline VOID SetHead(CLink *pHead) {m_pHead = pHead;}; inline VOID SetTail(CLink *pTail) {m_pTail = pTail;}; inline VOID SetHeadNext(CLink *pNext) {m_pHead->SetNext(pNext);}; inline VOID SetHeadPrev(CLink *pPrev) {m_pHead->SetPrev(pPrev);}; protected: // CLink Allocation inline CLink *AllocateLink(); inline VOID FreeLink(CLink *pCLink); // Insertion and Deletion inline VOID InsertNext(CLink *pCurr, CLink *pCLink); inline CLink *RemoveNext(CLink *pCurr); inline VOID InsertPrev(CLink *pCurr, CLink *pCLink); inline CLink *RemovePrev(CLink *pCurr); protected: CLink *m_pHead; CLink *m_pTail; // This is the same Sentinal Node as the Head // UINT_32 m_uiAllocations; // UINT_32 m_uiLength; /* #ifdef CLINKBUFFER CLink *m_pFree; CLinkBuffer *m_pCLinkBuffer; #endif // CLINKBUFFER */ }; ////////////////////////////////////////////////// // Inlined Functions // template inline BOOL CCircularList::Initialized() const { return (m_pHead != NULL) && (m_pTail != NULL) && 1; // (m_uiLength >= 1) && // (m_uiAllocations >= 1); } template inline BOOL CCircularList::Valid() const { return Initialized() && (m_pHead == m_pTail) && 1; // (m_uiAllocations == m_uiLength); } template inline TPData CCircularList::Insert(TPData pData, TKey key) { return InsertForward(pData, key); } template inline TPData CCircularList::Remove(TKey key) { return RemoveForward(key); } template inline TPData CCircularList::Peek(TKey key) const { return PeekForward(key); } /* template inline UINT_32 CCircularList::GetLength() { return m_uiLength - 1; } */ ////////////////////////////////////////////////////////////////////////////// // CCircularListIter Class // template class CCircularListIter { public: inline CCircularListIter(); inline ~CCircularListIter(); inline BOOL Init(CCircularList *pCCircularList); protected: inline VOID Uninit(); inline BOOL Valid(); public: inline VOID SetCurr(CLink *); // Iteration Functions inline TPData Peek(TKey key); inline TPData PeekForward(TKey key); inline TPData PeekBackward(TKey key); inline TPData PeekFirst(TKey *pTKey = NULL); inline TPData PeekNext(TKey *pTKey = NULL); inline TPData PeekLast(TKey *pTKey = NULL); inline TPData PeekPrev(TKey *pTKey = NULL); inline CLink *PeekFirstLink(TKey *pTKey = NULL); inline CLink *PeekNextLink(TKey *pTKey = NULL); inline CLink *PeekLastLink(TKey *pTKey = NULL); inline CLink *PeekPrevLink(TKey *pTKey = NULL); protected: CCircularList *m_pCCircularList; CLink *m_pCurr; }; ////////////////////////////////////////////////// // Inlined Functions // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Class Implementations // ////////////////////////////////////////////////////////////////////////////// // CCircularList Class // template inline CCircularList::CCircularList() { m_pHead = NULL; m_pTail = NULL; // m_uiAllocations = 0; // m_uiLength = 0; /* #ifdef CLINKBUFFER m_pFree = NULL; m_pCLinkBuffer = NULL; #endif CLINKBUFFER */ } template inline CCircularList::~CCircularList() { Uninit(); } template inline BOOL CCircularList::Init() { ASSERT( m_pHead == NULL && m_pTail == NULL && 1); // m_uiLength == 0 ); m_pHead = AllocateLink(); ASSERT( m_pHead != NULL ); m_pHead->SetNext(m_pHead); m_pHead->SetPrev(m_pHead); m_pTail = m_pHead; // m_uiLength = 1; ASSERT( Valid() ); return TRUE; } template inline VOID CCircularList::Uninit() { ASSERT(m_pHead == m_pTail); if (m_pHead != NULL) FreeLink(m_pHead); m_pHead = NULL; m_pTail = NULL; // m_uiAllocations = 0; // m_uiLength = 0; /* #ifdef CLINKBUFFER while ( m_pCLinkBuffer != NULL ) { CLinkBuffer *pCLinkBuffer; pCLinkBuffer = m_pCLinkBuffer; m_pCLinkBuffer = m_pCLinkBuffer->GetNext(); delete pCLinkBuffer; } m_pFree = NULL; #endif // CLINKBUFFER */ } template inline TPData CCircularList::InsertForward(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Find the correct position in the CCircularList for the CLink for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetNext()->GetKey() > key ) { break; } } // Insert the CLink at the current position in the CCircularList InsertNext(pCurr, pCLink); return pData; } template inline TPData CCircularList::InsertBackward(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Find the correct position in the CCircularList for the CLink for ( pCurr = m_pTail; pCurr->GetPrev() != m_pHead; pCurr = pCurr->GetPrev() ) { if ( pCurr->GetPrev()->GetKey() < key ) { break; } } // Insert the CLink at the current position in the CCircularList InsertPrev(pCurr, pCLink); return pData; } template inline TPData CCircularList::InsertFirst(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Insert the CLink at the beginning of the CCircularList InsertNext(m_pHead, pCLink); return pData; } template inline TPData CCircularList::InsertLast(TPData pData, TKey key) { ASSERT( Valid() ); CLink *pCLink; // Allocate and Initialize a CLink pCLink = AllocateLink(); ASSERT( pCLink != NULL ); pCLink->Init(key, pData); // Insert the CLink at the end of the CCircularList InsertPrev(m_pTail, pCLink); return pData; } template inline TPData CCircularList::RemoveForward(TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; TPData pData; pData = NULL; // Find the correct position in the CCircularList for the CLink for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetNext()->GetKey() < key ) { // Not there yet continue; } else if ( pCurr->GetNext()->GetKey() == key ) { // We found it // Remove this next CLink pCLink = RemoveNext(pCurr); ASSERT( pCLink != NULL ); // Pull out the Data from the CLink pData = pCLink->GetData(NULL); // Deallocate the CLink FreeLink(pCLink); break; } else { // We passed it break; } } return pData; } template inline TPData CCircularList::RemoveBackward(TKey key) { ASSERT( Valid() ); CLink *pCurr; CLink *pCLink; TPData pData; pData = NULL; // Find the correct position in the CCircularList for the CLink for ( pCurr = m_pTail; pCurr->GetPrev() != m_pHead; pCurr = pCurr->GetPrev() ) { if ( pCurr->GetPrev()->GetKey() > key ) { // Not there yet continue; } else if ( pCurr->GetPrev()->GetKey() == key ) { // We found it // Remove this prev CLink pCLink = RemovePrev(pCurr); ASSERT( pCLink != NULL ); // Pull out the Data from the CLink pData = pCLink->GetData(NULL); // Deallocate the CLink FreeLink(pCLink); break; } else { // We passed it break; } } return pData; } template inline TPData CCircularList::RemoveFirst(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); CLink *pCLink; TPData pData; // Remove the CLink at the beginning of the CCircularList pCLink = RemoveNext(m_pHead); if ( pCLink == NULL ) { return NULL; } // Pull out the Data from the CLink pData = pCLink->GetData(pTKey); // Deallocate the CLink FreeLink(pCLink); return pData; } template inline TPData CCircularList::RemoveLast(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); CLink *pCLink; TPData pData; // Remove the CLink at the end of the CCircularList pCLink = RemovePrev(m_pTail); if ( pCLink == NULL ) { return NULL; } // Pull out the Data from the CLink pData = pCLink->GetData(pTKey); // Deallocate the CLink FreeLink(pCLink); return pData; } template inline VOID CCircularList::RemoveAll() { ASSERT( Valid() ); CLink *pCLink; pCLink = RemoveNext(m_pHead); while ( pCLink != NULL ) { FreeLink(pCLink); pCLink = RemoveNext(m_pHead); } } template inline TPData CCircularList::PeekForward(TKey key) const { ASSERT( Valid() ); CLink *pCurr; TPData pData; pData = NULL; // Find the correct position in the CCircularList for the CLink for ( pCurr = m_pHead->GetNext(); pCurr != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr->GetKey() < key ) { // Not there yet continue; } else if ( pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CCircularList::PeekBackward(TKey key) const { ASSERT( Valid() ); CLink *pCurr; TPData pData; pData = NULL; // Find the correct position in the CCircularList for the CLink for ( pCurr = m_pTail->GetPrev(); pCurr != m_pHead; pCurr = pCurr->GetPrev() ) { if ( pCurr->GetKey() > key ) { // Not there yet continue; } else if ( pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CCircularList::PeekFirst(TKey *pTKey /*= NULL */) const { CLink *pCurr; ASSERT( Valid() ); pCurr = m_pHead->GetNext(); if ( pCurr == m_pTail ) { pCurr = NULL; return NULL; } return pCurr->GetData(pTKey); } template inline TPData CCircularList::PeekLast(TKey *pTKey/* = NULL */) const { CLink *pCurr; ASSERT( Valid() ); pCurr = m_pTail->GetPrev(); if ( pCurr == m_pHead ) { pCurr = NULL; return NULL; } return pCurr->GetData(pTKey); } template inline CLink *CCircularList::PeekFirstLink(TKey */*pTKey = NULL */) const { CLink *pCurr; ASSERT( Valid() ); pCurr = m_pHead->GetNext(); if ( pCurr == m_pTail ) { pCurr = NULL; return NULL; } return pCurr; } template inline CLink *CCircularList::PeekLastLink(TKey */*pTKey = NULL */) const { CLink *pCurr; ASSERT( Valid() ); pCurr = m_pTail->GetPrev(); if ( pCurr == m_pHead ) { pCurr = NULL; return NULL; } return pCurr; } template inline VOID CCircularList::Display() { ASSERT( Valid() ); CLink *pCurr; for ( pCurr = m_pHead; pCurr->GetNext() != m_pTail; pCurr = pCurr->GetNext() ) { if ( pCurr == m_pHead ) { printf("(HEAD)->"); } pCurr->GetNext()->Display(); printf("->"); if ( m_pTail == pCurr->GetNext() ) { printf("<-(TAIL)"); } } printf("\n"); } /* #ifdef CLINKBUFFER template inline CLink *CCircularList::AllocateLink() { CLink *pCLink; // ASSERT( m_uiAllocations == m_uiLength ); if ( m_pFree == NULL ) { //printf("*** Allocating a new link Buffer ***\n"); // The free list is empty so // dynamically allocate a new buffer CLinkBuffer *pCLinkBuffer; pCLinkBuffer = new CLinkBuffer; ASSERT( pCLinkBuffer != NULL ); pCLinkBuffer->Init(); // Insert the new buffer at the beginning of the buffer list // so that we can deallocate it later pCLinkBuffer->SetNext(m_pCLinkBuffer); m_pCLinkBuffer = pCLinkBuffer; // Set the free list to be the list contained in the buffer m_pFree = m_pCLinkBuffer->GetBuffer(); ASSERT( m_pFree != NULL ); } ASSERT( m_pFree != NULL ); // Take the first free link off the free list pCLink = m_pFree; m_pFree = m_pFree->GetNext(); pCLink->SetNext(NULL); // m_uiAllocations++; return pCLink; } template inline VOID CCircularList::FreeLink(CLink *pCLink) { ASSERT( pCLink != NULL ); // Insert the newly freed link at the beginning of the free list to be reused pCLink->SetNext(m_pFree); m_pFree = pCLink; // m_uiAllocations--; // ASSERT( m_uiAllocations == m_uiLength ); } #else // CLINKBUFFER */ template inline CLink *CCircularList::AllocateLink() { CLink *pCLink; // Won't be "Valid" before we've allocated the first link // ASSERT( Valid() ); pCLink = new CLink; ASSERT( pCLink != NULL ); // m_uiAllocations++; return pCLink; } template inline VOID CCircularList::FreeLink(CLink *pCLink) { ASSERT( Initialized() ); ASSERT( pCLink != NULL ); delete pCLink; // m_uiAllocations--; ASSERT( Valid() ); } /* #endif // CLINKBUFFER */ template inline VOID CCircularList::InsertNext(CLink *pCurr, CLink *pCLink) { ASSERT( Initialized() ); ASSERT( pCurr != NULL && pCLink != NULL ); // if ((pCurr == m_pHead) && (m_uiLength == 1)) { if ((pCurr == m_pHead) && ((pCurr->GetNext()) == pCurr)) { pCLink->SetNext(pCLink); pCLink->SetPrev(pCLink); } else if (pCurr == m_pHead) { pCLink->SetNext(pCurr->GetNext()); pCLink->SetPrev(pCurr->GetPrev()); pCurr->GetPrev()->SetNext(pCLink); } else { pCLink->SetNext(pCurr->GetNext()); pCLink->SetPrev(pCurr); } pCurr->GetNext()->SetPrev(pCLink); pCurr->SetNext(pCLink); // m_uiLength++; ASSERT( Valid() ); } template inline CLink *CCircularList::RemoveNext(CLink *pCurr) { ASSERT( Valid() ); ASSERT( pCurr != NULL ); CLink *pCLink; pCLink = pCurr->GetNext(); // list is empty if ( pCLink == m_pTail ) { return NULL; } // only one elt in list else if ( pCLink == pCLink->GetPrev() ) { m_pTail->SetNext(m_pTail); m_pTail->SetPrev(m_pTail); } // Removing first elt in list else if ( pCurr == m_pTail) { pCurr->SetNext(pCLink->GetNext()); pCurr->GetNext()->SetPrev(pCLink->GetPrev()); pCLink->GetPrev()->SetNext(pCLink->GetNext()); } else { pCurr->SetNext(pCLink->GetNext()); pCurr->GetNext()->SetPrev(pCurr); } // m_uiLength--; return pCLink; } template inline VOID CCircularList::InsertPrev(CLink *pCurr, CLink *pCLink) { ASSERT( Initialized() ); ASSERT( pCurr != NULL && pCLink != NULL ); if ((pCurr == m_pHead) && ((pCurr->GetNext()) == pCurr)) { // if ((pCurr == m_pTail) && (m_uiLength == 1)) { pCLink->SetNext(pCLink); pCLink->SetPrev(pCLink); } else if (pCurr == m_pHead) { pCLink->SetNext(pCurr->GetNext()); pCLink->SetPrev(pCurr->GetPrev()); pCurr->GetNext()->SetPrev(pCLink); } else { pCLink->SetPrev(pCurr->GetPrev()); pCLink->SetNext(pCurr); } pCurr->GetPrev()->SetNext(pCLink); pCurr->SetPrev(pCLink); // m_uiLength++; ASSERT( Valid() ); } template inline CLink *CCircularList::RemovePrev(CLink *pCurr) { ASSERT( Valid() ); ASSERT( pCurr != NULL ); CLink *pCLink; pCLink = pCurr->GetPrev(); // list is empty if ( pCLink == m_pTail ) { return NULL; } // only one elt in list else if ( pCLink == pCLink->GetPrev()) { m_pTail->SetNext(m_pTail); m_pTail->SetPrev(m_pTail); } // Removing last elt in list else if ( pCurr == m_pTail) { pCurr->SetPrev(pCLink->GetPrev()); pCurr->GetPrev()->SetNext(pCLink->GetNext()); pCLink->GetNext()->SetPrev(pCLink->GetPrev()); } else { pCurr->SetPrev(pCLink->GetPrev()); pCurr->GetPrev()->SetNext(pCurr); } // m_uiLength--; return pCLink; } ////////////////////////////////////////////////////////////////////////////// // CCircularListIter Class // template inline CCircularListIter::CCircularListIter() { m_pCCircularList = NULL; m_pCurr = NULL; } template inline CCircularListIter::~CCircularListIter() { Uninit(); } template inline BOOL CCircularListIter::Init(CCircularList *pCCircularList) { ASSERT( pCCircularList != NULL ); Uninit(); m_pCCircularList = pCCircularList; m_pCurr = NULL; return TRUE; } template inline VOID CCircularListIter::Uninit() { m_pCCircularList = NULL; m_pCurr = NULL; } template inline BOOL CCircularListIter::Valid() { return (m_pCCircularList != NULL); } template inline VOID CCircularListIter::SetCurr(CLink *pCurr) { m_pCurr = pCurr; } template inline TPData CCircularListIter::Peek(TKey key) { return PeekForward(key); } template inline TPData CCircularListIter::PeekForward(TKey key) { ASSERT( Valid() ); TPData pData; pData = NULL; // Find the correct position in the CCircularList for the CLink for ( m_pCurr = m_pCCircularList->m_pHead->GetNext(); m_pCurr != m_pCCircularList->m_pTail; m_pCurr = m_pCurr->GetNext() ) { if ( m_pCurr->GetKey() < key ) { // Not there yet continue; } else if ( m_pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = m_pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CCircularListIter::PeekBackward(TKey key) { ASSERT( Valid() ); TPData pData; pData = NULL; // Find the correct position in the CCircularList for the CLink for ( m_pCurr = m_pCCircularList->m_pTail->GetPrev(); m_pCurr != m_pCCircularList->m_pHead; m_pCurr = m_pCurr->GetPrev() ) { if ( m_pCurr->GetKey() > key ) { // Not there yet continue; } else if ( m_pCurr->GetKey() == key ) { // We found it // Pull out the Data from the CLink pData = m_pCurr->GetData(NULL); break; } else { // We passed it break; } } return pData; } template inline TPData CCircularListIter::PeekFirst(TKey *pTKey/* = NULL */) { ASSERT( Valid() ); m_pCurr = m_pCCircularList->m_pHead->GetNext(); if ( m_pCurr == m_pCCircularList->m_pTail ) { m_pCurr = NULL; return NULL; } return m_pCurr->GetData(pTKey); } template inline TPData CCircularListIter::PeekNext(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetNext(); return m_pCurr->GetData(pTKey); } template inline TPData CCircularListIter::PeekLast(TKey *pTKey/* = NULL */) { ASSERT( Valid() ); m_pCurr = m_pCCircularList->m_pTail->GetPrev(); if ( m_pCurr == m_pCCircularList->m_pHead ) { m_pCurr = NULL; return NULL; } return m_pCurr->GetData(pTKey); } template inline TPData CCircularListIter::PeekPrev(TKey *pTKey/* = NULL*/) { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetPrev(); return m_pCurr->GetData(pTKey); } template inline CLink *CCircularListIter::PeekFirstLink(TKey */*pTKey = NULL*/) { ASSERT( Valid() ); m_pCurr = m_pCCircularList->m_pHead->GetNext(); if ( m_pCurr == m_pCCircularList->m_pTail ) { m_pCurr = NULL; return NULL; } return m_pCurr; } template inline CLink *CCircularListIter::PeekNextLink(TKey */*pTKey = NULL*/) { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetNext(); return m_pCurr; } template inline CLink *CCircularListIter::PeekLastLink(TKey */*pTKey = NULL*/) { ASSERT( Valid() ); m_pCurr = m_pCCircularList->m_pTail->GetPrev(); if ( m_pCurr == m_pCCircularList->m_pHead ) { m_pCurr = NULL; return NULL; } return m_pCurr; } template inline CLink *CCircularListIter::PeekPrevLink(TKey */*pTKey = NULL*/) { ASSERT( Valid() ); if ( m_pCurr == NULL ) { return NULL; } m_pCurr = m_pCurr->GetPrev(); return m_pCurr; } inline VOID SetNull(DOUBLE *pd) { *pd = 0.0; } inline VOID SetNull(FLOAT *pf) { *pf = 0.0; } inline VOID SetNull(UINT_32 *pui) { *pui = 0; } inline VOID SetNull(UINT_8 *pui) { *pui = 0; } inline VOID Print(DOUBLE *pd) { printf("%f\n",*pd); } inline VOID Print(UINT_32 *pui) { printf("%li\n",*pui); } #endif // __LIST_H__