`vec`

library#include "/package/prog/prjlibs/include/vec.h" typedef VEC_T(int) intvec_t; void VEC_INIT(int, intvec_t*pvec); void VEC_FREE(int, intvec_t*pvec); size_t VEC_LEN(int, intvec_t*pvec); size_t VEC_BLEN(int, intvec_t*pvec);int* VEC_ELTS(int, intvec_t const*`);`

pvecint* VEC_ELT(int, intvec_t const*pvec, size_ti); type_status VEC_ALLOC(int, intvec_t*pvec, size_tnewlength, type_booladditional); type_status VEC_ALLOCFIT(int, intvec_t*pvec); type_status VEC_TRUNC(int, intvec_t*pvec, size_tnewlength); size_t VEC_DIFFI(int, intvec_t const*pvec0, intvec_t const*pvec1); type_bool VEC_EQ(int, intvec_t const*pvec0, intvec_t const*pvec1); type_status VEC_INSN(int, intvec_t*pvec, size_tposition, int const*newitems, size_tnitems); type_status VEC_INSA(int, intvec_t*pvec, size_tposition, int const*newitems, type_booltrim); type_status VEC_INS1(int, intvec_t*pvec, size_tposition, intnewitem); type_status VEC_PUSHN(int, intvec_t*pvec, int const*newitems, size_tnitems); type_status VEC_PUSHA(int, intvec_t*pvec, int const*newitems, type_booltrim); type_status VEC_PUSH1(int, intvec_t*pvec, intnewitem); type_status VEC_UNSHIFTN(int, intvec_t*pvec, int const*newitems, size_tnitems); type_status VEC_UNSHIFTA(int, intvec_t*pvec, int const*newitems, type_booltrim); type_status VEC_UNSHIFT1(int, intvec_t*pvec, intnewitem); type_status VEC_CUTN(int, intvec_t*pvec, size_tposition, int*olditems, size_tnitems); type_status VEC_CUT1(int, intvec_t*pvec, size_tposition, int*olditem);int* VEC_POPN(int, intvec_t*pvec, size_tnitems);int* VEC_POP1(int, intvec_t*pvec); type_status VEC_SHIFTN(int, intvec_t*pvec, int*olditems, size_tnitems);int* VEC_SHIFT1(int, intvec_t*pvec); type_status VEC_INSS(VEC_T(char)*cvec, size_tposition, char const*newitems, type_booltrim); type_status VEC_PUSHS(VEC_T(char)*cvec, char const*newitems, type_booltrim); type_status VEC_UNSHIFTS(VEC_T(char)*cvec, char const*newitems, type_booltrim);

The `vec`

library provides type-generic, type-safe, dynamically
allocated vectors.

`VEC_T(type)`

specifies a vector type for elements of the given type. The given type has the same restrictions as with`WARN_TYPE`

. Each invocation of the`VEC_T`

macro denotes a distinct type, even if the element type is the same. Use a typedef to declare multiple variables as the same vector type.`VEC_TD(type, name)`

is an abbreviation for "`typedef VEC_T(type) name`

".`VEC_0(type)`

is the initializer for`VEC_T(type)`

vectors.`VEC_INIT(type, pvec)`

:`pvec`

is a pointer to a`VEC_T(type)`

vector.`VEC_INIT`

initializes the pointed-to vector just like`VEC_0(type)`

, but it can also be used with dynamically allocated objects where direct initialization is not possible.`VEC_FREE(type, pvec)`

frees the vector-managed memory and reinitializes the given vector. The vector object itself is not freed.`VEC_LEN(type, pvec)`

returns the number of objects in the given vector.`VEC_BLEN(type, pvec)`

returns the number of bytes in the given vector.`VEC_ELTS(type, pvec)`

returns a pointer to the space allocated for objects in the vector, or`NULL`

if there is no allocated space. The pointer may be used until the next operation that modifies the vector.`VEC_ELT(type, pvec, i)`

returns a pointer to the`i`

th object in the vector, or`NULL`

if the vector does not contain that many objects.`i`

counts starting from 0. The pointer may be used until the next operation that modifies the vector.`VEC_ALLOC(type, pvec, newlength, additional)`

