mirror of https://github.com/tongzx/nt5src
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.
294 lines
6.3 KiB
294 lines
6.3 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 2000.
|
|
//
|
|
// File: U L I S T . H
|
|
//
|
|
// Contents: Simple list class
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: mbend 1 Nov 2000
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include "array.h"
|
|
|
|
template <class Type>
|
|
class CUList
|
|
{
|
|
class Node
|
|
{
|
|
public:
|
|
Node() : m_pNext(NULL)
|
|
{
|
|
}
|
|
~Node()
|
|
{
|
|
Node * pNode = m_pNext;
|
|
while(pNode)
|
|
{
|
|
Node * pNodeDel = pNode;
|
|
pNode = pNodeDel->m_pNext;
|
|
pNodeDel->m_pNext = NULL;
|
|
delete pNodeDel;
|
|
}
|
|
m_pNext = NULL;
|
|
}
|
|
|
|
Node * m_pNext;
|
|
Type m_type;
|
|
private:
|
|
Node(const Node &);
|
|
Node & operator=(const Node &);
|
|
};
|
|
|
|
public:
|
|
CUList() : m_pList(NULL) {}
|
|
~CUList()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
class Iterator
|
|
{
|
|
friend CUList<Type>;
|
|
public:
|
|
Iterator() : m_ppNode(NULL) {}
|
|
HRESULT HrGetItem(Type ** ppItem)
|
|
{
|
|
if(!m_ppNode || !*m_ppNode)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
*ppItem = &(*m_ppNode)->m_type;
|
|
return S_OK;
|
|
}
|
|
BOOL FIsItem() const
|
|
{
|
|
return NULL != m_ppNode && NULL != *m_ppNode;
|
|
}
|
|
|
|
// Return S_FALSE at the end of the list
|
|
|
|
HRESULT HrNext()
|
|
{
|
|
if(!m_ppNode || !*m_ppNode)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
m_ppNode = &(*m_ppNode)->m_pNext;
|
|
if(!*m_ppNode)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
HRESULT HrErase()
|
|
{
|
|
if(!m_ppNode || !*m_ppNode)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
CUList<Type>::Node * pNode = *m_ppNode;
|
|
*m_ppNode = (*m_ppNode)->m_pNext;
|
|
pNode->m_pNext = NULL;
|
|
delete pNode;
|
|
if(!*m_ppNode)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
HRESULT HrRemoveTransfer(Type & type)
|
|
{
|
|
if(!m_ppNode || !*m_ppNode)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
CUList<Type>::Node * pNode = *m_ppNode;
|
|
*m_ppNode = (*m_ppNode)->m_pNext;
|
|
pNode->m_pNext = NULL;
|
|
TypeTransfer(type, pNode->m_type);
|
|
delete pNode;
|
|
if(!*m_ppNode)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
HRESULT HrMoveToList(CUList<Type> & list)
|
|
{
|
|
if(!m_ppNode || !*m_ppNode)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
CUList<Type>::Node * pNode = *m_ppNode;
|
|
*m_ppNode = (*m_ppNode)->m_pNext;
|
|
pNode->m_pNext = list.m_pList;
|
|
list.m_pList = pNode;
|
|
if(!*m_ppNode)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
return S_OK;
|
|
}
|
|
private:
|
|
Iterator(const Iterator &);
|
|
Iterator & operator=(const Iterator &);
|
|
void Init(CUList<Type>::Node ** ppNode)
|
|
{
|
|
m_ppNode = ppNode;
|
|
}
|
|
CUList<Type>::Node ** m_ppNode;
|
|
};
|
|
|
|
friend class CUList<Type>::Iterator;
|
|
|
|
HRESULT GetIterator(Iterator & iterator)
|
|
{
|
|
iterator.Init(&m_pList);
|
|
return m_pList ? S_OK : S_FALSE;
|
|
}
|
|
|
|
// Sizing functions
|
|
|
|
long GetCount() const
|
|
{
|
|
Node * pNode = m_pList;
|
|
for(long n = 0; NULL != pNode; ++n, pNode = pNode->m_pNext);
|
|
return n;
|
|
}
|
|
BOOL IsEmpty() const
|
|
{
|
|
return NULL == m_pList;
|
|
}
|
|
void Clear()
|
|
{
|
|
delete m_pList;
|
|
m_pList = NULL;
|
|
}
|
|
|
|
// Insertion function
|
|
|
|
HRESULT HrPushFrontDefault()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
Node * pNode = new Node;
|
|
if(pNode)
|
|
{
|
|
pNode->m_pNext = m_pList;
|
|
m_pList = pNode;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HrPushFront(const Type & type)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
Node * pNode = new Node;
|
|
if(pNode)
|
|
{
|
|
hr = HrTypeAssign(pNode->m_type, type);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
pNode->m_pNext = m_pList;
|
|
m_pList = pNode;
|
|
}
|
|
if(FAILED(hr))
|
|
{
|
|
delete pNode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT HrPushFrontTransfer(Type & type)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
Node * pNode = new Node;
|
|
if(pNode)
|
|
{
|
|
TypeTransfer(pNode->m_type, type);
|
|
pNode->m_pNext = m_pList;
|
|
m_pList = pNode;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
Type & Front()
|
|
{
|
|
Assert(m_pList);
|
|
return m_pList->m_type;
|
|
}
|
|
|
|
// Removal
|
|
|
|
HRESULT HrPopFrontTransfer(Type & type)
|
|
{
|
|
if(!m_pList)
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
TypeTransfer(type, m_pList->m_type);
|
|
Node * pNode = m_pList;
|
|
m_pList = pNode->m_pNext;
|
|
pNode->m_pNext = NULL;
|
|
delete pNode;
|
|
return S_OK;
|
|
}
|
|
|
|
void Swap(CUList & ref)
|
|
{
|
|
Node * pNode = ref.m_pList;
|
|
ref.m_pList = m_pList;
|
|
m_pList = pNode;
|
|
}
|
|
|
|
// List manipulation
|
|
|
|
void Append(CUList<Type> & list)
|
|
{
|
|
// Find end of list
|
|
Node ** ppNode = &m_pList;
|
|
while(*ppNode != NULL)
|
|
{
|
|
ppNode = &(*ppNode)->m_pNext;
|
|
}
|
|
*ppNode = list.m_pList;
|
|
list.m_pList = NULL;
|
|
}
|
|
void Prepend(CUList<Type> & list)
|
|
{
|
|
// Find end of list
|
|
Node ** ppNode = &list.m_pList;
|
|
while(*ppNode != NULL)
|
|
{
|
|
ppNode = &(*ppNode)->m_pNext;
|
|
}
|
|
*ppNode = m_pList;
|
|
m_pList = list.m_pList;
|
|
list.m_pList = NULL;
|
|
}
|
|
|
|
private:
|
|
CUList(const CUList &);
|
|
CUList & operator=(const CUList &);
|
|
|
|
Node * m_pList;
|
|
};
|