vector

Simple type-agnostic dynamic array

Structs

Vector

Vector struct

typedef struct Vector {
size_t capacity;
size_t length;
void **elements;
void (*destroy)(void *data);
} Vector;

Members:

  • capacity: The size of elements in memory
  • length: The number of real elements stored in the backing elements array
  • elements: The dynamic array of void * that holds the vector's members
  • destroy: Optional deallocation function for data inside a node. Typical usage is NULL for stack allocated data and free() for data created with malloc()

Functions

vec_init

Initialize the vector with a default capacity of 2. User is responsible for freeing elements of the vector with vec_destroy(). Returns a non-zero integer if there is an error

int vec_init(Vector *vec, void (*destroy)(void *data));

vec_init_with_capacity

Initialize the vector with a user-specified capacity. User is responsible for freeing elements of the vector with vec_destroy(). Returns a non-zero integer if there is an error

int vec_init_with_capacity(Vector *vec, void (*destroy)(void *data), size_t cap);

vec_destroy

Frees the underlying array inside a Vector. If destroy was provided when creating the vector, then it is called against each element in the array before the array is freed. Does not destroy the vector itself, that is left up to the user

void vec_destroy(Vector *vec);

/* Usage */
vec_destroy(vec);
free(vec);

vec_insert

Insert data into the vector at a specified index. Any elements at that array and beyond will be moved up to make room. Returns a non-zero integer if there is an error

int vec_insert(Vector *vec, void *data, size_t index);

/* Usage */

// vec: 1 2 3 4
int i = 99;
vec_insert(vec, &i, 2);
// vec: 1 2 99 3 4

vec_push

Insert data at the end of the vector. Returns a non-zero integer if there is an error

int vec_push(Vector *vec, void *data);

/* Usage */

// vec: 1 2 3
int *i = malloc(sizeof(int));
*i = 4;
vec_push(vec, i);
// vec: 1 2 3 4

vec_safe_at

Gets the stored data at a specified index. Uses safety checks to make sure index is not out of bounds. Returns NULL if there is an error

void *vec_safe_at(Vector *vec, size_t index);

vec_remove

Removes an element from the array and returns the pointer, then moves elements to shrink the array accordingly. Returns NULL if the index is not valid

void *vec_remove(Vector *vec, size_t index);

/* Usage */
// vec: 1 2 3 4
int *t = NULL;
t = (int*)vec_remove(vec, 2);
assert(*t == 3);
// vec: 1 2 4

vec_shrink

Shrinks the capacity of the vector down to the current length. Returns a non-zero integer if there is an error

int vec_shrink(Vector *vec);

vec_max

Finds the largest value in the vector and returns a void pointer to the underlying data. Requires a comparison function to compare the data in the vector. This function must return 1 if a > b, -1 if a < b, or 0 if a == b. See the supplied comparison functions below for reference

const void *vec_min(const Vector *vec, int(*cmp)(const void *a, const void *b));

vec_min

Finds the smallest value in the vector and returns a void pointer to the underlying data. Requires a comparison function to compare the data in the vector. This function must return 1 if a > b, -1 if a < b, or 0 if a == b. See the supplied comparison functions below for reference

const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b));

Comparison Functions

Comparison functions to compare data in a vector. These functions must return 1 if a > b, -1 if a < b, or 0 if a == b.

int vec_cmp_int(const void *a, const void *b);
int vec_cmp_char(const void *a, const void *b);

Macros

vec_at

Grabs the element at index i without safety checks for better performance. Use with caution

#define vec_at(v, i) (v)->elements[(i)]

vec_len

Returns the length of the vector

#define vec_len(v) (v)->length

vec_cap

Returns the capacity of the vector

#define vec_cap(v) (v)->capacity