12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /* 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 <https://www.gnu.org/licenses/>.
- */
- #define ArrayList_NOCREATE
- #include "util/ArrayList.h"
- #include "util/Bits.h"
- #include "util/QSort.h"
- #include <stddef.h>
- #include <stdlib.h>
- 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;
- }
|