diff options
author | Omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-02-24 22:47:46 +1100 |
---|---|---|
committer | Omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-02-24 22:47:46 +1100 |
commit | 7b3afcaf77f96e7d62f6cd1623ead7f17512d79f (patch) | |
tree | b5f82c64e9c06a84e4d095ab4ac48712e860b673 /src/std | |
parent | b047be5252aeb981faea077409c1768fda0301d9 (diff) |
repo init. partial port of existing code
Diffstat (limited to 'src/std')
-rw-r--r-- | src/std/containers/darray.h | 147 | ||||
-rw-r--r-- | src/std/containers/ring_queue.c | 66 | ||||
-rw-r--r-- | src/std/containers/ring_queue.h | 35 | ||||
-rw-r--r-- | src/std/mem.h | 14 | ||||
-rw-r--r-- | src/std/str.c | 14 | ||||
-rw-r--r-- | src/std/str.h | 30 |
6 files changed, 306 insertions, 0 deletions
diff --git a/src/std/containers/darray.h b/src/std/containers/darray.h new file mode 100644 index 0000000..729b4cf --- /dev/null +++ b/src/std/containers/darray.h @@ -0,0 +1,147 @@ +/** + * @file darray.h + * @brief Typed dynamic array + * @copyright Copyright (c) 2023 + */ +// COPIED FROM KITC WITH SOME MINOR ADJUSTMENTS + +#ifndef KITC_TYPED_ARRAY_H +#define KITC_TYPED_ARRAY_H + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define DARRAY_DEFAULT_CAPACITY 64 +#define DARRAY_RESIZE_FACTOR 3 + +/** @brief create a new darray type and functions with type `N` */ +#define typed_array(T) \ + struct { \ + /* @brief current number of items in the array */ \ + size_t len; \ + size_t capacity; \ + T *data; \ + } + +#define typed_array_iterator(T) \ + struct { \ + T##_darray *array; \ + size_t current_idx; \ + } + +#define PREFIX static + +#define KITC_DECL_TYPED_ARRAY(T) \ + typedef typed_array(T) T##_darray; \ + typedef typed_array_iterator(T) T##_darray_iter; \ + \ + /* Create a new one growable array */ \ + PREFIX T##_darray *T##_darray_new(size_t starting_capacity) { \ + T##_darray *d = malloc(sizeof(T##_darray)); \ + T *data = malloc(starting_capacity * sizeof(T)); \ + \ + d->len = 0; \ + d->capacity = starting_capacity; \ + d->data = data; \ + \ + return d; \ + } \ + \ + PREFIX void T##_darray_free(T##_darray *d) { \ + if (d != NULL) { \ + free(d->data); \ + free(d); \ + } \ + } \ + \ + PREFIX T *T##_darray_resize(T##_darray *d, size_t capacity) { \ + /* resize the internal data block */ \ + T *new_data = realloc(d->data, sizeof(T) * capacity); \ + /* TODO: handle OOM error */ \ + \ + d->capacity = capacity; \ + d->data = new_data; \ + return new_data; \ + } \ + \ + PREFIX void T##_darray_push(T##_darray *d, T value) { \ + if (d->len >= d->capacity) { \ + size_t new_capacity = \ + d->capacity > 0 ? d->capacity * DARRAY_RESIZE_FACTOR : DARRAY_DEFAULT_CAPACITY; \ + T *resized = T##_darray_resize(d, new_capacity); \ + } \ + \ + d->data[d->len] = value; \ + d->len += 1; \ + } \ + \ + PREFIX void T##_darray_push_copy(T##_darray *d, const T *value) { \ + if (d->len >= d->capacity) { \ + size_t new_capacity = \ + d->capacity > 0 ? d->capacity * DARRAY_RESIZE_FACTOR : DARRAY_DEFAULT_CAPACITY; \ + T *resized = T##_darray_resize(d, new_capacity); \ + } \ + \ + T *place = d->data + d->len; \ + d->len += 1; \ + memcpy(place, value, sizeof(T)); \ + } \ + \ + PREFIX void T##_darray_pop(T##_darray *d, T *dest) { \ + T *item = d->data + (d->len - 1); \ + d->len -= 1; \ + memcpy(dest, item, sizeof(T)); \ + } \ + \ + PREFIX void T##_darray_ins(T##_darray *d, const T *value, size_t index) { \ + /* check if requires resize */ \ + if (d->len + 1 > d->capacity) { \ + size_t new_capacity = \ + d->capacity > 0 ? d->capacity * DARRAY_RESIZE_FACTOR : DARRAY_DEFAULT_CAPACITY; \ + T *resized = T##_darray_resize(d, new_capacity); \ + } \ + \ + /* shift existing data after index */ \ + T *insert_dest = d->data + index; \ + T *shift_dest = insert_dest + 1; \ + \ + int num_items = d->len - index; \ + \ + d->len += 1; \ + memcpy(shift_dest, insert_dest, num_items * sizeof(T)); \ + memcpy(insert_dest, value, sizeof(T)); \ + } \ + \ + PREFIX void T##_darray_clear(T##_darray *d) { \ + d->len = 0; \ + memset(d->data, 0, d->capacity * sizeof(T)); \ + } \ + \ + PREFIX size_t T##_darray_len(T##_darray *d) { return d->len; } \ + \ + PREFIX void T##_darray_print(T##_darray *d) { \ + printf("len: %zu ", d->len); \ + printf("capacity: %zu\n", d->capacity); \ + for (int i = 0; i < d->len; i++) { \ + printf("Index %d holds value %d\n", i, d->data[i]); \ + } \ + } \ + \ + PREFIX T##_darray_iter T##_darray_iter_new(T##_darray *d) { \ + T##_darray_iter iterator; \ + iterator.array = d; \ + iterator.current_idx = 0; \ + return iterator; \ + } \ + \ + PREFIX void *T##_darray_iter_next(T##_darray_iter *iterator) { \ + if (iterator->current_idx < iterator->array->len) { \ + return &iterator->array->data[iterator->current_idx++]; \ + } else { \ + return NULL; \ + } \ + } + +#endif // KITC_TYPED_ARRAY_H diff --git a/src/std/containers/ring_queue.c b/src/std/containers/ring_queue.c new file mode 100644 index 0000000..a9d3506 --- /dev/null +++ b/src/std/containers/ring_queue.c @@ -0,0 +1,66 @@ +#include "ring_queue.h" +#include <stdlib.h> +#include "defines.h" + +ring_queue* ring_queue_new(size_t type_size, size_t capacity, void* memory) { + ring_queue* q = malloc(sizeof(ring_queue)); + q->len = 0; + q->capacity = capacity; + q->type_size = type_size; + q->head = 0; + q->tail = -1; + + if (memory) { + // caller owns the memory + q->owns_memory = false; + q->data = memory; + } else { + // ring queue should own the memory + q->owns_memory = true; + q->data = malloc(capacity * type_size); + } + + return q; +} + +void ring_queue_free(ring_queue* queue) { + if (queue) { + if (queue->owns_memory) { + free(queue->data); + } + free(queue); + } +} + +bool ring_queue_enqueue(ring_queue* queue, const void* value) { + if (queue->len == queue->capacity) { + return false; + } + + queue->tail = (queue->tail + 1) % queue->capacity; + memcpy(queue->data + (queue->tail * queue->type_size), value, queue->type_size); + queue->len++; + return true; +} + +bool ring_queue_dequeue(ring_queue* queue, void* out_value) { + if (queue->len == 0) { + // queue is empty + return false; + } + + memcpy(out_value, queue->data + (queue->head * queue->type_size), queue->type_size); + queue->head = (queue->head + 1) % queue->capacity; + queue->len--; + return true; +} + +bool ring_queue_peek(const ring_queue* queue, void* out_value) { + if (queue->len == 0) { + // queue is empty + return false; + } + + memcpy(out_value, queue->data + (queue->head * queue->type_size), queue->type_size); + return true; +}
\ No newline at end of file diff --git a/src/std/containers/ring_queue.h b/src/std/containers/ring_queue.h new file mode 100644 index 0000000..15d5da4 --- /dev/null +++ b/src/std/containers/ring_queue.h @@ -0,0 +1,35 @@ +/** + * @file ring_queue.h + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2024-02-24 + * + * @copyright Copyright (c) 2024 + * + */ +#pragma once +#include "defines.h" + +/** + * @brief a fixed-size ring queue + */ +typedef struct ring_queue { + size_t len; + size_t capacity; + size_t type_size; + void* data; + bool owns_memory; + int32_t head; + int32_t tail; +} ring_queue; + +ring_queue* ring_queue_new(size_t type_size, size_t capacity, void* memory_block); + +void ring_queue_free(ring_queue* queue); + +bool ring_queue_enqueue(ring_queue* queue, const void* value); + +bool ring_queue_dequeue(ring_queue* queue, void* out_value); + +bool ring_queue_peek(const ring_queue* queue, void* out_value);
\ No newline at end of file diff --git a/src/std/mem.h b/src/std/mem.h new file mode 100644 index 0000000..74222a7 --- /dev/null +++ b/src/std/mem.h @@ -0,0 +1,14 @@ +/** + * @file mem.h + * @brief Allocators, memory tracking + * @version 0.1 + * @date 2024-02-24 + * + * @copyright Copyright (c) 2024 + * + */ +#pragma once + +#include "defines.h" + +typedef void* (*alloc)(size_t amount);
\ No newline at end of file diff --git a/src/std/str.c b/src/std/str.c new file mode 100644 index 0000000..27f8f68 --- /dev/null +++ b/src/std/str.c @@ -0,0 +1,14 @@ +#include "str.h" + +bool str8_equals(str8 a, str8 b) { + if (a.len != b.len) { + return false; + } + + for (size_t i = 0; i < a.len; i++) { + if (a.buf[i] != b.buf[i]) { + return false; + } + } + return true; +}
\ No newline at end of file diff --git a/src/std/str.h b/src/std/str.h new file mode 100644 index 0000000..3d3cb41 --- /dev/null +++ b/src/std/str.h @@ -0,0 +1,30 @@ +/** + * @brief + * + */ +#pragma once + +#include "defines.h" + +/** + * @brief Fat pointer representing a UTF8 (TODO) encoded string + * @note when using `printf` you must use %s.*s length, string + */ +typedef struct { + u8 *buf; + size_t len; +} str8; + +/** @brief Compare two strings for exact equality */ +bool str8_equals(str8 a, str8 b); + +/** + * @brief Compare the first `first_nchars` of each string for equality + If either of the strings are shorter than the number only the characters up until the end + of the shorter string will be compared. + * @returns 0 if they are fully equal up until `first_nchars`, i.e they never differed, else it + returns the index at which the first string differed from the second string. +*/ +size_t str8_nequals(str8 a, str8 b, size_t first_nchars); + +bool str8_ends_with(str8 input_str, str8 suffix);
\ No newline at end of file |