564 // lists are compatible |
565 // lists are compatible |
565 return list->cl->compare(list, other); |
566 return list->cl->compare(list, other); |
566 } |
567 } |
567 } |
568 } |
568 |
569 |
569 CxIterator cxListMutIteratorAt( |
570 size_t cxListSize(const CxList *list) { |
570 CxList *list, |
571 return list->collection.size; |
571 size_t index |
572 } |
572 ) { |
573 |
573 if (list == NULL) list = cxEmptyList; |
574 int cxListAdd(CxList *list, const void *elem) { |
574 CxIterator it = list->cl->iterator(list, index, false); |
575 list->collection.sorted = false; |
575 it.base.mutating = true; |
576 return list->cl->insert_element(list, list->collection.size, elem) == NULL; |
576 return it; |
577 } |
577 } |
578 |
578 |
579 size_t cxListAddArray(CxList *list, const void *array, size_t n) { |
579 CxIterator cxListMutBackwardsIteratorAt( |
580 list->collection.sorted = false; |
580 CxList *list, |
581 return list->cl->insert_array(list, list->collection.size, array, n); |
581 size_t index |
582 } |
582 ) { |
583 |
583 if (list == NULL) list = cxEmptyList; |
584 int cxListInsert(CxList *list, size_t index, const void *elem) { |
584 CxIterator it = list->cl->iterator(list, index, true); |
585 list->collection.sorted = false; |
585 it.base.mutating = true; |
586 return list->cl->insert_element(list, index, elem) == NULL; |
586 return it; |
587 } |
587 } |
588 |
588 |
589 void *cxListEmplaceAt(CxList *list, size_t index) { |
589 void cxListFree(CxList *list) { |
590 list->collection.sorted = false; |
590 if (list == NULL) return; |
591 return list->cl->insert_element(list, index, NULL); |
591 list->cl->deallocate(list); |
592 } |
592 } |
593 |
593 |
594 void *cxListEmplace(CxList *list) { |
594 int cxListSet( |
595 list->collection.sorted = false; |
595 CxList *list, |
596 return list->cl->insert_element(list, list->collection.size, NULL); |
596 size_t index, |
597 } |
597 const void *elem |
598 |
598 ) { |
599 int cxListInsertSorted(CxList *list, const void *elem) { |
|
600 assert(list->collection.sorted || list->collection.size == 0); |
|
601 list->collection.sorted = true; |
|
602 const void *data = list->collection.store_pointer ? &elem : elem; |
|
603 return list->cl->insert_sorted(list, data, 1) == 0; |
|
604 } |
|
605 |
|
606 int cxListInsertUnique(CxList *list, const void *elem) { |
|
607 assert(list->collection.sorted || list->collection.size == 0); |
|
608 list->collection.sorted = true; |
|
609 const void *data = list->collection.store_pointer ? &elem : elem; |
|
610 return list->cl->insert_unique(list, data, 1) == 0; |
|
611 } |
|
612 |
|
613 size_t cxListInsertArray(CxList *list, size_t index, const void *array, size_t n) { |
|
614 list->collection.sorted = false; |
|
615 return list->cl->insert_array(list, index, array, n); |
|
616 } |
|
617 |
|
618 size_t cxListInsertSortedArray(CxList *list, const void *array, size_t n) { |
|
619 assert(list->collection.sorted || list->collection.size == 0); |
|
620 list->collection.sorted = true; |
|
621 return list->cl->insert_sorted(list, array, n); |
|
622 } |
|
623 |
|
624 size_t cxListInsertUniqueArray(CxList *list, const void *array, size_t n) { |
|
625 assert(list->collection.sorted || list->collection.size == 0); |
|
626 list->collection.sorted = true; |
|
627 return list->cl->insert_unique(list, array, n); |
|
628 } |
|
629 |
|
630 int cxListInsertAfter(CxIterator *iter, const void *elem) { |
|
631 CxList* list = (CxList*)iter->src_handle.m; |
|
632 list->collection.sorted = false; |
|
633 return list->cl->insert_iter(iter, elem, 0); |
|
634 } |
|
635 |
|
636 int cxListInsertBefore(CxIterator *iter, const void *elem) { |
|
637 CxList* list = (CxList*)iter->src_handle.m; |
|
638 list->collection.sorted = false; |
|
639 return list->cl->insert_iter(iter, elem, 1); |
|
640 } |
|
641 |
|
642 int cxListRemove(CxList *list, size_t index) { |
|
643 return list->cl->remove(list, index, 1, NULL) == 0; |
|
644 } |
|
645 |
|
646 int cxListRemoveAndGet(CxList *list, size_t index, void *targetbuf) { |
|
647 return list->cl->remove(list, index, 1, targetbuf) == 0; |
|
648 } |
|
649 |
|
650 int cxListRemoveAndGetFirst(CxList *list, void *targetbuf) { |
|
651 return list->cl->remove(list, 0, 1, targetbuf) == 0; |
|
652 } |
|
653 |
|
654 int cxListRemoveAndGetLast(CxList *list, void *targetbuf) { |
|
655 // note: index may wrap - member function will catch that |
|
656 return list->cl->remove(list, list->collection.size - 1, 1, targetbuf) == 0; |
|
657 } |
|
658 |
|
659 size_t cxListRemoveArray(CxList *list, size_t index, size_t num) { |
|
660 return list->cl->remove(list, index, num, NULL); |
|
661 } |
|
662 |
|
663 size_t cxListRemoveArrayAndGet(CxList *list, size_t index, size_t num, void *targetbuf) { |
|
664 return list->cl->remove(list, index, num, targetbuf); |
|
665 } |
|
666 |
|
667 void cxListClear(CxList *list) { |
|
668 list->cl->clear(list); |
|
669 list->collection.sorted = true; // empty lists are always sorted |
|
670 } |
|
671 |
|
672 int cxListSwap(CxList *list, size_t i, size_t j) { |
|
673 list->collection.sorted = false; |
|
674 return list->cl->swap(list, i, j); |
|
675 } |
|
676 |
|
677 void *cxListAt(const CxList *list, size_t index) { |
|
678 return list->cl->at(list, index); |
|
679 } |
|
680 |
|
681 void *cxListFirst(const CxList *list) { |
|
682 return list->cl->at(list, 0); |
|
683 } |
|
684 |
|
685 void *cxListLast(const CxList *list) { |
|
686 return list->cl->at(list, list->collection.size - 1); |
|
687 } |
|
688 |
|
689 int cxListSet(CxList *list, size_t index, const void *elem) { |
599 if (index >= list->collection.size) { |
690 if (index >= list->collection.size) { |
600 return 1; |
691 return 1; |
601 } |
692 } |
602 |
693 |
603 if (list->collection.store_pointer) { |
694 if (list->collection.store_pointer) { |
609 memcpy(target, elem, list->collection.elem_size); |
700 memcpy(target, elem, list->collection.elem_size); |
610 } |
701 } |
611 |
702 |
612 return 0; |
703 return 0; |
613 } |
704 } |
|
705 |
|
706 CxIterator cxListIteratorAt(const CxList *list, size_t index) { |
|
707 if (list == NULL) list = cxEmptyList; |
|
708 return list->cl->iterator(list, index, false); |
|
709 } |
|
710 |
|
711 CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index) { |
|
712 if (list == NULL) list = cxEmptyList; |
|
713 return list->cl->iterator(list, index, true); |
|
714 } |
|
715 |
|
716 CxIterator cxListMutIteratorAt(CxList *list, size_t index) { |
|
717 if (list == NULL) list = cxEmptyList; |
|
718 CxIterator it = list->cl->iterator(list, index, false); |
|
719 it.base.mutating = true; |
|
720 return it; |
|
721 } |
|
722 |
|
723 CxIterator cxListMutBackwardsIteratorAt(CxList *list, size_t index) { |
|
724 if (list == NULL) list = cxEmptyList; |
|
725 CxIterator it = list->cl->iterator(list, index, true); |
|
726 it.base.mutating = true; |
|
727 return it; |
|
728 } |
|
729 |
|
730 CxIterator cxListIterator(const CxList *list) { |
|
731 if (list == NULL) list = cxEmptyList; |
|
732 return list->cl->iterator(list, 0, false); |
|
733 } |
|
734 |
|
735 CxIterator cxListMutIterator(CxList *list) { |
|
736 if (list == NULL) list = cxEmptyList; |
|
737 return cxListMutIteratorAt(list, 0); |
|
738 } |
|
739 |
|
740 CxIterator cxListBackwardsIterator(const CxList *list) { |
|
741 if (list == NULL) list = cxEmptyList; |
|
742 return list->cl->iterator(list, list->collection.size - 1, true); |
|
743 } |
|
744 |
|
745 CxIterator cxListMutBackwardsIterator(CxList *list) { |
|
746 if (list == NULL) list = cxEmptyList; |
|
747 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
|
748 } |
|
749 |
|
750 size_t cxListFind(const CxList *list, const void *elem) { |
|
751 return list->cl->find_remove((CxList*)list, elem, false); |
|
752 } |
|
753 |
|
754 bool cxListContains(const CxList* list, const void* elem) { |
|
755 return list->cl->find_remove((CxList*)list, elem, false) < list->collection.size; |
|
756 } |
|
757 |
|
758 bool cxListIndexValid(const CxList *list, size_t index) { |
|
759 return index < list->collection.size; |
|
760 } |
|
761 |
|
762 size_t cxListFindRemove(CxList *list, const void *elem) { |
|
763 return list->cl->find_remove(list, elem, true); |
|
764 } |
|
765 |
|
766 void cxListSort(CxList *list) { |
|
767 if (list->collection.sorted) return; |
|
768 list->cl->sort(list); |
|
769 list->collection.sorted = true; |
|
770 } |
|
771 |
|
772 void cxListReverse(CxList *list) { |
|
773 // still sorted, but not according to the cmp_func |
|
774 list->collection.sorted = false; |
|
775 list->cl->reverse(list); |
|
776 } |
|
777 |
|
778 void cxListFree(CxList *list) { |
|
779 if (list == NULL) return; |
|
780 list->cl->deallocate(list); |
|
781 } |