rewritten
This commit is contained in:
parent
67b13237d6
commit
f5eb46d234
329
amxmodx/CList.h
329
amxmodx/CList.h
|
@ -36,83 +36,270 @@
|
|||
// class CList
|
||||
// *****************************************************
|
||||
// Linked list
|
||||
|
||||
template <typename T, typename F = char* >
|
||||
class CList {
|
||||
public:
|
||||
class iterator;
|
||||
class CListEle {
|
||||
friend class CList<T,F>;
|
||||
friend class iterator;
|
||||
T* obj;
|
||||
CListEle* next;
|
||||
CListEle( T* a , CListEle* nn ) : obj(a) , next(nn) {}
|
||||
public:
|
||||
T& operator* () { return *obj; }
|
||||
};
|
||||
private:
|
||||
CListEle *head;
|
||||
public:
|
||||
CList<T,F>() { head = 0; }
|
||||
~CList<T,F>() { clear(); }
|
||||
void clear() {
|
||||
iterator a = begin();
|
||||
while( a ) a.remove();
|
||||
}
|
||||
bool empty() const{
|
||||
return (head ? false : true);
|
||||
}
|
||||
void put( T* a ) {
|
||||
head = new CListEle( a , head );
|
||||
}
|
||||
int size() const{
|
||||
CListEle *p = head;
|
||||
int i = 0;
|
||||
while (p)
|
||||
class CList
|
||||
{
|
||||
private:
|
||||
// One list element
|
||||
class CElement
|
||||
{
|
||||
T *m_pObject; // pointer to the object
|
||||
CElement *m_pNext; // pointer to the next element
|
||||
CElement *m_pPrev; // pointer to the previous element
|
||||
public:
|
||||
// dereference operator
|
||||
T& operator* ()
|
||||
{
|
||||
return *m_pObject;
|
||||
}
|
||||
|
||||
// constructor
|
||||
CElement(T *pObj)
|
||||
{
|
||||
m_pObject = pObj;
|
||||
m_pNext = NULL;
|
||||
m_pPrev = NULL;
|
||||
}
|
||||
|
||||
// destructor
|
||||
~CElement()
|
||||
{
|
||||
delete m_pObject;
|
||||
if (m_pNext)
|
||||
m_pNext->m_pPrev = m_pPrev;
|
||||
if (m_pPrev)
|
||||
m_pPrev->m_pNext = m_pNext;
|
||||
}
|
||||
|
||||
// returns object pointer
|
||||
T *GetObj()
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
// returns next element pointer
|
||||
CElement *GetNext()
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
// sets next element
|
||||
void SetNext(CElement *newNext)
|
||||
{
|
||||
m_pNext = newNext;
|
||||
}
|
||||
|
||||
// returns previous element pointer
|
||||
CElement *GetPrev()
|
||||
{
|
||||
return m_pPrev;
|
||||
}
|
||||
|
||||
// sets previous element
|
||||
void SetPrev(CElement *newPrev)
|
||||
{
|
||||
m_pPrev = newPrev;
|
||||
}
|
||||
};
|
||||
|
||||
// CList<T,F> class
|
||||
CElement *m_pHead; // head of the linked list
|
||||
CElement *m_pTail; // tail of the linked list
|
||||
public:
|
||||
// iterator class
|
||||
class iterator
|
||||
{
|
||||
friend class CList<T,F>;
|
||||
CList<T,F> *m_pList; // The list that created this iterator
|
||||
CElement *m_CurPos; // Current position in the list
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
m_pList = NULL;
|
||||
m_CurPos = NULL;
|
||||
}
|
||||
|
||||
// constructor based on list, element
|
||||
iterator(CList<T,F> *pList, CElement *startPos)
|
||||
{
|
||||
m_pList = pList;
|
||||
m_CurPos = startPos;
|
||||
}
|
||||
|
||||
// constructor based on other iterator
|
||||
iterator(iterator &other)
|
||||
{
|
||||
m_pList = other.m_pList;
|
||||
m_CurPos = other.m_CurPos;
|
||||
}
|
||||
|
||||
// dereference operator
|
||||
T & operator* () const
|
||||
{
|
||||
return *m_CurPos->GetObj();
|
||||
}
|
||||
|
||||
T * operator-> () const
|
||||
{
|
||||
return m_CurPos->GetObj();
|
||||
}
|
||||
|
||||
// validity check operator
|
||||
inline operator bool () const
|
||||
{
|
||||
return m_pList!=NULL && m_CurPos!=NULL && m_CurPos->GetObj()!=NULL;
|
||||
}
|
||||
|
||||
// pre increment operator
|
||||
inline iterator& operator ++ ()
|
||||
{
|
||||
m_CurPos = m_CurPos->GetNext();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// post increment operator
|
||||
inline iterator operator++(int)
|
||||
{
|
||||
iterator tmp(*this);
|
||||
m_CurPos = m_CurPos)->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// returns iterator that points to next element
|
||||
iterator GetNext()
|
||||
{
|
||||
iterator tmp(*this);
|
||||
return ++tmp;
|
||||
}
|
||||
|
||||
iterator remove()
|
||||
{
|
||||
return m_pList->remove(*this);
|
||||
}
|
||||
iterator put(T *obj)
|
||||
{
|
||||
return m_pList->put(obj, *this);
|
||||
}
|
||||
};
|
||||
|
||||
CList<T,F>()
|
||||
{
|
||||
m_pHead = NULL;
|
||||
m_pTail = NULL;
|
||||
}
|
||||
~CList<T,F>()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// removes the object referenced by where
|
||||
// sets where to the next object
|
||||
// returns an iterator pointing to the next object
|
||||
iterator remove(iterator &where)
|
||||
{
|
||||
iterator tmp(where.GetNext());
|
||||
if (where.m_CurPos == m_pHead)
|
||||
m_pHead = where.m_CurPos->GetNext();
|
||||
if (where.m_CurPos == m_pTail)
|
||||
m_pTail = where.m_CurPos->GetPrev();
|
||||
delete where.m_CurPos;
|
||||
where = tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// puts an element to the end of the list
|
||||
// returns an iterator pointing to it
|
||||
iterator put_back(T *pObj)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
if (!m_pHead)
|
||||
{
|
||||
m_pHead = pTmp;
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTmp->SetNext(NULL);
|
||||
pTmp->SetPrev(m_pTail);
|
||||
m_pTail->SetNext(pTmp);
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
return iterator(this, pTmp);
|
||||
}
|
||||
|
||||
iterator put_front(T *pObj)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
if (!m_pHead)
|
||||
{
|
||||
m_pHead = pTmp;
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTmp->SetNext(m_pHead);
|
||||
pTmp->SetPrev(NULL);
|
||||
m_pHead->SetPrev(pTmp);
|
||||
m_pHead = pTmp;
|
||||
}
|
||||
return iterator(this, pTmp);
|
||||
}
|
||||
|
||||
// alias for put_back
|
||||
iterator put(T *pObj)
|
||||
{
|
||||
return put_back(pObj);
|
||||
}
|
||||
|
||||
// puts an element after where
|
||||
// sets where to point to the new element
|
||||
// returns an iterator pointing to the new element
|
||||
iterator put(T *pObj, iterator where)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
if (where.m_pNext)
|
||||
where.m_pNext->m_pPrev = pTmp;
|
||||
else // where = tail
|
||||
m_pTail = pObj;
|
||||
where.m_pNext = pTmp;
|
||||
pTmp->SetPrev(where.m_CurPos);
|
||||
pTmp->SetNext(where.m_pNext->m_CurPos);
|
||||
return ++where;
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(this, m_pHead);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
iterator iter = begin();
|
||||
while (iter) iter.remove();
|
||||
}
|
||||
iterator find(F desc)
|
||||
{
|
||||
iterator iter = begin();
|
||||
while(iter)
|
||||
{
|
||||
if (*iter == desc)
|
||||
break;
|
||||
++iter;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
iterator iter = begin();
|
||||
int i=0;
|
||||
while (iter)
|
||||
{
|
||||
p = p->next;
|
||||
++i;
|
||||
++iter;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
class iterator {
|
||||
CListEle** a;
|
||||
public:
|
||||
iterator(CListEle** i=0) : a(i){}
|
||||
T& operator*() const { return *(*a)->obj;}
|
||||
inline operator bool () const { return (a && *a); }
|
||||
inline iterator& operator++() {
|
||||
a = &(*a)->next;
|
||||
return *this;
|
||||
}
|
||||
inline iterator operator++(int) {
|
||||
iterator tmp(a);
|
||||
a = &(*a)->next;
|
||||
return tmp;
|
||||
}
|
||||
iterator& remove(){
|
||||
CListEle* aa = (*a)->next;
|
||||
delete (*a)->obj;
|
||||
delete *a;
|
||||
*a = aa;
|
||||
return *this;
|
||||
}
|
||||
iterator& put( T* aa ){
|
||||
*a = new CListEle( aa , *a );
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
inline iterator begin() { return iterator(&head); }
|
||||
iterator find( F a ){
|
||||
iterator cc = begin();
|
||||
while(cc){
|
||||
if ( *cc == a )
|
||||
break;
|
||||
++cc;
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user