git / brickware / marrow.git - main

(45 minutes ago)commit 7790c99: Meh. Halfway vector implementation. Not happy with the name

tree / vector.h

vector.h

raw

#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