From f78fc942c251a3f63587df3732612508e4b65def Mon Sep 17 00:00:00 2001 From: Warwick Date: Fri, 26 Apr 2024 12:18:50 +0100 Subject: [PATCH] Initial append --- CMakeLists.txt | 17 +++++++++++++++++ src/dyn_arr.c | 39 +++++++++++++++++++++++++++++++++++++++ src/dyn_arr.h | 24 ++++++++++++++++++++++++ src/main.c | 14 ++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 src/dyn_arr.c create mode 100644 src/dyn_arr.h create mode 100644 src/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b3644d2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) +project(dynarr + VERSION 0 + DESCRIPTION "Simple Dynamic Arrays" + HOMEPAGE_URL "https://git.warwick-new.co.uk/" + LANGUAGES C +) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Executables +file(GLOB_RECURSE SOURCE_FILES + ${CMAKE_SOURCE_DIR}/src/*.c) +file(GLOB_RECURSE HEADER_FILES + ${CMAKE_SOURCE_DIR}/src/*.h) +add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/src/dyn_arr.c b/src/dyn_arr.c new file mode 100644 index 0000000..027c538 --- /dev/null +++ b/src/dyn_arr.c @@ -0,0 +1,39 @@ +// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c +#include "dyn_arr.h" +#include +#include +#include +#define ARRAY_GROWTH_MULTIPLIER 1.3 + +void *dyn_arr_init(size_t item_size, size_t capacity) { + void *dyna_ptr = NULL; + size_t size = item_size * capacity + sizeof(dyna_header); + dyna_header *header = malloc(size); + + if (header) { + header->capacity = capacity; + header->length = 0; + dyna_ptr = header + 1; + } + + return dyna_ptr; +} + +void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size) { + dyna_header *header = dyna_get_header(array); + size_t minimum_capacity = header->length + item_count; + + if (header->capacity > minimum_capacity) { + return header + 1; + } + + size_t new_capacity = header->capacity * ARRAY_GROWTH_MULTIPLIER; + while (new_capacity < minimum_capacity) { + new_capacity *= ARRAY_GROWTH_MULTIPLIER; + } + + size_t new_size = sizeof(dyna_header) + new_capacity * item_size; + header = realloc(header, new_size); + header->capacity = new_capacity; + return header + 1; +} diff --git a/src/dyn_arr.h b/src/dyn_arr.h new file mode 100644 index 0000000..7c8e636 --- /dev/null +++ b/src/dyn_arr.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#define ARRAY_INITIAL_CAPACITY 4 + +typedef struct dyna_header { + size_t capacity; + size_t length; +} dyna_header; + +#define dyna_init(T) (T *)dyn_arr_init(sizeof(T), ARRAY_INITIAL_CAPACITY) +void *dyn_arr_init(size_t item_size, size_t capacity); + +#define dyna_append(array, value) \ + ((array) = dyna_ensure_capacity(array, 1, sizeof(value)), \ + (array)[dyna_get_header(array)->length] = (value), \ + &(array)[dyna_get_header(array)->length++]) + +#define dyna_get_header(array) ((dyna_header *)(array) - 1) +#define dyna_length(array) (array_header(array)->length) +#define dyna_capacity(array) (array_header(array)->capacity) + +void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..db9f74e --- /dev/null +++ b/src/main.c @@ -0,0 +1,14 @@ +#include "dyn_arr.h" +#include +#include + +int main() { + int *dyna_array = dyna_init(int); + + for (int i = 0; i < 999999999; i++) { + dyna_append(dyna_array, i); + } + printf("capacity %zu\n", dyna_get_header(dyna_array)->capacity); + + return EXIT_SUCCESS; +}