A type-safe dynamic array implementation for C.
The vec.c and vec.h files can be dropped into an existing C project and compiled along with it.
Before using a vector it should first be initialised using the vec_init()
function.
vec_int_t v;
vec_init(&v);
vec_push(&v, 123);
vec_push(&v, 456);
To access the elements of the vector directly the vector's data
field can be
used.
printf("%d\n", v.data[1]); /* Prints the value at index 1 */
The current length of the vector is stored in the length
field of the vector
printf("%d\n", v.length); /* Prints the length of the vector */
When you are done with the vector the vec_deinit()
function should be called
on it. This will free any memory the vector allocated during use.
vec_deinit(&v);
vec.h provides the following predefined vector types:
Contained Type | Type name |
---|---|
void* | vec_void_t |
char* | vec_str_t |
int | vec_int_t |
char | vec_char_t |
float | vec_float_t |
double | vec_double_t |
To define a new vector type the vec_t()
macro should be used:
/* Creates the type uint_vec_t for storing unsigned ints */
typedef vec_t(unsigned int) uint_vec_t;
All vector functions are macro functions. The parameter v
in each function
should be a pointer to the vec struct which the operation is to be performed
on.
Creates a vec struct for containing values of type T
.
/* Typedefs the struct `fp_vec_t` as a container for type FILE* */
typedef vec_t(FILE*) fp_vec_t;
Initialises the vector, this must be called before the vector can be used.
Deinitialises the vector, freeing the memory the vector allocated during use; this should be called when we're finished with a vector.
Pushes a value to the end of the vector. Returns 0 if the operation was successful, otherwise -1 is returned and the vector remains unchanged.
Removes and returns the value at the end of the vector.
Removes the number of values specified by count
, starting at the index
start
.
vec_splice(&v, 2, 4); /* Removes the values at indices 2, 3, 4 and 5 */
Removes the number of values specified by count
, starting at the index
start
; the removed values are replaced with the last count
values of the
vector. This does not preserve ordering but is O(1).
Inserts the value val
at index idx
shifting the elements after the index
to make room for the new value.
/* Inserts the value 123 at the beginning of the vec */
vec_insert(&v, 0, 123);
Returns 0 if the operation was successful, otherwise -1 is returned and the vector remains unchanged.
Sorts the values of the vector; fn
should be a qsort-compatible compare
function.
Swaps the values at the indices idx1
and idx2
with one another.
Truncates the vector's length to len
. If len
is greater than the vector's
current length then no change is made.
Clears all values from the vector reducing the vector's length to 0.
Returns the first value in the vector. This should not be used on an empty vector.
Returns the last value in the vector. This should not be used on an empty vector.
Reserves capacity for at least n
elements in the given vector; if n
is
less than the current capacity then vec_reserve()
does nothing. Returns 0 if
the operation was successful, otherwise -1 is returned and the vector remains
unchanged.
Reduces the vector's capacity to the smallest size required to store its current number of values. Returns 0 if the operation is successful, otherwise -1 is returned and the vector remains unchanged.
Pushes the contents of the array arr
to the end of the vector. count
should
be the number of elements in the array.
Appends the contents of the v2
vector to the v
vector.
Finds the first occurrence of the value val
in the vector. idx
should be an
int where the value's index will be written; idx
is set to -1 if val
could
not be found in the vector.
Removes the first occurrence of the value val
from the vector. If the val
is not contained in the vector then vec_remove()
does nothing.
Reverses the order of the vector's values in place. For example, a vector
containing 4, 5, 6
would contain 6, 5, 4
after reversing.
Iterates the values of the vector from the first to the last. var
should be a
variable of the vector's contained type where the value will be stored with
each iteration. iter
should be an int used to store the index during
iteration.
/* Iterates and prints the value and index of each value in the float vec */
int i; float val;
vec_foreach(&v, val, i) {
printf("%d : %f\n", i, val);
}
Iterates the values of the vector from the last to the first. See
vec_foreach()
Iterates the value pointers of the vector from first to last. var
should be a
variable of the vector's contained type's pointer. See vec_foreach()
.
/* Iterates and prints the value and index of each value in the float vector */
int i; float *val;
vec_foreach_ptr(&v, val, i) {
printf("%d : %f\n", i, *val);
}
Iterates the value pointers of the vector from last to first. See
vec_foreach_ptr()
This library is free software; you can redistribute it and/or modify it under the terms of the MIT license. See LICENSE for details.