X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=common%2Farray.h;h=4a5b88dc89728dcb75420f4cb7d0d4bda7ebac90;hb=e327d3786ba0371eaaff8e6ba0fe3fc39f095ae2;hp=b4dea94af489083e4e9f24e7e77159113fbe9e65;hpb=9c710cd68a1826f033133240a944399adb28c4c0;p=apps%2Fpfixtools.git diff --git a/common/array.h b/common/array.h index b4dea94..4a5b88d 100644 --- a/common/array.h +++ b/common/array.h @@ -43,8 +43,9 @@ #define PRIV_ARRAY(Type) \ struct { \ Type *data; \ - ssize_t len; \ - ssize_t size; \ + uint32_t len; \ + uint32_t size; \ + unsigned locked : 1; \ } #define PARRAY(Type) \ @@ -57,6 +58,9 @@ static inline void Type ## _ptr_array_delete(Type ## _ptr_array_t **array) \ { \ if (*array) { \ + if ((*array)->locked) { \ + array_unlock(**array); \ + } \ array_wipe(**array); \ p_delete(array); \ } \ @@ -73,6 +77,9 @@ static inline void Type ## _array_delete(Type ## _array_t **array) \ { \ if (*array) { \ + if ((*array)->locked) { \ + array_unlock(**array); \ + } \ array_wipe(**array); \ p_delete(array); \ } \ @@ -83,11 +90,18 @@ #define A(Type) Type ## _array_t #define PA(Type) Type ## _ptr_array_t -#define ARRAY_INIT { NULL, 0, 0 } +#define ARRAY_INIT { NULL, 0, 0, false } #define array_init(array) (array) = ARRAY_INIT + +#define array_can_edit(array) (!(array).locked) + +#define array_ensure_can_edit(array) \ + assert(array_can_edit(array) && "Trying to edit array while it is locked") + #define array_wipe(array) \ do { \ + array_ensure_can_edit(array); \ p_delete(&(array).data); \ (array).len = 0; \ (array).size = 0; \ @@ -97,9 +111,9 @@ array_ensure_capacity_delta(array, 1); \ (array).data[(array).len++] = (obj); \ } while (0) -#define array_append(array, objs, len) \ +#define array_append(array, objs, Len) \ do { \ - const ssize_t __len = (len); \ + const typeof((array).len) __len = (Len); \ array_ensure_capacity_delta(array, __len); \ memcpy((array).data + (array).len, objs, \ __len * sizeof(*(array).data)); \ @@ -107,9 +121,10 @@ } while (0) #define array_ensure_capacity(array, goal) \ do { \ + array_ensure_can_edit(array); \ if ((array).size < (goal)) { \ - const ssize_t required_size = (goal); \ - ssize_t next_size = (array).size; \ + const typeof((array).size) required_size = (goal); \ + typeof((array).size) next_size = (array).size; \ do { \ next_size = p_alloc_nr(next_size); \ } while (next_size < required_size); \ @@ -119,22 +134,31 @@ #define array_ensure_capacity_delta(array, delta) \ array_ensure_capacity(array, (array).len + (delta)) #define array_ensure_exact_capacity(array, goal) \ - if (array_size(array) < (goal)) { \ + if ((array).size < (goal)) { \ + array_ensure_can_edit(array); \ p_allocgrow(&(array).data, (goal), &(array).size); \ } -#define array_adjust(array) \ +#define array_shrink(array, cap) \ do { \ - p_shrink(&(array).data, (array).len, &(array).size); \ + array_ensure_can_edit(array); \ + if ((cap) < (array).size && (array).size != (array).len) { \ + p_shrink(&(array).data, MAX((array).len, (cap)), &(array).size); \ + } \ } while (0) -#define array_elt(array, n) (array).data[(n)] -#define array_ptr(array, n) (array).data + (n) +#define array_adjust(array) array_shrink(array, 0) + +#define array_elt(array, n) ((array).data[(n)]) +#define array_last(array) array_elt(array, (array).len - 1) +#define array_pop_last(array) array_elt(array, --((array).len)) + +#define array_ptr(array, n) ((array).data + (n)) #define foreach(var, array) \ - for (int __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ + for (uint32_t __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ var = array_ptr(array, __Ai); #define array_foreach(array, action) \ - for (int __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ + for (uint32_t __Ai = 0 ; __Ai < (array).len ; ++__Ai) { \ action(array_ptr(array, __Ai)); \ } #define array_deep_wipe(array, wipe) \ @@ -143,14 +167,25 @@ array_wipe(array); \ } while (0) +#define array_len(array) (array).len +#define array_size(array) (array).size +#define array_elt_len(array) sizeof(*(array).data) +#define array_byte_len(array) ((array).len * array_elt_len(array)) + #define array_lock(array) \ - !(mlock((array).data, (array).len * sizeof(*(array).data)) != 0) + ((array).locked \ + || (mlock((array).data, array_byte_len(array)) == 0 \ + && ((array).locked = true))) #define array_unlock(array) \ - (void)munlock((array).data, (array).len * sizeof(*(array).data)) + if ((array).locked) { \ + (void)munlock((array).data, array_byte_len(array)); \ + (array).locked = false; \ + } ARRAY(char) ARRAY(int) ARRAY(bool) +ARRAY(uint16_t) ARRAY(uint32_t) PARRAY(void)