12 typedef struct W_ArrayBag
{
19 static int getItemCount(WMBag
*bag
);
20 static int appendBag(WMBag
*bag
, WMBag
*appendedBag
);
21 static int putInBag(WMBag
*bag
, void *item
);
22 static int insertInBag(WMBag
*bag
, int index
, void *item
);
23 static int removeFromBag(WMBag
*bag
, void *item
);
24 static int deleteFromBag(WMBag
*bag
, int index
);
25 static void* getFromBag(WMBag
*bag
, int index
);
26 static int firstInBag(WMBag
*bag
, void *item
);
27 static int countInBag(WMBag
*bag
, void *item
);
28 static void* replaceInBag(WMBag
*bag
, int index
, void *item
);
29 static void sortBag(WMBag
*bag
, int (*comparer
)(const void*, const void*));
30 static void emptyBag(WMBag
*bag
);
31 static void freeBag(WMBag
*bag
);
32 static WMBag
* mapBag(WMBag
*bag
, void *(*function
)(void *));
33 static int findInBag(WMBag
*bag
, int (*match
)(void*));
34 static void* first(WMBag
*bag
, void **ptr
);
35 static void* last(WMBag
*bag
, void **ptr
);
36 static void* next(WMBag
*bag
, void **ptr
);
37 static void* previous(WMBag
*bag
, void **ptr
);
40 static W_BagFunctions arrayFunctions
= {
63 #define ARRAY ((W_ArrayBag*)bag->data)
67 WMCreateArrayBagWithDestructor(int size
, void (*destructor
)(void*))
72 wassertrv(size
> 0, NULL
);
74 bag
= wmalloc(sizeof(WMBag
));
76 array
= wmalloc(sizeof(W_ArrayBag
));
80 array
->items
= wmalloc(sizeof(void*) * size
);
84 bag
->func
= arrayFunctions
;
86 bag
->destructor
= destructor
;
93 WMCreateArrayBag(int size
)
95 return WMCreateArrayBagWithDestructor(size
, NULL
);
100 getItemCount(WMBag
*bag
)
107 appendBag(WMBag
*bag
, WMBag
*appendedBag
)
109 W_ArrayBag
*array1
= ARRAY
;
110 W_ArrayBag
*array2
= (W_ArrayBag
*)appendedBag
->data
;
112 if (array1
->count
+ array2
->count
>= array1
->size
) {
114 wrealloc(array1
->items
, sizeof(void*) * (array1
->size
+array2
->count
));
115 array1
->size
+= array2
->count
;
118 memcpy(array1
->items
+ array1
->count
, array2
->items
,
119 sizeof(void*) * array2
->count
);
121 array1
->count
+= array2
->count
;
129 putInBag(WMBag
*bag
, void *item
)
131 return insertInBag(bag
, ARRAY
->count
, item
);
137 insertInBag(WMBag
*bag
, int index
, void *item
)
139 W_ArrayBag
*array
= ARRAY
;
141 if (array
->count
== array
->size
) {
143 array
->items
= wrealloc(array
->items
, sizeof(void*) * array
->size
);
146 if (index
>= 0 && index
< array
->count
) {
147 memmove(&array
->items
[index
+1], &array
->items
[index
],
148 (array
->count
- index
) * sizeof(void*));
150 /* If index is invalid, place it at end */
151 index
= array
->count
;
153 array
->items
[index
] = item
;
161 removeFromBag(WMBag
*bag
, void *item
)
164 W_ArrayBag
*array
= ARRAY
;
166 for (i
= 0; i
< array
->count
; i
++) {
167 if (array
->items
[i
] == item
) {
169 bag
->destructor(array
->items
[i
]);
171 memmove(&array
->items
[i
], &array
->items
[i
+ 1],
172 (array
->count
- i
- 1) * sizeof(void*));
185 deleteFromBag(WMBag
*bag
, int index
)
187 W_ArrayBag
*array
= ARRAY
;
189 if (index
< 0 || index
>= array
->count
)
192 if (index
< array
->count
-1) {
194 bag
->destructor(array
->items
[index
]);
196 memmove(&array
->items
[index
], &array
->items
[index
+ 1],
197 (array
->count
- index
- 1) * sizeof(void*));
206 getFromBag(WMBag
*bag
, int index
)
208 if (index
< 0 || index
>= ARRAY
->count
)
211 return ARRAY
->items
[index
];
217 firstInBag(WMBag
*bag
, void *item
)
220 int count
= ARRAY
->count
;
221 W_ArrayBag
*array
= ARRAY
;
223 for (j
= 0; j
< count
; j
++) {
224 if (array
->items
[j
] == item
)
234 countInBag(WMBag
*bag
, void *item
)
237 int count
= ARRAY
->count
;
238 W_ArrayBag
*array
= ARRAY
;
240 for (j
= 0, i
= 0; j
< count
; j
++) {
241 if (array
->items
[j
] == item
)
249 replaceInBag(WMBag
*bag
, int index
, void *item
)
253 if (index
< 0 || index
>= ARRAY
->count
)
256 old
= ARRAY
->items
[index
];
258 ARRAY
->items
[index
] = item
;
265 sortBag(WMBag
*bag
, int (*comparer
)(const void*, const void*))
267 qsort(ARRAY
->items
, ARRAY
->count
, sizeof(void*), comparer
);
275 W_ArrayBag
*array
= ARRAY
;
277 if (bag
->destructor
) {
278 while (--array
->count
) {
279 bag
->destructor(array
->items
[array
->count
]);
298 mapBag(WMBag
*bag
, void *(*function
)(void *))
302 WMBag
*new = WMCreateArrayBagWithDestructor(ARRAY
->size
, bag
->destructor
);
304 for (i
= 0; i
< ARRAY
->count
; i
++) {
305 data
= (*function
)(ARRAY
->items
[i
]);
315 findInBag(WMBag
*bag
, int (*match
)(void*))
319 for (i
= 0; i
< ARRAY
->count
; i
++) {
320 if ((*match
)(ARRAY
->items
[i
]))
329 first(WMBag
*bag
, void **ptr
)
333 if (ARRAY
->count
== 0)
337 return ARRAY
->items
[0];
342 last(WMBag
*bag
, void **ptr
)
346 if (ARRAY
->count
== 0)
349 *(int*)ptr
= ARRAY
->count
-1;
351 return ARRAY
->items
[ARRAY
->count
-1];
356 next(WMBag
*bag
, void **ptr
)
362 if (*(int*)ptr
>= ARRAY
->count
) {
367 return ARRAY
->items
[*(int*)ptr
];
372 previous(WMBag
*bag
, void **ptr
)
378 if (*(int*)ptr
< 0) {
383 return ARRAY
->items
[*(int*)ptr
];