From 65790e883f9557c449114156456a55692f8cc269 Mon Sep 17 00:00:00 2001 From: Randy Jordan Date: Wed, 10 Jun 2026 07:54:03 -0500 Subject: [PATCH] arrays --- include/platform/dsa/ci2_array.h | 62 +++++++++++++++++ include/platform/mem/ci2_arena.h | 22 +++--- include/platform/mem/ci2_mem.h | 24 +++---- "src/\\" | 91 +++++++++++++++++++++++++ src/ci2_arena.c | 20 ++++-- src/ci2_array.c | 111 +++++++++++++++++++++++++++++++ 6 files changed, 303 insertions(+), 27 deletions(-) create mode 100644 include/platform/dsa/ci2_array.h create mode 100644 "src/\\" create mode 100644 src/ci2_array.c diff --git a/include/platform/dsa/ci2_array.h b/include/platform/dsa/ci2_array.h new file mode 100644 index 0000000..ed53594 --- /dev/null +++ b/include/platform/dsa/ci2_array.h @@ -0,0 +1,62 @@ +/* - | Copyright | ------------------------------------------------------------ + Copyright (c) 2026 Randy Jordan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * --------------------------------------------------------------------------*/ +#ifndef CI2_ARRAY_H +#define CI2_ARRAY_H + +struct CI2_Array +{ + void** items; + int cap; + int len; +}; +typedef struct CI2_Array CI2_Array; + +void +ci2_array_init(struct CI2_Array* a, int cap); + +int +ci2_array_len(struct CI2_Array* a); + +void +ci2_array_add(struct CI2_Array* a, void* p); + +void +ci2_array_set(struct CI2_Array* a, int index, void* p); + +void* +ci2_array_get(struct CI2_Array* a, int index); + +void +ci2_array_delete(struct CI2_Array* a, int index); + +void +ci2_array_free(struct CI2_Array* a); + +#define CI2_ARRAY_ADD(vec, item) ci2_array_add(&vec, (void*)item) +#define CI2_ARRAY_SET(vec, id, item) ci2_array_set(&vec, id, (void*)item) +#define CI2_ARRAY_GET(vec, type, id) (type) ci2_array_get(&vec, id) +#define CI2_ARRAY_DELETE(vec, id) ci2_array_delete(&vec, id) +#define CI2_ARRAY_TOTAL(vec) ci2_array_total(&vec) +#define CI2_ARRAY_FREE(vec) ci2_array_free(&vec) + +#endif // ci2_array.h diff --git a/include/platform/mem/ci2_arena.h b/include/platform/mem/ci2_arena.h index 27a616d..e2c491d 100644 --- a/include/platform/mem/ci2_arena.h +++ b/include/platform/mem/ci2_arena.h @@ -25,31 +25,37 @@ SOFTWARE. #include -struct Arena +struct CI2_Arena { char* beg; char* end; }; -typedef struct Arena Arena; +typedef struct CI2_Arena CI2_Arena; /* Initialize an Arena with an existing buffer */ extern void -arena_back(struct Arena* a, char* buf, ptrdiff_t len); +ci2_arena_back(struct CI2_Arena* a, char* buf, ptrdiff_t len); /* Allocate a new Arena */ -extern struct Arena -arena_new(ptrdiff_t cap); +extern struct CI2_Arena +ci2_arena_new(ptrdiff_t cap); /* Get the current capacity of an Arena */ extern ptrdiff_t -arena_capacity(struct Arena a); +ci2_arena_capacity(struct CI2_Arena a); /* Make an allocation from an Arena and do not zero.*/ extern void* -arena_malloc(struct Arena* a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count); +ci2_arena_malloc(struct CI2_Arena* a, + ptrdiff_t size, + ptrdiff_t align, + ptrdiff_t count); /* Make an allocation from an Arena and zero.*/ extern void* -arena_calloc(struct Arena* a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count); +ci2_arena_calloc(struct CI2_Arena* a, + ptrdiff_t size, + ptrdiff_t align, + ptrdiff_t count); #endif // ci2_arena.h diff --git a/include/platform/mem/ci2_mem.h b/include/platform/mem/ci2_mem.h index 9c4d16e..c5f523f 100644 --- a/include/platform/mem/ci2_mem.h +++ b/include/platform/mem/ci2_mem.h @@ -1,5 +1,5 @@ /* - | Copyright | ------------------------------------------------------------ - Copyright (c) 2026 Randy Jordan + Copyright (c) 2026 Randy Jordan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -36,10 +36,10 @@ ci2_malloc(size_t nbytes, const char* file, const char* func, int line); /* Allocate an object and zero ci2ory. May throw exception. */ CI2_API void* ci2_calloc(size_t count, - size_t nbytes, - const char* file, - const char* func, - int line); + size_t nbytes, + const char* file, + const char* func, + int line); /* Free and null a pointer */ CI2_API void @@ -48,22 +48,22 @@ ci2_free(void** ptr, const char* file, const char* func, int line); /* Resize a non-null pointer */ CI2_API void* ci2_resize(void* ptr, - size_t nbytes, - const char* file, - const char* func, - int line); + size_t nbytes, + const char* file, + const char* func, + int line); #define CI2_MALLOC(nbytes) ci2_malloc((nbytes), __FILE__, CI2_FUNC, __LINE__) #define CI2_CALLOC(count, nbytes) \ - ci2_calloc((count), (nbytes), __FILE__, CI2_FUNC, __LINE__) + ci2_calloc((count), (nbytes), __FILE__, CI2_FUNC, __LINE__) #define CI2_NEW(p) ((p) = CI2_MALLOC((size_t)sizeof *(p))) #define CI2_NEW0(p) ((p) = CI2_CALLOC(1, (size_t)sizeof *(p))) #define CI2_FREE(ptr) \ - ((void)(ci2_free((ptr), __FILE__, CI2_FUNC, __LINE__), (ptr) = 0)) + ((void)(ci2_free((ptr), __FILE__, CI2_FUNC, __LINE__), (ptr) = 0)) #define CI2_RESIZE(ptr, nbytes) \ - ((ptr) = ci2_resize((ptr), (nbytes), __FILE__, CI2_FUNC, __LINE__)) + ((ptr) = ci2_resize((ptr), (nbytes), __FILE__, CI2_FUNC, __LINE__)) #endif // ci2_mem.h diff --git "a/src/\\" "b/src/\\" new file mode 100644 index 0000000..5dc9452 --- /dev/null +++ "b/src/\\" @@ -0,0 +1,91 @@ +/* - | Copyright | ------------------------------------------------------------ + Copyright (c) 2026 Randy Jordan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * --------------------------------------------------------------------------*/ +#include "../include/platform/mem/ci2_arena.h" +#include +#include +#include +#include + +/* Initialize an Arena with an existing buffer */ +void +ci2_arena_back(struct CI2_Arena* a, char* buf, ptrdiff_t len) +{ + assert(a != NULL); + assert(buf != NULL); + a->beg = buf; + a->end = buf + len; +} + +/* Allocate a new Arena */ +struct CI2_Arena +ci2_arena_new(ptrdiff_t cap) +{ + struct Arena a = { 0 }; + a.beg = malloc(cap); + a.end = a.beg ? a.beg + cap : 0; + return a; +} + +/* Get the current capacity of an Arena */ +ptrdiff_t +ci2_arena_capacity(struct CI2_Arena a) +{ + ptrdiff_t res = a.end - a.beg; + return res; +} + +/* Make an allocation from an Arena and do not zero.*/ +void* +ci2_arena_calloc(struct CI2_Arena* a, + ptrdiff_t size, + ptrdiff_t align, + ptrdiff_t count) +{ + ptrdiff_t padding = -(uintptr_t)a->beg & (align - 1); + ptrdiff_t available = a->end - a->beg - padding; + if (available < 0 || count > available / size) { + return NULL; + } + ptrdiff_t total = padding + count * size; + void* p = a->beg + total; + a->beg += total; + return memset(p, 0, total); +} + +/* Make an allocation from an Arena and zero.*/ +void* +ci2_arena_malloc(struct CI2_Arena* a, + ptrdiff_t size, + ptrdiff_t align, + ptrdiff_t count) +{ + ptrdiff_t padding = -(uintptr_t)a->beg & (align - 1); + ptrdiff_t available = a->end - a->beg - padding; + if (available < 0 || count > available / size) { + return NULL; + } + ptrdiff_t total = padding + count * size; + void* p = a->beg + total; + a->beg += total; + return p; +} diff --git a/src/ci2_arena.c b/src/ci2_arena.c index ed3ae87..d51a1b2 100644 --- a/src/ci2_arena.c +++ b/src/ci2_arena.c @@ -28,7 +28,7 @@ SOFTWARE. /* Initialize an Arena with an existing buffer */ void -arena_back(struct Arena* a, char* buf, ptrdiff_t len) +ci2_arena_back(struct CI2_Arena* a, char* buf, ptrdiff_t len) { assert(a != NULL); assert(buf != NULL); @@ -37,10 +37,10 @@ arena_back(struct Arena* a, char* buf, ptrdiff_t len) } /* Allocate a new Arena */ -struct Arena -arena_new(ptrdiff_t cap) +struct CI2_Arena +ci2_arena_new(ptrdiff_t cap) { - struct Arena a = { 0 }; + struct CI2_Arena a = { 0 }; a.beg = malloc(cap); a.end = a.beg ? a.beg + cap : 0; return a; @@ -48,7 +48,7 @@ arena_new(ptrdiff_t cap) /* Get the current capacity of an Arena */ ptrdiff_t -arena_capacity(struct Arena a) +ci2_arena_capacity(struct CI2_Arena a) { ptrdiff_t res = a.end - a.beg; return res; @@ -56,7 +56,10 @@ arena_capacity(struct Arena a) /* Make an allocation from an Arena and do not zero.*/ void* -arena_calloc(struct Arena* a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) +ci2_arena_calloc(struct CI2_Arena* a, + ptrdiff_t size, + ptrdiff_t align, + ptrdiff_t count) { ptrdiff_t padding = -(uintptr_t)a->beg & (align - 1); ptrdiff_t available = a->end - a->beg - padding; @@ -71,7 +74,10 @@ arena_calloc(struct Arena* a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) /* Make an allocation from an Arena and zero.*/ void* -arena_malloc(struct Arena* a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) +ci2_arena_malloc(struct CI2_Arena* a, + ptrdiff_t size, + ptrdiff_t align, + ptrdiff_t count) { ptrdiff_t padding = -(uintptr_t)a->beg & (align - 1); ptrdiff_t available = a->end - a->beg - padding; diff --git a/src/ci2_array.c b/src/ci2_array.c new file mode 100644 index 0000000..da8141d --- /dev/null +++ b/src/ci2_array.c @@ -0,0 +1,111 @@ +/* - | Copyright | ------------------------------------------------------------ + Copyright (c) 2026 Randy Jordan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * --------------------------------------------------------------------------*/ +#include "../include/platform/dsa/ci2_array.h" +#include +#include + +void +ci2_array_init(CI2_Array* v, int i) +{ + v->cap = i; + v->len = 0; + v->items = malloc(sizeof(void*) * v->cap); +} + +int +ci2_array_len(CI2_Array* v) +{ + return v->len; +} + +static void +ci2_array_resize(CI2_Array* v, int cap) +{ +#ifdef DEBUG_ON + printf("ci2_array_resize: %d to %d\n", v->cap, cap); +#endif + void** items = realloc(v->items, sizeof(void*) * cap); + + if (items) { + v->items = items; + v->cap = cap; + } +} + +void +ci2_array_add(CI2_Array* v, void* item) +{ + if (v->cap == v->len) + ci2_array_resize(v, v->cap * 2); + + v->items[v->len++] = item; +} + +void +ci2_array_set(CI2_Array* v, int index, void* item) +{ + if (index >= 0 && index < v->len) + v->items[index] = item; +} + +void* +ci2_array_get(CI2_Array* v, int index) +{ + if (index >= 0 && index < v->len) + return v->items[index]; + + return NULL; +} + +void +ci2_array_delete(struct CI2_Array* v, int index) +{ + + if (index < 0 || index >= v->len) + + return; + + v->items[index] = NULL; + + int i; + + for (i = index; i < v->len - 1; i++) { + + v->items[i] = v->items[i + 1]; + } + + v->items[i] = NULL; + + v->len--; + + if (v->len > 0 && v->len == v->cap / 4) + + ci2_array_resize(v, v->cap / 2); +} + +void +ci2_array_free(struct CI2_Array* v) +{ + + free(v->items); +}