NAME
VECTOR,
VECTOR_INIT, VECTOR_FREE,
VECTOR_COPY, VECTOR_RESERVE,
VECTOR_ALLOC, VECTOR_CALLOC,
VECTOR_POP, VECTOR_CLEAR,
VECTOR_SORT, VECTOR_SEARCH,
VECTOR_FIRST, VECTOR_LAST,
VECTOR_LENGTH, VECTOR_EMPTY,
VECTOR_STRIDE —
vector structure
SYNOPSIS
#include
<libks/vector.h>
type *
VECTOR(type);
int
VECTOR_INIT(type
*v);
void
VECTOR_FREE(type
*v);
type *
VECTOR_COPY(const
type *v);
int
VECTOR_RESERVE(type *v,
size_t len);
type *
VECTOR_ALLOC(type
*v);
type *
VECTOR_CALLOC(type
*v);
type *
VECTOR_POP(type
*v);
void
VECTOR_CLEAR(type
*v);
void
VECTOR_SORT(type
*v, int (*cmp)(const type
*, const type *));
type *
VECTOR_SEARCH(type
*v, int (*cmp)(const type
*, typeof(needle)),
needle);
type *
VECTOR_FIRST(type
*v);
type *
VECTOR_LAST(type
*v);
size_t
VECTOR_LENGTH(const
type *v);
int
VECTOR_EMPTY(const
type *v);
size_t
VECTOR_STRIDE(const
type *v);
DESCRIPTION
The vector structure stores elements of a certain type in consecutive memory, allowing for random access using the [] operator. A vector pointer is in practice a pointer to the first element stored in the vector. Thus, such pointer can be used to reference the vector and any element interchangeably.
The
VECTOR()
macro declares a new vector capable of storing elements of the given
type. As it expands to a pointer to
type, there is strictly no need to declare a vector
using this macro. Implying that vector.h is only
required to be included in implementation files.
The
VECTOR_INIT()
function initializes a vector. This function must be called before making
use of the vector.
The
VECTOR_FREE()
function frees all memory associated with the vector. If the given pointer
is NULL, nothing is done. If each individual element
requires handling before being freed, consider using
VECTOR_POP() until the vector is empty before
calling VECTOR_FREE().
The
VECTOR_COPY()
function returns a copy of the vector.
The
VECTOR_RESERVE()
allocates memory for at least len number of
elements.
The
VECTOR_ALLOC()
function allocates an uninitialized element.
The
VECTOR_CALLOC()
function allocates a zero initialized element.
The
VECTOR_POP()
function returns a pointer to the last element in the vector. As this is the
last reference to the element, the underlying memory only remains valid
until either VECTOR_FREE(),
VECTOR_RESERVE(),
VECTOR_ALLOC(),
VECTOR_CALLOC(),
VECTOR_POP(), VECTOR_CLEAR()
or VECTOR_SORT() is being called. If the vector is
empty, NULL is returned.
The
VECTOR_CLEAR()
function removes all elements.
The
VECTOR_SORT()
function sorts all elements using
qsort(3).
The
VECTOR_SEARCH()
searches for the first element in which the cmp
predicate yields a match as signalled by returning zero. If
needle is less than the given element,
cmp must return an integer less than zero. If
needle is greater than the given element,
cmp must return an integer greater than zero. Note
that the vector is required to be sorted.
The
VECTOR_FIRST()
function returns a pointer to the first element in the vector. If the vector
is empty, NULL is returned.
The
VECTOR_LAST()
function returns a pointer to the last element in the vector. If the vector
is empty, NULL is returned.
The
VECTOR_LENGTH()
function returns the length of the vector.
The
VECTOR_EMPTY()
function returns non-zero if the vector is empty. Otherwise, zero is
returned.
The
VECTOR_STRIDE()
function returns the vector element size.
RETURN VALUES
The VECTOR_INIT() and
VECTOR_RESERVE() returns zero on success. Otherwise,
non-zero is returned and errno is set accordingly.
The VECTOR_ALLOC() and
VECTOR_CALLOC() returns NULL
on error and sets errno accordingly.
EXAMPLES
The following example demonstrates how to store a primitive type
such as integers. Since the number of elements is known in advance,
VECTOR_RESERVE() is used to reduce the number of
performed allocations.
VECTOR(int) numbers;
if (VECTOR_INIT(numbers))
err(1, NULL);
if (VECTOR_RESERVE(numbers, 100))
err(1, NULL);
for (int i = 0; i < 100; i++)
*VECTOR_ALLOC(numbers) = i + 1;
for (int i = 0; i < VECTOR_LENGTH(numbers); i++)
printf("%d = %d\n", i, numbers[i]);
VECTOR_FREE(numbers);
The following example demonstrates how to store a more complex structure in which each element requires handling before the vector can be freed.
struct record {
int id;
char *name;
};
VECTOR(struct record) records;
if (VECTOR_INIT(records))
err(1, NULL);
for (int i = 0; i < 100; i++) {
struct record *rd;
rd = VECTOR_ALLOC(records);
if (rd == NULL)
err(1, NULL);
rd->id = i + 1;
rd->name = malloc(128);
if (rd->name == NULL)
err(1, NULL);
snprintf(rd->name, 128, "r%d", rd->id);
}
while (!VECTOR_EMPTY(records)) {
struct record *rd;
rd = VECTOR_POP(records);
free(rd->name);
}
VECTOR_FREE(records);
SEE ALSO
AUTHORS
Anton Lindqvist <anton@basename.se>