/* 1 The File List2.h */ #ifndef LIST_H #define LIST_H #ifndef NULL #define NULL 0 #endif namespace periodic{ // forward declaration of the list class templateclass List; // forward declaration of the Iterator class template class Iterator; /* 1.1 The Class Element This class provides Elements for a double linked list. */ template class Element{ friend class List; friend class Iterator; public: /* ~Constructor~ Creates a new element whith the given entry. */ Element(T entry){ this->entry=entry; next=NULL; prev=NULL; } /* ~Connect~ Connects this element with the argument. */ void Connect(Element* e){ this->next= e; e->prev=this; } /* ~Destructor~ The destructor does nothing. To delete the entry of the element, use the destroy function first. */ ~Element(){} /* ~Destroy~ This function deletes the entry of this element. This should only be used in combination with the destructor. */ void Destroy(){ entry = 0; } /* ~GetEntry~ Returns the content of this element. */ T GetEntry(){ return entry; } /* ~GetNext~ */ Element* GetNext(){ return next;} /* ~GetPrev~ */ Element* GetPrev(){ return prev; } private: T entry; Element* next; Element* prev; }; /* 1.2 The Class List This class provides a double linked list with operations to insert, delete, and iterating over elements. */ template class List{ friend class Iterator; public: /** ~Constructor~ This constructor creates a new empty double linked list. */ List(){ first=NULL; last=NULL; current=NULL; length=0; } /* ~IsEmpty~ This function returns true iff the list does not contain any element. */ bool IsEmpty(){ return first==0; } /** ~Append function~ This function appends a new element at the end of the list. The position of the current element is not influenced by this operation except the list original list was empty. */ void Append(T entry){ Element *ne = new Element(entry); if(!last){ // the first element first = ne; current = ne; last = ne; }else{ last->Connect(ne); last=ne; } length++; } /** ~The Insert function~ This function inserts a new element before the current element. The new element will be also the new current element. For inserting an element at the end of the list, use the append function. */ void Insert(T entry){ Element* ne = new Element(entry); if(!current){ // special case : list is empty first = ne; last = ne; current=ne; }else if(current==first){ // special case: the first element ne->connect(first); current=ne; first=ne; }else{ // normal case: insert in the middle Element* prev = current->prev; prev->connect(ne); ne->connect(current); current=ne; } length++; } /** ~Contains function~ This function checks whether the given element is a member of this list. */ bool Contains(T entry){ Element* scan = first; while(scan){ if((scan->entry)==entry) return true; scan = scan->next; } return false; } /** ~The GoStart function~ This function sets the current element of the list to the begin of the list. */ void GoStart(){ current = first; } /** ~The GoEnd function~ When calling this function, the current element of this list is set to the last element of this list. */ void GoEnd(){ current = last; } /** ~GoNext~ This function moves the current element one position to behind. If the list is empty or the current element is already at the end of this list, the list remains unchanged. The return value is an indicator for the success of this function. */ bool GoNext(){ if(current==last){ //is also the case when the list is empty return false; } current = current->GetNext(); return true; } /* ~GoBack~ This function moves the current element back one position if possible. */ bool GoBack(){ if(current==first) // also if the list is empty return false; current = current->prev; return true; } /* ~OnEnd~ This function returns false if after the current element at leat one further element exists. */ bool OnEnd(){ return current==last; } /* ~OnStart~ This function returns true if the current element is at the begin of the list. */ bool OnStart(){ return current==first; } /* ~Get~ This function returns the element under the cursor. If the list is empty, the return value will be NULL. */ T Get(){ if(!current) return NULL; return current->entry; } /* ~GetFirst~ Returns the fisrt element from this list. If this list is empty, NULL is returned. */ T GetFirst(){ if(!first) return NULL; return first->entry; } /* ~ GetLast~ Returns the last element from this list. If the list is empty, null will be returned. */ T GetLast(){ if(!last) return NULL; else return last->entry; } /* ~Delete~ This function deletes the element under the cursor. The new current element will be the element after the original one if available otherwise the element before it. */ bool Delete(){ if(!current) return false; Element* victim = current; if(current==first){ // remove the first element current = current->GetNext(); first= current; if(current){ current->prev=NULL; }else{ if(victim==last) // the only element in this list last = NULL; } delete victim; } else if(current==last){ //remove the last element; last = last->prev; current=last; if(current) current->next = NULL; delete victim; }else{ // normal case delete in the middle current = current->next; (victim->prev)->connect(current); delete victim; } length--; return true; } /* ~Destructor~ This destructor removes all elements from the list. Because the destroy function of the elements is not called within this function, the content in the elements are not deallocated. */ ~List(){ while(first){ current=first; first=first->next; delete(current); } } /* ~Destroy~ This function removes all elements of this list. Also the content of the single entries is removed. After calling this function, the list will be empty. */ void Destroy(){ while(first){ current=first; first=first->next; current->Destroy(); delete current; } first = current = last = 0; length=0; } /* ~GetLength~ This function computes the length of this list. In a later version isd would be better to store the length in an extra member. */ int GetLength()const{ return length; } /* ~ConvertToArray~ This function creates a new array containing the elements in the list. The caller has to deallocate the memory occupied by this array. */ T* ConvertToArray(){ T* res = new T[length]; Element* scan = first; int pos=0; while(scan){ res[pos++]=scan->entry; scan = scan->next; } return res; } private: Element* first; Element* last; Element* current; int length; }; /* 1.3 An Iterator class Note that you can't change (insert,delete,append) the list when you use an iterator on it. */ template class Iterator{ public: /* ~Constructor~ */ Iterator(List* L){ this->elem = L->first; this->L = L; } /* ~Reset~ This function sets the position of this iterator to the begin of the list. */ void Reset(){ elem = L->first; } /* ~HasNext~ This function checks whether a further element is available. */ bool HasNext(){ return (elem!=0); } /* ~Next~ This function returns the next value of this iterator if available. If no next element exists (check it by the HasNext function), the result will be undefined. */ T Next(){ T res; res = elem->entry; elem = elem->next; return res; } /* ~SetList~ Changes this iterator to be an iterator on the argument. */ void SetList(List l){ this->L = l; this->elem=L->first; } private: List* L; Element* elem; }; } // namespace periodic #endif