123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- /*
- EQ2Emulator: Everquest II Server Emulator
- Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
- This file is part of EQ2Emulator.
- EQ2Emulator is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- EQ2Emulator is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef LINKEDLIST_H
- #define LINKEDLIST_H
- #include "types.h"
- enum direction{FORWARD,BACKWARD};
- template<class TYPE> class LinkedListIterator;
- template<class TYPE>
- class ListElement
- {
- private:
- TYPE data;
- ListElement<TYPE>* next;
- ListElement<TYPE>* prev;
- public:
- ListElement ();
- ListElement (const TYPE&);
- ListElement (const ListElement<TYPE>&);
- ~ListElement ();
- ListElement<TYPE>& operator= (const ListElement<TYPE>&);
- ListElement<TYPE>* GetLast ()
- {
- ListElement<TYPE>* tmp = this;
- while (tmp->GetNext()) {
- tmp = tmp->GetNext();
- }
- return tmp;
- }
- ListElement<TYPE>* GetNext () const { return next ; }
- ListElement<TYPE>* GetPrev () const { return prev ; }
- inline TYPE& GetData () { return data ; }
- inline const TYPE& GetData () const { return data ; }
- void SetData ( const TYPE& d ) { data = d ; } // Quagmire - this may look like a mem leak, but dont change it, this behavior is expected where it's called
- void SetLastNext ( ListElement<TYPE>* p )
- {
- GetLast()->SetNext(p);
- }
- void SetNext (ListElement<TYPE>* n) { next = n ; }
- void SetPrev (ListElement<TYPE>* p) { prev = p ; }
- void ReplaceData(const TYPE&);
- };
- template<class TYPE>
- class LinkedList
- {
- private:
- int32 count;
- ListElement<TYPE>* first;
- bool list_destructor_invoked;
- public:
- LinkedList();
- ~LinkedList();
- bool dont_delete;
- LinkedList<TYPE>& operator= (const LinkedList<TYPE>&);
- void Append (const TYPE&);
- void Insert (const TYPE&);
- TYPE Pop();
- TYPE PeekTop();
- void Clear();
- void LCount() { count--; }
- void ResetCount() { count=0; }
- int32 Count() { return count; }
- friend class LinkedListIterator<TYPE>;
- };
- template<class TYPE>
- class LinkedListIterator
- {
- private:
- LinkedList<TYPE>& list;
- ListElement<TYPE>* current_element;
- direction dir;
-
- public:
- LinkedListIterator(LinkedList<TYPE>& l,direction d = FORWARD) : list(l), dir(d) {};
- void Advance();
- const TYPE& GetData();
- bool IsFirst()
- {
- if (current_element->GetPrev() == 0)
- return true;
- else
- return false;
- }
- bool IsLast()
- {
- if (current_element->GetNext() == 0)
- return true;
- else
- return false;
- }
- bool MoreElements();
- void MoveFirst();
- void MoveLast();
- void RemoveCurrent(bool DeleteData = true);
- void Replace(const TYPE& new_data);
- void Reset();
- void SetDir(direction);
- };
- template<class TYPE>
- void LinkedListIterator<TYPE>::Advance()
- {
- if (current_element == 0)
- {
- return;
- }
- if (dir == FORWARD)
- {
- current_element = current_element->GetNext();
- }
- else
- {
- current_element = current_element->GetPrev();
- }
- if (list.list_destructor_invoked)
- {
- while(current_element && current_element->GetData() == 0)
- {
- // if (current_element == 0)
- // {
- // return;
- // }
- if (dir == FORWARD)
- {
- current_element = current_element->GetNext();
- }
- else
- {
- current_element = current_element->GetPrev();
- }
- }
- }
- }
- template<class TYPE>
- bool LinkedListIterator<TYPE>::MoreElements()
- {
- if (current_element == 0)
- return false;
- return true;
- }
- template<class TYPE>
- const TYPE& LinkedListIterator<TYPE>::GetData()
- {
- return current_element->GetData();
- }
- template<class TYPE>
- void LinkedListIterator<TYPE>::MoveFirst()
- {
- ListElement<TYPE>* prev = current_element->GetPrev();
- ListElement<TYPE>* next = current_element->GetNext();
- if (prev == 0)
- {
- return;
- }
- // if (prev != 0)
- // {
- prev->SetNext(next);
- // }
- if (next != 0)
- {
- next->SetPrev(prev);
- }
- current_element->SetPrev(0);
- current_element->SetNext(list.first);
- list.first->SetPrev(current_element);
- list.first = current_element;
- }
- template<class TYPE>
- void LinkedListIterator<TYPE>::MoveLast()
- {
- ListElement<TYPE>* prev = current_element->GetPrev();
- ListElement<TYPE>* next = current_element->GetNext();
- if (next == 0)
- {
- return;
- }
- if (prev != 0)
- {
- prev->SetNext(next);
- }
- else
- {
- list.first = next;
- }
- // if (next != 0)
- // {
- next->SetPrev(prev);
- // }
- current_element->SetNext(0);
- current_element->SetPrev(next->GetLast());
- next->GetLast()->SetNext(current_element);
- }
- template<class TYPE>
- void LinkedListIterator<TYPE>::RemoveCurrent(bool DeleteData)
- {
- ListElement<TYPE>* save;
- if (list.first == current_element)
- {
- list.first = current_element->GetNext();
- }
- if (current_element->GetPrev() != 0)
- {
- current_element->GetPrev()->SetNext(current_element->GetNext());
- }
- if (current_element->GetNext() != 0)
- {
- current_element->GetNext()->SetPrev(current_element->GetPrev());
- }
- if (dir == FORWARD)
- {
- save = current_element->GetNext();
- }
- else
- {
- save = current_element->GetPrev();
- }
- current_element->SetNext(0);
- current_element->SetPrev(0);
- if (!DeleteData)
- current_element->SetData(0);
- safe_delete(current_element);
- current_element = save;
- list.LCount();
- }
- template<class TYPE>
- void LinkedListIterator<TYPE>::Replace(const TYPE& new_data)
- {
- current_element->ReplaceData(new_data);
- }
- template<class TYPE>
- void LinkedListIterator<TYPE>::Reset()
- {
- if (!(&list))
- {
- current_element=0;
- return;
- }
-
- if (dir == FORWARD)
- {
- current_element = list.first;
- }
- else
- {
- if (list.first == 0)
- {
- current_element = 0;
- }
- else
- {
- current_element = list.first->GetLast();
- }
- }
- if (list.list_destructor_invoked)
- {
- while(current_element && current_element->GetData() == 0)
- {
- // if (current_element == 0)
- // {
- // return;
- // }
- if (dir == FORWARD)
- {
- current_element = current_element->GetNext();
- }
- else
- {
- current_element = current_element->GetPrev();
- }
- }
- }
- }
- template<class TYPE>
- void LinkedListIterator<TYPE>::SetDir(direction d)
- {
- dir = d;
- }
- template<class TYPE>
- ListElement<TYPE>::ListElement(const TYPE& d)
- {
- data = d;
- next = 0;
- prev = 0;
- }
- template<class TYPE>
- ListElement<TYPE>::~ListElement()
- {
- // cout << "ListElement<TYPE>::~ListElement()" << endl;
- if (data != 0)
- safe_delete(data);
- data = 0;
- if (next != 0)
- {
- safe_delete(next);
- next = 0;
- }
- }
- template<class TYPE>
- void ListElement<TYPE>::ReplaceData(const TYPE& new_data)
- {
- if (data != 0)
- safe_delete(data);
- data = new_data;
- }
- template<class TYPE>
- LinkedList<TYPE>::LinkedList()
- {
- list_destructor_invoked = false;
- first = 0;
- count = 0;
- dont_delete = false;
- }
- template<class TYPE>
- LinkedList<TYPE>::~LinkedList()
- {
- list_destructor_invoked = true;
- if(!dont_delete)
- Clear();
- }
- template<class TYPE>
- void LinkedList<TYPE>::Clear() {
- while (first) {
- ListElement<TYPE>* tmp = first;
- first = tmp->GetNext();
- tmp->SetNext(0);
- safe_delete(tmp);
- }
- ResetCount();
- }
- template<class TYPE>
- void LinkedList<TYPE>::Append(const TYPE& data)
- {
- ListElement<TYPE>* new_element = new ListElement<TYPE>(data);
-
- if (first == 0)
- {
- first = new_element;
- }
- else
- {
- new_element->SetPrev(first->GetLast());
- first->SetLastNext(new_element);
- }
- count++;
- }
- template<class TYPE>
- void LinkedList<TYPE>::Insert(const TYPE& data)
- {
- ListElement<TYPE>* new_element = new ListElement<TYPE>(data);
- new_element->SetNext(first);
- if (first != 0)
- {
- first->SetPrev(new_element);
- }
- first = new_element;
- count++;
- }
- template<class TYPE>
- TYPE LinkedList<TYPE>::Pop() {
- TYPE ret = 0;
- if (first) {
- ListElement<TYPE>* tmpdel = first;
- first = tmpdel->GetNext();
- if (first)
- first->SetPrev(0);
- ret = tmpdel->GetData();
- tmpdel->SetData(0);
- tmpdel->SetNext(0);
- safe_delete(tmpdel);
- count--;
- }
- return ret;
- }
- template<class TYPE>
- TYPE LinkedList<TYPE>::PeekTop() {
- if (first)
- return first->GetData();
- return 0;
- }
- #endif
|