utils.h (4143B)
1 #ifndef UTILS_H 2 #define UTILS_H 3 4 #include <assert.h> 5 #include <stdalign.h> 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <string.h> 9 10 #define KiB (1024ull) 11 #define MiB (1024 * KiB) 12 #define GiB (1024 * MiB) 13 #define TiB (1024 * GiB) 14 15 #define ARRLEN(arr) (sizeof (arr) / sizeof (arr)[0]) 16 17 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 18 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 19 #define CLAMP(min, max, v) MIN((max), MAX((min), (v))) 20 21 #define IS_POW2(v) (((v) & ((v) - 1)) == 0) 22 23 #define IS_ALIGNED(v, align) (((v) & ((align) - 1)) == 0) 24 #define ALIGN_PREV(v, align) ((v) & ~((align) - 1)) 25 #define ALIGN_NEXT(v, align) ALIGN_PREV((v) + ((align) - 1), (align)) 26 27 #define TYPEOF(v) (__typeof__ (v)) 28 29 #define TO_PARENT_PTR(ptr, T, member) \ 30 ((T *) (((uintptr_t) (ptr)) - offsetof(T, member))) 31 32 // ======================================================================= 33 34 struct arena { 35 void *ptr; 36 size_t cap, len; 37 }; 38 39 inline void 40 arena_reset(struct arena *arena) 41 { 42 arena->len = 0; 43 } 44 45 inline void * 46 arena_alloc(struct arena *arena, size_t size, size_t alignment) 47 { 48 assert(size); 49 assert(alignment); 50 assert(IS_POW2(alignment)); 51 52 uintptr_t base = (uintptr_t) arena->ptr; 53 uintptr_t end = base + arena->cap; 54 55 uintptr_t aligned_ptr = ALIGN_NEXT(base + arena->len, alignment); 56 if (end < aligned_ptr + size) 57 return NULL; 58 59 arena->len = (aligned_ptr + size) - base; 60 61 return (void *) aligned_ptr; 62 } 63 64 #define ARENA_ALLOC_ARRAY(arena, T, n) \ 65 arena_alloc((arena), sizeof(T) * (n), alignof(T)) 66 67 #define ARENA_ALLOC_SIZED(arena, T) \ 68 ARENA_ALLOC_ARRAY((arena), T, 1) 69 70 // ======================================================================= 71 72 struct list_node { 73 struct list_node *prev, *next; 74 }; 75 76 #define LIST_INIT(list) ((struct list_node) { &(list), &(list), }) 77 78 #define LIST_HEAD(list) ((list)->next) 79 #define LIST_TAIL(list) ((list)->prev) 80 81 #define LIST_EMPTY(list) \ 82 (LIST_HEAD(list) == (list) && LIST_TAIL(list) == (list)) 83 84 #define LIST_NODE_ITER(list, it) \ 85 for ((it) = LIST_HEAD(list); (it) != (list); (it) = LIST_HEAD(it)) 86 87 #define LIST_NODE_RITER(list, it) \ 88 for ((it) = LIST_TAIL(list); (it) != (list); (it) = LIST_TAIL(it)) 89 90 #define LIST_NODE_ENTRY(node, T, member) \ 91 TO_PARENT_PTR((node), T, member) 92 93 #define LIST_ENTRY_ITER(list, it, member) \ 94 for ((it) = LIST_NODE_ENTRY(LIST_HEAD(list), \ 95 TYPEOF(*(it)), member); \ 96 &(it)->member != (list); \ 97 (it) = LIST_NODE_ENTRY(LIST_HEAD(&(it)->member), \ 98 TYPEOF(*(it)), member)) 99 100 #define LIST_ENTRY_RITER(list, it, member) \ 101 for ((it) = LIST_NODE_ENTRY(LIST_TAIL(list), \ 102 TYPEOF(*(it)), member); \ 103 &(it)->member != (list); \ 104 (it) = LIST_NODE_ENTRY(LIST_TAIL(&(it)->member), \ 105 TYPEOF(*(it)), member)) 106 107 108 inline void 109 list_node_link(struct list_node *node, 110 struct list_node *prev, 111 struct list_node *next) 112 { 113 node->prev = prev; 114 prev->next = node; 115 node->next = next; 116 next->prev = node; 117 } 118 119 inline struct list_node * 120 list_node_unlink(struct list_node *node) 121 { 122 node->prev->next = node->next; 123 node->next->prev = node->prev; 124 return node; 125 } 126 127 inline void 128 list_push_head(struct list_node *restrict list, 129 struct list_node *restrict node) 130 { 131 list_node_link(node, list, LIST_HEAD(list)); 132 } 133 134 inline void 135 list_push_tail(struct list_node *restrict list, 136 struct list_node *restrict node) 137 { 138 list_node_link(node, LIST_TAIL(list), list); 139 } 140 141 inline struct list_node * 142 list_pop_head(struct list_node *list) 143 { 144 struct list_node *res = list_node_unlink(LIST_HEAD(list)); 145 return res; 146 } 147 148 inline struct list_node * 149 list_pop_tail(struct list_node *list) 150 { 151 struct list_node *res = list_node_unlink(LIST_TAIL(list)); 152 return res; 153 } 154 155 // ====================================================================== 156 157 struct stringview { 158 unsigned char *ptr; 159 size_t len; 160 }; 161 162 #define FROM_CSTR(cstr) ((struct stringview) { (cstr), strlen(cstr), }) 163 164 inline int 165 svcmp(struct stringview a, struct stringview b) 166 { 167 if (a.len != b.len) 168 return a.len - b.len; 169 170 return strncmp((char *) a.ptr, (char *) b.ptr, a.len); 171 } 172 173 inline unsigned char * 174 svstr(struct stringview haystack, struct stringview needle) 175 { 176 return NULL; 177 } 178 179 #endif /* UTILS_H */