Mercurial > lbo > hg > ylisp
view src/base/vec.h @ 137:08d010255027
base: add some little doc bits
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 01 Sep 2019 22:57:51 +0200 |
parents | 7b041326c9f7 |
children | 800a02381024 |
line wrap: on
line source
#ifndef base_vec_h #define base_vec_h #include <assert.h> #include <stdbool.h> #include <stdlib.h> /** * @file vec.h * @addtogroup base-vec * @{ * @brief Simple growable contiguous vector/array implementation. */ /** * @brief A vector of n elements of each size bytes starting at base. * * At the cost of access performance we optimize for memory by fitting yvec_t * into 16 bytes. * * All yvec_t values must be initialized using YVEC_INIT, YVEC_NEW, yvec_init, * or yvec_new before use; even before calling functions like yvec_copy(). */ typedef struct { /// Start of vector. void *base; /// Total capacity. size_t cap : 24; /// Current length. size_t len : 24; /// Size of each element. size_t size : 16; } yvec_t; typedef const char yconstchar; /// Initialize a vector pointed to by `vecp` with `n` elements of type `TYPE`. #define YVEC_INIT(vecp, n, TYPE) yvec_init(vecp, sizeof(TYPE), n) /// Retrieve the element at `index` of type `TYPE`, casting the result to /// `TYPE*`. #define YVEC_AT(vecp, index, TYPE) ((TYPE *)yvec_at(vecp, index)) /// Append an element (elemp is pointer to the element) to a `yvec_t` (vecp is /// a pointer to the vector), asserting that the size of the element type is /// the same as the one expected by the vector. #define YVEC_PUSH(vecp, elemp) \ (assert((vecp)->size == sizeof(*(elemp))), yvec_push(vecp, (void *)(elemp))) /// Create a new vector from `src` with `len` elements of `TYPE`. #define YVEC_NEW(src, len, TYPE) yvec_new(src, sizeof(TYPE), len) /** * @brief Initialize a new vector and return it, from an array of `len` * elements of each `size` bytes. Use `YVEC_NEW()` to directly specify the type * of the array. */ yvec_t yvec_new(void *src, size_t size, size_t len); /** * @brief Initialize a vector with `n` elements of `size` bytes each. See also * `YVEC_INIT()`. The vector is guaranteed to only contain zero values. The * initial length is 0. The next `size` appends are "free" (they won't allocate * more memory). */ void yvec_init(yvec_t *vec, size_t size, size_t len); /** * @brief Remove an element and returns true if the vector had at least one * element. The element is stored into `dst`, which must point to a memory area * of at least `vec->size` bytes. */ bool yvec_pop(yvec_t *vec, void *dst); /** * @brief Append an element. See also `yvec_push()`, which asserts that the * element size matches the size expected by the vector. Returns the index of * the pushed element. * * Elements are appended at `vec[vec.len]`. Use `yvec_resize()` to change the * length. */ size_t yvec_push(yvec_t *vec, const void *element); /** * @brief Append several elements from a raw array. The size of elements must * be equal to `vec->size`. */ void yvec_push_multi(yvec_t *vec, const void *elements, size_t n); /** * @brief Prepend an element to the vector. */ void yvec_push_front(yvec_t* vec, const void *element); /** * @brief Prepend multiple elements to the vector. */ void yvec_push_front_multi(yvec_t* vec, const void *element, size_t n); /** * @brief Reverse a vec in-place. */ void yvec_reverse(yvec_t* vec); /** * @brief Append `v2` to `v1`, leaving `v2` untouched. */ void yvec_append(yvec_t *v1, yvec_t *v2); /** * @brief Resize a vector, growing it if needed. `yvec_resize` never releases * memory. It is valid to call `yvec_resize()` on a null, i.e. initialized, * vector. */ void yvec_resize(yvec_t *vec, size_t new_size); /** * @brief Retrieve element at `index`. See also `YVEC_AT()`. * * Returns `NULL` if the index is out of bounds. Check `vec->len` for the * current length. */ void *yvec_at(yvec_t *vec, size_t index); /** * @brief Copy the entire contents to a new yvec. `dst` is destroyed before * copying. */ void yvec_copy(yvec_t *src, yvec_t *dst); /** * @brief Return a copy of `src` (the full buffer is copied). */ yvec_t yvec_clone(yvec_t *src); /** * @brief Deallocate a vector. Resets all fields to 0. */ void yvec_destroy(yvec_t *vec); /** * @} */ #endif