00001 #ifndef LINKLIST_H
00002 #define LINKLIST_H
00003
00004 template<class TYPE>
00005 class ListItem;
00006
00007 template<class TYPE>
00008 class List
00009 {
00010 public:
00011 List();
00012 virtual ~List();
00013
00014 void remove(TYPE *item);
00015
00016 void remove_pointer(ListItem<TYPE> *item);
00017
00018
00019 TYPE *append();
00020 TYPE *append(TYPE *new_item);
00021 TYPE *insert_before(TYPE *item);
00022 TYPE *insert_before(TYPE *item, TYPE *new_item);
00023 TYPE *insert_after(TYPE *item);
00024 TYPE *insert_after(TYPE *item, TYPE *new_item);
00025 TYPE *get_item_number(int number);
00026 int get_item_number(TYPE *item);
00027 void swap(TYPE *item1, TYPE *item2);
00028
00029
00030 int total();
00031 int number_of(TYPE *item);
00032
00033
00034 #define PREVIOUS current->previous
00035 #define NEXT current->next
00036
00037
00038 TYPE *first;
00039 TYPE *last;
00040 };
00041
00042 template<class TYPE>
00043 class ListItem
00044 {
00045 public:
00046 ListItem();
00047 virtual ~ListItem();
00048
00049 int get_item_number();
00050 TYPE *previous;
00051 TYPE *next;
00052 List<TYPE> *owner;
00053 };
00054
00055 template<class TYPE>
00056 List<TYPE>::List()
00057 {
00058 last = first = 0;
00059 }
00060
00061 template<class TYPE>
00062 List<TYPE>::~List()
00063 {
00064 while(last)
00065 {
00066 delete last;
00067 }
00068 }
00069
00070 template<class TYPE>
00071 int List<TYPE>::total()
00072 {
00073 int total = 0;
00074 TYPE* current;
00075
00076 for(current = first; current; current = NEXT)
00077 {
00078 total++;
00079 }
00080 return total;
00081 }
00082
00083 template<class TYPE>
00084 int List<TYPE>::number_of(TYPE *item)
00085 {
00086 TYPE* current;
00087 int total = 0;
00088 for(current = first; current; current = NEXT)
00089 {
00090 if(current == item) return total;
00091 total++;
00092 }
00093 return 0;
00094 }
00095
00096 template<class TYPE>
00097 TYPE* List<TYPE>::get_item_number(int number)
00098 {
00099 TYPE* current;
00100 int i;
00101 for(i = 0, current = first; current && i < number; current = NEXT, i++)
00102 {
00103 ;
00104 }
00105 return current;
00106 }
00107
00108 template<class TYPE>
00109 int List<TYPE>::get_item_number(TYPE *item)
00110 {
00111 TYPE* current;
00112 int i;
00113 for(i = 0, current = first; current && current != item; current = NEXT, i++)
00114 {
00115 ;
00116 }
00117 return i;
00118 }
00119
00120
00121 template<class TYPE>
00122 TYPE* List<TYPE>::append()
00123 {
00124 TYPE* current_item;
00125
00126 if(!last)
00127 {
00128 current_item = last = first = new TYPE;
00129 current_item->previous = current_item->next = 0;
00130 current_item->owner = this;
00131 return current_item;
00132 }
00133 else
00134 {
00135 current_item = last->next = new TYPE;
00136 current_item->previous = last;
00137 current_item->next = 0;
00138 last = current_item;
00139 current_item->owner = this;
00140 return current_item;
00141 }
00142 }
00143
00144 template<class TYPE>
00145 TYPE* List<TYPE>::append(TYPE *new_item)
00146 {
00147 TYPE* current_item;
00148
00149 if(!last)
00150 {
00151 current_item = last = first = new_item;
00152 current_item->previous = current_item->next = 0;
00153 current_item->owner = this;
00154 return current_item;
00155 }
00156 else
00157 {
00158 current_item = last->next = new_item;
00159 current_item->previous = last;
00160 current_item->next = 0;
00161 last = current_item;
00162 current_item->owner = this;
00163 return current_item;
00164 }
00165 }
00166
00167 template<class TYPE>
00168 TYPE* List<TYPE>::insert_before(TYPE *item)
00169 {
00170 TYPE* new_item = new TYPE;
00171 return insert_before(item, new_item);
00172 }
00173
00174 template<class TYPE>
00175 TYPE* List<TYPE>::insert_before(TYPE *item, TYPE *new_item)
00176 {
00177 if(!item) return append(new_item);
00178
00179 TYPE* current_item = new_item;
00180
00181 if(item == first) first = current_item;
00182
00183 current_item->previous = item->previous;
00184 current_item->next = item;
00185
00186 if(current_item->previous) current_item->previous->next = current_item;
00187
00188 if(current_item->next) current_item->next->previous = current_item;
00189
00190 current_item->owner = this;
00191 return current_item;
00192 }
00193
00194 template<class TYPE>
00195 TYPE* List<TYPE>::insert_after(TYPE *item)
00196 {
00197 TYPE *new_item = new TYPE;
00198 return insert_after(item, new_item);
00199 }
00200
00201 template<class TYPE>
00202 TYPE* List<TYPE>::insert_after(TYPE *item, TYPE *new_item)
00203 {
00204 if(!item) return append(new_item);
00205
00206 TYPE* current_item = new_item;
00207
00208 if(item == last) last = current_item;
00209
00210 current_item->previous = item;
00211 current_item->next = item->next;
00212
00213 if(current_item->previous) current_item->previous->next = current_item;
00214
00215 if(current_item->next) current_item->next->previous = current_item;
00216
00217 current_item->owner = this;
00218 return current_item;
00219 }
00220
00221 template<class TYPE>
00222 void List<TYPE>::swap(TYPE *item1, TYPE *item2)
00223 {
00224 TYPE **temp_array;
00225 int total = this->total();
00226 temp_array = new TYPE*[total];
00227
00228 for(int i = 0; i < total; i++)
00229 {
00230 temp_array[i] = get_item_number(i);
00231 }
00232 while(last) remove_pointer(last);
00233 for(int i = 0; i < total; i++)
00234 {
00235 if(temp_array[i] == item1) append(item2);
00236 else
00237 if(temp_array[i] == item2) append(item1);
00238 else
00239 append(temp_array[i]);
00240 }
00241 delete [] temp_array;
00242
00243 #if 0
00244 TYPE *new_item0, *new_item1, *new_item2, *new_item3;
00245
00246
00247
00248
00249 new_item0 = item1->previous;
00250 new_item1 = item2;
00251 new_item2 = item1;
00252 new_item3 = item2->next;
00253
00254 if(new_item0)
00255 new_item0->next = new_item1;
00256 else
00257 first = new_item1;
00258
00259 if(new_item1) new_item1->next = new_item2;
00260 if(new_item2) new_item2->next = new_item3;
00261 if(new_item3)
00262 new_item3->previous = new_item2;
00263 else
00264 last = new_item2;
00265
00266 if(new_item2) new_item2->previous = new_item1;
00267 if(new_item1) new_item1->previous = new_item0;
00268 #endif
00269 }
00270
00271 template<class TYPE>
00272 void List<TYPE>::remove(TYPE *item)
00273 {
00274 if(!item) return;
00275 delete item;
00276 }
00277
00278 template<class TYPE>
00279 void List<TYPE>::remove_pointer(ListItem<TYPE> *item)
00280 {
00281
00282 if(!item) return;
00283
00284 item->owner = 0;
00285
00286 if(item == last && item == first)
00287 {
00288
00289 last = first = 0;
00290 return;
00291 }
00292
00293 if(item == last) last = item->previous;
00294 else
00295 if(item == first) first = item->next;
00296
00297 if(item->previous) item->previous->next = item->next;
00298
00299 if(item->next) item->next->previous = item->previous;
00300 }
00301
00302 template<class TYPE>
00303 ListItem<TYPE>::ListItem()
00304 {
00305 next = previous = 0;
00306
00307 owner = 0;
00308 }
00309
00310 template<class TYPE>
00311 ListItem<TYPE>::~ListItem()
00312 {
00313
00314 if(owner) owner->remove_pointer(this);
00315 }
00316
00317 template<class TYPE>
00318 int ListItem<TYPE>::get_item_number()
00319 {
00320 return owner->get_item_number((TYPE*)this);
00321 }
00322
00323 #endif