src/list.c

changeset 1436
c331add0d9f8
parent 1433
81c301a59b7c
equal deleted inserted replaced
1435:48ebf22b698e 1436:c331add0d9f8
802 802
803 void cxListFree(CxList *list) { 803 void cxListFree(CxList *list) {
804 if (list == NULL) return; 804 if (list == NULL) return;
805 list->cl->deallocate(list); 805 list->cl->deallocate(list);
806 } 806 }
807
808 size_t cxListClone(CxList *dst, const CxList *src, cx_clone_func clone_func,
809 const CxAllocator *clone_allocator, void *data) {
810
811 // remember the original size
812 size_t orig_size = dst->collection.size;
813
814 // first, try to allocate the memory in the new list
815 CxIterator empl_iter = cxListEmplaceArray(dst, src->collection.size);
816
817 // get an iterator over the source elements
818 CxIterator src_iter = cxListIterator(src);
819
820 // now clone the elements
821 size_t cloned = empl_iter.elem_count;
822 if (cxCollectionStoresPointers(dst)) {
823 for (size_t i = 0 ; i < empl_iter.elem_count; i++) {
824 void *src_elem = cxIteratorCurrent(src_iter);
825 void **dest_memory = cxIteratorCurrent(empl_iter);
826 void *dest_ptr = clone_func(NULL, src_elem, clone_allocator, data);
827 if (dest_ptr == NULL) {
828 cloned = i;
829 break;
830 }
831 *dest_memory = dest_ptr;
832 cxIteratorNext(src_iter);
833 cxIteratorNext(empl_iter);
834 }
835 } else {
836 for (size_t i = 0 ; i < empl_iter.elem_count; i++) {
837 void *src_elem = cxIteratorCurrent(src_iter);
838 void *dest_memory = cxIteratorCurrent(empl_iter);
839 if (clone_func(dest_memory, src_elem, clone_allocator, data) == NULL) {
840 cloned = i;
841 break;
842 }
843 cxIteratorNext(src_iter);
844 cxIteratorNext(empl_iter);
845 }
846 }
847
848 // if we could not clone everything, free the allocated memory
849 // (disable the destructors!)
850 if (cloned < src->collection.size) {
851 cx_destructor_func destr_bak = dst->collection.simple_destructor;
852 cx_destructor_func2 destr2_bak = dst->collection.advanced_destructor;
853 dst->collection.simple_destructor = NULL;
854 dst->collection.advanced_destructor = NULL;
855 cxListRemoveArray(dst,
856 orig_size + cloned,
857 dst->collection.size - cloned - orig_size);
858 dst->collection.simple_destructor = destr_bak;
859 dst->collection.advanced_destructor = destr2_bak;
860 }
861
862 // return how many elements we have cloned
863 return cloned;
864 }

mercurial