www.pudn.com > WinGOS.rar > List.h
// CList.h: interface for the CArray class. // ////////////////////////////////////////////////////////////////////// #ifndef _GOS_LIST_H_ #define _GOS_LIST_H_ ///////////////////////////////////////////////////////////////////////////// // CListinline functions template __inline int CList ::GetSize() const { return m_nCount; } template __inline BOOL CList ::IsEmpty() const { return !m_nCount; } template __inline TYPE& CList ::GetHead() { return m_pNodeHead->data; } template __inline TYPE& CList ::GetTail() { return m_pNodeTail->data; } template __inline POSITION CList ::GetHeadPosition() const { return (POSITION) m_pNodeHead; } template __inline POSITION CList ::GetTailPosition() const { return (POSITION) m_pNodeTail; } template __inline TYPE& CList ::GetNext(POSITION& rPosition) // return *Position++ { CNode* pNode = (CNode*) rPosition; rPosition = (POSITION) pNode->pNext; return pNode->data; } template __inline TYPE& CList ::GetPrev(POSITION& rPosition) // return *Position-- { CNode* pNode = (CNode*) rPosition; rPosition = (POSITION) pNode->pPrev; return pNode->data; } template __inline TYPE& CList ::GetAt(POSITION position) { CNode* pNode = (CNode*) position; return pNode->data; } template __inline void CList ::SetAt(POSITION pos, const TYPE& newElement) { CNode* pNode = (CNode*) pos; pNode->data = newElement; } template CList ::CList(int nBlockSize) { m_nCount = 0; m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL; m_pBlocks = NULL; m_nBlockSize = nBlockSize; DEBUG_ONLY(nBlockSize=CHeap::ElementCount(sizeof(CNode),nBlockSize,sizeof(CPlex*))); ASSERT(m_nBlockSize==nBlockSize); } template void CList ::RemoveAll() { // destroy elements m_nCount = 0; m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL; m_pBlocks->FreeDataChain(); m_pBlocks = NULL; } template CList ::~CList() { RemoveAll(); ASSERT(m_nCount == 0); } template PVOID CList ::NewNode(CNode* pPrev, CNode* pNext) { if (m_pNodeFree == NULL) { CNode* pNode = (CNode*)CPlex::CreateHead(m_pBlocks, m_nBlockSize*sizeof(CNode)); pNode += m_nBlockSize - 1; for (int i = m_nBlockSize-1; i >= 0; i--, pNode--) { pNode->pNext = m_pNodeFree; m_pNodeFree = pNode; } } ASSERT(m_pNodeFree != NULL); // we must have something CNode* pNode = m_pNodeFree; m_pNodeFree = m_pNodeFree->pNext; pNode->pPrev = pPrev; pNode->pNext = pNext; m_nCount++; ASSERT(m_nCount > 0); // make sure we don't overflow return pNode; } template void CList ::FreeNode(CNode* pNode) { pNode->pNext = m_pNodeFree; m_pNodeFree = pNode; m_nCount--; ASSERT(m_nCount >= 0); // make sure we don't underflow // if no more elements, cleanup completely if (m_nCount == 0)RemoveAll(); } template POSITION CList ::AddHead(const TYPE& newElement) { CNode* pNewNode = (CNode*)NewNode(NULL, m_pNodeHead); pNewNode->data = newElement; if (m_pNodeHead != NULL) m_pNodeHead->pPrev = pNewNode; else m_pNodeTail = pNewNode; m_pNodeHead = pNewNode; return (POSITION) pNewNode; } template POSITION CList ::AddTail(const TYPE& newElement) { CNode* pNewNode = (CNode*)NewNode(m_pNodeTail, NULL); pNewNode->data = newElement; if (m_pNodeTail != NULL) m_pNodeTail->pNext = pNewNode; else m_pNodeHead = pNewNode; m_pNodeTail = pNewNode; return (POSITION) pNewNode; } template void CList ::AddHead(CList* pNewList) { ASSERT(pNewList); // add a list of same elements to head (maintain order) POSITION pos = pNewList->GetTailPosition(); while (pos != NULL) AddHead(pNewList->GetPrev(pos)); } template void CList ::AddTail(CList* pNewList) { ASSERT(pNewList); // add a list of same elements POSITION pos = pNewList->GetHeadPosition(); while (pos != NULL) AddTail(pNewList->GetNext(pos)); } template TYPE CList ::RemoveHead() { ASSERT(m_pNodeHead != NULL); // don't call on empty list !!! CNode* pOldNode = m_pNodeHead; TYPE returnValue = pOldNode->data; m_pNodeHead = pOldNode->pNext; if (m_pNodeHead != NULL) m_pNodeHead->pPrev = NULL; else m_pNodeTail = NULL; FreeNode(pOldNode); return returnValue; } template TYPE CList ::RemoveTail() { ASSERT(m_pNodeTail != NULL); // don't call on empty list !!! CNode* pOldNode = m_pNodeTail; TYPE returnValue = pOldNode->data; m_pNodeTail = pOldNode->pPrev; if (m_pNodeTail != NULL) m_pNodeTail->pNext = NULL; else m_pNodeHead = NULL; FreeNode(pOldNode); return returnValue; } template POSITION CList ::InsertBefore(POSITION position, const TYPE& newElement) { if (position == NULL) return AddHead(newElement); // insert before nothing -> head of the list // Insert it before position CNode* pOldNode = (CNode*)position; CNode* pNewNode = (CNode*)NewNode(pOldNode->pPrev, pOldNode); pNewNode->data = newElement; if (pOldNode->pPrev != NULL) pOldNode->pPrev->pNext = pNewNode; else m_pNodeHead = pNewNode; pOldNode->pPrev = pNewNode; return (POSITION) pNewNode; } template POSITION CList ::InsertAfter(POSITION position, const TYPE& newElement) { if (position == NULL) return AddTail(newElement); // insert after nothing -> tail of the list // Insert it before position CNode* pOldNode = (CNode*)position; CNode* pNewNode = (CNode*)NewNode(pOldNode, pOldNode->pNext); pNewNode->data = newElement; if (pOldNode->pNext != NULL) pOldNode->pNext->pPrev = pNewNode; else m_pNodeTail = pNewNode; pOldNode->pNext = pNewNode; return (POSITION) pNewNode; } template void CList ::RemoveAt(POSITION position) { CNode* pOldNode = (CNode*) position; // remove pOldNode from list if (pOldNode == m_pNodeHead) m_pNodeHead = pOldNode->pNext; else pOldNode->pPrev->pNext = pOldNode->pNext; if (pOldNode == m_pNodeTail) m_pNodeTail = pOldNode->pPrev; else pOldNode->pNext->pPrev = pOldNode->pPrev; FreeNode(pOldNode); } template POSITION CList ::FindIndex(int nIndex) const { if (nIndex >= m_nCount || nIndex < 0) return NULL; // went too far CNode* pNode = m_pNodeHead; while (nIndex--) pNode = pNode->pNext; return (POSITION) pNode; } template int CList ::GetIndex(POSITION position) const { CNode* pNode; int nIndex=0; for(pNode = m_pNodeHead ; pNode ; pNode = pNode->pNext) { if((POSITION)pNode==position) return nIndex; nIndex++; } return -1; } template POSITION CList ::Find(const TYPE& searchValue, POSITION startAfter) const { CNode* pNode = (CNode*) startAfter; if (pNode == NULL) pNode = m_pNodeHead; // start at head else pNode = pNode->pNext; // start after the one specified for (; pNode != NULL; pNode = pNode->pNext) if(pNode->data==searchValue) return (POSITION)pNode; return NULL; } #endif _GOS_LIST_H_