aboutsummaryrefslogtreecommitdiff
path: root/include/shared/array_list.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/shared/array_list.h')
-rw-r--r--include/shared/array_list.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/include/shared/array_list.h b/include/shared/array_list.h
new file mode 100644
index 0000000..8b942ad
--- /dev/null
+++ b/include/shared/array_list.h
@@ -0,0 +1,105 @@
+#ifndef SHARED_ARRAY_LIST_H_
+#define SHARED_ARRAY_LIST_H_
+
+#include "kern/common.h"
+#include "kern/mem.h"
+
+#define ALLOC kalloc
+#define FREE kfree
+
+#define array_list_t(type) array_list_##type##_t
+#define array_list_new(type) array_list_##type##_new
+#define array_list_length(type) array_list_##type##_length
+#define array_list_reserve(type) array_list_##type##_reserve
+#define array_list_add(type) array_list_##type##_add
+#define array_list_remove(type) array_list_##type##remove
+#define array_list_ref(type) array_list_##type##_get
+#define array_list_free(type) array_list_##type##_free
+
+#define array_list_foreach(ar, val) \
+ typeof((ar)->elements[0]) val; \
+ if ((ar)->size > 0) val = (ar)->elements[0]; \
+ for (size_t _idx_ = 0; _idx_ < (ar)->size; \
+ val = (++_idx_) >= (ar)->size ? val : (ar)->elements[_idx_])
+
+#define ARRAY_LIST_DECL(type) \
+ typedef struct { \
+ size_t reserved; \
+ size_t size; \
+ type* elements; \
+ } array_list_t(type); \
+ size_t array_list_length(type)(const array_list_t(type)*); \
+ array_list_t(type) * array_list_new(type)(); \
+ bool array_list_reserve(type)(array_list_t(type)*, size_t len); \
+ bool array_list_add(type)(array_list_t(type)*, type val); \
+ bool array_list_remove(type)(array_list_t(type)*, size_t idx, type * out); \
+ type* array_list_ref(type)(array_list_t(type)*, size_t idx); \
+ void array_list_free(type)(array_list_t(type)*);
+
+#define ARRAY_LIST_IMPL(type) \
+ array_list_t(type) * array_list_new(type)() \
+ { \
+ array_list_t(type)* ret = ALLOC(sizeof(array_list_t(type))); \
+ ret->size = 0; \
+ ret->reserved = 0; \
+ ret->elements = NULL; \
+ return ret; \
+ } \
+ size_t array_list_length(type)(const array_list_t(type) * lst) \
+ { \
+ return lst->size; \
+ } \
+ bool array_list_reserve(type)(array_list_t(type) * lst, size_t newlen) \
+ { \
+ if (lst->reserved < newlen) { \
+ type* new_arr = ALLOC(sizeof(type) * newlen); \
+ if (!new_arr) { \
+ return 0; \
+ } \
+ for (size_t i = 0; i < lst->size; ++i) { \
+ new_arr[i] = lst->elements[i]; \
+ } \
+ FREE(lst->elements); \
+ lst->elements = new_arr; \
+ lst->reserved = newlen; \
+ } \
+ return 1; \
+ } \
+ bool array_list_add(type)(array_list_t(type) * lst, type v) \
+ { \
+ if (lst->size == lst->reserved) { \
+ if (!array_list_reserve(type)( \
+ lst, lst->reserved == 0 ? 4 : lst->reserved * 2)) { \
+ return 0; \
+ } \
+ } \
+ lst->elements[lst->size++] = v; \
+ return 1; \
+ } \
+ bool array_list_remove(type)( \
+ array_list_t(type) * lst, size_t idx, type * out) \
+ { \
+ if (idx >= lst->size) { \
+ return 0; \
+ } \
+ if (out) *out = lst->elements[idx]; \
+ for (size_t i = idx; i < lst->size - 1; ++i) { \
+ lst->elements[i] = lst->elements[i + 1]; \
+ } \
+ lst->size--; \
+ return 1; \
+ } \
+ type* array_list_ref(type)(array_list_t(type) * lst, size_t idx) \
+ { \
+ if (idx >= lst->size) { \
+ return NULL; \
+ } \
+ return &lst->elements[idx]; \
+ } \
+ void array_list_free(type)(array_list_t(type) * lst) \
+ { \
+ FREE(lst->elements); \
+ FREE(lst); \
+ }
+
+#endif /* SHARED_ARRAY_LIST_H_ */