SystemCall run(block) can now exit the run if it returns false
[io/quag.git] / libs / basekit / source / List_inline.h
blobf25f9d7818e35ade7798f8a308406ed2afb59480
1 /*#io
2 docCopyright("Steve Dekorte", 2002)
3 docLicense("BSD revised")
4 docDescription("List is an array of void pointers.
5 The List is not responsible for io_freeing it's elements.
6 ")
7 */
9 #ifdef LIST_C
10 #define IO_IN_C_FILE
11 #endif
12 #include "Common_inline.h"
13 #ifdef IO_DECLARE_INLINES
15 #define LIST_FOREACH(list, index, value, code) \
16 { \
17 const List *foreachList = list; \
18 size_t index, foreachMax = foreachList->size; \
20 for (index = 0; index < foreachMax; index ++) \
21 { \
22 void *value = foreachList->items[index]; \
23 code; \
24 } \
27 #define LIST_SAFEFOREACH(list, index, value, code) \
28 { \
29 const List *foreachList = list; \
30 size_t index; \
32 for (index = 0; index < List_size(foreachList); index ++) \
33 { \
34 void *value = List_at_(foreachList, index); \
35 code; \
36 } \
39 #define LIST_REVERSEFOREACH(list, index, value, code) \
40 { \
41 const List *foreachList = list; \
42 size_t index = List_size(foreachList); \
44 while (index) \
45 { \
46 void *value = List_at_(foreachList, (index --)); \
47 code; \
48 } \
51 #define LIST_SAFEREVERSEFOREACH(list, index, value, code) \
52 { \
53 const List *foreachList = list; \
54 size_t index = List_size(foreachList); \
56 for (index = List_size(foreachList) - 1; index > 0; index --) \
57 { \
58 void *value = List_at_(foreachList, index); \
59 code; \
60 if (index > List_size(foreachList) - 1) { index = List_size(foreachList) - 1; } \
61 } \
64 #define LIST_DO_(list, func) \
65 { \
66 const List *foreachList = list; \
67 size_t index, foreachMax = List_size(foreachList); \
69 for (index = 0; index < foreachMax; index ++) \
70 { \
71 func(List_at_(foreachList, index)); \
72 } \
75 IOINLINE size_t List_size(const List *self)
77 return self->size;
80 IOINLINE void List_ifNeededSizeTo_(List *self, size_t newSize)
82 if (newSize * sizeof(void *) >= self->memSize)
84 List_preallocateToSize_(self, newSize);
88 IOINLINE void *List_rawAt_(List *self, size_t index)
90 return self->items[index];
94 IOINLINE void *List_at_(const List *self, size_t index)
96 if (index < self->size)
98 return self->items[index];
101 return (void *)NULL;
104 // --------------------------------------------
106 IOINLINE long List_indexOf_(List *self, void *item)
108 LIST_FOREACH(self, i, v, if(v == item) return i);
109 return -1;
112 IOINLINE int List_contains_(List *self, void *item)
114 LIST_FOREACH(self, i, v, if(v == item) return 1);
115 return 0;
118 IOINLINE void *List_append_(List *self, void *item)
120 List_ifNeededSizeTo_(self, self->size + 1);
121 self->items[self->size] = item;
122 self->size ++;
123 return item;
126 IOINLINE void List_appendSeq_(List *self, const List *otherList)
128 LIST_FOREACH(otherList, i, v, List_append_(self, v));
131 IOINLINE void List_compactIfNeeded(List *self)
133 if(self->memSize > 1024 && self->size * sizeof(void *) * 4 < self->memSize)
135 List_compact(self);
139 IOINLINE void List_removeIndex_(List *self, size_t index)
141 if (index >= 0 && index < self->size)
143 if ( index != self->size - 1)
145 memmove(&self->items[index], &self->items[index + 1],
146 (self->size - 1 - index) * sizeof(void *));
149 self->size --;
151 List_compactIfNeeded(self);
155 IOINLINE void List_removeIndex_toIndex_(List *self, size_t index1, size_t index2)
157 long length;
159 if (index1 < 0)
161 index1 = 0;
164 if (index1 > self->size - 1)
166 index1 = self->size - 1;
169 if (index2 < 0)
171 index2 = 0;
174 if (index2 > self->size - 1)
176 index2 = self->size - 1;
179 length = index2 - index1;
181 if (length <= 0)
183 return;
186 memmove(&self->items[index1], &self->items[index2],
187 (self->size - index2) * sizeof(void *));
189 self->size -= length;
191 List_compactIfNeeded(self);
194 IOINLINE void List_remove_(List *self, void *item)
196 size_t index;
198 for (index = 0; index < self->size; index ++)
200 if (self->items[index] == item)
202 List_removeIndex_(self, index);
207 IOINLINE int List_removeFirst_(List *self, void *item)
209 int i, max = self->size;
211 for (i = 0; i < max; i ++)
213 if (self->items[i] == item)
215 List_removeIndex_(self, i);
216 return 1;
220 return 0;
223 IOINLINE void List_removeLast_(List *self, void *item)
225 int index = self->size - 1;
227 for (index = self->size - 1; index > -1; index --)
229 if (self->items[index] == item)
231 List_removeIndex_(self, index);
232 break;
237 IOINLINE void List_removeItems_(List *self, List *other)
239 LIST_FOREACH(other, i, v, List_remove_(self, v));
242 IOINLINE void List_at_insert_(List *self, size_t index, void *item)
244 if (index < 0)
246 return;
249 if (index > self->size - 1)
251 List_preallocateToSize_(self, index + 1);
253 else
255 List_ifNeededSizeTo_(self, self->size + 1);
258 memmove(&self->items[index + 1], &self->items[index],
259 (self->size - index) * sizeof(void *));
261 self->items[index] = item;
262 self->size ++;
265 IOINLINE void List_at_put_(List *self, size_t index, void *item)
267 if (index < 0)
269 return;
272 List_ifNeededSizeTo_(self, index);
273 self->items[index] = item;
275 if (index + 1 > self->size)
277 self->size = index + 1;
281 IOINLINE void List_swap_with_(List *self, long index1, long index2)
283 if (index1 < 0 || index2 < 0)
285 return;
288 if (index1 != index2)
290 void **items = self->items;
291 register void *v1 = items[index1];
293 items[index1] = items[index2];
294 items[index2] = v1;
298 IOINLINE void List_reverse(List *self)
300 register void **i = self->items;
301 register void **j = i + (self->size - 1);
302 register void *iv;
304 while (j > i)
306 iv = *i;
307 *i = *j;
308 *j = iv;
309 j --;
310 i ++;
314 // stack --------------------------------------------------
316 IOINLINE void List_push_(List *self, void *item)
318 List_ifNeededSizeTo_(self, self->size + 1);
319 self->items[self->size] = item;
320 self->size ++;
323 IOINLINE void *List_pop(List *self)
325 void *item;
327 if (!self->size)
329 return (void *)NULL;
332 self->size --;
333 item = self->items[self->size];
334 List_compactIfNeeded(self);
335 return item;
338 IOINLINE void *List_top(const List *self)
340 if (!self->size)
342 return (void *)NULL;
345 return self->items[self->size - 1];
348 /* --- perform -------------------------------------------------- */
350 IOINLINE int List_removeTrueFor_(List *self, ListCollectCallback* callback)
352 size_t getIndex = 0;
353 size_t putIndex = 0;
354 size_t count = self->size;
355 void **items = self->items;
357 while (getIndex < count)
359 void *item = items[getIndex];
361 if (item && !((*callback)(item)))
363 if (getIndex!=putIndex)
365 items[putIndex] = item;
368 putIndex ++;
371 getIndex ++;
374 self->size = putIndex;
376 return getIndex - putIndex;
379 IOINLINE void List_qsort(List *self, ListSortCallback *callback)
381 qsort(self->items, self->size, sizeof(void *), *callback);
384 IOINLINE void *List_bsearch(List *self, const void *key, ListSortCallback *callback)
386 return bsearch(key, self->items, self->size, sizeof(void *), callback);
389 IOINLINE void *List_first(const List *self)
391 return List_at_(self, 0);
394 IOINLINE void *List_last(List *self)
396 return List_at_(self, List_size(self) - 1);
399 #undef IO_IN_C_FILE
400 #endif