00001 // list.h 00002 // Data structures to manage LISP-like lists. 00003 // 00004 // As in LISP, a list can contain any type of data structure 00005 // as an item on the list: thread control blocks, 00006 // pending interrupts, etc. Allocation and deallocation of the 00007 // items on the list are to be done by the caller. 00008 // 00009 // Copyright (c) 1992-1996 The Regents of the University of California. 00010 // All rights reserved. See copyright.h for copyright notice and limitation 00011 // of liability and disclaimer of warranty provisions. 00012 00013 #ifndef LIST_H 00014 #define LIST_H 00015 00016 #include "copyright.h" 00017 #include "debug.h" 00018 00019 // The following class defines a "list element" -- which is 00020 // used to keep track of one item on a list. It is equivalent to a 00021 // LISP cell, with a "car" ("next") pointing to the next element on the list, 00022 // and a "cdr" ("item") pointing to the item on the list. 00023 // 00024 // This class is private to this module (and classes that inherit 00025 // from this module). Made public for notational convenience. 00026 00027 template <class T> 00028 class ListElement { 00029 public: 00030 ListElement(T itm); // initialize a list element 00031 ListElement *next; // next element on list, NULL if this is last 00032 T item; // item on the list 00033 }; 00034 00035 // The following class defines a "list" -- a singly linked list of 00036 // list elements, each of which points to a single item on the list. 00037 // The class has been tested only for primitive types (ints, pointers); 00038 // no guarantees it will work in general. For instance, all types 00039 // to be inserted into a list must have a "==" operator defined. 00040 00041 template <class T> class ListIterator; 00042 00043 template <class T> 00044 class List { 00045 public: 00046 List(); // initialize the list 00047 virtual ~List(); // de-allocate the list 00048 00049 virtual void Prepend(T item);// Put item at the beginning of the list 00050 virtual void Append(T item); // Put item at the end of the list 00051 00052 T Front() { return first->item; } 00053 // Return first item on list 00054 // without removing it 00055 T RemoveFront(); // Take item off the front of the list 00056 void Remove(T item); // Remove specific item from list 00057 00058 bool IsInList(T item) const;// is the item in the list? 00059 00060 unsigned int NumInList() { return numInList;}; 00061 // how many items in the list? 00062 bool IsEmpty() const { return (numInList == 0); }; 00063 // is the list empty? 00064 00065 void Apply(void (*f)(T)) const; 00066 // apply function to all elements in list 00067 00068 virtual void SanityCheck() const; 00069 // has this list been corrupted? 00070 void SelfTest(T *p, int numEntries); 00071 // verify module is working 00072 00073 protected: 00074 ListElement<T> *first; // Head of the list, NULL if list is empty 00075 ListElement<T> *last; // Last element of list 00076 int numInList; // number of elements in list 00077 00078 friend class ListIterator<T>; 00079 }; 00080 00081 // The following class defines a "sorted list" -- a singly linked list of 00082 // list elements, arranged so that "Remove" always returns the smallest 00083 // element. 00084 // All types to be inserted onto a sorted list must have a "Compare" 00085 // function defined: 00086 // int Compare(T x, T y) 00087 // returns -1 if x < y 00088 // returns 0 if x == y 00089 // returns 1 if x > y 00090 00091 template <class T> 00092 class SortedList : public List<T> { 00093 public: 00094 SortedList(int (*comp)(T x, T y)) : List<T>() { compare = comp;}; 00095 ~SortedList() {}; // base class destructor called automatically 00096 00097 void Insert(T item); // insert an item onto the list in sorted order 00098 00099 void SanityCheck() const; // has this list been corrupted? 00100 void SelfTest(T *p, int numEntries); 00101 // verify module is working 00102 00103 private: 00104 int (*compare)(T x, T y); // function for sorting list elements 00105 00106 void Prepend(T item) { Insert(item); } // *pre*pending has no meaning 00107 // in a sorted list 00108 void Append(T item) { Insert(item); } // neither does *ap*pend 00109 00110 }; 00111 00112 // The following class can be used to step through a list. 00113 // Example code: 00114 // ListIterator<T> *iter(list); 00115 // 00116 // for (; !iter->IsDone(); iter->Next()) { 00117 // Operation on iter->Item() 00118 // } 00119 00120 template <class T> 00121 class ListIterator { 00122 public: 00123 ListIterator(List<T> *list) { current = list->first; } 00124 // initialize an iterator 00125 00126 bool IsDone() { return current == NULL; }; 00127 // return TRUE if we are at the end of the list 00128 00129 T Item() { ASSERT(!IsDone()); return current->item; }; 00130 // return current element on list 00131 00132 void Next() { current = current->next; }; 00133 // update iterator to point to next 00134 00135 private: 00136 ListElement<T> *current; // where we are in the list 00137 }; 00138 00139 #include "list.cc" // templates are really like macros 00140 // so needs to be included in every 00141 // file that uses the template 00142 #endif // LIST_H