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.
1015 lines
23 KiB
1015 lines
23 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// Module: clist.h
|
|
//
|
|
// Description: list classes
|
|
//
|
|
//
|
|
//@@BEGIN_MSINTERNAL
|
|
// Development Team:
|
|
// Mike McLaughlin
|
|
//
|
|
// History: Date Author Comment
|
|
//
|
|
//@@END_MSINTERNAL
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
|
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
|
// PURPOSE.
|
|
//
|
|
// Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Macros
|
|
//---------------------------------------------------------------------------
|
|
|
|
#define FOR_EACH_LIST_ITEM(pl, p) { \
|
|
PCLIST_ITEM pli; \
|
|
for(pli = (pl)->GetListFirst(); \
|
|
!(pl)->IsListEnd(pli); \
|
|
pli = (pl)->GetListNext(pli)) { \
|
|
p = (pl)->GetListData(pli); \
|
|
(pl)->AssertList(p);
|
|
|
|
#define FOR_EACH_LIST_ITEM_DELETE(pl, p) { \
|
|
PCLIST_ITEM pli, pliNext; \
|
|
for(pli = (pl)->GetListFirst(); !(pl)->IsListEnd(pli); pli = pliNext) { \
|
|
pliNext = (pl)->GetListNext(pli); \
|
|
p = (pl)->GetListData(pli); \
|
|
(pl)->AssertList(p);
|
|
|
|
#define DELETE_LIST_ITEM(pl) \
|
|
pliNext = (pl)->GetListFirst();
|
|
|
|
#define FOR_EACH_LIST_ITEM_BACKWARD(pl, p) { \
|
|
PCLIST_ITEM pli; \
|
|
for(pli = (pl)->GetListLast(); \
|
|
!(pl)->IsListEnd(pli); \
|
|
pli = (pl)->GetListPrevious(pli)) { \
|
|
p = (pl)->GetListData(pli); \
|
|
(pl)->AssertList(p);
|
|
|
|
#define END_EACH_LIST_ITEM } }
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#define FOR_EACH_CLIST_ITEM(pl, p) { \
|
|
for(p = (pl)->GetListFirst(); \
|
|
!(pl)->IsListEnd(p); \
|
|
p = (pl)->GetListNext(p)) { \
|
|
Assert(p);
|
|
|
|
#define FOR_EACH_CLIST_ITEM_DELETE(pl, p, type) { \
|
|
type *pNext; \
|
|
for(p = (pl)->GetListFirst(); !(pl)->IsListEnd(p); p = pNext) { \
|
|
Assert(p); \
|
|
pNext = (pl)->GetListNext(p);
|
|
|
|
#define END_EACH_CLIST_ITEM } }
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Abstract List Classes
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CList : public CObj
|
|
{
|
|
public:
|
|
} CLIST, *PCLIST;
|
|
|
|
typedef class CListItem : public CObj
|
|
{
|
|
public:
|
|
} CLIST_ITEM, *PCLIST_ITEM;
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Singlely Linked List
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListSingle : public CList
|
|
{
|
|
friend class CListSingleItem;
|
|
public:
|
|
CListSingle()
|
|
{
|
|
m_plsiHead = NULL;
|
|
};
|
|
VOID DestroyList()
|
|
{
|
|
m_plsiHead = NULL;
|
|
};
|
|
BOOL IsLstEmpty()
|
|
{
|
|
Assert(this);
|
|
return(m_plsiHead == NULL);
|
|
};
|
|
CListSingleItem *GetListFirst()
|
|
{
|
|
Assert(this);
|
|
return(m_plsiHead);
|
|
};
|
|
BOOL IsListEnd(CListSingleItem *plsi)
|
|
{
|
|
Assert(this);
|
|
return(plsi == NULL);
|
|
};
|
|
CListSingleItem *GetListData(CListSingleItem *plsi)
|
|
{
|
|
return plsi;
|
|
}
|
|
CListSingleItem *GetListNext(CListSingleItem *plsi);
|
|
CListSingleItem **GetListEnd();
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (CListSingleItem::*pfn)(
|
|
)
|
|
);
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (CListSingleItem::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
);
|
|
void ReverseList();
|
|
protected:
|
|
CListSingleItem *m_plsiHead;
|
|
public:
|
|
DefineSignature(0x2048534C); // LSH
|
|
|
|
} CLIST_SINGLE, *PCLIST_SINGLE;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListSingleItem : public CListItem
|
|
{
|
|
friend class CListData;
|
|
friend class CListSingle;
|
|
public:
|
|
CListSingleItem()
|
|
{
|
|
m_plsiNext = NULL;
|
|
};
|
|
VOID AddList(CListSingle *pls)
|
|
{
|
|
Assert(pls);
|
|
Assert(this);
|
|
ASSERT(m_plsiNext == NULL);
|
|
m_plsiNext = pls->m_plsiHead;
|
|
pls->m_plsiHead = this;
|
|
};
|
|
VOID AddListEnd(CListSingle *pls)
|
|
{
|
|
Assert(pls);
|
|
Assert(this);
|
|
ASSERT(m_plsiNext == NULL);
|
|
*(pls->GetListEnd()) = this;
|
|
};
|
|
VOID RemoveList(CListSingle *pls);
|
|
private:
|
|
CListSingleItem *m_plsiNext;
|
|
public:
|
|
DefineSignature(0x2049534C); // LSI
|
|
|
|
} CLIST_SINGLE_ITEM, *PCLIST_SINGLE_ITEM;
|
|
|
|
inline CListSingleItem *
|
|
CListSingle::GetListNext(CListSingleItem *plsi)
|
|
{
|
|
Assert(this);
|
|
return plsi->m_plsiNext;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Doublely Linked List
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListDouble : public CList
|
|
{
|
|
friend class CListDoubleItem;
|
|
public:
|
|
CListDouble()
|
|
{
|
|
InitializeListHead(&m_leHead);
|
|
};
|
|
VOID DestroyList()
|
|
{
|
|
};
|
|
BOOL IsLstEmpty()
|
|
{
|
|
Assert(this);
|
|
return IsListEmpty(&m_leHead);
|
|
};
|
|
ULONG CountList();
|
|
CListDoubleItem *GetListFirst();
|
|
CListDoubleItem *GetListLast();
|
|
BOOL IsListEnd(CListDoubleItem *pldi);
|
|
CListDoubleItem *GetListNext(CListDoubleItem *pldi);
|
|
CListDoubleItem *GetListPrevious(CListDoubleItem *pldi);
|
|
CListDoubleItem *GetListData(CListDoubleItem *pldi)
|
|
{
|
|
return pldi;
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (CListDoubleItem::*pfn)(
|
|
)
|
|
);
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (CListDoubleItem::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
);
|
|
protected:
|
|
LIST_ENTRY m_leHead;
|
|
public:
|
|
DefineSignature(0x2048424C); // LBH
|
|
|
|
} CLIST_DOUBLE, *PCLIST_DOUBLE;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListDoubleItem : public CListItem
|
|
{
|
|
friend class CListDouble;
|
|
public:
|
|
VOID AddList(CListDouble *plb)
|
|
{
|
|
Assert(plb);
|
|
Assert(this);
|
|
ASSERT(m_le.Flink == NULL);
|
|
ASSERT(m_le.Blink == NULL);
|
|
InsertHeadList(&plb->m_leHead, &m_le);
|
|
};
|
|
VOID AddListEnd(CListDouble *plb)
|
|
{
|
|
Assert(plb);
|
|
Assert(this);
|
|
ASSERT(m_le.Flink == NULL);
|
|
ASSERT(m_le.Blink == NULL);
|
|
InsertTailList(&plb->m_leHead, &m_le);
|
|
};
|
|
VOID RemoveList()
|
|
{
|
|
Assert(this);
|
|
ASSERT(m_le.Flink != NULL);
|
|
ASSERT(m_le.Blink != NULL);
|
|
RemoveEntryList(&m_le);
|
|
m_le.Flink = NULL;
|
|
m_le.Blink = NULL;
|
|
};
|
|
VOID RemoveListCheck()
|
|
{
|
|
Assert(this);
|
|
if(m_le.Flink != NULL) {
|
|
RemoveList();
|
|
}
|
|
};
|
|
protected:
|
|
LIST_ENTRY m_le;
|
|
public:
|
|
DefineSignature(0x2049424C); // LBI
|
|
|
|
} CLIST_DOUBLE_ITEM, *PCLIST_DOUBLE_ITEM;
|
|
|
|
inline CListDoubleItem *
|
|
CListDouble::GetListFirst()
|
|
{
|
|
Assert(this);
|
|
ASSERT(m_leHead.Flink != NULL);
|
|
return CONTAINING_RECORD(m_leHead.Flink, CListDoubleItem, m_le);
|
|
}
|
|
|
|
inline CListDoubleItem *
|
|
CListDouble::GetListLast()
|
|
{
|
|
Assert(this);
|
|
ASSERT(m_leHead.Blink != NULL);
|
|
return CONTAINING_RECORD(m_leHead.Blink, CListDoubleItem, m_le);
|
|
}
|
|
|
|
inline BOOL
|
|
CListDouble::IsListEnd(CListDoubleItem *pldi)
|
|
{
|
|
Assert(this);
|
|
return(&pldi->m_le == &m_leHead);
|
|
}
|
|
|
|
inline CListDoubleItem *
|
|
CListDouble::GetListNext(CListDoubleItem *pldi)
|
|
{
|
|
Assert(this);
|
|
ASSERT(pldi->m_le.Flink != NULL);
|
|
return CONTAINING_RECORD(pldi->m_le.Flink, CListDoubleItem, m_le);
|
|
}
|
|
|
|
inline CListDoubleItem *
|
|
CListDouble::GetListPrevious(CListDoubleItem *pldi)
|
|
{
|
|
Assert(this);
|
|
ASSERT(pldi->m_le.Blink != NULL);
|
|
return CONTAINING_RECORD(pldi->m_le.Blink, CListDoubleItem, m_le);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Linked List of Data Pointers
|
|
//---------------------------------------------------------------------------
|
|
|
|
class CListDataItem;
|
|
|
|
typedef class CListDataData : public CListSingleItem
|
|
{
|
|
friend class CListData;
|
|
public:
|
|
CListDataData(
|
|
CListDataItem *pldi
|
|
)
|
|
{
|
|
m_pldiData = pldi;
|
|
};
|
|
CListDataData(
|
|
PVOID p
|
|
)
|
|
{
|
|
m_pldiData = (CListDataItem *)p;
|
|
};
|
|
private:
|
|
CListDataItem *m_pldiData;
|
|
public:
|
|
DefineSignature(0x2044444C); // LDD
|
|
|
|
} CLIST_DATA_DATA, *PCLIST_DATA_DATA;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListData : public CListSingle
|
|
{
|
|
public:
|
|
~CListData()
|
|
{
|
|
CListData::DestroyList();
|
|
};
|
|
VOID DestroyList();
|
|
ULONG CountList();
|
|
CListDataData *GetListFirst()
|
|
{
|
|
Assert(this);
|
|
return (CListDataData *)CListSingle::GetListFirst();
|
|
};
|
|
CListDataData *GetListNext(CListDataData *pldd)
|
|
{
|
|
Assert(this);
|
|
return (CListDataData *)CListSingle::GetListNext(pldd);
|
|
};
|
|
CListDataItem *GetListData(CListDataData *pldd)
|
|
{
|
|
Assert(this);
|
|
return pldd->m_pldiData;
|
|
};
|
|
CListDataItem *GetListFirstData()
|
|
{
|
|
Assert(this);
|
|
return GetListData(GetListFirst());
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (CListDataItem::*pfn)(
|
|
)
|
|
);
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (CListDataItem::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
);
|
|
NTSTATUS CreateUniqueList(
|
|
OUT CListData *pldOut,
|
|
IN PVOID (*GetFunction)(
|
|
IN PVOID pData
|
|
),
|
|
IN BOOL (*CompareFunction)(
|
|
IN PVOID pIn,
|
|
IN PVOID pOut
|
|
)
|
|
);
|
|
BOOL CheckDupList(
|
|
PVOID p
|
|
);
|
|
NTSTATUS AddList(
|
|
PVOID p
|
|
);
|
|
NTSTATUS AddListDup(
|
|
PVOID p
|
|
);
|
|
NTSTATUS AddListEnd(
|
|
PVOID p
|
|
);
|
|
NTSTATUS AddListOrdered(
|
|
PVOID p,
|
|
LONG lFieldOffset
|
|
);
|
|
VOID RemoveList(
|
|
PVOID p
|
|
);
|
|
VOID JoinList(
|
|
CListData *pld
|
|
);
|
|
private:
|
|
CListDataData **GetListEnd()
|
|
{
|
|
return((CListDataData **)CListSingle::GetListEnd());
|
|
};
|
|
public:
|
|
DefineSignature(0x2048444C); // LDH
|
|
|
|
} CLIST_DATA, *PCLIST_DATA;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListDataItem : public CListItem
|
|
{
|
|
public:
|
|
ENUMFUNC Destroy()
|
|
{
|
|
delete this;
|
|
return(STATUS_CONTINUE);
|
|
};
|
|
BOOL CheckDupList(
|
|
PCLIST_DATA pld
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(pld->CheckDupList((PVOID)this));
|
|
};
|
|
NTSTATUS AddList(
|
|
PCLIST_DATA pld
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(pld->AddList((PVOID)this));
|
|
};
|
|
NTSTATUS AddListDup(
|
|
PCLIST_DATA pld
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(pld->AddListDup((PVOID)this));
|
|
};
|
|
NTSTATUS AddListEnd(
|
|
PCLIST_DATA pld
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(pld->AddListEnd((PVOID)this));
|
|
};
|
|
VOID RemoveList(
|
|
PCLIST_DATA pld
|
|
)
|
|
{
|
|
Assert(this);
|
|
pld->RemoveList((PVOID)this);
|
|
};
|
|
DefineSignature(0x2049444C); // LDI
|
|
|
|
} CLIST_DATA_ITEM, *PCLIST_DATA_ITEM;
|
|
|
|
typedef PVOID (*UNIQUE_LIST_PFN)(PVOID);
|
|
typedef BOOL (*UNIQUE_LIST_PFN2)(PVOID, PVOID);
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Multi-Headed Linked List
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListMultiData : public CListDoubleItem
|
|
{
|
|
friend class CListMulti;
|
|
friend class CListMultiItem;
|
|
public:
|
|
CListMultiData(
|
|
PVOID p
|
|
)
|
|
{
|
|
m_plmiData = (CListMultiItem *)p;
|
|
};
|
|
~CListMultiData()
|
|
{
|
|
CListMultiData::RemoveList();
|
|
};
|
|
VOID RemoveList()
|
|
{
|
|
Assert(this);
|
|
CListDoubleItem::RemoveList();
|
|
m_ldiItem.RemoveList();
|
|
};
|
|
private:
|
|
CListDoubleItem m_ldiItem;
|
|
CListMultiItem *m_plmiData;
|
|
public:
|
|
DefineSignature(0x20444d4C); // LMD
|
|
|
|
} CLIST_MULTI_DATA, *PCLIST_MULTI_DATA;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListMulti : public CListDouble
|
|
{
|
|
friend class CListMultiItem;
|
|
public:
|
|
~CListMulti()
|
|
{
|
|
CListMulti::DestroyList();
|
|
};
|
|
VOID DestroyList();
|
|
ENUMFUNC EnumerateList(
|
|
ENUMFUNC (CListMultiItem::*pfn)(
|
|
)
|
|
);
|
|
ENUMFUNC EnumerateList(
|
|
ENUMFUNC (CListMultiItem::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
);
|
|
CListMultiData *GetListFirst()
|
|
{
|
|
Assert(this);
|
|
return (CListMultiData *)CListDouble::GetListFirst();
|
|
};
|
|
CListMultiData *GetListLast()
|
|
{
|
|
Assert(this);
|
|
return (CListMultiData *)CListDouble::GetListLast();
|
|
};
|
|
BOOL IsListEnd(CListMultiData *plmd)
|
|
{
|
|
Assert(this);
|
|
return CListDouble::IsListEnd(plmd);
|
|
};
|
|
CListMultiData *GetListNext(CListMultiData *plmd)
|
|
{
|
|
Assert(this);
|
|
return (CListMultiData *)CListDouble::GetListNext(plmd);
|
|
};
|
|
CListMultiData *GetListPrevious(CListMultiData *plmd)
|
|
{
|
|
Assert(this);
|
|
return (CListMultiData *)CListDouble::GetListPrevious(plmd);
|
|
};
|
|
CListMultiItem *GetListData(CListMultiData *plmd)
|
|
{
|
|
Assert(this);
|
|
return plmd->m_plmiData;
|
|
};
|
|
CListMultiItem *GetListFirstData()
|
|
{
|
|
Assert(this);
|
|
return GetListData(GetListFirst());
|
|
};
|
|
BOOL CheckDupList(
|
|
PVOID p
|
|
);
|
|
NTSTATUS AddList(
|
|
PVOID p,
|
|
CListMultiItem *plmi
|
|
);
|
|
NTSTATUS AddList(
|
|
CListMultiItem *plmi
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(AddList((PVOID)plmi, plmi));
|
|
};
|
|
NTSTATUS AddListEnd(
|
|
PVOID p,
|
|
CListMultiItem *plmi
|
|
);
|
|
NTSTATUS AddListEnd(
|
|
CListMultiItem *plmi
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(AddListEnd((PVOID)plmi, plmi));
|
|
};
|
|
NTSTATUS AddListOrdered(
|
|
PVOID p,
|
|
CListMultiItem *plmi,
|
|
LONG lFieldOffset
|
|
);
|
|
NTSTATUS AddListOrdered(
|
|
CListMultiItem *plmi,
|
|
LONG lFieldOffset
|
|
)
|
|
{
|
|
Assert(this);
|
|
return(AddListOrdered((PVOID)plmi, plmi, lFieldOffset));
|
|
};
|
|
VOID RemoveList(
|
|
PVOID p
|
|
);
|
|
VOID JoinList(
|
|
CListMulti *plm
|
|
);
|
|
DefineSignature(0x20484D4C); // LMH
|
|
|
|
} CLIST_MULTI, *PCLIST_MULTI;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
typedef class CListMultiItem : public CListDouble
|
|
{
|
|
public:
|
|
~CListMultiItem();
|
|
BOOL CheckDupList(
|
|
PCLIST_MULTI plm
|
|
)
|
|
{
|
|
return(plm->CheckDupList((PVOID)this));
|
|
};
|
|
NTSTATUS AddList(
|
|
PCLIST_MULTI plm
|
|
)
|
|
{
|
|
Assert(plm);
|
|
Assert(this);
|
|
return(plm->AddList(this));
|
|
};
|
|
NTSTATUS AddListEnd(
|
|
PCLIST_MULTI plm
|
|
)
|
|
{
|
|
Assert(plm);
|
|
Assert(this);
|
|
return(plm->AddListEnd(this));
|
|
};
|
|
NTSTATUS AddListOrdered(
|
|
PCLIST_MULTI plm,
|
|
LONG lFieldOffset
|
|
)
|
|
{
|
|
Assert(plm);
|
|
Assert(this);
|
|
return(plm->AddListOrdered(this, lFieldOffset));
|
|
};
|
|
VOID RemoveList(
|
|
PCLIST_MULTI plm
|
|
)
|
|
{
|
|
Assert(this);
|
|
plm->RemoveList((PVOID)this);
|
|
};
|
|
DefineSignature(0x20494d4C); // LMI
|
|
|
|
} CLIST_MULTI_ITEM, *PCLIST_MULTI_ITEM;
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Templates
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListSingleDestroy : public CListSingle
|
|
{
|
|
public:
|
|
~ListSingleDestroy()
|
|
{
|
|
ListSingleDestroy::DestroyList();
|
|
};
|
|
VOID DestroyList()
|
|
{
|
|
ListSingleDestroy::EnumerateList(TYPE::Destroy);
|
|
CListSingle::DestroyList();
|
|
};
|
|
VOID AssertList(TYPE *p)
|
|
{
|
|
Assert(p);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (TYPE::*pfn)(
|
|
)
|
|
)
|
|
{
|
|
return CListSingle::EnumerateList(
|
|
(ENUMFUNC (CListSingleItem::*)())pfn);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (TYPE::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
)
|
|
{
|
|
return CListSingle::EnumerateList(
|
|
(ENUMFUNC (CListSingleItem::*)(PVOID))pfn,
|
|
pReference);
|
|
};
|
|
PCLIST_ITEM GetListFirst()
|
|
{
|
|
return CListSingle::GetListFirst();
|
|
};
|
|
BOOL IsListEnd(PCLIST_ITEM pli)
|
|
{
|
|
return CListSingle::IsListEnd((CListSingleItem *)pli);
|
|
};
|
|
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
|
|
{
|
|
return CListSingle::GetListNext((CListSingleItem *)pli);
|
|
};
|
|
TYPE *GetListData(PCLIST_ITEM pli)
|
|
{
|
|
return (TYPE *)CListSingle::GetListData((CListSingleItem *)pli);
|
|
};
|
|
TYPE *GetListFirstData()
|
|
{
|
|
return (TYPE *)CListSingle::GetListData(CListSingle::GetListFirst());
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListDouble : public CListDouble
|
|
{
|
|
public:
|
|
VOID AssertList(TYPE *p)
|
|
{
|
|
Assert(p);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (TYPE::*pfn)()
|
|
)
|
|
{
|
|
return CListDouble::EnumerateList(
|
|
(ENUMFUNC (CListDoubleItem::*)())pfn);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
IN ENUMFUNC (TYPE::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
)
|
|
{
|
|
return CListDouble::EnumerateList(
|
|
(ENUMFUNC (CListDoubleItem::*)(PVOID))pfn,
|
|
pReference);
|
|
};
|
|
PCLIST_ITEM GetListFirst()
|
|
{
|
|
return CListDouble::GetListFirst();
|
|
};
|
|
PCLIST_ITEM GetListLast()
|
|
{
|
|
return CListDouble::GetListLast();
|
|
};
|
|
BOOL IsListEnd(PCLIST_ITEM pli)
|
|
{
|
|
return CListDouble::IsListEnd((CListDoubleItem *)pli);
|
|
};
|
|
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
|
|
{
|
|
return CListDouble::GetListNext((CListDoubleItem *)pli);
|
|
};
|
|
PCLIST_ITEM GetListPrevious(PCLIST_ITEM pli)
|
|
{
|
|
return CListDouble::GetListPrevious((CListDoubleItem *)pli);
|
|
};
|
|
TYPE *GetListData(PCLIST_ITEM pli)
|
|
{
|
|
return (TYPE *)CListDouble::GetListData((CListDoubleItem *)pli);
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListDoubleDestroy : public ListDouble<TYPE>
|
|
{
|
|
public:
|
|
~ListDoubleDestroy()
|
|
{
|
|
ListDoubleDestroy::DestroyList();
|
|
};
|
|
VOID DestroyList()
|
|
{
|
|
ListDoubleDestroy::EnumerateList(TYPE::Destroy);
|
|
CListDouble::DestroyList();
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListDoubleField : public CListDouble
|
|
{
|
|
public:
|
|
VOID AssertList(TYPE *p)
|
|
{
|
|
Assert(p);
|
|
};
|
|
CListItem *GetListFirst()
|
|
{
|
|
return (CListItem *)CONTAINING_RECORD(
|
|
CListDouble::GetListFirst(), TYPE, ldiNext);
|
|
};
|
|
BOOL IsListEnd(CListItem *pli)
|
|
{
|
|
return CListDouble::IsListEnd(&((TYPE *)pli)->ldiNext);
|
|
};
|
|
CListItem *GetListNext(CListItem *pli)
|
|
{
|
|
return (CListItem *)CONTAINING_RECORD(
|
|
CListDouble::GetListNext(&((TYPE *)pli)->ldiNext), TYPE, ldiNext);
|
|
};
|
|
TYPE *GetListData(CListItem *pli)
|
|
{
|
|
return CONTAINING_RECORD(
|
|
CListDouble::GetListData(&((TYPE *)pli)->ldiNext), TYPE, ldiNext);
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListDataAssertLess : public CListData
|
|
{
|
|
public:
|
|
VOID AssertList(TYPE *p)
|
|
{
|
|
};
|
|
PCLIST_ITEM GetListFirst()
|
|
{
|
|
return CListData::GetListFirst();
|
|
};
|
|
BOOL IsListEnd(PCLIST_ITEM pli)
|
|
{
|
|
return CListData::IsListEnd((CListDataData *)pli);
|
|
};
|
|
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
|
|
{
|
|
return CListData::GetListNext((CListDataData *)pli);
|
|
};
|
|
TYPE *GetListData(PCLIST_ITEM pli)
|
|
{
|
|
return (TYPE *)CListData::GetListData((CListDataData *)pli);
|
|
};
|
|
TYPE *GetListFirstData()
|
|
{
|
|
return (TYPE *)CListData::GetListFirstData();
|
|
};
|
|
NTSTATUS AddList(
|
|
TYPE *p
|
|
)
|
|
{
|
|
return CListData::AddList((PVOID)p);
|
|
};
|
|
NTSTATUS AddListDup(
|
|
TYPE *p
|
|
)
|
|
{
|
|
return CListData::AddListDup((PVOID)p);
|
|
};
|
|
NTSTATUS AddListEnd(
|
|
TYPE *p
|
|
)
|
|
{
|
|
return CListData::AddListEnd((PVOID)p);
|
|
};
|
|
NTSTATUS AddListOrdered(
|
|
TYPE *p,
|
|
LONG lFieldOffset
|
|
)
|
|
{
|
|
return CListData::AddListOrdered((PVOID)p, lFieldOffset);
|
|
};
|
|
VOID RemoveList(
|
|
TYPE *p
|
|
)
|
|
{
|
|
CListData::RemoveList((PVOID)p);
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListData : public ListDataAssertLess<TYPE>
|
|
{
|
|
public:
|
|
VOID AssertList(TYPE *p)
|
|
{
|
|
Assert(p);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
ENUMFUNC (TYPE::*pfn)()
|
|
)
|
|
{
|
|
return CListData::EnumerateList((ENUMFUNC (CListDataItem::*)())pfn);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
ENUMFUNC (TYPE::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
)
|
|
{
|
|
return CListData::EnumerateList(
|
|
(ENUMFUNC (CListDataItem::*)(PVOID))pfn,
|
|
pReference);
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListDataDestroy : public ListData<TYPE>
|
|
{
|
|
public:
|
|
~ListDataDestroy()
|
|
{
|
|
ListDataDestroy::DestroyList();
|
|
};
|
|
VOID DestroyList()
|
|
{
|
|
ListDataDestroy::EnumerateList(TYPE::Destroy);
|
|
CListData::DestroyList();
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListMulti : public CListMulti
|
|
{
|
|
public:
|
|
VOID AssertList(TYPE *p)
|
|
{
|
|
Assert(p);
|
|
};
|
|
PCLIST_ITEM GetListFirst()
|
|
{
|
|
return CListMulti::GetListFirst();
|
|
};
|
|
PCLIST_ITEM GetListLast()
|
|
{
|
|
return CListMulti::GetListLast();
|
|
};
|
|
BOOL IsListEnd(PCLIST_ITEM pli)
|
|
{
|
|
return CListMulti::IsListEnd((CListMultiData *)pli);
|
|
};
|
|
PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
|
|
{
|
|
return CListMulti::GetListNext((CListMultiData *)pli);
|
|
};
|
|
PCLIST_ITEM GetListPrevious(PCLIST_ITEM pli)
|
|
{
|
|
return CListMulti::GetListPrevious((CListMultiData *)pli);
|
|
};
|
|
TYPE *GetListData(PCLIST_ITEM pli)
|
|
{
|
|
return (TYPE *)CListMulti::GetListData((CListMultiData *)pli);
|
|
};
|
|
TYPE *GetListFirstData()
|
|
{
|
|
return (TYPE *)CListMulti::GetListFirstData();
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
ENUMFUNC (TYPE::*pfn)()
|
|
)
|
|
{
|
|
return CListMulti::EnumerateList((ENUMFUNC (CListMultiItem::*)())pfn);
|
|
};
|
|
ENUMFUNC EnumerateList(
|
|
ENUMFUNC (TYPE::*pfn)(
|
|
PVOID pReference
|
|
),
|
|
PVOID pReference
|
|
)
|
|
{
|
|
return CListMulti::EnumerateList(
|
|
(ENUMFUNC (CListMultiItem::*)(PVOID))pfn,
|
|
pReference);
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
class ListMultiDestroy : public ListMulti<TYPE>
|
|
{
|
|
public:
|
|
~ListMultiDestroy()
|
|
{
|
|
ListMultiDestroy::DestroyList();
|
|
};
|
|
VOID DestroyList()
|
|
{
|
|
ListMultiDestroy::EnumerateList(TYPE::Destroy);
|
|
CListMulti::DestroyList();
|
|
};
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
// End of File: clist.h
|
|
//---------------------------------------------------------------------------
|