mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
195 lines
2.8 KiB
C
195 lines
2.8 KiB
C
![]() |
#pragma once
|
||
|
|
||
|
#include "../Common.h"
|
||
|
|
||
|
// Doubly Linked Intrusive List (no 'node' wrapper, requires mNext member in T)
|
||
|
|
||
|
NS_BF_BEGIN;
|
||
|
|
||
|
template <typename T>
|
||
|
class DLIList
|
||
|
{
|
||
|
public:
|
||
|
T mHead;
|
||
|
T mTail;
|
||
|
|
||
|
struct RemovableIterator
|
||
|
{
|
||
|
public:
|
||
|
T* mPrevNextPtr;
|
||
|
|
||
|
public:
|
||
|
RemovableIterator(T* prevNextPtr)
|
||
|
{
|
||
|
mPrevNextPtr = prevNextPtr;
|
||
|
}
|
||
|
|
||
|
RemovableIterator& operator++()
|
||
|
{
|
||
|
T newNode = *mPrevNextPtr;
|
||
|
if (newNode != NULL)
|
||
|
mPrevNextPtr = &newNode->mNext;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
bool operator!=(const RemovableIterator& itr) const
|
||
|
{
|
||
|
if (itr.mPrevNextPtr == NULL)
|
||
|
return *mPrevNextPtr != NULL;
|
||
|
return *itr.mPrevNextPtr != *mPrevNextPtr;
|
||
|
}
|
||
|
|
||
|
T operator*()
|
||
|
{
|
||
|
return *mPrevNextPtr;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
DLIList()
|
||
|
{
|
||
|
mHead = NULL;
|
||
|
mTail = NULL;
|
||
|
}
|
||
|
|
||
|
void Size()
|
||
|
{
|
||
|
int size = 0;
|
||
|
T checkNode = mHead;
|
||
|
while (checkNode != NULL)
|
||
|
{
|
||
|
size++;
|
||
|
checkNode = checkNode->mNext;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PushBack(T node)
|
||
|
{
|
||
|
BF_ASSERT(node->mNext == NULL);
|
||
|
|
||
|
if (mHead == NULL)
|
||
|
mHead = node;
|
||
|
else
|
||
|
{
|
||
|
mTail->mNext = node;
|
||
|
node->mPrev = mTail;
|
||
|
}
|
||
|
mTail = node;
|
||
|
}
|
||
|
|
||
|
void AddAfter(T refNode, T newNode)
|
||
|
{
|
||
|
auto prevNext = refNode->mNext;
|
||
|
refNode->mNext = newNode;
|
||
|
newNode->mPrev = refNode;
|
||
|
newNode->mNext = prevNext;
|
||
|
if (prevNext != NULL)
|
||
|
prevNext->mPrev = newNode;
|
||
|
if (refNode == mTail)
|
||
|
mTail = newNode;
|
||
|
}
|
||
|
|
||
|
void PushFront(T node)
|
||
|
{
|
||
|
if (mHead == NULL)
|
||
|
mTail = node;
|
||
|
else
|
||
|
{
|
||
|
mHead->mPrev = node;
|
||
|
node->mNext = mHead;
|
||
|
}
|
||
|
mHead = node;
|
||
|
}
|
||
|
|
||
|
T PopFront()
|
||
|
{
|
||
|
T node = mHead;
|
||
|
mHead = node->mNext;
|
||
|
mHead->mPrev = NULL;
|
||
|
node->mNext = NULL;
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
void Remove(T node)
|
||
|
{
|
||
|
if (node->mPrev == NULL)
|
||
|
{
|
||
|
mHead = node->mNext;
|
||
|
if (mHead != NULL)
|
||
|
mHead->mPrev = NULL;
|
||
|
}
|
||
|
else
|
||
|
node->mPrev->mNext = node->mNext;
|
||
|
|
||
|
if (node->mNext == NULL)
|
||
|
{
|
||
|
mTail = node->mPrev;
|
||
|
if (mTail != NULL)
|
||
|
mTail->mNext = NULL;
|
||
|
}
|
||
|
else
|
||
|
node->mNext->mPrev = node->mPrev;
|
||
|
|
||
|
node->mPrev = NULL;
|
||
|
node->mNext = NULL;
|
||
|
}
|
||
|
|
||
|
void Replace(T oldNode, T newNode)
|
||
|
{
|
||
|
if (oldNode->mPrev != NULL)
|
||
|
{
|
||
|
oldNode->mPrev->mNext = newNode;
|
||
|
newNode->mPrev = oldNode->mPrev;
|
||
|
oldNode->mPrev = NULL;
|
||
|
}
|
||
|
else
|
||
|
mHead = newNode;
|
||
|
|
||
|
if (oldNode->mNext != NULL)
|
||
|
{
|
||
|
oldNode->mNext->mPrev = newNode;
|
||
|
newNode->mNext = oldNode->mNext;
|
||
|
oldNode->mNext = NULL;
|
||
|
}
|
||
|
else
|
||
|
mTail = newNode;
|
||
|
}
|
||
|
|
||
|
void Clear()
|
||
|
{
|
||
|
T checkNode = mHead;
|
||
|
while (checkNode != NULL)
|
||
|
{
|
||
|
T next = checkNode->mNext;
|
||
|
checkNode->mNext = NULL;
|
||
|
checkNode->mPrev = NULL;
|
||
|
checkNode = next;
|
||
|
}
|
||
|
|
||
|
mHead = NULL;
|
||
|
mTail = NULL;
|
||
|
}
|
||
|
|
||
|
void ClearFast()
|
||
|
{
|
||
|
mHead = NULL;
|
||
|
mTail = NULL;
|
||
|
}
|
||
|
|
||
|
bool IsEmpty()
|
||
|
{
|
||
|
return mHead == NULL;
|
||
|
}
|
||
|
|
||
|
RemovableIterator begin()
|
||
|
{
|
||
|
return RemovableIterator(&mHead);
|
||
|
}
|
||
|
|
||
|
RemovableIterator end()
|
||
|
{
|
||
|
return RemovableIterator(NULL);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
NS_BF_END;
|