allocates enough space in the vector for`newlength`

objects, or, if`additional`

is nonzero,`newlength+currentlength`

objects. It returns 0 for success and -1 for failure, setting`errno`

.`VEC_ALLOCFIT(type, pvec)`

resizes the vector to be just big enough to hold the data it already contains, releasing any extra allocated memory. It returns 0 for success and -1 for failure, setting`errno`

. In the case of failure, the vector is unchanged.`VEC_TRUNC(type, pvec, newlength)`

reduces the length of the vector to`newlength`

. It returns 0 for success, or -1 (setting`errno`

) if the vector is already shorter than the given length.`VEC_DIFFI(type, pvec0, pvec1)`

returns the length of the longest common prefix of the two vectors. This is the index of the first pair of objects within the two vectors that differ from each other, if there are any differing objects, or else the length of the shorter vector. This is probably not useful if the type has any padding, since the bytes may differ even when the logical values are the same.`VEC_EQ(type, pvec0, pvec1)`

returns nonzero if the two vectors have the same length and contents. This is probably not useful if the type has any padding, since the bytes may differ even when the logical values are the same.`VEC_INSN(type, pvec, position, newitems, nitems)`

inserts nitems number of items found at newitems into the vector at the given position, growing the vector if necessary. It returns 0 for success or -1 for error, setting`errno`

.`VEC_INSA(type, pvec, position, newitems, trim)`

is like`VEC_INSN`

, but newitems must be an array, not a pointer. The elements of the array are inserted into the vector. If trim is nonzero, the last element of the array is omitted; only the first n-1 elements are inserted.`VEC_INS1(type, pvec, position, newitem)`

inserts a single value at the given position. newitem is an expression of the given type, not a pointer to the value. The expression may not be evaluated if allocation within the vector fails.`VEC_PUSHN`

,`VEC_PUSHA`

, and`VEC_PUSH1`

are like the corresponding`VEC_INS*`

functions, but they always add elements at the end of the vector.`VEC_UNSHIFTN`

,`VEC_UNSHIFTA`

, and`VEC_UNSHIFT1`

are like the corresponding`VEC_INS*`

functions, but they always add elements at the beginning of the vector.`VEC_CUTN(type, pvec, position, olditems, nitems)`

removes nitems number of items from the vector at the given position, copying those objects to olditems if olditems is non-NULL, and reduces the length of the vector. It returns 0 for success or -1 for error, setting`errno`

.`VEC_CUT1(type, pvec, position, olditem)`

is like`VEC_CUTN`

, but removes only one object.`VEC_POPN`

and`VEC_POP1`

are like the corresponding`VEC_CUT*`

functions, but they always remove objects from the end of the vector. They return a pointer to the elements that were removed for success, or NULL for failure. This pointer can be used until the next operation that modifies the vector.`VEC_SHIFTN`

is like`VEC_CUTN`

, but it always removes objects from the beginning of the vector.`VEC_SHIFT1`

is like`VEC_POP1`

, but it always removes an object from the beginning of the vector. Since it returns a pointer to the removed object, this may require growing the vector temporarily. Use`VEC_SHIFTN`

instead, even to remove just one object, if you do not need the pointer. This pointer can be used until the next operation that modifies the vector.`VEC_INSS`

,`VEC_PUSHS`

, and`VEC_UNSHIFTS`

are like the corresponding`VEC_*N`

functions, but they works only with char vectors, and the number of elements to insert is determined by`strlen()`

. If`trim`

is nonzero, the terminating null character is not inserted.

To link your program with the vec library, add
`/package/prog/prjlibs/library/vec.a`

to the end of the link
command line.

Performance tips:

- Allocating space for many objects all at once is faster than
reallocating each time you want to store an object in the vector. If you
can estimate how many objects will be stored in the vector
simultaneously, you can allocate all the space ahead of time with
`VEC_ALLOC`

. You should still use the`INS`

,`PUSH`

, or`UNSHIFT`

functions to add items - this will keep the vector's length accurate, and will allocate more memory if your estimate turns out to be too small. - The
`INS`

and`UNSHIFT`

functions have to copy objects within the vector if you insert objects before the end. If you can structure your code to use`PUSH`

, less copying will be needed.