summaryrefslogtreecommitdiff
path: root/amr_array.h
diff options
context:
space:
mode:
Diffstat (limited to 'amr_array.h')
-rw-r--r--amr_array.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/amr_array.h b/amr_array.h
new file mode 100644
index 0000000..d9546d2
--- /dev/null
+++ b/amr_array.h
@@ -0,0 +1,110 @@
+// AMR ARRAY
+// GENERAL ARRAYS FOR C
+// > Mainly for prototyping and small internal programs
+//
+// Documentation:
+//
+// AMR_MALLOC:
+// malloc function, can be replace with a custom allocator (todo)
+// AMR_FREE:
+// free function, can be replace with a custom allocator (todo)
+// amr_arr_len:
+// get array length
+// amr_arr_cap:
+// get array capacity
+// amr_arr_init:
+// initialize array, see usage for how to use.
+// amr_arr_tinit:
+// initialize array with type. gets around void cast issue, annoying on
+// c++
+// amr_arr_push(arr, value):
+// push an element on to the end of an array.
+// will not care about holes in array.
+// amr_arr_pushcarr(arr, carr):
+// push a c-style constant size array
+// amr_arr_join(arr_a, arr_b):
+// join/push all items from array b into array a
+// amr_arr_clear(arr):
+// clears array. (actually just resets the len variable of array,
+// since operations first work on array len, this is all
+// we need to "clear" it)
+//
+// Usage:
+//
+// typdef T arr_t; // optional, but recommended to signify a type is an array.
+// // Highlights intent, prevents confusion
+//
+// int main() {
+// arr_t *myarr;
+// amr_arr_init(myarr, capacity);
+//
+// amr_arr_push(myarr, 2);
+// ...
+// }
+
+#ifndef __AMR_INCLUDE_AMR_ARRAY_H
+#define __AMR_INCLUDE_AMR_ARRAY_H
+
+#include "stdlib.h"
+#include "assert.h"
+#include "string.h"
+
+struct ArrayHeader {
+ int len;
+ int cap;
+};
+typedef struct ArrayHeader ArrayHeader;
+
+#define __CARR_LEN(CARR) (sizeof((CARR))/sizeof((CARR)[0]))
+#define AMR_MALLOC(x) malloc((x))
+#define AMR_FREE(p) free((p))
+#define amr_arr_len(A) ((((ArrayHeader*)(A)) - 1)->len)
+#define amr_arr_cap(A) ((((ArrayHeader*)(A)) -1)->cap)
+
+#define amr_arr_init(ARR, CAP) { \
+ ArrayHeader *H = (ArrayHeader*)AMR_MALLOC((CAP)*sizeof((ARR)[0]) + sizeof(ArrayHeader)); \
+ H->len = 0; \
+ H->cap = (CAP); \
+ ARR = (void*)(H+1); \
+}
+
+#define amr_arr_tinit(T, ARR, CAP) { \
+ ArrayHeader *H = (ArrayHeader*)AMR_MALLOC((CAP)*sizeof((ARR)[0]) + sizeof(ArrayHeader)); \
+ H->len = 0; \
+ H->cap = (CAP); \
+ ARR = (T*)(H+1); \
+}
+
+#define amr_arr_push(ARR, VAL) { \
+ ArrayHeader *H = ((ArrayHeader*)(ARR)-1); \
+ assert(H->len+1 <= H->cap); \
+ (ARR)[H->len++] = (VAL); \
+}
+
+#define amr_arr_pushcarr(ARR, ELE) { \
+ ArrayHeader *H = ((ArrayHeader*)(ARR)-1); \
+ assert(H->len+(__CARR_LEN((ELE))) <= H->cap); \
+ memcpy((ARR)+H->len, (ELE), sizeof((ELE))); \
+ H->len += (__CARR_LEN((ELE))); \
+}
+
+#define amr_arr_join(A, B) { \
+ ArrayHeader *HA = (ArrayHeader*)(A)-1; \
+ ArrayHeader *HB = (ArrayHeader*)(B)-1; \
+ assert(HA->len + HB->len <= HA->cap); \
+ memcpy((A) + HA->len, (B), sizeof((B)[0])*HB->len); \
+ HA->len += HB->len; \
+}
+
+#define amr_arr_clear(ARR) { \
+ ArrayHeader *H = (ArrayHeader*)(ARR)-1; \
+ H->len = 0; \
+}
+
+#define amr_arr_free(ARR) { \
+ AMR_FREE((ArrayHeader*)(ARR)-1); \
+}
+
+#endif // __AMR_INCLUDE_AMR_ARRAY_H
+
+