00001 // list.cc 00002 // 00003 // Routines to manage a singly-linked list of "things". 00004 // 00005 // A "ListElement" is allocated for each item to be put on the 00006 // list; it is de-allocated when the item is removed. This means 00007 // we don't need to keep a "next" pointer in every object we 00008 // want to put on a list. 00009 // 00010 // NOTE: Mutual exclusion must be provided by the caller. 00011 // If you want a synchronized list, you must use the routines 00012 // in synchlist.cc. 00013 // 00014 // Copyright (c) 1992-1993 The Regents of the University of California. 00015 // All rights reserved. See copyright.h for copyright notice and limitation 00016 // of liability and disclaimer of warranty provisions. 00017 00018 #include "copyright.h" 00019 #include "list.h" 00020 00021 //---------------------------------------------------------------------- 00022 // ListElement::ListElement 00023 // Initialize a list element, so it can be added somewhere on a list. 00024 // 00025 // "itemPtr" is the item to be put on the list. It can be a pointer 00026 // to anything. 00027 // "sortKey" is the priority of the item, if any. 00028 //---------------------------------------------------------------------- 00029 00030 ListElement::ListElement(void *itemPtr, int sortKey) 00031 { 00032 item = itemPtr; 00033 key = sortKey; 00034 next = NULL; // assume we'll put it at the end of the list 00035 } 00036 00037 //---------------------------------------------------------------------- 00038 // List::List 00039 // Initialize a list, empty to start with. 00040 // Elements can now be added to the list. 00041 //---------------------------------------------------------------------- 00042 00043 List::List() 00044 { 00045 first = last = NULL; 00046 } 00047 00048 //---------------------------------------------------------------------- 00049 // List::~List 00050 // Prepare a list for deallocation. If the list still contains any 00051 // ListElements, de-allocate them. However, note that we do *not* 00052 // de-allocate the "items" on the list -- this module allocates 00053 // and de-allocates the ListElements to keep track of each item, 00054 // but a given item may be on multiple lists, so we can't 00055 // de-allocate them here. 00056 //---------------------------------------------------------------------- 00057 00058 List::~List() 00059 { 00060 while (Remove() != NULL) 00061 ; // delete all the list elements 00062 } 00063 00064 //---------------------------------------------------------------------- 00065 // List::Append 00066 // Append an "item" to the end of the list. 00067 // 00068 // Allocate a ListElement to keep track of the item. 00069 // If the list is empty, then this will be the only element. 00070 // Otherwise, put it at the end. 00071 // 00072 // "item" is the thing to put on the list, it can be a pointer to 00073 // anything. 00074 //---------------------------------------------------------------------- 00075 00076 void 00077 List::Append(void *item) 00078 { 00079 ListElement *element = new ListElement(item, 0); 00080 00081 if (IsEmpty()) { // list is empty 00082 first = element; 00083 last = element; 00084 } else { // else put it after last 00085 last->next = element; 00086 last = element; 00087 } 00088 } 00089 00090 //---------------------------------------------------------------------- 00091 // List::Prepend 00092 // Put an "item" on the front of the list. 00093 // 00094 // Allocate a ListElement to keep track of the item. 00095 // If the list is empty, then this will be the only element. 00096 // Otherwise, put it at the beginning. 00097 // 00098 // "item" is the thing to put on the list, it can be a pointer to 00099 // anything. 00100 //---------------------------------------------------------------------- 00101 00102 void 00103 List::Prepend(void *item) 00104 { 00105 ListElement *element = new ListElement(item, 0); 00106 00107 if (IsEmpty()) { // list is empty 00108 first = element; 00109 last = element; 00110 } else { // else put it before first 00111 element->next = first; 00112 first = element; 00113 } 00114 } 00115 00116 //---------------------------------------------------------------------- 00117 // List::Remove 00118 // Remove the first "item" from the front of the list. 00119 // 00120 // Returns: 00121 // Pointer to removed item, NULL if nothing on the list. 00122 //---------------------------------------------------------------------- 00123 00124 void * 00125 List::Remove() 00126 { 00127 return SortedRemove(NULL); // Same as SortedRemove, but ignore the key 00128 } 00129 00130 //---------------------------------------------------------------------- 00131 // List::Mapcar 00132 // Apply a function to each item on the list, by walking through 00133 // the list, one element at a time. 00134 // 00135 // Unlike LISP, this mapcar does not return anything! 00136 // 00137 // "func" is the procedure to apply to each element of the list. 00138 //---------------------------------------------------------------------- 00139 00140 void 00141 List::Mapcar(VoidFunctionPtr func) 00142 { 00143 for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) { 00144 DEBUG('l', "In mapcar, about to invoke %x(%x)\n", func, ptr->item); 00145 (*func)((int)ptr->item); 00146 } 00147 } 00148 00149 //---------------------------------------------------------------------- 00150 // List::IsEmpty 00151 // Returns TRUE if the list is empty (has no items). 00152 //---------------------------------------------------------------------- 00153 00154 bool 00155 List::IsEmpty() 00156 { 00157 if (first == NULL) 00158 return TRUE; 00159 else 00160 return FALSE; 00161 } 00162 00163 //---------------------------------------------------------------------- 00164 // List::SortedInsert 00165 // Insert an "item" into a list, so that the list elements are 00166 // sorted in increasing order by "sortKey". 00167 // 00168 // Allocate a ListElement to keep track of the item. 00169 // If the list is empty, then this will be the only element. 00170 // Otherwise, walk through the list, one element at a time, 00171 // to find where the new item should be placed. 00172 // 00173 // "item" is the thing to put on the list, it can be a pointer to 00174 // anything. 00175 // "sortKey" is the priority of the item. 00176 //---------------------------------------------------------------------- 00177 00178 void 00179 List::SortedInsert(void *item, int sortKey) 00180 { 00181 ListElement *element = new ListElement(item, sortKey); 00182 ListElement *ptr; // keep track 00183 00184 if (IsEmpty()) { // if list is empty, put 00185 first = element; 00186 last = element; 00187 } else if (sortKey < first->key) { 00188 // item goes on front of list 00189 element->next = first; 00190 first = element; 00191 } else { // look for first elt in list bigger than item 00192 for (ptr = first; ptr->next != NULL; ptr = ptr->next) { 00193 if (sortKey < ptr->next->key) { 00194 element->next = ptr->next; 00195 ptr->next = element; 00196 return; 00197 } 00198 } 00199 last->next = element; // item goes at end of list 00200 last = element; 00201 } 00202 } 00203 00204 //---------------------------------------------------------------------- 00205 // List::SortedRemove 00206 // Remove the first "item" from the front of a sorted list. 00207 // 00208 // Returns: 00209 // Pointer to removed item, NULL if nothing on the list. 00210 // Sets *keyPtr to the priority value of the removed item 00211 // (this is needed by interrupt.cc, for instance). 00212 // 00213 // "keyPtr" is a pointer to the location in which to store the 00214 // priority of the removed item. 00215 //---------------------------------------------------------------------- 00216 00217 void * 00218 List::SortedRemove(int *keyPtr) 00219 { 00220 ListElement *element = first; 00221 void *thing; 00222 00223 if (IsEmpty()) 00224 return NULL; 00225 00226 thing = first->item; 00227 if (first == last) { // list had one item, now has none 00228 first = NULL; 00229 last = NULL; 00230 } else { 00231 first = element->next; 00232 } 00233 if (keyPtr != NULL) 00234 *keyPtr = element->key; 00235 delete element; 00236 return thing; 00237 } 00238
1.2.14 written by Dimitri van Heesch,
© 1997-2002