rewritten
This commit is contained in:
parent
67b13237d6
commit
f5eb46d234
329
amxmodx/CList.h
329
amxmodx/CList.h
|
@ -36,83 +36,270 @@
|
||||||
// class CList
|
// class CList
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// Linked list
|
// Linked list
|
||||||
|
|
||||||
template <typename T, typename F = char* >
|
template <typename T, typename F = char* >
|
||||||
class CList {
|
class CList
|
||||||
public:
|
{
|
||||||
class iterator;
|
private:
|
||||||
class CListEle {
|
// One list element
|
||||||
friend class CList<T,F>;
|
class CElement
|
||||||
friend class iterator;
|
{
|
||||||
T* obj;
|
T *m_pObject; // pointer to the object
|
||||||
CListEle* next;
|
CElement *m_pNext; // pointer to the next element
|
||||||
CListEle( T* a , CListEle* nn ) : obj(a) , next(nn) {}
|
CElement *m_pPrev; // pointer to the previous element
|
||||||
public:
|
public:
|
||||||
T& operator* () { return *obj; }
|
// dereference operator
|
||||||
};
|
T& operator* ()
|
||||||
private:
|
{
|
||||||
CListEle *head;
|
return *m_pObject;
|
||||||
public:
|
}
|
||||||
CList<T,F>() { head = 0; }
|
|
||||||
~CList<T,F>() { clear(); }
|
// constructor
|
||||||
void clear() {
|
CElement(T *pObj)
|
||||||
iterator a = begin();
|
{
|
||||||
while( a ) a.remove();
|
m_pObject = pObj;
|
||||||
}
|
m_pNext = NULL;
|
||||||
bool empty() const{
|
m_pPrev = NULL;
|
||||||
return (head ? false : true);
|
}
|
||||||
}
|
|
||||||
void put( T* a ) {
|
// destructor
|
||||||
head = new CListEle( a , head );
|
~CElement()
|
||||||
}
|
{
|
||||||
int size() const{
|
delete m_pObject;
|
||||||
CListEle *p = head;
|
if (m_pNext)
|
||||||
int i = 0;
|
m_pNext->m_pPrev = m_pPrev;
|
||||||
while (p)
|
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;
|
++i;
|
||||||
|
++iter;
|
||||||
}
|
}
|
||||||
return i;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user