VLC 4.0.0-dev
|
Files | |
file | vlc_vector.h |
This provides convenience helpers for vectors. | |
Macros | |
#define | VLC_VECTOR(type) |
Vector struct body. More... | |
#define | VLC_VECTOR_INITIALIZER { 0, 0, NULL } |
Static initializer for a vector. More... | |
#define | vlc_vector_init(pv) |
Initialize an empty vector. More... | |
#define | vlc_vector_destroy(pv) free((pv)->data) |
Destroy a vector. More... | |
#define | vlc_vector_clear(pv) |
Clear a vector. More... | |
#define | VLC_VECTOR_MINCAP_ ((size_t) 10) |
The minimal allocation size, in number of items. More... | |
#define | VLC_VECTOR_FAILFLAG_ (~(((size_t) -1) >> 1)) /* only the MSB */ |
#define | vlc_vector_realloc_(pv, newcap) |
Realloc the underlying array to newcap . More... | |
#define | vlc_vector_resize_(pv, newcap) |
Resize the vector to newcap exactly. More... | |
#define | vlc_vector_max_cap_(pv) (SIZE_MAX / 2 / sizeof(*(pv)->data)) |
#define | vlc_vector_reserve(pv, mincap) |
Increase the capacity of the vector to at least mincap . More... | |
#define | vlc_vector_reserve_internal_(pv, mincap) |
#define | vlc_vector_shrink_to_fit(pv) |
Resize the vector so that its capacity equals its actual size. More... | |
#define | vlc_vector_autoshrink(pv) |
Resize the vector down automatically. More... | |
#define | vlc_vector_check_same_ptr_type_(a, b) (void) ((a) == (b)) /* warn on type mismatch */ |
#define | vlc_vector_push(pv, item) |
Push an item at the end of the vector. More... | |
#define | vlc_vector_push_all(pv, items, count) vlc_vector_push_all_internal_(pv, items, vlc_vector_enforce_size_t_(count)) |
Append count items at the end of the vector. More... | |
#define | vlc_vector_push_all_internal_(pv, items, count) |
#define | vlc_vector_insert_hole(pv, index, count) |
Insert an hole of size count to the given index. More... | |
#define | vlc_vector_insert_hole_internal_(pv, index, count) |
#define | vlc_vector_insert(pv, index, item) |
Insert an item at the given index. More... | |
#define | vlc_vector_insert_all(pv, index, items, count) |
Insert count items at the given index. More... | |
#define | vlc_vector_move_slice(pv, index, count, target) |
Move a slice of items to a given target index. More... | |
#define | vlc_vector_move_slice_internal_(pv, index, count, target) |
#define | vlc_vector_move(pv, index, target) vlc_vector_move_slice(pv, index, 1, target) |
Move an item to a given target index. More... | |
#define | vlc_vector_remove_slice_noshrink(pv, index, count) |
Remove a slice of items, without shrinking the array. More... | |
#define | vlc_vector_remove_slice_noshrink_internal_(pv, index, count) |
#define | vlc_vector_remove_slice(pv, index, count) |
Remove a slice of items. More... | |
#define | vlc_vector_remove_noshrink(pv, index) vlc_vector_remove_slice_noshrink(pv, index, 1) |
Remove an item, without shrinking the array. More... | |
#define | vlc_vector_remove(pv, index) |
Remove an item. More... | |
#define | vlc_vector_swap_remove(pv, index) |
Remove an item. More... | |
#define | vlc_vector_index_of(pv, item, pidx) |
Return the index of an item. More... | |
#define | vlc_vector_foreach(item, pv) |
For-each loop. More... | |
Functions | |
static size_t | vlc_vector_min_ (size_t a, size_t b) |
static size_t | vlc_vector_max_ (size_t a, size_t b) |
static size_t | vlc_vector_between_ (size_t x, size_t min, size_t max) |
static size_t | vlc_vector_enforce_size_t_ (size_t value) |
static void * | vlc_vector_reallocdata_ (void *ptr, size_t count, size_t size, size_t *restrict pcap, size_t *restrict psize) |
Realloc data and update vector fields. More... | |
static bool | vlc_vector_test_and_reset_failflag_ (size_t *pcap) |
Test and reset the fail flag. More... | |
static size_t | vlc_vector_growsize_ (size_t value) |
static void | vlc_vector_reverse_array_ (char *array, size_t len) |
Reverse a char array in place. More... | |
static void | vlc_vector_rotate_array_left_ (char *array, size_t len, size_t distance) |
Right-rotate a (char) array in place. More... | |
static void | vlc_vector_rotate_array_right_ (char *array, size_t len, size_t distance) |
Right-rotate a (char) array in place. More... | |
static void | vlc_vector_move_ (char *array, size_t index, size_t count, size_t target) |
Move items in a (char) array in place. More... | |
#define VLC_VECTOR | ( | type | ) |
Vector struct body.
A vector is a dynamic array, managed by the vlc_vector_* helpers.
It is generic over the type of its items, so it is implemented as macros.
To use a vector, a new type must be defined:
The struct may be anonymous:
It is convenient to define a typedef to an anonymous structure:
Vector size is accessible via vec.size
, and items are intended to be accessed directly, via vec.data[i]
.
Functions and macros having name ending with '_' are private.
#define vlc_vector_autoshrink | ( | pv | ) |
Resize the vector down automatically.
Shrink only when necessary (in practice when cap > (size+5)*1.5)
pv | a pointer to the vector |
#define vlc_vector_check_same_ptr_type_ | ( | a, | |
b | |||
) | (void) ((a) == (b)) /* warn on type mismatch */ |
#define vlc_vector_clear | ( | pv | ) |
Clear a vector.
Remove all items from the vector.
#define vlc_vector_destroy | ( | pv | ) | free((pv)->data) |
Destroy a vector.
The vector may not be used anymore unless vlc_vector_init() is called.
#define VLC_VECTOR_FAILFLAG_ (~(((size_t) -1) >> 1)) /* only the MSB */ |
#define vlc_vector_foreach | ( | item, | |
pv | |||
) |
For-each loop.
Use only for vectors of primitive types or pointers (every struct would be copied for a vector of structs).
[out] | item | the iteration variable |
[out] | pv | a pointer to the vector |
#define vlc_vector_index_of | ( | pv, | |
item, | |||
pidx | |||
) |
Return the index of an item.
Iterate over all items to find a given item.
Use only for vectors of primitive types or pointers.
The result is written to *(pidx)
:
pv | a pointer to the vector | |
item | the item to find (compared with ==) | |
[out] | pidx | a pointer to the result (ssize_t *) |
#define vlc_vector_init | ( | pv | ) |
Initialize an empty vector.
#define VLC_VECTOR_INITIALIZER { 0, 0, NULL } |
Static initializer for a vector.
#define vlc_vector_insert | ( | pv, | |
index, | |||
item | |||
) |
Insert an item at the given index.
The items in range [index; size-1] will be moved.
pv | a pointer to the vector |
index | the index where the item is to be inserted |
item | the item to append |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_insert_all | ( | pv, | |
index, | |||
items, | |||
count | |||
) |
Insert count
items at the given index.
The items in range [index; size-1] will be moved.
pv | a pointer to the vector |
index | the index where the items are to be inserted |
items | the items array to append |
count | the number of items in the array |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_insert_hole | ( | pv, | |
index, | |||
count | |||
) |
Insert an hole of size count
to the given index.
The items in range [index; size-1] will be moved. The items in the hole are left uninitialized.
pv | a pointer to the vector |
index | the index where the hole is to be inserted |
count | the number of items in the hole |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_insert_hole_internal_ | ( | pv, | |
index, | |||
count | |||
) |
#define vlc_vector_max_cap_ | ( | pv | ) | (SIZE_MAX / 2 / sizeof(*(pv)->data)) |
#define VLC_VECTOR_MINCAP_ ((size_t) 10) |
The minimal allocation size, in number of items.
Private.
#define vlc_vector_move | ( | pv, | |
index, | |||
target | |||
) | vlc_vector_move_slice(pv, index, 1, target) |
Move an item to a given target index.
The items will be moved so that its new position is target
.
pv | a pointer to the vector |
index | the index of the item to move |
target | the new index of the moved item |
#define vlc_vector_move_slice | ( | pv, | |
index, | |||
count, | |||
target | |||
) |
Move a slice of items to a given target index.
The items in range [index; count] will be moved so that the new position of the first item is target
.
pv | a pointer to the vector |
index | the index of the first item to move |
count | the number of items to move |
target | the new index of the moved slice |
#define vlc_vector_move_slice_internal_ | ( | pv, | |
index, | |||
count, | |||
target | |||
) |
#define vlc_vector_push | ( | pv, | |
item | |||
) |
Push an item at the end of the vector.
The amortized complexity is O(1).
pv | a pointer to the vector |
item | the item to append |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_push_all | ( | pv, | |
items, | |||
count | |||
) | vlc_vector_push_all_internal_(pv, items, vlc_vector_enforce_size_t_(count)) |
Append count
items at the end of the vector.
pv | a pointer to the vector |
items | the items array to append |
count | the number of items in the array |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_push_all_internal_ | ( | pv, | |
items, | |||
count | |||
) |
#define vlc_vector_realloc_ | ( | pv, | |
newcap | |||
) |
Realloc the underlying array to newcap
.
Private.
pv | a pointer to the vector |
newcap | (size_t) the requested size |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_remove | ( | pv, | |
index | |||
) |
Remove an item.
The items in range [index+1; size-1] will be moved.
pv | a pointer to the vector |
index | the index of item to remove |
#define vlc_vector_remove_noshrink | ( | pv, | |
index | |||
) | vlc_vector_remove_slice_noshrink(pv, index, 1) |
Remove an item, without shrinking the array.
If you have no good reason to use the _noshrink() version, use vlc_vector_remove() instead.
The items in range [index+1; size-1] will be moved.
pv | a pointer to the vector |
index | the index of item to remove |
#define vlc_vector_remove_slice | ( | pv, | |
index, | |||
count | |||
) |
Remove a slice of items.
The items in range [index+count; size-1] will be moved.
pv | a pointer to the vector |
index | the index of the first item to remove |
count | the number of items to remove |
#define vlc_vector_remove_slice_noshrink | ( | pv, | |
index, | |||
count | |||
) |
Remove a slice of items, without shrinking the array.
If you have no good reason to use the _noshrink() version, use vlc_vector_remove_slice() instead.
The items in range [index+count; size-1] will be moved.
pv | a pointer to the vector |
index | the index of the first item to remove |
count | the number of items to remove |
#define vlc_vector_remove_slice_noshrink_internal_ | ( | pv, | |
index, | |||
count | |||
) |
#define vlc_vector_reserve | ( | pv, | |
mincap | |||
) |
Increase the capacity of the vector to at least mincap
.
pv | a pointer to the vector |
mincap | (size_t) the requested capacity |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_reserve_internal_ | ( | pv, | |
mincap | |||
) |
#define vlc_vector_resize_ | ( | pv, | |
newcap | |||
) |
Resize the vector to newcap
exactly.
If newcap
is 0, the vector is cleared.
Private.
pv | a pointer to the vector |
newcap | (size_t) the requested capacity |
true | if no allocation failed |
false | on allocation failure (the vector is left untouched) |
#define vlc_vector_shrink_to_fit | ( | pv | ) |
Resize the vector so that its capacity equals its actual size.
pv | a pointer to the vector |
#define vlc_vector_swap_remove | ( | pv, | |
index | |||
) |
Remove an item.
The removed item is replaced by the last item of the vector.
This does not preserve ordering, but is O(1). This is useful when the order of items is not meaningful.
pv | a pointer to the vector |
index | the index of item to remove |
|
inlinestatic |
References vlc_vector_max_(), and vlc_vector_min_().
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Referenced by vlc_vector_between_().
|
inlinestatic |
Referenced by vlc_vector_between_(), and vlc_vector_reallocdata_().
|
inlinestatic |
Move items in a (char) array in place.
Move slice [index, count] to target.
References count, vlc_vector_rotate_array_left_(), and vlc_vector_rotate_array_right_().
|
inlinestatic |
Realloc data and update vector fields.
On reallocation success, return the reallocated array and update the vector capacity and size.
On reallocation failure, return ptr
, keep *psize
untouched, and set the failflag in *pcap
to indicate allocation failure (to be consumed by vlc_vector_test_and_reset_failflag_()
).
This weird behavior allows to simultaneously:
Private.
ptr | the current data to realloc | |
count | the requested capacity, in number of items | |
size | the size of one item | |
[in,out] | pcap | a pointer to the cap field of the vector |
[in,out] | psize | a pointer to the size field of the vector |
ptr
if reallocation failed References count, vlc_reallocarray(), VLC_VECTOR_FAILFLAG_, and vlc_vector_min_().
|
inlinestatic |
Reverse a char array in place.
Referenced by vlc_vector_rotate_array_left_().
|
inlinestatic |
Right-rotate a (char) array in place.
For example, left-rotating a char array containing {1, 2, 3, 4, 5, 6} with distance 4 will result in {5, 6, 1, 2, 3, 4}.
Private.
References vlc_vector_reverse_array_().
Referenced by vlc_vector_move_(), and vlc_vector_rotate_array_right_().
|
inlinestatic |
Right-rotate a (char) array in place.
For example, left-rotating a char array containing {1, 2, 3, 4, 5, 6} with distance 2 will result in {5, 6, 1, 2, 3, 4}.
Private.
References vlc_vector_rotate_array_left_().
Referenced by vlc_vector_move_().
|
inlinestatic |
Test and reset the fail flag.
true | if the flag was set |
false | if the flag was not set |
References VLC_VECTOR_FAILFLAG_.