SilentPatch/SilentPatchSA/LinkListSA.h

179 lines
3.2 KiB
C
Raw Normal View History

2014-05-30 20:14:47 +02:00
#ifndef __LINKLIST__
#define __LINKLIST__
template <class T>
2014-08-03 15:38:53 +02:00
class CLinkSA
2014-05-30 20:14:47 +02:00
{
2017-03-02 21:47:09 +01:00
template <class T>
friend class CLinkListSA;
2014-05-30 20:14:47 +02:00
public:
2014-08-03 15:38:53 +02:00
inline void Insert(CLinkSA<T>* pAttach) {
2014-05-30 20:14:47 +02:00
pAttach->m_pNext = m_pNext;
m_pNext->m_pPrev = pAttach;
2014-08-03 15:38:53 +02:00
2014-05-30 20:14:47 +02:00
pAttach->m_pPrev = this;
m_pNext = pAttach;
}
2016-11-20 15:58:39 +01:00
inline void InsertBefore(CLinkSA<T>* pAttach) {
pAttach->m_pPrev = m_pPrev;
m_pPrev->m_pNext = pAttach;
pAttach->m_pNext = this;
m_pPrev = pAttach;
}
2014-05-30 20:14:47 +02:00
inline void Remove(void) {
m_pNext->m_pPrev = m_pPrev;
m_pPrev->m_pNext = m_pNext;
}
2017-03-02 21:47:09 +01:00
inline T& operator*(void) {
return m_pItem;
}
inline const T& operator*(void) const {
2014-05-30 20:14:47 +02:00
return m_pItem;
}
2017-03-02 21:47:09 +01:00
private:
2014-05-30 20:14:47 +02:00
T m_pItem; // 0-4
// an item
2014-08-03 15:38:53 +02:00
CLinkSA<T>* m_pPrev; // 4-8
2014-05-30 20:14:47 +02:00
//next link in the list
2014-08-03 15:38:53 +02:00
CLinkSA<T>* m_pNext; // 8-12
2014-05-30 20:14:47 +02:00
//prev link in the list
};
template <class T>
2014-08-03 15:38:53 +02:00
class CLinkListSA {
2014-05-30 20:14:47 +02:00
public:
2014-08-03 15:38:53 +02:00
CLinkListSA(void)
2014-05-30 20:14:47 +02:00
: m_plnLinks(nullptr)
{
}
2016-11-20 15:58:39 +01:00
void Init(size_t nNumLinks) {
2014-08-03 15:38:53 +02:00
m_plnLinks = new CLinkSA<T>[nNumLinks];
2014-05-30 20:14:47 +02:00
m_lnListHead.m_pNext = &m_lnListTail;
m_lnListTail.m_pPrev = &m_lnListHead;
m_lnFreeListHead.m_pNext = &m_lnFreeListTail;
m_lnFreeListTail.m_pPrev = &m_lnFreeListHead;
2016-11-20 15:58:39 +01:00
for(size_t i = nNumLinks; i > 0; --i) {
m_lnFreeListHead.Insert(&m_plnLinks[i - 1]);
2014-05-30 20:14:47 +02:00
}
}
void Shutdown(void) {
delete[] m_plnLinks;
m_plnLinks = nullptr;
}
2014-08-03 15:38:53 +02:00
CLinkSA<T>* InsertSorted(const T& pItem) {
CLinkSA<T>* pLink = m_lnFreeListHead.m_pNext;
2014-05-30 20:14:47 +02:00
if(pLink == &m_lnFreeListTail) {
return nullptr;
}
pLink->m_pItem = pItem;
pLink->Remove();
2014-08-03 15:38:53 +02:00
CLinkSA<T>* pInsertAfter = &m_lnListHead;
2014-05-30 20:14:47 +02:00
while(pInsertAfter->m_pNext != &m_lnListTail && pInsertAfter->m_pNext->m_pItem < pItem) {
pInsertAfter = pInsertAfter->m_pNext;
}
pInsertAfter->Insert(pLink);
return pLink;
}
2014-08-03 15:38:53 +02:00
CLinkSA<T>* Insert(const T& pItem) {
CLinkSA<T>* pLink = m_lnFreeListHead.m_pNext;
2014-05-30 20:14:47 +02:00
if(pLink == &m_lnFreeListTail) {
return nullptr;
}
pLink->m_pItem = pItem;
pLink->Remove();
m_lnListHead.Insert(pLink);
return pLink;
}
2016-11-20 15:58:39 +01:00
CLinkSA<T>* InsertFront(const T& pItem) {
return Insert(pItem);
}
CLinkSA<T>* InsertBack(const T& pItem) {
CLinkSA<T>* pLink = m_lnFreeListHead.m_pNext;
if(pLink == &m_lnFreeListTail) {
return nullptr;
}
pLink->m_pItem = pItem;
pLink->Remove();
m_lnListTail.InsertBefore(pLink);
return pLink;
}
2014-05-30 20:14:47 +02:00
void Clear(void) {
while(m_lnListHead.m_pNext != &m_lnListTail) {
2016-11-20 15:58:39 +01:00
Remove( m_lnListHead.m_pNext );
2014-05-30 20:14:47 +02:00
}
}
2014-08-03 15:38:53 +02:00
void Remove(CLinkSA<T>* pLink) {
2014-05-30 20:14:47 +02:00
pLink->Remove();
m_lnFreeListHead.Insert(pLink);
}
2014-08-03 15:38:53 +02:00
CLinkSA<T>* Next(CLinkSA<T>* pCurrent) {
2016-11-20 15:58:39 +01:00
if(pCurrent == nullptr) {
2014-05-30 20:14:47 +02:00
pCurrent = &m_lnListHead;
}
if(pCurrent->m_pNext == &m_lnListTail) {
2016-11-20 15:58:39 +01:00
return nullptr;
2014-05-30 20:14:47 +02:00
}
2017-03-02 21:47:09 +01:00
return pCurrent->m_pNext;
2014-05-30 20:14:47 +02:00
}
2016-11-20 15:58:39 +01:00
CLinkSA<T>* Prev(CLinkSA<T>* pCurrent) {
if(pCurrent == nullptr) {
pCurrent = &m_lnListTail;
}
if(pCurrent->m_pPrev == &m_lnListHead) {
return nullptr;
}
2017-03-02 21:47:09 +01:00
return pCurrent->m_pPrev;
2016-11-20 15:58:39 +01:00
}
2017-03-02 21:47:09 +01:00
private:
2014-08-03 15:38:53 +02:00
CLinkSA<T> m_lnListHead; // 0-12
2014-05-30 20:14:47 +02:00
//head of the list of active links
2014-08-03 15:38:53 +02:00
CLinkSA<T> m_lnListTail; // 12-24
2014-05-30 20:14:47 +02:00
//tail of the list of active links
2014-08-03 15:38:53 +02:00
CLinkSA<T> m_lnFreeListHead; // 24-36
2014-05-30 20:14:47 +02:00
//head of the list of free links
2014-08-03 15:38:53 +02:00
CLinkSA<T> m_lnFreeListTail; // 36-48
2014-05-30 20:14:47 +02:00
//tail of the list of free links
2014-08-03 15:38:53 +02:00
CLinkSA<T>* m_plnLinks; // 48-52
2014-05-30 20:14:47 +02:00
//pointer to actual array of links
};
#endif