This commits introduces a number of new helper macros to deal with vectors
and refactors the existing code for better resource utilization.
The allocation strategy is changed from multiple of 8 to exponential growth
by factor 1.5 in order to minimize the number of reallocations and
potentially needed memory copies.
The newly introduced macros are:
- uc_vector_capacity(init_capacity, add_items)
Derive the resulting vector capacity from the given item count
and initial capacity.
- uc_vector_extend(vector, add_items)
Increase vector capacity by given amount of items, zero-initialize
added capacity and return pointer to first new item past the current
length.
- uc_vector_reduce(vector, remove_items)
Reduce vector capacity by given amount of items.
- uc_vector_pop(vector)
Return pointer to last element and decrement count, or NULL if the
vector is empty.
- uc_vector_foreach(vector, itervar)
A for() loop wrapper to iterate vectors, providing an iter variable
to the loop body.
- uc_vector_foreach_reverse(vector, itervar)
A for() loop wrapper to iterate vectors backwards, providing an iter
variable to the loop body.
The uc_vector_push() macro has been changed into a variadic macro which
internally prefixes the argument list with a cast to the vector element
type, allowing user to pass compound expressions like struct initializers
in order to simplify adding elements:
uc_vector_push(&my_collection, {
.foo = 1,
.bar = "qrx"
});
Like uc_vector_pop(), the uc_vector_last() macro has been made safe to
use on empty vectors, it'll now return NULL in this case.
Finally the vector realloc logic was moved into static functions within
the header file, allowing all vector using code of a compilation unit to
share the reallocation, shrinking the size of libucode.so by 1-2KB as a
side effect.
Signed-off-by: Jo-Philipp Wich <[email protected]>