This class implements dynamically resizable arrays.
Throughout the documentation, the following prefixes will be used:
Global_
The library prefix: for applications, this is typically
empty, for an xyz-Library, this is either XYZ_, xyz_ or
Xyz, depending on the identifier in occurs in.
Template
Instantiation
Global_VECTOR_OK
XYZ_VECTOR_OK
Global_vector_new
xyz_vector_new
Vector_
This is equivalent to Global_vector_oType, or the name
that was set with -name=... for this data structure.
The case and underbar convention is adjusted, too.
Assuming a library prefix xyz and oType == char, you get:
It was tried to keep the argument order consistent, with some rules:
for functions returning multiple values into pointer arguments, these
are always before input arguments. (e.g. Vector_locate (output, self, ...)).
(Mnemonic: like memcpy, strcpy, assignment statement etc.)
if Vector_errno is not interesting, either because it is not
set or because only memory overflow or assertion failures may be
a possible sources of an error, the C functions return void:
The C++ functions still return the object reference.
Status Codes
These are undef'ed first because there is only one error code for all
the arrays in your program.
All the functions returing error codes will both return this error
and write it into Global_vector_errno.
Condition
Description
Macro to use
= Global_VECTOR_OK
Ok.
Global_VECTOR_IS_OK(X)
< Global_VECTOR_OK
Error: operation did
not succeed.
Global_VECTOR_IS_ERROR(X)
> Global_VECTOR_OK
Warning: operation
succeeded but not
perfectly. (e.g. rehash
failed)
Global_VECTOR_IS_WARNING(X)
In all cases, the consistency of the data structure is guaranteed.
Warnings are only visible in Global_vector_errno; the functions still return
VECTOR_OK.
This might be strange: it makes a new vector from the contents of the other
vector and then detaches the data from the other vector. Its purpose is
mainly useful in C++ where you can clone vectors from a static vector
by this means. E.g.:
Clears the vector by initialising a new completely empty
table not consuming any memory. The effect is mainly that
you can use the value of Vector_as_array and Vector_as_open_array
independently from the vector. The old function
delete_flat is now a sequence of detach() and delete().
Note
This function should be used when the vector is not
needed anymore after a cast to a raw array (e.g. by
Vector_as_array).
Compare this function with Vector_detach_as_is(). These functions
are important to distinguish if you defined Global_oType_UPDATE_POS.
Returns the found element or the zero element on failure.
If index is out of range, a message is also output to
stderr if you defined Global_ERWIN_VERBOSE.
Returns a pointer to the element at index or an signals an error if
the index is out of range. (This is the same behaviour towards errors
as Vector_nth has)
Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
Returns a pointer to the element at index if it is in range.
If is is one too large, returns a pointer to the element after the end,
mimicking string behaviour. That element is guaranteed to be allocated,
of couse. If you write to that element, it only is guarateed to have
any effect up to the next change to the vector size. Don't change that
element, though.
Because this function is so similar to adding an integer to a 'char const *',
i.e., to get a suffix string, this function always zero-terminates the
vector like Vector_as_array() does. So Vector_nth_ptr_char(self,0) is
equivalent to Vector_as_array().
Note
This behaves a bit strange together with ALLOW_OUTOFRANGE:
Accesses to any element starting from a[nentries()] make the vector
larger for the non-const version! This includes the nentries()th
element, which, even if only read with this function, enlarges the
vector due to the potential threat of the user writing to it.
In case ALLOW_OUTOFRANGE is off, this never makes the vector larger,
but does allow access to nentries()th element. That element is always
ensured to be ZERO, however, so you cannot write to it.
This signals an error if the index is out of range.
(This is the some behaviour towards errors as Vector_nth_char has.)
Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
Returns a pointer to the element at index or an signals an error if
the index is out of range. (This is the same behaviour towards errors
as Vector_nth has)
Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
Returns a pointer to the element at index if it is in range.
If is is one too large, returns a pointer to the element after the end,
mimicking string behaviour. That element is guaranteed to be allocated,
of couse. If you write to that element, it only is guarateed to have
any effect up to the next change to the vector size. Don't change that
element, though.
Because this function is so similar to adding an integer to a 'char const *',
i.e., to get a suffix string, this function always zero-terminates the
vector like Vector_as_array() does. So Vector_nth_ptr_char(self,0) is
equivalent to Vector_as_array().
Note
This behaves a bit strange together with ALLOW_OUTOFRANGE:
Accesses to any element starting from a[nentries()] make the vector
larger for the non-const version! This includes the nentries()th
element, which, even if only read with this function, enlarges the
vector due to the potential threat of the user writing to it.
In case ALLOW_OUTOFRANGE is off, this never makes the vector larger,
but does allow access to nentries()th element. That element is always
ensured to be ZERO, however, so you cannot write to it.
This signals an error if the index is out of range.
(This is the some behaviour towards errors as Vector_nth_char has.)
Does not output anything to stderr even if you define Global_ERWIN_VERBOSE.
int Vector_swap_erase (Vector_t * self, int index, int number_of_elements)
This is similar to Vector_erase, but instead of shifting all elements after
the ones erased, this functions copies elements from the end of the vector
into the gap. This is faster if number_of_elements is small.
The order of the copied elements is reversed.
int Vector_erase (Vector_t * self, int index, int number_of_elements)
The values erased from the the vector are freed. If number_of_elements
is negative, the end of the vector is cut off. If index or
number_of_elements are out of range, they are adjusted appropriately.
E.g.:
if index == -2 and count == 5
then elements 0,1,2 are erased,
if index >= nentries
nothing is erased,
if index + count >= nentries
only the tail of the vector is erased.
However, all this is only done if Vector_ALLOW_OUTOFRANGE is true.
Otherwise, you'll get an assertion failure in all these cases,
because index or count are out of range.
if count < 0
then count is adjusted to nelements - index, e.g.
index == 2, count = -1 will cut off the last two elements of
the vector.
(The absolute value of count is not considered here, only the fact
that it is < 0). This adjustment always happens, i.e., even if
Vector_ALLOW_OUTOFRANGE is false.
Erases the second of two adjacent elements that is equal (wrt. the
given function) to the first. This is repeated recursively so that
groups of adjacent equal elements are reduced to one element.
Before erasing, the function calls back combine to let the user
adjust things (e.g. copy something from the moribund entry to
the surviving one).
The default cmp function, used if cmp is NULL, is Global_oType_CMP.
In a sorted vector, this procedure erases all equal elements.
The values erased from the vector are freed using oType_OFREE.
int Vector_swap_erase (Vector_t * self, int index, int number_of_elements)
This is similar to Vector_erase, but instead of shifting all elements after
the ones erased, this functions copies elements from the end of the vector
into the gap. This is faster if number_of_elements is small.
The order of the copied elements is reversed.
This functions generates an assertion failure if the number of
elements to chop is greater than the number of elements in the
vector. However, if Vector_ALLOW_OUTOFRANGE is true, then
this operation simply clears the vector without assertion failure
in this case.
Due to the fact that the equivalent using Vector_swap_erase is
very trivial: Vector_swap_erase (self, 0, 1), there is no
Vector_swap_chop() in C (but in C++, we still have it).
Tries to finds an entry equal to needle. Returns the index of the first element >= start
or -1 of nothing was found. The search is performed from the beginning to the end.
If start is negativ, search is started at the last but start-th position. So to search
the whole vector, start should be 0.
Note
This function is not called `Vector_search', because it does not only
perform the search, but also returns the result of that search.
Tries to finds an entry equal to needle. Returns the index of the first element >= start
or -1 of nothing was found. The search is performed from the beginning to the end.
If start is negativ, search is started at the last but start-th position. So to search
the whole vector, start should be 0.
Note
This function is not called `Vector_search', because it does not only
perform the search, but also returns the result of that search.
Tries to finds an entry equal to needle. Returns the index of the first element <= start
or -1 of nothing was found. The search is performed from the end to the beginning.
If start is negativ, search is started at the last but start-th position. So to search
the whole vector, start should be -1.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Tries to finds an entry equal to needle. Returns the index of the first element <= start
or -1 of nothing was found. The search is performed from the end to the beginning.
If start is negativ, search is started at the last but start-th position. So to search
the whole vector, start should be -1.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.
Return the position of `needle' or -1 if it is not found.
Note that it is no problem to search for the zero element Global_oType_ZERO.
These all use the Vector_EQUAL macro.
Negative values for start will count from the end of the vector.