2 * Dynamically Resized Array
4 * Authors: Alfredo K. Kojima <kojima@windowmaker.org>
5 * Dan Pascu <dan@windowmaker.org>
7 * This code is released to the Public Domain, but
8 * proper credit is always appreciated :)
18 #define INITIAL_SIZE 8
19 #define RESIZE_INCREMENT 8
22 typedef struct W_Array
{
23 void **items
; /* the array data */
24 int itemCount
; /* # of items in array */
25 int allocSize
; /* allocated size of array */
26 WMFreeDataProc
*destructor
; /* the destructor to free elements */
31 WMCreateArray(int initialSize
)
33 return WMCreateArrayWithDestructor(initialSize
, NULL
);
38 WMCreateArrayWithDestructor(int initialSize
, WMFreeDataProc
*destructor
)
42 array
= wmalloc(sizeof(WMArray
));
44 if (initialSize
<= 0) {
45 initialSize
= INITIAL_SIZE
;
48 array
->items
= wmalloc(sizeof(void*) * initialSize
);
51 array
->allocSize
= initialSize
;
52 array
->destructor
= destructor
;
59 WMCreateArrayWithArray(WMArray
*array
)
63 newArray
= wmalloc(sizeof(WMArray
));
65 newArray
->items
= wmalloc(sizeof(void*) * array
->allocSize
);
66 memcpy(newArray
->items
, array
->items
, sizeof(void*)*array
->itemCount
);
68 newArray
->itemCount
= array
->itemCount
;
69 newArray
->allocSize
= array
->allocSize
;
70 newArray
->destructor
= NULL
;
77 WMEmptyArray(WMArray
*array
)
79 if (array
->destructor
) {
80 while (array
->itemCount
> 0) {
82 array
->destructor(array
->items
[array
->itemCount
]);
85 /*memset(array->items, 0, array->itemCount * sizeof(void*));*/
91 WMFreeArray(WMArray
*array
)
100 WMGetArrayItemCount(WMArray
*array
)
102 return array
->itemCount
;
107 WMAppendArray(WMArray
*array
, WMArray
*other
)
109 if (other
->itemCount
== 0)
112 if (array
->itemCount
+ other
->itemCount
> array
->allocSize
) {
113 array
->allocSize
+= other
->allocSize
;
114 array
->items
= wrealloc(array
->items
, sizeof(void*)*array
->allocSize
);
117 memcpy(array
->items
+array
->itemCount
, other
->items
,
118 sizeof(void*)*other
->itemCount
);
119 array
->itemCount
+= other
->itemCount
;
124 WMAddToArray(WMArray
*array
, void *item
)
126 if (array
->itemCount
>= array
->allocSize
) {
127 array
->allocSize
+= RESIZE_INCREMENT
;
128 array
->items
= wrealloc(array
->items
, sizeof(void*)*array
->allocSize
);
130 array
->items
[array
->itemCount
] = item
;
137 WMInsertInArray(WMArray
*array
, int index
, void *item
)
139 wassertr(index
>= 0 && index
<= array
->itemCount
);
141 if (array
->itemCount
>= array
->allocSize
) {
142 array
->allocSize
+= RESIZE_INCREMENT
;
143 array
->items
= wrealloc(array
->items
, sizeof(void*)*array
->allocSize
);
145 if (index
< array
->itemCount
) {
146 memmove(array
->items
+index
+1, array
->items
+index
,
147 sizeof(void*)*(array
->itemCount
-index
));
149 array
->items
[index
] = item
;
156 WMReplaceInArray(WMArray
*array
, int index
, void *item
)
160 wassertrv(index
>= 0 && index
<= array
->itemCount
, NULL
);
162 /* is it really useful to perform append if index == array->itemCount ? -Dan */
163 if (index
== array
->itemCount
) {
164 WMAddToArray(array
, item
);
168 old
= array
->items
[index
];
169 array
->items
[index
] = item
;
176 WMDeleteFromArray(WMArray
*array
, int index
)
178 wassertrv(index
>= 0 && index
< array
->itemCount
, 0);
180 if (array
->destructor
) {
181 array
->destructor(array
->items
[index
]);
184 if (index
< array
->itemCount
-1) {
185 memmove(array
->items
+index
, array
->items
+index
+1,
186 sizeof(void*)*(array
->itemCount
-index
-1));
196 WMRemoveFromArrayMatching(WMArray
*array
, WMMatchDataProc
*match
, void *cdata
)
201 for (i
= 0; i
< array
->itemCount
; i
++) {
202 if ((*match
)(array
->items
[i
], cdata
)) {
203 WMDeleteFromArray(array
, i
);
208 for (i
= 0; i
< array
->itemCount
; i
++) {
209 if (array
->items
[i
] == cdata
) {
210 WMDeleteFromArray(array
, i
);
221 WMGetFromArray(WMArray
*array
, int index
)
223 if (index
< 0 || index
>= array
->itemCount
)
226 return array
->items
[index
];
231 WMPopFromArray(WMArray
*array
)
235 return array
->items
[array
->itemCount
];
240 WMFindInArray(WMArray
*array
, WMMatchDataProc
*match
, void *cdata
)
245 for (i
= 0; i
< array
->itemCount
; i
++) {
246 if ((*match
)(array
->items
[i
], cdata
))
250 for (i
= 0; i
< array
->itemCount
; i
++) {
251 if (array
->items
[i
] == cdata
)
261 WMCountInArray(WMArray
*array
, void *item
)
265 for (i
=0, count
=0; i
<array
->itemCount
; i
++) {
266 if (array
->items
[i
] == item
)
275 WMSortArray(WMArray
*array
, WMCompareDataProc
*comparer
)
277 qsort(array
->items
, array
->itemCount
, sizeof(void*), comparer
);
282 WMMapArray(WMArray
*array
, void (*function
)(void*, void*), void *data
)
286 for (i
=0; i
<array
->itemCount
; i
++) {
287 (*function
)(array
->items
[i
], data
);
293 WMGetSubarrayWithRange(WMArray
* array
, WMRange aRange
)
297 if (aRange
.count
<= 0)
298 return WMCreateArray(0);
300 if (aRange
.position
< 0)
302 if (aRange
.position
>= array
->itemCount
)
303 aRange
.position
= array
->itemCount
- 1;
304 if (aRange
.position
+ aRange
.count
> array
->itemCount
)
305 aRange
.count
= array
->itemCount
- aRange
.position
;
307 newArray
= WMCreateArray(aRange
.count
);
308 memcpy(newArray
->items
, array
->items
+aRange
.position
,
309 sizeof(void*)*aRange
.count
);
310 newArray
->itemCount
= aRange
.count
;
317 WMArrayFirst(WMArray
*array
, WMArrayIterator
*iter
)
319 if (array
->itemCount
== 0) {
324 return array
->items
[0];
330 WMArrayLast(WMArray
*array
, WMArrayIterator
*iter
)
332 if (array
->itemCount
== 0) {
336 *iter
= array
->itemCount
-1;
337 return array
->items
[*iter
];
343 WMArrayNext(WMArray
*array
, WMArrayIterator
*iter
)
345 if (*iter
>= 0 && *iter
< array
->itemCount
-1) {
346 return array
->items
[++(*iter
)];
355 WMArrayPrevious(WMArray
*array
, WMArrayIterator
*iter
)
357 if (*iter
> 0 && *iter
< array
->itemCount
) {
358 return array
->items
[--(*iter
)];