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.
12 #include "Common_inline.h"
13 #ifdef IO_DECLARE_INLINES
15 #define LIST_FOREACH(list, index, value, code) \
17 const List *foreachList = list; \
18 size_t index, foreachMax = foreachList->size; \
20 for (index = 0; index < foreachMax; index ++) \
22 void *value = foreachList->items[index]; \
27 #define LIST_SAFEFOREACH(list, index, value, code) \
29 const List *foreachList = list; \
32 for (index = 0; index < List_size(foreachList); index ++) \
34 void *value = List_at_(foreachList, index); \
39 #define LIST_REVERSEFOREACH(list, index, value, code) \
41 const List *foreachList = list; \
42 size_t index = List_size(foreachList); \
46 void *value = List_at_(foreachList, (index --)); \
51 #define LIST_SAFEREVERSEFOREACH(list, index, value, code) \
53 const List *foreachList = list; \
54 size_t index = List_size(foreachList); \
56 for (index = List_size(foreachList) - 1; index > 0; index --) \
58 void *value = List_at_(foreachList, index); \
60 if (index > List_size(foreachList) - 1) { index = List_size(foreachList) - 1; } \
64 #define LIST_DO_(list, func) \
66 const List *foreachList = list; \
67 size_t index, foreachMax = List_size(foreachList); \
69 for (index = 0; index < foreachMax; index ++) \
71 func(List_at_(foreachList, index)); \
75 IOINLINE
size_t List_size(const List
*self
)
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
];
104 // --------------------------------------------
106 IOINLINE
long List_indexOf_(List
*self
, void *item
)
108 LIST_FOREACH(self
, i
, v
, if(v
== item
) return i
);
112 IOINLINE
int List_contains_(List
*self
, void *item
)
114 LIST_FOREACH(self
, i
, v
, if(v
== item
) return 1);
118 IOINLINE
void *List_append_(List
*self
, void *item
)
120 List_ifNeededSizeTo_(self
, self
->size
+ 1);
121 self
->items
[self
->size
] = 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
)
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 *));
151 List_compactIfNeeded(self
);
155 IOINLINE
void List_removeIndex_toIndex_(List
*self
, size_t index1
, size_t index2
)
164 if (index1
> self
->size
- 1)
166 index1
= self
->size
- 1;
174 if (index2
> self
->size
- 1)
176 index2
= self
->size
- 1;
179 length
= index2
- index1
;
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
)
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
);
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
);
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
)
249 if (index
> self
->size
- 1)
251 List_preallocateToSize_(self
, index
+ 1);
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
;
265 IOINLINE
void List_at_put_(List
*self
, size_t index
, void *item
)
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)
288 if (index1
!= index2
)
290 void **items
= self
->items
;
291 register void *v1
= items
[index1
];
293 items
[index1
] = items
[index2
];
298 IOINLINE
void List_reverse(List
*self
)
300 register void **i
= self
->items
;
301 register void **j
= i
+ (self
->size
- 1);
314 // stack --------------------------------------------------
316 IOINLINE
void List_push_(List
*self
, void *item
)
318 List_ifNeededSizeTo_(self
, self
->size
+ 1);
319 self
->items
[self
->size
] = item
;
323 IOINLINE
void *List_pop(List
*self
)
333 item
= self
->items
[self
->size
];
334 List_compactIfNeeded(self
);
338 IOINLINE
void *List_top(const List
*self
)
345 return self
->items
[self
->size
- 1];
348 /* --- perform -------------------------------------------------- */
350 IOINLINE
int List_removeTrueFor_(List
*self
, ListCollectCallback
* callback
)
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
;
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);