| 27 */ |
27 */ |
| 28 |
28 |
| 29 #include "cx/list.h" |
29 #include "cx/list.h" |
| 30 |
30 |
| 31 #include <string.h> |
31 #include <string.h> |
| |
32 #include <errno.h> |
| 32 #include <assert.h> |
33 #include <assert.h> |
| 33 |
34 |
| 34 // we don't want to include the full array_list.h. |
35 // we don't want to include the full array_list.h. |
| 35 // therefore, we only forward declare the one function we want to use |
36 // therefore, we only forward declare the one function we want to use |
| 36 CX_EXPORT void cx_array_qsort_c(void *array, size_t nmemb, size_t size, |
37 CX_EXPORT void cx_array_qsort_c(void *array, size_t nmemb, size_t size, |
| 416 return list->collection.size; |
417 return list->collection.size; |
| 417 } |
418 } |
| 418 |
419 |
| 419 int cxListAdd(CxList *list, const void *elem) { |
420 int cxListAdd(CxList *list, const void *elem) { |
| 420 list->collection.sorted = false; |
421 list->collection.sorted = false; |
| |
422 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
423 errno = EINVAL; |
| |
424 return 1; |
| |
425 } |
| 421 return list->cl->insert_element(list, list->collection.size, cx_ref(list, elem)) == NULL; |
426 return list->cl->insert_element(list, list->collection.size, cx_ref(list, elem)) == NULL; |
| 422 } |
427 } |
| 423 |
428 |
| 424 size_t cxListAddArray(CxList *list, const void *array, size_t n) { |
429 size_t cxListAddArray(CxList *list, const void *array, size_t n) { |
| 425 list->collection.sorted = false; |
430 list->collection.sorted = false; |
| 426 return list->cl->insert_array(list, list->collection.size, array, n); |
431 return list->cl->insert_array(list, list->collection.size, array, n); |
| 427 } |
432 } |
| 428 |
433 |
| 429 int cxListInsert(CxList *list, size_t index, const void *elem) { |
434 int cxListInsert(CxList *list, size_t index, const void *elem) { |
| 430 list->collection.sorted = false; |
435 list->collection.sorted = false; |
| |
436 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
437 errno = EINVAL; |
| |
438 return 1; |
| |
439 } |
| 431 return list->cl->insert_element(list, index, cx_ref(list, elem)) == NULL; |
440 return list->cl->insert_element(list, index, cx_ref(list, elem)) == NULL; |
| 432 } |
441 } |
| 433 |
442 |
| 434 void *cxListEmplaceAt(CxList *list, size_t index) { |
443 void *cxListEmplaceAt(CxList *list, size_t index) { |
| 435 list->collection.sorted = false; |
444 list->collection.sorted = false; |
| 463 } |
472 } |
| 464 |
473 |
| 465 int cxListInsertSorted(CxList *list, const void *elem) { |
474 int cxListInsertSorted(CxList *list, const void *elem) { |
| 466 assert(cxCollectionSorted(list)); |
475 assert(cxCollectionSorted(list)); |
| 467 list->collection.sorted = true; |
476 list->collection.sorted = true; |
| |
477 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
478 errno = EINVAL; |
| |
479 return 1; |
| |
480 } |
| 468 return list->cl->insert_sorted(list, cx_ref(list, elem), 1) == 0; |
481 return list->cl->insert_sorted(list, cx_ref(list, elem), 1) == 0; |
| 469 } |
482 } |
| 470 |
483 |
| 471 int cxListInsertUnique(CxList *list, const void *elem) { |
484 int cxListInsertUnique(CxList *list, const void *elem) { |
| 472 if (cxCollectionSorted(list)) { |
485 if (cxCollectionSorted(list)) { |
| 473 list->collection.sorted = true; |
486 list->collection.sorted = true; |
| |
487 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
488 errno = EINVAL; |
| |
489 return 1; |
| |
490 } |
| 474 return list->cl->insert_unique(list, cx_ref(list, elem), 1) == 0; |
491 return list->cl->insert_unique(list, cx_ref(list, elem), 1) == 0; |
| 475 } else { |
492 } else { |
| 476 if (cxListContains(list, elem)) { |
493 if (cxListContains(list, elem)) { |
| 477 return 0; |
494 return 0; |
| 478 } else { |
495 } else { |
| 513 } |
530 } |
| 514 |
531 |
| 515 int cxListInsertAfter(CxIterator *iter, const void *elem) { |
532 int cxListInsertAfter(CxIterator *iter, const void *elem) { |
| 516 CxList* list = iter->src_handle; |
533 CxList* list = iter->src_handle; |
| 517 list->collection.sorted = false; |
534 list->collection.sorted = false; |
| |
535 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
536 errno = EINVAL; |
| |
537 return 1; |
| |
538 } |
| 518 return list->cl->insert_iter(iter, cx_ref(list, elem), 0); |
539 return list->cl->insert_iter(iter, cx_ref(list, elem), 0); |
| 519 } |
540 } |
| 520 |
541 |
| 521 int cxListInsertBefore(CxIterator *iter, const void *elem) { |
542 int cxListInsertBefore(CxIterator *iter, const void *elem) { |
| 522 CxList* list = iter->src_handle; |
543 CxList* list = iter->src_handle; |
| 523 list->collection.sorted = false; |
544 list->collection.sorted = false; |
| |
545 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
546 errno = EINVAL; |
| |
547 return 1; |
| |
548 } |
| 524 return list->cl->insert_iter(iter, cx_ref(list, elem), 1); |
549 return list->cl->insert_iter(iter, cx_ref(list, elem), 1); |
| 525 } |
550 } |
| 526 |
551 |
| 527 int cxListRemove(CxList *list, size_t index) { |
552 int cxListRemove(CxList *list, size_t index) { |
| 528 return list->cl->remove(list, index, 1, NULL) == 0; |
553 return list->cl->remove(list, index, 1, NULL) == 0; |
| 624 if (list == NULL) list = cxEmptyList; |
649 if (list == NULL) list = cxEmptyList; |
| 625 return cx_pl_iter_wrap(list, list->cl->iterator(list, list->collection.size - 1, true)); |
650 return cx_pl_iter_wrap(list, list->cl->iterator(list, list->collection.size - 1, true)); |
| 626 } |
651 } |
| 627 |
652 |
| 628 size_t cxListFind(const CxList *list, const void *elem) { |
653 size_t cxListFind(const CxList *list, const void *elem) { |
| |
654 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
655 return list->collection.size; |
| |
656 } |
| 629 return list->cl->find_remove((CxList*)list, cx_ref(list, elem), false); |
657 return list->cl->find_remove((CxList*)list, cx_ref(list, elem), false); |
| 630 } |
658 } |
| 631 |
659 |
| 632 bool cxListContains(const CxList* list, const void* elem) { |
660 bool cxListContains(const CxList* list, const void* elem) { |
| |
661 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
662 return false; |
| |
663 } |
| 633 return list->cl->find_remove((CxList*)list, cx_ref(list, elem), false) < list->collection.size; |
664 return list->cl->find_remove((CxList*)list, cx_ref(list, elem), false) < list->collection.size; |
| 634 } |
665 } |
| 635 |
666 |
| 636 bool cxListIndexValid(const CxList *list, size_t index) { |
667 bool cxListIndexValid(const CxList *list, size_t index) { |
| 637 return index < list->collection.size; |
668 return index < list->collection.size; |
| 638 } |
669 } |
| 639 |
670 |
| 640 size_t cxListFindRemove(CxList *list, const void *elem) { |
671 size_t cxListFindRemove(CxList *list, const void *elem) { |
| |
672 if (!cxCollectionStoresPointers(list) && elem == NULL) { |
| |
673 return list->collection.size; |
| |
674 } |
| 641 return list->cl->find_remove(list, cx_ref(list, elem), true); |
675 return list->cl->find_remove(list, cx_ref(list, elem), true); |
| 642 } |
676 } |
| 643 |
677 |
| 644 void cxListSort(CxList *list) { |
678 void cxListSort(CxList *list) { |
| 645 if (list->collection.sorted) return; |
679 if (list->collection.sorted) return; |