#ifndef DYNAMIC_ARRAY_H #define DYNAMIC_ARRAY_H #define DYNAMIC_ARRAY_VERSION_MAJOR 0 #define DYNAMIC_ARRAY_VERSION_MINOR 1 #define DYNAMIC_ARRAY_VERSION_BUILD 0 #define DYNAMIC_ARRAY_VERSION \ ((DYNAMIC_ARRAY_VERSION_MAJOR << 16) | (DYNAMIC_ARRAY_VERSION_MINOR << 8) | \ DYNAMIC_ARRAY_VERSION_BUILD) #include #include #define DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE 10 #define DYNAMIC_ARRAY_CAPACITY_FACTOR 2 // [ HEADER | ARRAY ELEMENTS ] // ↑ // THIS IS THE POINTER RETURNED BY ALL MACROS typedef struct { size_t size; size_t capacity; } ArrayHeader; #define array_create(arr) \ do { \ ArrayHeader* header = \ malloc(sizeof(*(arr)) * DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE + sizeof(ArrayHeader)); \ if (header == NULL) { \ abort(); \ } \ header->size = 0; \ header->capacity = DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE; \ \ (arr) = (void*)(header + 1); \ } while (0) #define array_get_header(arr) ((arr) ? ((ArrayHeader*)(arr) - 1) : NULL) #define array_destroy(arr) \ do { \ if ((arr) == NULL) { \ break; \ } \ free(array_get_header(arr)); \ (arr) = NULL; \ } while (0) #define array_push_value(arr, value) \ do { \ if ((arr) == NULL) { \ array_create(arr); \ } \ ArrayHeader* header = array_get_header(arr); \ if (header->size >= header->capacity) { \ size_t new_capacity = header->capacity * DYNAMIC_ARRAY_CAPACITY_FACTOR; \ ArrayHeader* new_header = \ realloc(header, sizeof(*(arr)) * new_capacity + sizeof(ArrayHeader)); \ if (new_header == NULL) { \ abort(); \ } \ header = new_header; \ header->capacity = new_capacity; \ (arr) = (void*)(header + 1); \ } \ (arr)[header->size] = (value); \ header->size++; \ } while (0) #define array_pop(arr) \ do { \ if ((arr) == NULL) { \ break; \ } \ ArrayHeader* header = array_get_header(arr); \ if (header->size == 0) { \ break; \ } \ header->size--; \ } while (0) #define array_size(arr) ((arr) ? array_get_header(arr)->size : 0) #define array_capacity(arr) ((arr) ? array_get_header(arr)->capacity : 0) #endif