~kdsch/c-modules

46d0bf0d98e75e3800b8fe783aadc50e27228ce4 — Karl Schultheisz 5 months ago
add dynamic-array.c
1 files changed, 80 insertions(+), 0 deletions(-)

A dynamic-array.c
A  => dynamic-array.c +80 -0
@@ 1,80 @@
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

enum status {
	STATUS_OK,
	STATUS_ERROR_OOM,
};

struct array {
	size_t capacity;
	size_t length;
	uint32_t *members;
};

void
array_init(struct array *a)
{
	assert(a != NULL);
	memset(a, 0, sizeof(*a));
}

static bool
array_full(const struct array *a)
{
	assert(a != NULL);

	return a->capacity == a->length;
}

static enum status
array_grow(struct array *a)
{
	assert(a != NULL);

	const size_t growth_factor = 2;
	const size_t initial_capacityacity = 1;
	const size_t new_capacity = a->capacity == 0 ? initial_capacityacity : growth_factor * a->capacity;

	uint32_t *const members = realloc(a->members, sizeof(a->members) * new_capacity);

	if (members == NULL) {
		return STATUS_ERROR_OOM;
	}

	a->members = members;
	a->capacity = new_capacity;
	return STATUS_OK;
}

enum status
array_append(struct array *a, uint32_t x)
{
	if (array_full(a)) {
		enum status status = array_grow(a);
		if (status != STATUS_OK) {
			return status;
		}
	}

	assert(a != NULL);
	assert(a->length < a->capacity);

	a->members[a->length] = x;
	a->length++;
	return STATUS_OK;
}

void
array_free(struct array *a)
{
	assert(a != NULL);

	memset(a->members, 0, sizeof(a->members[0]) * a->capacity);
	free(a->members);
	memset(a, 0, sizeof(*a));
}