diff options
| author | Syndamia <kamen@syndamia.com> | 2026-04-28 14:06:44 +0300 |
|---|---|---|
| committer | Syndamia <kamen@syndamia.com> | 2026-05-12 07:08:56 +0300 |
| commit | 0d249b1d47a7f84cfe5f09ad070d1affd26566da (patch) | |
| tree | f395f67eecb27daea3fc4a9ad8e59bf40f988984 | |
| parent | 5c36b582ad60a569ed996fe188ed92ef6bd7fc5f (diff) | |
| download | foollib-0d249b1d47a7f84cfe5f09ad070d1affd26566da.tar foollib-0d249b1d47a7f84cfe5f09ad070d1affd26566da.tar.gz foollib-0d249b1d47a7f84cfe5f09ad070d1affd26566da.zip | |
feat!: Refactor using MemoryManager
The idea is to provide a universal memory management "API", through
which you allocate and deallocate. This allows our implementations (for
String and Vector) to be more generic.
It does also allow usage of different allocators depending on situation.
| -rw-r--r-- | Array.c | 97 | ||||
| -rw-r--r-- | Array.h | 18 | ||||
| -rw-r--r-- | BumpAlloc.c | 133 | ||||
| -rw-r--r-- | BumpAlloc.h | 11 | ||||
| -rw-r--r-- | GlobalArena.c | 23 | ||||
| -rw-r--r-- | GlobalArena.h | 15 | ||||
| -rw-r--r-- | MemoryManager.c | 31 | ||||
| -rw-r--r-- | MemoryManager.h | 16 | ||||
| -rw-r--r-- | String.c | 235 | ||||
| -rw-r--r-- | String.h | 26 | ||||
| -rw-r--r-- | Types.h | 40 | ||||
| -rw-r--r-- | Vector.c | 117 | ||||
| -rw-r--r-- | Vector.h | 18 | ||||
| -rw-r--r-- | example.c | 38 |
14 files changed, 434 insertions, 384 deletions
diff --git a/Array.c b/Array.c deleted file mode 100644 index 6be8c1a..0000000 --- a/Array.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "Array.h" -#include "Types.h" -#include "GlobalArena.h" -#include <stdlib.h> -#include <string.h> - -struct ArrayMeta { - BumpArena b; - usize element_size; - usize count; - usize length; -}; - -static inline struct ArrayMeta* -A_metadata(void* arr) { - return arr - sizeof(struct ArrayMeta); -} - -typedef void* Array; - -Array -A_new(BumpArena b, usize element_size, usize length) { - if (NULL == b) - return NULL; - - struct ArrayMeta am = { - .b = b, - .element_size = element_size, - .count = 0, - .length = length, - }; - - void* start = B_alloc(b, sizeof(am) + element_size * length); - if (NULL == start) - return NULL; - - memcpy(start, &am, sizeof(am)); - return start + sizeof(am); -} - -usize -A_length(Array arr) { - if (NULL == arr) - return 0; - return A_metadata(arr)->length; -} - -usize -A_count(Array arr) { - if (NULL == arr) - return 0; - return A_metadata(arr)->count; -} - -Result -A_push(Array arr, void *value) { - if (NULL == arr) - return R_Uninitialized; - - struct ArrayMeta *am = A_metadata(arr); - - if (am->count >= am->length) { - if (!B_resizeable(am->b, arr)) - return R_OutOfBounds; - - RETURN_NOTOK(B_resize(am->b, sizeof(*am) + am->element_size * (am->length << 1))); - am->length <<= 1; - } - - memcpy(arr + am->count++ * am->element_size, value, am->element_size); - - return R_Ok; -} - -Result -A_ppush(Array arr, void *pvalue) { - void* temp = pvalue; - return A_push(arr, &temp); -} - -void* -A_pop(Array arr) { - if (NULL == arr) - return NULL; - - struct ArrayMeta *am = A_metadata(arr); - - if (am->count == 0) - return NULL; - - return arr + am->element_size * --am->count; -} - -Array -AG_new(usize element_size, usize length) { - return A_new(g_arena, element_size, length); -} diff --git a/Array.h b/Array.h deleted file mode 100644 index 508a069..0000000 --- a/Array.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _ARRAY -#define _ARRAY - -#include "Types.h" -#include "BumpAlloc.h" - -typedef void* Array; - -Array A_new(BumpArena b, usize element_size, usize length); -usize A_length(Array arr); -usize A_count(Array arr); -Result A_push(Array arr, void *value); -Result A_ppush(Array arr, void *value); -void* A_pop(Array arr); - -Array AG_new(usize element_size, usize length); - -#endif /* _ARRAY */ diff --git a/BumpAlloc.c b/BumpAlloc.c index 1d1e1c1..09af8fa 100644 --- a/BumpAlloc.c +++ b/BumpAlloc.c @@ -3,54 +3,81 @@ #include <stdio.h> #include <stdlib.h> -struct BumpArena { +struct BumpAlloc { void* memory; usize size; usize top; }; -BumpArena -B_create(usize size) { - struct BumpArena *b = malloc(sizeof(struct BumpArena)); - b->memory = malloc(size); - b->size = size; - b->top = 0; +static inline usize* +top_size(struct BumpAlloc* b) { + return (usize*)(b->memory + b->top); +} + +static int +bump_resizeable(struct BumpAlloc *b, void *ptr) { + if (NULL == b) + return 0; - return b; + return b->memory + b->top - *top_size(b) <= ptr && + ptr < b->memory + b->top; } Result -B_destroy(BumpArena bp) { - if (NULL == bp) +bump_free(MemoryManager mm, void **ptr) { + if (NULL == mm.priv) return R_Uninitialized; - struct BumpArena b = *(struct BumpArena*)bp; + struct BumpAlloc *b = (struct BumpAlloc*)mm.priv; + + if (NULL != ptr) { + if (bump_resizeable(b, *ptr)) + *ptr = NULL; + else + return R_InvalidArgument; + } + + if (b->top > 0) { + b->top -= *top_size(b); + if (b->top > 0) + b->top -= sizeof(usize); + } + + return R_Ok; +} + +Result +bump_destroy(MemoryManager *mm) { + if (NULL == mm->priv) + return R_Uninitialized; + + struct BumpAlloc b = *(struct BumpAlloc*)mm->priv; if (NULL == b.memory) { - free(bp); + free(mm->priv); + mm->priv = NULL; return R_Uninitialized; } free(b.memory); - free(bp); + free(mm->priv); + mm->priv = NULL; return R_Ok; } -static inline usize* -top_size(struct BumpArena* b) { - return (usize*)(b->memory + b->top); -} +Result +bump_alloc(MemoryManager mm, void** ptr, usize size) { + if (NULL == mm.priv) + return R_Uninitialized; -void* -B_alloc(BumpArena bp, usize size) { - if (bp == NULL || size == 0) - return NULL; + if (0 == size || NULL == ptr) + return R_NullArgument; - struct BumpArena *b = (struct BumpArena*)bp; + struct BumpAlloc *b = (struct BumpAlloc*)mm.priv; if (size + b->top + sizeof(usize) > b->size) - return NULL; + return R_OutOfMemory; if (b->top > 0) b->top += sizeof(usize); @@ -60,37 +87,31 @@ B_alloc(BumpArena bp, usize size) { // Keep allocated memory size at the end of every allocation *top_size(b) = size; - return b->memory + start; -} - -int -B_resizeable(BumpArena bp, void* ptr) { - if (NULL == bp) - return 0; - - struct BumpArena *b = (struct BumpArena*)bp; - - return b->memory + b->top - *top_size(b) <= ptr && - ptr < b->memory + b->top; + *ptr = b->memory + start; + return R_Ok; } Result -B_resize(BumpArena bp, usize size) { - if (NULL == bp) +bump_resize(MemoryManager mm, void **ptr, usize size) { + if (NULL == mm.priv) return R_Uninitialized; - struct BumpArena *b = (struct BumpArena*)bp; + if (size == 0) + return bump_free(mm, ptr); - if (size == 0) { - B_free(bp); - return R_Ok; - } + if (NULL == ptr) + return R_NullArgument; + + struct BumpAlloc *b = (struct BumpAlloc*)mm.priv; + + if (NULL == ptr || !bump_resizeable(b, *ptr)) + return R_InvalidArgument; usize last_size = *top_size(b); usize start = b->top - last_size; if (start + size + sizeof(usize) > b->size) - return R_OutOfBounds; + return R_OutOfMemory; *top_size(b) = 0; b->top = start + size; @@ -99,18 +120,18 @@ B_resize(BumpArena bp, usize size) { return R_Ok; } -Result -B_free(BumpArena bp) { - if (NULL == bp) - return R_Uninitialized; - - struct BumpArena *b = (struct BumpArena*)bp; - - if (b->top > 0) { - b->top -= *top_size(b); - if (b->top > 0) - b->top -= sizeof(usize); - } +MemoryManager +M_bump(usize size) { + struct BumpAlloc *b = malloc(sizeof(struct BumpAlloc)); + b->memory = malloc(size); + b->size = size; + b->top = 0; - return R_Ok; + return (MemoryManager){ + .alloc = &bump_alloc, + .realloc = &bump_resize, + .free = &bump_free, + .destroy = &bump_destroy, + .priv = b, + }; } diff --git a/BumpAlloc.h b/BumpAlloc.h index a381134..6ba9caa 100644 --- a/BumpAlloc.h +++ b/BumpAlloc.h @@ -2,15 +2,8 @@ #define _BUMP_ALLOC #include "Types.h" +#include "MemoryManager.h" -typedef void* BumpArena; - -BumpArena B_create(usize size); -Result B_destroy(BumpArena b); - -void* B_alloc(BumpArena b, usize size); -int B_resizeable(BumpArena b, void* ptr); -Result B_resize(BumpArena b, usize size); -Result B_free(BumpArena b); +MemoryManager M_bump(usize size); #endif /* _BUMP_ALLOC */ diff --git a/GlobalArena.c b/GlobalArena.c deleted file mode 100644 index e19e38d..0000000 --- a/GlobalArena.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "GlobalArena.h" - -BumpArena g_arena = NULL; - -void* -BG_alloc(usize size) { - return B_alloc(g_arena, size); -} - -int -BG_resizeable(void* ptr) { - return B_resizeable(g_arena, ptr); -} - -Result -BG_resize(usize size) { - return B_resize(g_arena, size); -} - -Result -BG_free() { - return B_free(g_arena); -} diff --git a/GlobalArena.h b/GlobalArena.h deleted file mode 100644 index 8c2b524..0000000 --- a/GlobalArena.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _GLOBAL_ARENA -#define _GLOBAL_ARENA - -#include "BumpAlloc.h" -#include "Array.h" - -// Global bump arena -extern BumpArena g_arena; - -void* BG_alloc(usize size); -int BG_resizeable(void* ptr); -Result BG_resize(usize size); -Result BG_free(); - -#endif /* _GLOBAL_ARENA */ diff --git a/MemoryManager.c b/MemoryManager.c new file mode 100644 index 0000000..68dab6e --- /dev/null +++ b/MemoryManager.c @@ -0,0 +1,31 @@ +#include "MemoryManager.h" +#include <stdlib.h> + +Result std_alloc(MemoryManager mm, void** ptr, usize size) { + *ptr = malloc(size); + return (*ptr == NULL) ? R_Err : R_Ok; +} + +Result std_realloc(MemoryManager mm, void** ptr, usize size) { + *ptr = realloc(*ptr, size); + return (*ptr == NULL) ? R_Err : R_Ok; +} + +Result std_free(MemoryManager mm, void** ptr) { + free(*ptr); + *ptr = NULL; + return R_Ok; +} + +Result std_destroy(MemoryManager *mm) { + return R_Unavailable; +} + +MemoryManager M_std() { + return (MemoryManager){ + .alloc = &std_alloc, + .realloc = &std_realloc, + .free = &std_free, + .destroy = &std_destroy, + }; +} diff --git a/MemoryManager.h b/MemoryManager.h new file mode 100644 index 0000000..95f864c --- /dev/null +++ b/MemoryManager.h @@ -0,0 +1,16 @@ +#ifndef _MEMORY_MANAGER +#define _MEMORY_MANAGER + +#include "Types.h" + +typedef struct MemoryManager { + Result (* const alloc)(struct MemoryManager mm, void **ptr, usize size); + Result (* const realloc)(struct MemoryManager mm, void **ptr, usize new_size); + Result (* const free)(struct MemoryManager mm, void **ptr); + Result (* const destroy)(struct MemoryManager *mm); + void *priv; +} MemoryManager; + +MemoryManager M_std(); + +#endif /* _MEMORY_MANAGER */ @@ -1,12 +1,10 @@ #include "String.h" -#include "GlobalArena.h" #include "Types.h" -#include <stdarg.h> #include <stdio.h> #include <string.h> struct StringMeta { - BumpArena b; + MemoryManager *mm; usize length; }; @@ -15,44 +13,48 @@ S_metadata(String s) { return (struct StringMeta*)(s - sizeof(struct StringMeta)); } -String -S_new(BumpArena b, const char* str) { - if (NULL == b || NULL == str) +static inline void* +S_start(MemoryManager *mm, usize length) { + if (NULL == mm) return NULL; struct StringMeta sm = { - .b = b, - .length = strlen(str), + .mm = mm, + .length = length, }; - void* start = B_alloc(b, sizeof(sm) + sm.length + 1); - if (NULL == start) + void* start = NULL; + if (R_Ok != mm->alloc(*mm, &start, sizeof(sm) + sm.length + 1) || + NULL == start) + { return NULL; + } memcpy(start, &sm, sizeof(sm)); - start += sizeof(sm); - memcpy(start, str, sm.length + 1); - - return start; + return start + sizeof(sm); } String -S_newlen(BumpArena b, usize length) { - if (NULL == b) +S_new(MemoryManager *mm, const char* str) { + if (NULL == str) return NULL; - struct StringMeta sm = { - .b = b, - .length = length, - }; + usize strlength = strlen(str); - void* start = B_alloc(b, sizeof(sm) + sm.length + 1); - if (NULL == start) - return NULL; + void* start = S_start(mm, strlength); - memcpy(start, &sm, sizeof(sm)); - start += sizeof(sm); - memset(start, '\0', sm.length + 1); + if (NULL != start) + memcpy(start, str, strlength + 1); + + return start; +} + +String +S_newlen(MemoryManager *mm, usize length) { + void* start = S_start(mm, length); + + if (NULL != start) + memset(start, '\0', length + 1); return start; } @@ -63,84 +65,28 @@ S_allocated(String s) { } String -S_dup(BumpArena b, String s) { - if (NULL == b || NULL == s) +S_dup(MemoryManager *mm, String s) { + if (NULL == mm || NULL == s) return NULL; usize allocated = S_allocated(s); - void* start = B_alloc(b, allocated); - if (NULL == start) + void* start = NULL; + if (R_Ok != mm->alloc(*mm, &start, allocated) || + NULL == start) + { return NULL; + } memcpy(start, s - sizeof(struct StringMeta), allocated); - return start + sizeof(struct StringMeta); } -usize -S_length(String s) { - if (NULL == s) - return 0; - return S_metadata(s)->length; -} - -Result -S_append(String s, const char* str) { - if (NULL == s || NULL == str) - return R_Uninitialized; - - struct StringMeta* sm = S_metadata(s); - - if (!B_resizeable(sm->b, s)) - return R_OutOfBounds; - - usize strlength = strlen(str); - RETURN_NOTOK(B_resize(sm->b, sizeof(*sm) + (sm->length + strlength) + 1)); - - strcat(s, str); - sm->length += strlength; - - return R_Ok; -} - -Result -S_prepend(String s, const char* str) { - if (NULL == s) - return R_Uninitialized; - - struct StringMeta* sm = S_metadata(s); - - if (!B_resizeable(sm->b, s)) - return R_OutOfBounds; - - usize strlength = strlen(str); - RETURN_NOTOK(B_resize(sm->b, sizeof(*sm) + (sm->length + strlength) + 1)); - - for (usize i = sm->length; i > 0; --i) - s[i - 1 + strlength] = s[i - 1]; - for (usize i = 0; i < strlength; ++i) - s[i] = str[i]; - - sm->length += strlength; - - return R_Ok; -} - -usize -S_find(String s, char c) { - if (NULL == s) - return -1; - - unsigned index = 0; - while (s[index] != '\0' && s[index] != c) - ++index; - - return index; -} +String +S_vconcat(MemoryManager *mm, va_list args) { + if (NULL == mm) + return NULL; -static String -S_vconcat(BumpArena b, va_list args) { usize length = 0; va_list temp; @@ -150,10 +96,10 @@ S_vconcat(BumpArena b, va_list args) { } va_end(temp); - String result = S_newlen(b, length); + String result = S_newlen(mm, length); if (NULL == result) - return result; + return NULL; if (0 < length) { for (const char* str = va_arg(args, const char*); str != NULL; str = va_arg(args, const char*)) @@ -163,25 +109,28 @@ S_vconcat(BumpArena b, va_list args) { } String -S_concat(BumpArena b, ...) { +S_concat(MemoryManager *mm, ...) { va_list args; usize length = 0; - va_start(args, b); - String result = S_vconcat(b, args); + va_start(args, mm); + String result = S_vconcat(mm, args); va_end(args); return result; } -static String -S_vprintf(BumpArena b, const char* fmt, va_list args) { +String +S_vprintf(MemoryManager *mm, const char* fmt, va_list args) { + if (NULL == mm) + return NULL; + va_list temp; va_copy(temp, args); usize length = vsnprintf(NULL, 0, fmt, temp); va_end(temp); - String result = S_newlen(b, length); + String result = S_newlen(mm, length); if (NULL == result) return NULL; @@ -190,54 +139,82 @@ S_vprintf(BumpArena b, const char* fmt, va_list args) { } String -S_printf(BumpArena b, const char* fmt, ...) { +S_printf(MemoryManager *mm, const char* fmt, ...) { va_list args; va_start(args, fmt); - String result = S_vprintf(b, fmt, args); + String result = S_vprintf(mm, fmt, args); va_end(args); return result; } -String -SG_new(const char* str) { - return S_new(g_arena, str); +usize +S_length(String s) { + if (NULL == s) + return 0; + return S_metadata(s)->length; } -String -SG_newlen(usize length) { - return S_newlen(g_arena, length); +static inline Result +S_resize(String *s, usize length) { + if (NULL == s || NULL == *s) + return R_Uninitialized; + + struct StringMeta *sm = S_metadata(*s); + + void *start = sm; + RETURN_NOTOK( + sm->mm->realloc(*sm->mm, &start, S_allocated(*s) + length)); + *s = start + sizeof(*sm); + + return R_Ok; } -String -SG_dup(String s) { - return S_dup(g_arena, s); +Result +S_append(String *s, const char* str) { + if (NULL == str) + return R_Uninitialized; + + usize strlength = strlen(str); + + RETURN_NOTOK(S_resize(s, strlength)); + + strcat(*s, str); + S_metadata(*s)->length += strlength; + + return R_Ok; } -String -SG_concat(const char* str, ...) { - if (str == NULL) - return NULL; +Result +S_prepend(String *s, const char* str) { + if (NULL == s) + return R_Uninitialized; - va_list args; + usize strlength = strlen(str); - va_start(args, str); - String result = S_vconcat(g_arena, args); - va_end(args); + RETURN_NOTOK(S_resize(s, strlength)); - S_prepend(result, str); + struct StringMeta *sm = S_metadata(*s); - return result; + for (usize i = sm->length; i > 0; --i) + *s[i - 1 + strlength] = *s[i - 1]; + for (usize i = 0; i < strlength; ++i) + *s[i] = str[i]; + + sm->length += strlength; + + return R_Ok; } -String -SG_printf(const char* fmt, ...) { - va_list args; +usize +S_find(String s, char c) { + if (NULL == s) + return -1; - va_start(args, fmt); - String result = S_vprintf(g_arena, fmt, args); - va_end(args); + unsigned index = 0; + while (s[index] != '\0' && s[index] != c) + ++index; - return result; + return index; } @@ -1,25 +1,23 @@ #ifndef _STRING #define _STRING -#include "BumpAlloc.h" +#include "MemoryManager.h" +#include <stdarg.h> typedef char* String; -String S_new(BumpArena b, const char* str); -String S_newlen(BumpArena b, usize length); -String S_dup(BumpArena b, String s); -String S_concat(BumpArena b, ...); -String S_printf(BumpArena b, const char* fmt, ...); +String S_new(MemoryManager *mm, const char* str); +String S_newlen(MemoryManager *mm, usize length); +String S_dup(MemoryManager *mm, String s); +String S_vconcat(MemoryManager *mm, va_list args); +String S_concat(MemoryManager *mm, ...); +String S_vprintf(MemoryManager *mm, const char* fmt, va_list args); +String S_printf(MemoryManager *mm, const char* fmt, ...); usize S_length(String s); -Result S_append(String s, const char* str); -Result S_prepend(String s, const char* str); +Result S_append(String *s, const char* str); +Result S_prepend(String *s, const char* str); usize S_find(String s, char c); - -String SG_new(const char* str); -String SG_newlen(usize length); -String SG_dup(String s); -String SG_concat(const char* str, ...); -String SG_printf(const char* fmt, ...); +Result S_free(String s); #endif /* _STRING */ @@ -15,15 +15,53 @@ typedef uint_fast64_t u64; typedef size_t usize; typedef enum Result { + /* Generic */ R_Ok = 0, R_Err, - R_Invalid, + R_NotImplemented, + /* Values */ R_Uninitialized, + R_InvalidValue, R_OutOfBounds, + /* Functions */ + R_InvalidArgument, + R_NullArgument, + /* Memory */ + R_OutOfMemory, + /* Resources */ + R_NotFound, + R_PermissionDenied, + R_Unreachable, + R_Unavailable, + /* Other */ R_PRIVATE } Result; +#if defined(__has_warning) +# if __has_warning("-Wc99-designator") +# pragma clang diagnostic ignored "-Wc99-designator" +# endif +#endif + +const static char* Result_TO_STR[R_PRIVATE+1] = { + [R_Ok] = "Ok", + [R_Err] = "Error", + [R_NotImplemented] = "Not implemented", + [R_Uninitialized] = "Uninitialized", + [R_InvalidValue] = "Invalid value", + [R_OutOfBounds] = "Out of bounds", + [R_InvalidArgument] = "Invalid argument", + [R_NullArgument] = "NULL argument", + [R_OutOfMemory] = "Out of memory", + [R_NotFound] = "Not found", + [R_PermissionDenied] = "Permission denied", + [R_Unreachable] = "Not reachable", + [R_Unavailable] = "Not available", + [R_PRIVATE] = "Unknown", +}; + #define RETURN_NOTOK(x) { Result r = x; if (R_Ok != r) return r; } +#define PRINT_NOTOK(x) { Result r = x; if (R_Ok != r) fprintf(stderr, "%s:%d %s() Error: %s (%d)\n", __FILE__, __LINE__, __func__, Result_TO_STR[r], r); } #define B(x) ((x) * 8) #define KiB(x) ((x) * 1024) diff --git a/Vector.c b/Vector.c new file mode 100644 index 0000000..2236c64 --- /dev/null +++ b/Vector.c @@ -0,0 +1,117 @@ +#include "Vector.h" +#include "Types.h" +#include <string.h> + +struct VectorMeta { + MemoryManager *mm; + usize element_size; + usize count; + usize length; +}; + +static inline struct VectorMeta* +V_metadata(void *arr) { + return arr - sizeof(struct VectorMeta); +} + +Vector +V_new(MemoryManager *mm, usize element_size, usize length) { + if (NULL == mm) + return NULL; + + struct VectorMeta vm = { + .mm = mm, + .element_size = element_size, + .count = 0, + .length = length, + }; + + void* start = NULL; + if (R_Ok != mm->alloc(*mm, &start, sizeof(vm) + element_size * length) || + NULL == start) + { + return NULL; + } + + memcpy(start, &vm, sizeof(vm)); + return start + sizeof(vm); +} + +usize +V_length(Vector arr) { + if (NULL == arr) + return 0; + return V_metadata(arr)->length; +} + +usize +V_count(Vector arr) { + if (NULL == arr) + return 0; + return V_metadata(arr)->count; +} + +void* +V_top(Vector arr) { + if (NULL == arr) + return NULL; + + struct VectorMeta *vm = V_metadata(arr); + + if (0 == vm->count) + return NULL; + + return arr + (vm->count - 1) * vm->element_size; +} + +Result +V_push(Vector *arr, void *pvalue) { + if (NULL == arr || NULL == *arr) + return R_Uninitialized; + + struct VectorMeta *vm = V_metadata(*arr); + + if (vm->count >= vm->length) { + void *start = vm; + RETURN_NOTOK( + vm->mm->realloc(*vm->mm, &start, sizeof(*vm) + vm->element_size * (vm->length << 1))); + + vm = start; + *arr = start + sizeof(*vm); + vm->length <<= 1; + } + + memcpy(*arr + vm->count++ * vm->element_size, pvalue, vm->element_size); + + return R_Ok; +} + +Result +V_pushp(Vector* *arr, void *value) { + void *temp = value; + return V_push((void**)arr, &temp); +} + +Result +V_pop(Vector *arr) { + if (NULL == arr || NULL == *arr) + return R_NullArgument; + + struct VectorMeta *vm = V_metadata(arr); + + if (vm->count == 0) + return R_OutOfBounds; + + --vm->count; + return R_Ok; +} + +Result +V_free(Vector *arr) { + if (NULL == arr || NULL == *arr) + return R_NullArgument; + + struct VectorMeta *vm = V_metadata(*arr); + *arr = vm; + return vm->mm->free(*vm->mm, arr); +} diff --git a/Vector.h b/Vector.h new file mode 100644 index 0000000..ae82c23 --- /dev/null +++ b/Vector.h @@ -0,0 +1,18 @@ +#ifndef _VECTOR +#define _VECTOR + +#include "Types.h" +#include "MemoryManager.h" + +typedef void* Vector; + +Vector V_new(MemoryManager *mm, usize element_size, usize length); +usize V_length(Vector arr); +usize V_count(Vector arr); +void* V_top(Vector arr); +Result V_push(Vector *arr, void *pointer_to_value); +Result V_pushp(Vector* *arr, void *value); +Result V_pop(Vector *arr); +Result V_free(Vector *arr); + +#endif /* _VECTOR */ @@ -1,38 +1,32 @@ -#include "Array.h" -#include "BumpAlloc.h" -#include "GlobalArena.h" +#include "Vector.h" #include "String.h" +#include "BumpAlloc.h" #include <stdio.h> int main() { - g_arena = B_create(KiB(4)); - BumpArena t_arena = B_create(KiB(4)); + MemoryManager g = M_bump(KiB(2)), + t = M_bump(KiB(3)); - String* hexes = AG_new(sizeof(String), 8); - Result status = R_Ok; + String *hexes = V_new(&g, sizeof(String), 8); + Result status = R_Ok; for (usize i = 7; i <= 4830; i += 69) { - status = A_ppush(hexes, S_printf(t_arena, "%x", i)); - - if (R_Ok != status) { - fprintf(stderr, "Error(%d): %lu %lu\n", status, i, A_count(hexes)); - } + PRINT_NOTOK(V_pushp((void***)&hexes, S_printf(&t, "%x", i))); } - String all = SG_printf("Total: %ld\n", A_count(hexes)); - for (usize i = 0; i + 4 < A_count(hexes); i += 4) { - Result status = S_append(all, S_concat(t_arena, hexes[0+i], " ", hexes[1+i], " ", hexes[2+i], " ", hexes[3+i], "\n", NULL)); - - if (R_Ok != status) { - fprintf(stderr, "Error(%d): %lu %lu\n", status, i, A_count(hexes)); - } + String all = S_printf(&g, "Total: %ld\n", V_count(hexes)); + for (usize i = 0; i + 4 < V_count(hexes); i += 4) { + PRINT_NOTOK( + S_append(&all, + S_concat(&t, + hexes[0+i], " ", hexes[1+i], " ", hexes[2+i], " ", hexes[3+i], "\n", + NULL))); } printf("%s", all); - - B_destroy(g_arena); - B_destroy(t_arena); + PRINT_NOTOK(g.destroy(&g)); + PRINT_NOTOK(t.destroy(&t)); return 0; } |
