diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/cbit/misc.h | 2 | ||||
-rw-r--r-- | lib/cbit/vec.h | 185 |
2 files changed, 94 insertions, 93 deletions
diff --git a/lib/cbit/misc.h b/lib/cbit/misc.h index 7c558ce..3be6dc4 100644 --- a/lib/cbit/misc.h +++ b/lib/cbit/misc.h @@ -37,7 +37,7 @@ if (1) \ goto __done_##ctr; \ else \ - __body_##ctr: + __body_##ctr: #define LET_(expr, ctr) LET__(expr, ctr) #define LET(expr) LET_(expr, __COUNTER__) diff --git a/lib/cbit/vec.h b/lib/cbit/vec.h index c291b41..3e8b7e3 100644 --- a/lib/cbit/vec.h +++ b/lib/cbit/vec.h @@ -4,10 +4,10 @@ #include <string.h> struct vec_internal { - size_t length; - size_t capacity; - void *els; - char storage[1]; // must be at least one byte so vec_free works correctly + size_t length; + size_t capacity; + void *els; + char storage[1]; // must be at least one byte so vec_free works correctly }; #ifdef __cplusplus @@ -24,100 +24,101 @@ void vec_realloc_internal_as_necessary(struct vec_internal *vi, #endif #define DECL_VEC(ty, name) \ - typedef ty __VEC_TY_##name; \ - struct vec_##name { \ - union { \ - struct vec_internal vi; \ - struct { \ - size_t length; \ - size_t capacity; \ - VEC_TY(name) *els; \ - VEC_TY(name) storage[1]; \ - }; \ - }; \ - }; \ - UNUSED_STATIC_INLINE \ - void vec_free_storage_##name(struct vec_##name *v) { \ - if (v->els != v->storage) \ - free(v->els); \ - } \ - UNUSED_STATIC_INLINE \ - struct vec_##name vec_borrow##name(VEC_TY(name) *els, size_t length) { \ - struct vec_##name v; \ - v.length = v.capacity = length; \ - v.els = els; \ - return v; \ - } \ - UNUSED_STATIC_INLINE \ - void vec_realloc_##name(struct vec_##name *v, size_t new_capacity) { \ - vec_realloc_internal(&v->vi, new_capacity, sizeof(v->els[0])); \ - } \ - UNUSED_STATIC_INLINE \ - void vec_resize_##name(struct vec_##name *v, size_t new_length) { \ - if (new_length >= v->capacity || new_length < v->capacity / 3) \ - vec_realloc_internal_as_necessary(&v->vi, new_length, sizeof(v->els[0])); \ - v->length = new_length; \ - } \ - UNUSED_STATIC_INLINE \ - VEC_TY(name) *vec_appendp_##name(struct vec_##name *v) { \ - size_t i = v->length++; \ - if (i == v->capacity) \ - vec_realloc_internal_as_necessary(&v->vi, i + 1, sizeof(v->els[0])); \ - return &v->els[i]; \ - } \ - UNUSED_STATIC_INLINE \ - void vec_append_##name(struct vec_##name *v, VEC_TY(name) val) { \ - *vec_appendp_##name(v) = val; \ - } \ - UNUSED_STATIC_INLINE \ - VEC_TY(name) vec_pop_##name(struct vec_##name *v) { \ - size_t i = v->length - 1; \ - VEC_TY(name) ret = v->els[i]; \ - if (v->els != v->storage && i < v->capacity / 3) \ - vec_realloc_internal_as_necessary(&v->vi, i, sizeof(v->els[0])); \ - v->length = i; \ - return ret; \ - } \ - UNUSED_STATIC_INLINE \ - void vec_concat_##name(struct vec_##name *v1, const struct vec_##name *v2) { \ - size_t l1 = v1->length, l2 = v2->length; \ - vec_resize_##name(v1, safe_add(l1, l2)); \ - memcpy(&v1->els[l1], v2->els, l2 * sizeof(v1->els[0])); \ - } \ - UNUSED_STATIC_INLINE \ - void vec_add_space_##name(struct vec_##name *v, size_t idx, size_t num) { \ - /* todo optimize */ \ - size_t orig = v->length; \ - vec_resize_##name(v, orig + num); \ - memmove(&v->els[idx + num], &v->els[idx], \ - (orig - idx) * sizeof(v->els[0])); \ - } \ - UNUSED_STATIC_INLINE \ - void vec_remove_##name(struct vec_##name *v, size_t idx, size_t num) { \ - /* todo optimize */ \ - size_t orig = v->length; \ - memmove(&v->els[idx], &v->els[idx + num], \ - (orig - (idx + num)) * sizeof(v->els[0])); \ - vec_resize_##name(v, orig - num); \ - } \ + typedef ty __VEC_TY_##name; \ + struct vec_##name { \ + union { \ + struct vec_internal vi; \ + struct { \ + size_t length; \ + size_t capacity; \ + VEC_TY(name) *els; \ + VEC_TY(name) storage[1]; \ + }; \ + }; \ + }; \ + UNUSED_STATIC_INLINE \ + void vec_free_storage_##name(struct vec_##name *v) { \ + if (v->els != v->storage) \ + free(v->els); \ + } \ + UNUSED_STATIC_INLINE \ + struct vec_##name vec_borrow##name(VEC_TY(name) *els, size_t length) { \ + struct vec_##name v; \ + v.length = v.capacity = length; \ + v.els = els; \ + return v; \ + } \ + UNUSED_STATIC_INLINE \ + void vec_realloc_##name(struct vec_##name *v, size_t new_capacity) { \ + vec_realloc_internal(&v->vi, new_capacity, sizeof(v->els[0])); \ + } \ + UNUSED_STATIC_INLINE \ + void vec_resize_##name(struct vec_##name *v, size_t new_length) { \ + if (new_length >= v->capacity || new_length < v->capacity / 3) \ + vec_realloc_internal_as_necessary(&v->vi, new_length, \ + sizeof(v->els[0])); \ + v->length = new_length; \ + } \ + UNUSED_STATIC_INLINE \ + VEC_TY(name) *vec_appendp_##name(struct vec_##name *v) { \ + size_t i = v->length++; \ + if (i == v->capacity) \ + vec_realloc_internal_as_necessary(&v->vi, i + 1, sizeof(v->els[0])); \ + return &v->els[i]; \ + } \ + UNUSED_STATIC_INLINE \ + void vec_append_##name(struct vec_##name *v, VEC_TY(name) val) { \ + *vec_appendp_##name(v) = val; \ + } \ + UNUSED_STATIC_INLINE \ + VEC_TY(name) vec_pop_##name(struct vec_##name *v) { \ + size_t i = v->length - 1; \ + VEC_TY(name) ret = v->els[i]; \ + if (v->els != v->storage && i < v->capacity / 3) \ + vec_realloc_internal_as_necessary(&v->vi, i, sizeof(v->els[0])); \ + v->length = i; \ + return ret; \ + } \ + UNUSED_STATIC_INLINE \ + void vec_concat_##name(struct vec_##name *v1, const struct vec_##name *v2) { \ + size_t l1 = v1->length, l2 = v2->length; \ + vec_resize_##name(v1, safe_add(l1, l2)); \ + memcpy(&v1->els[l1], v2->els, l2 * sizeof(v1->els[0])); \ + } \ + UNUSED_STATIC_INLINE \ + void vec_add_space_##name(struct vec_##name *v, size_t idx, size_t num) { \ + /* todo optimize */ \ + size_t orig = v->length; \ + vec_resize_##name(v, orig + num); \ + memmove(&v->els[idx + num], &v->els[idx], \ + (orig - idx) * sizeof(v->els[0])); \ + } \ + UNUSED_STATIC_INLINE \ + void vec_remove_##name(struct vec_##name *v, size_t idx, size_t num) { \ + /* todo optimize */ \ + size_t orig = v->length; \ + memmove(&v->els[idx], &v->els[idx + num], \ + (orig - (idx + num)) * sizeof(v->els[0])); \ + vec_resize_##name(v, orig - num); \ + } \ #define VEC_TY(name) __VEC_TY_##name #define VEC_STORAGE_CAPA(name, n) \ - struct { \ - struct vec_##name v; \ - VEC_TY(name) rest[(n)-1]; \ - } + struct { \ + struct vec_##name v; \ + VEC_TY(name) rest[(n)-1]; \ + } #define VEC_STORAGE(ty) \ - VEC_STORAGE_CAPA(ty, 5) + VEC_STORAGE_CAPA(ty, 5) #define VEC_STORAGE_INIT(vs, name) do { \ - struct vec_##name *v = &(vs)->v; \ - v->length = 0; \ - v->capacity = (sizeof((vs)->rest) / sizeof(VEC_TY(name))) + 1; \ - v->els = v->storage; \ + struct vec_##name *v = &(vs)->v; \ + v->length = 0; \ + v->capacity = (sizeof((vs)->rest) / sizeof(VEC_TY(name))) + 1; \ + v->els = v->storage; \ } while (0) #define VEC_STORAGE_INIT_STATIC(vs, name) \ @@ -129,7 +130,7 @@ void vec_realloc_internal_as_necessary(struct vec_internal *vi, /* guaranteed to *not* cache vec->length - pretty simple */ #define VEC_FOREACH(vec, idx_var, ptr_var, name) \ - LET(struct vec_##name *__vfe_v = (vec)) \ - for (size_t idx_var = 0; idx_var < __vfe_v->length; idx_var++) \ - LET_LOOP(ptr_var = &__vfe_v->els[idx_var]) + LET(struct vec_##name *__vfe_v = (vec)) \ + for (size_t idx_var = 0; idx_var < __vfe_v->length; idx_var++) \ + LET_LOOP(ptr_var = &__vfe_v->els[idx_var]) |