src/list.c

changeset 371
365b24f20f98
parent 335
872ae61c8945
child 390
d345541018fa
equal deleted inserted replaced
370:07ac32b385e4 371:365b24f20f98
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "ucx/list.h" 29 #include "ucx/list.h"
30 30
31 UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void *data) { 31 UcxList *ucx_list_clone(const UcxList *l, copy_func fnc, void *data) {
32 return ucx_list_clone_a(ucx_default_allocator(), l, fnc, data); 32 return ucx_list_clone_a(ucx_default_allocator(), l, fnc, data);
33 } 33 }
34 34
35 UcxList *ucx_list_clone_a(UcxAllocator *alloc, UcxList *l, 35 UcxList *ucx_list_clone_a(UcxAllocator *alloc, const UcxList *l,
36 copy_func fnc, void *data) { 36 copy_func fnc, void *data) {
37 UcxList *ret = NULL; 37 UcxList *ret = NULL;
38 while (l) { 38 while (l) {
39 if (fnc) { 39 if (fnc) {
40 ret = ucx_list_append_a(alloc, ret, fnc(l->data, data)); 40 ret = ucx_list_append_a(alloc, ret, fnc(l->data, data));
170 } 170 }
171 171
172 return (UcxList*)(index == 0 ? e : NULL); 172 return (UcxList*)(index == 0 ? e : NULL);
173 } 173 }
174 174
175 ssize_t ucx_list_find(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) { 175 ssize_t ucx_list_find(const UcxList *l, void *elem,
176 cmp_func fnc, void *cmpdata) {
176 ssize_t index = 0; 177 ssize_t index = 0;
177 UCX_FOREACH(e, l) { 178 UCX_FOREACH(e, l) {
178 if (fnc) { 179 if (fnc) {
179 if (fnc(elem, e->data, cmpdata) == 0) { 180 if (fnc(elem, e->data, cmpdata) == 0) {
180 return index; 181 return index;
187 index++; 188 index++;
188 } 189 }
189 return -1; 190 return -1;
190 } 191 }
191 192
192 int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) { 193 int ucx_list_contains(const UcxList *l, void *elem,
194 cmp_func fnc, void *cmpdata) {
193 return ucx_list_find(l, elem, fnc, cmpdata) > -1; 195 return ucx_list_find(l, elem, fnc, cmpdata) > -1;
194 } 196 }
195 197
196 size_t ucx_list_size(const UcxList *l) { 198 size_t ucx_list_size(const UcxList *l) {
197 if (l == NULL) return 0; 199 if (l == NULL) return 0;
332 } 334 }
333 335
334 alfree(alloc, e); 336 alfree(alloc, e);
335 return l; 337 return l;
336 } 338 }
339
340
341 static UcxList* ucx_list_setoperation_a(UcxAllocator *allocator,
342 UcxList const *left, UcxList const *right,
343 cmp_func cmpfnc, void* cmpdata,
344 copy_func cpfnc, void* cpdata,
345 int op) {
346
347 UcxList *res = NULL;
348 UcxList *cur = NULL;
349 const UcxList *src = left;
350
351 do {
352 UCX_FOREACH(node, src) {
353 void* elem = node->data;
354 if (
355 (op == 0 && !ucx_list_contains(res, elem, cmpfnc, cmpdata)) ||
356 (op == 1 && ucx_list_contains(right, elem, cmpfnc, cmpdata)) ||
357 (op == 2 && !ucx_list_contains(right, elem, cmpfnc, cmpdata))) {
358 UcxList *nl = almalloc(allocator, sizeof(UcxList));
359 nl->prev = cur;
360 nl->next = NULL;
361 if (cpfnc) {
362 nl->data = cpfnc(elem, cpdata);
363 } else {
364 nl->data = elem;
365 }
366 if (cur != NULL)
367 cur->next = nl;
368 cur = nl;
369 if (res == NULL)
370 res = cur;
371 }
372 }
373 if (op == 0 && src == left)
374 src = right;
375 else
376 src = NULL;
377 } while (src != NULL);
378
379 return res;
380 }
381
382 UcxList* ucx_list_union(UcxList const *left, UcxList const *right,
383 cmp_func cmpfnc, void* cmpdata,
384 copy_func cpfnc, void* cpdata) {
385 return ucx_list_union_a(ucx_default_allocator(),
386 left, right, cmpfnc, cmpdata, cpfnc, cpdata);
387 }
388
389 UcxList* ucx_list_union_a(UcxAllocator *allocator,
390 UcxList const *left, UcxList const *right,
391 cmp_func cmpfnc, void* cmpdata,
392 copy_func cpfnc, void* cpdata) {
393
394 return ucx_list_setoperation_a(allocator, left, right,
395 cmpfnc, cmpdata, cpfnc, cpdata, 0);
396 }
397
398 UcxList* ucx_list_intersection(UcxList const *left, UcxList const *right,
399 cmp_func cmpfnc, void* cmpdata,
400 copy_func cpfnc, void* cpdata) {
401 return ucx_list_intersection_a(ucx_default_allocator(), left, right,
402 cmpfnc, cmpdata, cpfnc, cpdata);
403 }
404
405 UcxList* ucx_list_intersection_a(UcxAllocator *allocator,
406 UcxList const *left, UcxList const *right,
407 cmp_func cmpfnc, void* cmpdata,
408 copy_func cpfnc, void* cpdata) {
409
410 return ucx_list_setoperation_a(allocator, left, right,
411 cmpfnc, cmpdata, cpfnc, cpdata, 1);
412 }
413
414 UcxList* ucx_list_difference(UcxList const *left, UcxList const *right,
415 cmp_func cmpfnc, void* cmpdata,
416 copy_func cpfnc, void* cpdata) {
417 return ucx_list_difference_a(ucx_default_allocator(), left, right,
418 cmpfnc, cmpdata, cpfnc, cpdata);
419 }
420
421 UcxList* ucx_list_difference_a(UcxAllocator *allocator,
422 UcxList const *left, UcxList const *right,
423 cmp_func cmpfnc, void* cmpdata,
424 copy_func cpfnc, void* cpdata) {
425
426 return ucx_list_setoperation_a(allocator, left, right,
427 cmpfnc, cmpdata, cpfnc, cpdata, 2);
428 }

mercurial