Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

238 lines
4.9 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) 1998-1998 Microsoft Corporation
//
// File: tlist.cpp
//
//--------------------------------------------------------------------------
//
// tlist.cpp
//
//#include "stdafx.h"
#include "tlist.h"
template <class T>
TListItem<T>::~TListItem()
{
//if (m_pNext != NULL) { delete m_pNext; }
// IMPORTANT: user of the list is required to delete content first!
//ZeroMemory(&m_Tinfo, sizeof(T));
}
template <class T>
void TListItem<T>::Delete(TListItem<T>* pFirst)
{
TListItem<T>* pScan = pFirst;
TListItem<T>* pNext = NULL;
while (pScan)
{
pNext = pScan->m_pNext;
delete pScan;
pScan = pNext;
}
}
template <class T>
LONG TListItem<T>::GetCount(void) const
{
LONG l;
const TListItem<T> *li;
for(l=0,li=this; li!=NULL ; li=li->m_pNext,++l);
return l;
}
template <class T>
TListItem<T>* TListItem<T>::Cat(TListItem<T> *pItem)
{
TListItem<T> *li;
if(this==NULL)
return pItem;
for(li=this ; li->m_pNext!=NULL ; li=li->m_pNext);
li->m_pNext=pItem;
return this;
}
template <class T>
TListItem<T>* TListItem<T>::Remove(TListItem<T> *pItem)
{
TListItem<T> *li,*prev;
if(pItem==this)
return m_pNext;
prev=NULL;
for(li=this; li!=NULL && li!=pItem ; li=li->m_pNext)
prev=li;
if(li==NULL) // item not found in list
return this;
// here it is guaranteed that prev is non-NULL since we checked for
// that condition at the very beginning
prev->SetNext(li->m_pNext);
li->SetNext(NULL);
return this;
}
template <class T>
TListItem<T>* TListItem<T>::GetPrev(TListItem<T> *pItem) const
{
const TListItem<T> *li,*prev;
prev=NULL;
for(li=this ; li!=NULL && li!=pItem ; li=li->m_pNext)
prev=li;
return (TListItem<T>*)prev;
}
template <class T>
TListItem<T> * TListItem<T>::GetItem(LONG index)
{
TListItem<T> *scan;
for (scan = this; scan!=NULL && index; scan = scan->m_pNext)
{
index--;
}
return (scan);
}
template <class T>
TListItem<T>* TListItem<T>::MergeSort(BOOL (* fcnCompare) (T&, T&))
{
if (m_pNext != NULL)
{
TListItem<T> *pList1, *pList2;
Divide(pList1, pList2);
return pList1->MergeSort(fcnCompare)->Merge(pList2->MergeSort(fcnCompare), fcnCompare);
}
return this;
}
template <class T>
void TListItem<T>::Divide(TListItem<T>*& pHead1, TListItem<T>*& pHead2)
{
TListItem<T> *pCurrent = this, *pTail1 = NULL, *pTail2 = NULL;
do
{
pHead1 = pCurrent;
pCurrent = pCurrent->m_pNext;
pHead1->m_pNext = pTail1;
pTail1 = pHead1;
if (pCurrent != NULL)
{
pHead2 = pCurrent;
pCurrent = pCurrent->m_pNext;
pHead2->m_pNext = pTail2;
pTail2 = pHead2;
}
} while (pCurrent != NULL);
}
template <class T>
TListItem<T>* TListItem<T>::Merge(TListItem<T>* pOtherList, BOOL (* fcnCompare) (T&, T&))
{
if (!pOtherList) return this;
TListItem<T>
*pThisList = this, *pResultHead = NULL, *pResultTail = NULL, *pMergeItem = NULL;
while (pThisList && pOtherList)
{
if ( fcnCompare(pThisList->m_Tinfo, pOtherList->m_Tinfo) )
{
pMergeItem = pThisList;
pThisList = pThisList->GetNext();
}
else
{
pMergeItem = pOtherList;
pOtherList = pOtherList->GetNext();
}
pMergeItem->SetNext(NULL);
if (!pResultTail)
{
pResultHead = pResultTail = pMergeItem;
}
else
{
pResultTail->SetNext(pMergeItem);
pResultTail = pMergeItem;
}
}
if (pThisList) pResultTail->SetNext(pThisList);
else pResultTail->SetNext(pOtherList);
return pResultHead;
}
template <class T>
void TList<T>::InsertBefore(TListItem<T> *pItem,TListItem<T> *pInsert)
{
TListItem<T> *prev = GetPrev(pItem);
pInsert->SetNext(pItem);
if (prev) prev->SetNext(pInsert);
else m_pHead = pInsert;
}
template <class T>
void TList<T>::AddTail(TListItem<T> *pItem)
{
m_pHead = m_pHead->AddTail(pItem);
}
template <class T>
void TList<T>::MergeSort(BOOL (* fcnCompare) (T&, T&))
{
if (m_pHead != NULL && m_pHead->GetNext() != NULL)
m_pHead = m_pHead->MergeSort(fcnCompare);
}
template <class T>
void TList<T>::Reverse(void)
{
if( m_pHead )
{
TListItem<T>* pNewHead = m_pHead;
TListItem<T>* pNext = m_pHead->GetNext();
pNewHead->SetNext(NULL);
for( m_pHead = pNext; m_pHead; m_pHead = pNext )
{
pNext = m_pHead->GetNext();
m_pHead->SetNext(pNewHead);
pNewHead = m_pHead;
}
m_pHead = pNewHead;
}
}
template <class T>
HRESULT TList<T>::Copy(TList<T>& rList)
{
HRESULT hr = S_OK;
TListItem<T>* pScan = m_pHead;
for (; pScan; pScan = pScan->GetNext())
{
T& rScan = pScan->GetItemValue();
TListItem<T>* pNew = new TListItem<T>(rScan);
if (pNew)
{
rList.AddHead(pNew);
}
else
{
hr = E_OUTOFMEMORY;
break;
}
}
if (SUCCEEDED(hr))
{
rList.Reverse();
}
return hr;
}