5 public class Item : struct
11 void Copy(Item src, int size)
13 memcpy((byte *)this + sizeof(class Item), (byte *)src + sizeof(class Item), size - sizeof(Item));
16 public class NamedItem : struct
23 public class OldLink : struct
35 public class NamedLink : struct
44 public class NamedLink64 : struct
48 NamedLink64 prev, next;
57 void Merge(OldList list1, OldList list2, int (*compare)(void *, void *, void *), void * data)
62 offset = list1.offset;
64 // Add the smallest elements while we have two lists
65 while((list1.first && list2.first))
67 if(compare(list1.first, list2.first, data) <= 0)
80 // Add the remaining elements
81 while((item = list1.first))
86 while((item = list2.first))
103 Item link = (Item) ((byte *)item + offset);
105 #ifdef MEMINFO // _DEBUG
109 for(i = first; i; i = l.next)
113 l = (OldLink)((byte *)i + offset);
114 if(i == last) { i = null; break; }
118 printf("Adding item already in list\n");
121 if(link.prev || link.next)
122 printf("Adding item with non-zero prev/next pointers\n");
128 ((Item) ((byte *)link.prev + offset)).next = item;
129 if(!first) first = item;
131 link.next = circ ? first : null;
133 ((Item) ((byte *)first + offset)).prev = item;
138 bool Insert(void * prevItem, void * item)
140 if(item && prevItem != item)
142 Item prevLink = (Item) ((byte *)prevItem + offset);
143 Item link = (Item) ((byte *)item + offset);
145 #ifdef MEMINFO // _DEBUG
149 for(i = first; i; i = l.next)
153 l = (OldLink)((byte *)i + offset);
154 if(i == last) { i = null; break; }
158 printf("Inserting item already in list\n");
163 link.prev = prevItem ? prevItem : (circ ? last : null);
166 link.next = prevLink.next;
167 prevLink.next = item;
176 ((Item)((byte *)link.prev + offset)).next = item;
181 if(prevItem == last) last = item;
183 ((Item)((byte *)link.next + offset)).prev = item;
190 void Remove(void * item)
194 Item link = (Item) ((byte *)item + offset);
196 #ifdef MEMINFO // _DEBUG
200 for(i = first; i; i = l.next)
204 l = (OldLink)((byte *)i + offset);
205 if(i == last) { i = null; break; }
208 printf("Removing item not found in list\n");
213 ((Item) ((byte *)link.prev + offset)).next = link.next;
215 ((Item) ((byte *)link.next + offset)).prev = link.prev;
216 if(circ && last == first)
220 if(last == item) last = link.prev;
221 if(first == item) first = link.next;
229 void Delete(void * item)
238 void Free(void (* freeFn)(void *))
242 for(item = first; item; item = next)
244 Item link = (Item) ((byte *)item + offset);
251 // Handle list->circular linked lists
252 if(next == first) break;
258 void RemoveAll(void (* freeFn)(void *))
262 for(item = first; item; item = next)
264 Item link = (Item) ((byte *)item + offset);
270 // Handle list->circular linked lists
271 if(next == first) break;
279 // Should this be done in Clear??
287 void Move(void * item, void * prevItem)
291 Item link = (Item) ((byte *)item + offset);
292 Item prevLink = (Item) ((byte *)prevItem + offset);
294 if(prevItem != item && (first != item || prevItem))
297 ((Item)((byte *)link.prev + offset)).next = link.next;
299 ((Item)((byte *)link.next + offset)).prev = link.prev;
300 if(item == first) first = link.next;
301 if(item == last) last = link.prev;
306 link.prev = prevItem ? prevItem : (circ ? last : null);
309 link.next = prevLink.next;
310 prevLink.next = item;
319 ((Item)((byte *)link.prev + offset)).next = item;
325 ((Item) ((byte *)link.next + offset)).prev = item;
330 void Swap(void * item1, void * item2)
332 Item link1 = (Item) ((byte *)item1 + offset);
333 Item link2 = (Item) ((byte *)item2 + offset);
334 Item prev1 = link1.prev, next1 = link1.next;
335 void * tmp1 = item1, * tmp2 = item2;
337 link1.prev = link2.prev;
338 link1.next = link2.next;
342 if(first == tmp1) first = item2;
343 else if(first == tmp2) first = item1;
345 if(last == tmp1) last = item1;
346 else if(last == tmp2) last = item2;
348 if(link1.next) ((Item) ((byte *)link1.next + offset)).prev = item2;
349 if(link1.prev) ((Item) ((byte *)link1.prev + offset)).next = item2;
350 if(link2.next) ((Item) ((byte *)link2.next + offset)).prev = item1;
351 if(link2.prev) ((Item) ((byte *)link2.prev + offset)).next = item1;
354 void Sort(int (*compare)(void *, void *, void *), void * data)
356 if(first && ((Item) ((byte *)first + offset)).next)
358 OldList list1, list2;
359 void * middle, * end;
361 // Find a middle point
362 for(middle = first, list1.count = 0, list2.count = 0,
363 end = ((Item) ((byte *)first + offset)).next;
365 middle = ((Item)((byte *)middle + offset)).next, list1.count++,
366 end = ((Item)((byte *)end + offset)).next, list2.count++)
368 end = ((Item)((byte *)end + offset)).next;
372 // Split into two lists
373 list1.offset = offset;
374 list2.offset = offset;
380 list2.first = ((Item)((byte *)middle + offset)).next;
383 ((Item)((byte *)list1.last + offset)).next = null;
384 ((Item)((byte *)list2.first + offset)).prev = null;
386 // Recurse with those two lists
387 list1.Sort(compare, data);
388 list2.Sort(compare, data);
390 // Merge the two lists together
391 Merge(list1, list2, compare, data);
395 void * FindName(const char * name, bool warn)
397 void * result = null;
404 for(item = first; item; item = link.next)
406 link = (NamedItem)(((byte *)item) + offset);
407 if(link.name && (compare = strcmp(link.name, name)) >= 0)
413 ; //LogErrorCode(ERR_NAME_INEXISTANT, name);
418 bool PlaceName(const char * name, void ** place)
425 for(item = first; item; item = link.next)
427 link = (NamedItem)((byte *)item + offset);
428 if(link.name && (compare = strcmp(link.name, name)) >= 0)
440 ; //LogErrorCode(ERR_NAME_EXISTS, name);
444 bool AddName(void * item)
448 NamedItem link = ((NamedItem)((byte *)item + offset));
450 if(PlaceName(link.name, &place))
458 OldLink FindLink(void * data)
462 for(item = first; item; item = link.next)
464 link = (OldLink)((byte *)item + offset);
465 if(link.data == data)
471 void * FindNamedLink(const char * name, bool warn)
475 void * item = FindName(name, warn);
476 return item ? ((NamedLink)((byte *)item + offset)).data : null;
481 void Copy(OldList src, int size, void (* copy)(void * dest, void * src))
485 for(item = src.first; item; item = item.next)
487 Item newItem = (Item) new0 byte[size];
489 newItem.Copy(item, size);
490 if(copy) copy(newItem, item);