/* vim: set expandtab ts=4 sw=4: */ /* * You may redistribute this program and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define ArrayList_NOCREATE #include "util/ArrayList.h" #include "util/Bits.h" #include "util/QSort.h" #include #include struct ArrayList_pvt { /** AckTung: The fields in ArrayList.h (struct ArrayList_NAME) must be reflected here first. */ int length; int capacity; void** elements; struct Allocator* alloc; Identity }; void* ArrayList_new(struct Allocator* alloc, int initialCapacity) { struct ArrayList_pvt* l = Allocator_calloc(alloc, sizeof(struct ArrayList_pvt), 1); l->elements = Allocator_calloc(alloc, sizeof(char*), initialCapacity); l->capacity = initialCapacity; l->alloc = alloc; Identity_set(l); return l; } void* ArrayList_get(struct ArrayList* vlist, int number) { struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist); if (number >= list->length || number < 0) { return NULL; } return list->elements[number]; } void* ArrayList_remove(struct ArrayList* vlist, int number) { struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist); if (number >= list->length) { return NULL; } void* out = list->elements[number]; if (number < list->length - 1) { Bits_memmove(&list->elements[number], &list->elements[number+1], sizeof(char*) * (list->length - number - 1)); } list->length--; return out; } int ArrayList_put(struct ArrayList* vlist, int number, void* val) { struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist); Assert_true(number >= 0 && number <= list->length); if (number >= list->capacity) { int capacity = list->capacity * 2; list->elements = Allocator_realloc(list->alloc, list->elements, capacity * sizeof(char*)); for (int i = list->capacity; i < capacity; i++) { list->elements[i] = NULL; } list->capacity = capacity; } list->elements[number] = val; if (number == list->length) { list->length++; } return number; } void ArrayList_sort(struct ArrayList* vlist, int (* compare)(const void* a, const void* b)) { struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist); QSort(list->elements, list->length, sizeof(char*), compare); } void* ArrayList_clone(struct ArrayList* vlist, struct Allocator* alloc) { struct ArrayList_pvt* list = Identity_check((struct ArrayList_pvt*) vlist); struct ArrayList_pvt* newlist = Allocator_clone(alloc, list); newlist->elements = Allocator_malloc(alloc, list->capacity * sizeof(char*)); Bits_memcpy(newlist->elements, list->elements, list->capacity * sizeof(char*)); newlist->alloc = alloc; return newlist; }