diff --git a/lib/containers.h b/lib/containers.h index 8c505f350..b8bf799ab 100644 --- a/lib/containers.h +++ b/lib/containers.h @@ -361,4 +361,42 @@ }) +#define TYPED_GPTRARRAY_FULL(type_name, contained_type, free_func) \ + typedef union { \ + GPtrArray a; \ + struct { \ + contained_type **pdata; \ + unsigned int len; \ + }; \ + } type_name; \ + static_assert(sizeof(GPtrArray) == sizeof(type_name), "sizeof ptrarray type mismatch"); \ + static_assert(G_STRUCT_OFFSET(GPtrArray, pdata) == G_STRUCT_OFFSET(type_name, pdata), \ + "pdata offset mismatch"); \ + static_assert(G_STRUCT_OFFSET(GPtrArray, len) == G_STRUCT_OFFSET(type_name, len), \ + "len offset mismatch"); \ + static inline type_name *type_name##_new_sized(unsigned int len) { \ + void (*func)(contained_type *) = free_func; \ + return (type_name *) g_ptr_array_new_full(len, (GDestroyNotify) func); \ + } \ + static inline type_name *type_name##_new(void) { \ + return type_name##_new_sized(0); \ + } + +#define TYPED_GPTRARRAY(type_name, contained_type) \ + TYPED_GPTRARRAY_FULL(type_name, contained_type, NULL) + +#define t_ptr_array_set_size(A, l) ({ \ + g_ptr_array_set_size(&(A)->a, l); \ + }) + +#define t_ptr_array_free(A, fd) ({ \ + g_ptr_array_free(&(A)->a, fd); \ + }) + +#define t_ptr_array_add(A, e) ({ \ + __typeof__(*(A)->pdata) __e = e; \ + g_ptr_array_add(&(A)->a, __e); \ + }) + + #endif