From daa68c4b2de9814b8331e7b9079d5fc49bee35c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Jan 2019 22:06:45 +0100 Subject: Add first parts of interface config handling --- src/vector.h | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/vector.h (limited to 'src/vector.h') diff --git a/src/vector.h b/src/vector.h new file mode 100644 index 0000000..02ea804 --- /dev/null +++ b/src/vector.h @@ -0,0 +1,113 @@ +/** + \file + + Typesafe dynamically sized arrays +*/ + + +#pragma once + +#include +#include + +/** A vector descriptor */ +typedef struct _vector_desc { + size_t allocated; /**< The number of elements currently allocated */ + size_t length; /**< The actual number of elements in the vector */ +} vector_desc_t; + +/** + A type for a vector of \e type elements + + \hideinitializer +*/ +#define VECTOR(type) struct { \ + vector_desc_t desc; \ + type *data; \ +} + +bool _vector_resize(vector_desc_t *desc, void **data, size_t n, size_t elemsize); +bool _vector_insert(vector_desc_t *desc, void **data, void *element, size_t pos, size_t elemsize); +void _vector_delete(vector_desc_t *desc, void **data, size_t pos, size_t elemsize); + +/** + Resizes the vector \e a to \e n elements + + \hideinitializer +*/ +#define VECTOR_RESIZE(v, n) ({ \ + __typeof__(v) *_v = &(v); \ + _vector_resize(&_v->desc, (void **)&_v->data, (n), sizeof(*_v->data)); \ +}) + +/** + Frees all resources used by the vector \e v + + \hideinitializer +*/ +#define VECTOR_FREE(v) free((v).data) + +/** + Returns the number of elements in the vector \e v + + \hideinitializer +*/ +#define VECTOR_LEN(v) ((v).desc.length) + +/** + Returns the element with index \e i in the vector \e v + + \hideinitializer +*/ +#define VECTOR_INDEX(v, i) ((v).data[i]) + +/** + Returns a pointer to the vector elements of \e v + + \hideinitializer +*/ +#define VECTOR_DATA(v) ((v).data) + +/** + Inserts the element \e elem at index \e pos of vector \e v + + \hideinitializer +*/ +#define VECTOR_INSERT(v, elem, pos) ({ \ + __typeof__(v) *_v = &(v); \ + __typeof__(*_v->data) _e = (elem); \ + _vector_insert(&_v->desc, (void **)&_v->data, &_e, (pos), sizeof(_e)); \ +}) + +/** + Adds the element \e elem at the end of vector \e v + + \hideinitializer +*/ +#define VECTOR_ADD(v, elem) ({ \ + __typeof__(v) *_v = &(v); \ + __typeof__(*_v->data) _e = (elem); \ + _vector_insert(&_v->desc, (void **)&_v->data, &_e, _v->desc.length, sizeof(_e)); \ +}) + +/** + Deletes the element at index \e pos of vector \e v + + \hideinitializer +*/ +#define VECTOR_DELETE(v, pos) ({ \ + __typeof__(v) *_v = &(v); \ + _vector_delete(&_v->desc, (void **)&_v->data, (pos), sizeof(*_v->data)); \ +}) + +/** + Performs a binary search on the vector \e v, returning a pointer to a matching vector element + + \hideinitializer +*/ +#define VECTOR_BSEARCH(key, v, cmp) ({ \ + __typeof__(v) *_v = &(v); \ + const __typeof__(*_v->data) *_key = (key); \ + int (*_cmp)(__typeof__(_key), __typeof__(_key)) = (cmp); \ + (__typeof__(_v->data))bsearch(_key, _v->data, _v->desc.length, sizeof(*_v->data), (int (*)(const void *, const void *))_cmp); \ +}) -- cgit v1.2.3