aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Array.c97
-rw-r--r--Array.h18
-rw-r--r--BumpAlloc.c133
-rw-r--r--BumpAlloc.h11
-rw-r--r--GlobalArena.c23
-rw-r--r--GlobalArena.h15
-rw-r--r--MemoryManager.c31
-rw-r--r--MemoryManager.h16
-rw-r--r--String.c235
-rw-r--r--String.h26
-rw-r--r--Types.h40
-rw-r--r--Vector.c117
-rw-r--r--Vector.h18
-rw-r--r--example.c38
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 */
diff --git a/String.c b/String.c
index dd34d34..17c2da0 100644
--- a/String.c
+++ b/String.c
@@ -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;
}
diff --git a/String.h b/String.h
index 9be9195..16f1990 100644
--- a/String.h
+++ b/String.h
@@ -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 */
diff --git a/Types.h b/Types.h
index 5801d93..f12a52e 100644
--- a/Types.h
+++ b/Types.h
@@ -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 */
diff --git a/example.c b/example.c
index 00f79da..2f50152 100644
--- a/example.c
+++ b/example.c
@@ -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;
}