#ifndef __VECTOR_H #define __VECTOR_H #define FASTCMP(a, b) ( ((a) > (b)) - ((a) < (b)) ) #define VEC_OKAY ( 0) #define VEC_ERR_ALLOC (-1) /* allocation failure */ #define VEC_ERR_NOSPACE (-2) /* capacity failure */ #define VECITEM(p, i, s) (((uint8_t *)(p)) + ((i) * (s))) #define VECITEM_CAST(p, i, t) ((t *)VECITEM((p), (i), (sizeof(t)))) /* access patterns for searching a list */ enum seek_mode { SEEK_SEQUENTIAL , SEEK_BINARY }; typedef int32_t (*comparator)(const void *a, const void *b); /* qsort_r is a non-standard function call, meaning different platforms * have different signatures. */ #ifdef __FreeBSD__ typedef int32_t (*comparator_r)(void *data, const void *a, const void *b); #define DEFINE_COMPARATOR_R(name) int32_t name(void *data, const void *a, const void *b) #else typedef int32_t (*comparator_r)(const void *a, const void *b, void *data); #define DEFINE_COMPARATOR_R(name) int32_t name(const void *a, const void *b, void *data) #endif /* simple list structure containing all details necessary for managing a * generic list */ struct vector { void *ptr; size_t capacity; size_t length; size_t size; }; /* * safe list allocation * * allocations (or reallocates) memory large enough to contain `num` elements * of size `size`. if `ptr` is NUL, allocation is attempted, otherwise `ptr` * is reallocated to the requested size. * * parameters: * - (alloc) allocator to use for memory allocation * - (ptr) original pointer * - (num) number of elements to allocate * - (size) size of each element * * returns: * a pointer to the newly allocated memory on success or a NUL pointer * on failure. */ void * lalloc(const struct allocator alloc, void *ptr, const size_t num, const size_t size); /* ensure list length * * ensure the given list has the capacity to store `cap` more elements. if * not, attempt to resize it. * * parameters: * - (alloc) allocator to use for memory allocation * - (dest) pointer to list * - (length) total element capacity in list `dest` * - (num) number of elements currently in list `dest` * - (cap) number of elements to be added to list `dest` * - (size) size of an element in list `dest` * * returns: * VEC_OKAY on capacity available. * VEC_OKAY if list was resized and capacity is available. * VEC_ERR_ALLOC if resize failed. */ int32_t lensure(const struct allocator alloc, void **dest, size_t *const length, const size_t num, const size_t cap, const size_t size); /* list duplicate * * create a copy of an anonymous list * * parameters: * - (alloc) allocator to use for memory allocation * - (dest) pointer to allocate for duplicated list * - (length) total element capacity in list `dest` * - (src) list to duplicate * - (num) number of elements currently in list `src` * - (size) size of an element in list `src` * * returns: * VEC_OKAY on successful duplication. * VEC_ERR_ALLOC if allocation failed. */ int32_t ldup(const struct allocator alloc, void **dest, size_t *const length, const void *src, const size_t num, const size_t size); /* list insert many * * insert a list of elements into a list at the specific index. * if space isn't available, the operation will fail. * * parameters: * - (dest) pointer to list * - (length) total element capacity in list `dest` * - (num) number of elements current in the list `dest` * - (size) size of an element in list `dest` * - (index) position to insert `items` at * - (items) elements to insert into `dest` * - (count) number of elements in `items` to insert * * returns: * VEC_OKAY on success. * VEC_ERR_NOSPACE on not enough available space. */ int32_t linserts(void *dest, const size_t length, const size_t num, const size_t size, const size_t index, const void *items, const size_t count); /* list insert singular * * insert an element into a list at the specific index. * if space isn't available, the operation will fail. * * parameters: * - (dest) pointer to list * - (length) total element capacity in list `dest` * - (num) number of elements currently in the list `dest` * - (size) size of an element in list `dest` * - (index) position to insert `item` at * - (item) element to insert into `dest` * * returns: * VEC_OKAY on success. * VEC_ERR_NOSPACE on not enough available space. */ int32_t linsert(void *dest, const size_t length, const size_t num, const size_t size, const size_t index, const void *item); /* list push * * append an item to the end of an anonymous pointer. * if space isn't available, the operation will fail. * * parameters: * - (dest) pointer to list * - (length) total element capacity in list `dest` * - (num) number of elements currently in list `dest` * - (size) size of an element in list `dest` * - (item) element to append to list `dest` * * returns: * VEC_OKAY on success. * VEC_ERR_NOSPACE on no available space. */ int32_t lpush(void *dest, const size_t length, const size_t num, const size_t size, const void *item); /* TODO * lsort * lsort_r * lindexof_mode * lindexof_mode_r * lindexof_r * lindexof * ldedup * ldedup_r * * vec_push * vec_indexof_mode_r * vec_indexof_mode * vec_indexof_r */ #endif