![]() |
ucx
UAP Common Extensions
|
Array list implementation. More...
#include "list.h"
Go to the source code of this file.
Data Structures | |
struct | cx_array_reallocator_s |
Defines a reallocation mechanism for arrays. More... | |
Macros | |
#define | CX_ARRAY_DECLARE_SIZED(type, name, size_type) |
Declares variables for an array that can be used with the convenience macros. | |
#define | CX_ARRAY_DECLARE(type, name) CX_ARRAY_DECLARE_SIZED(type, name, size_t) |
Declares variables for an array that can be used with the convenience macros. | |
#define | cx_array_initialize(array, capacity) |
Initializes an array with the given capacity. | |
#define | cx_array_initialize_a(allocator, array, capacity) |
Initializes an array with the given capacity using the specified allocator. | |
#define | cx_array_simple_copy_a(reallocator, array, index, src, count) |
Convenience macro that uses cx_array_copy() with a default layout and the specified reallocator. | |
#define | cx_array_simple_copy(array, index, src, count) cx_array_simple_copy_a(NULL, array, index, src, count) |
Convenience macro that uses cx_array_copy() with a default layout and the default reallocator. | |
#define | cx_array_simple_reserve_a(reallocator, array, count) |
Convenience macro that uses cx_array_reserve() with a default layout and the specified reallocator. | |
#define | cx_array_simple_reserve(array, count) cx_array_simple_reserve_a(NULL, array, count) |
Convenience macro that uses cx_array_reserve() with a default layout and the default reallocator. | |
#define | cx_array_add(target, size, capacity, elem_size, elem, reallocator) |
Adds an element to an array with the possibility of allocating more space. | |
#define | cx_array_simple_add_a(reallocator, array, elem) cx_array_simple_copy_a(reallocator, array, array##_size, &(elem), 1) |
Convenience macro that uses cx_array_add() with a default layout and the specified reallocator. | |
#define | cx_array_simple_add(array, elem) cx_array_simple_add_a(cx_array_default_reallocator, array, elem) |
Convenience macro that uses cx_array_add() with a default layout and the default reallocator. | |
#define | cx_array_add_sorted(target, size, capacity, elem_size, elem, cmp_func, reallocator) cx_array_insert_sorted((void**)(target), size, capacity, cmp_func, elem, elem_size, 1, reallocator) |
Inserts an element into a sorted array. | |
#define | cx_array_simple_add_sorted_a(reallocator, array, elem, cmp_func) |
Convenience macro for cx_array_add_sorted() with a default layout and the specified reallocator. | |
#define | cx_array_simple_add_sorted(array, elem, cmp_func) cx_array_simple_add_sorted_a(NULL, array, elem, cmp_func) |
Convenience macro for cx_array_add_sorted() with a default layout and the default reallocator. | |
#define | cx_array_simple_insert_sorted_a(reallocator, array, src, n, cmp_func) |
Convenience macro for cx_array_insert_sorted() with a default layout and the specified reallocator. | |
#define | cx_array_simple_insert_sorted(array, src, n, cmp_func) cx_array_simple_insert_sorted_a(NULL, array, src, n, cmp_func) |
Convenience macro for cx_array_insert_sorted() with a default layout and the default reallocator. | |
#define | cxArrayListCreateSimple(elem_size, initial_capacity) cxArrayListCreate(NULL, NULL, elem_size, initial_capacity) |
Allocates an array list for storing elements with elem_size bytes each. | |
Typedefs | |
typedef struct cx_array_reallocator_s | CxArrayReallocator |
Typedef for the array reallocator struct. | |
Functions | |
CxArrayReallocator | cx_array_reallocator (const struct cx_allocator_s *allocator, const void *stackmem) |
Creates a new array reallocator. | |
int | cx_array_reserve (void **array, void *size, void *capacity, unsigned width, size_t elem_size, size_t elem_count, CxArrayReallocator *reallocator) |
Reserves memory for additional elements. | |
int | cx_array_copy (void **target, void *size, void *capacity, unsigned width, size_t index, const void *src, size_t elem_size, size_t elem_count, CxArrayReallocator *reallocator) |
Copies elements from one array to another. | |
int | cx_array_insert_sorted (void **target, size_t *size, size_t *capacity, cx_compare_func cmp_func, const void *src, size_t elem_size, size_t elem_count, CxArrayReallocator *reallocator) |
Inserts a sorted array into another sorted array. | |
size_t | cx_array_binary_search_inf (const void *arr, size_t size, size_t elem_size, const void *elem, cx_compare_func cmp_func) |
Searches the largest lower bound in a sorted array. | |
size_t | cx_array_binary_search (const void *arr, size_t size, size_t elem_size, const void *elem, cx_compare_func cmp_func) |
Searches an item in a sorted array. | |
size_t | cx_array_binary_search_sup (const void *arr, size_t size, size_t elem_size, const void *elem, cx_compare_func cmp_func) |
Searches the smallest upper bound in a sorted array. | |
void | cx_array_swap (void *arr, size_t elem_size, size_t idx1, size_t idx2) |
Swaps two array elements. | |
CxList * | cxArrayListCreate (const CxAllocator *allocator, cx_compare_func comparator, size_t elem_size, size_t initial_capacity) |
Allocates an array list for storing elements with elem_size bytes each. | |
Variables | |
const unsigned | cx_array_swap_sbo_size |
The maximum item size in an array list that fits into stack buffer when swapped. | |
CxArrayReallocator * | cx_array_default_reallocator |
A default stdlib-based array reallocator. | |
Array list implementation.
#define cx_array_add | ( | target, | |
size, | |||
capacity, | |||
elem_size, | |||
elem, | |||
reallocator ) |
Adds an element to an array with the possibility of allocating more space.
The element elem
is added to the end of the target
array which contains size
elements, already. The capacity
must point to a variable denoting the current maximum number of elements the array can hold.
If the capacity is insufficient to hold the new element, an attempt to increase the capacity
is made and the new capacity is written back.
The @ SIZE_TYPE is flexible and can be any unsigned integer type. It is important, however, that size
and capacity
are pointers to variables of the same type.
target | (void** ) a pointer to the target array |
size | (SIZE_TYPE* ) a pointer to the size of the target array |
capacity | (SIZE_TYPE* ) a pointer to the capacity of the target array |
elem_size | (size_t ) the size of one element |
elem | (void* ) a pointer to the element to add |
reallocator | (CxArrayReallocator* ) the array reallocator to use |
zero | success |
non-zero | failure |
#define cx_array_add_sorted | ( | target, | |
size, | |||
capacity, | |||
elem_size, | |||
elem, | |||
cmp_func, | |||
reallocator ) cx_array_insert_sorted((void**)(target), size, capacity, cmp_func, elem, elem_size, 1, reallocator) |
Inserts an element into a sorted array.
If the target array is not already sorted with respect to the specified cmp_func
, the behavior is undefined.
If the capacity is insufficient to hold the new data, a reallocation attempt is made.
The @ SIZE_TYPE is flexible and can be any unsigned integer type. It is important, however, that size
and capacity
are pointers to variables of the same type.
target | (void** ) a pointer to the target array |
size | (SIZE_TYPE* ) a pointer to the size of the target array |
capacity | (SIZE_TYPE* ) a pointer to the capacity of the target array |
elem_size | (size_t ) the size of one element |
elem | (void* ) a pointer to the element to add |
cmp_func | (cx_cmp_func ) the compare function for the elements |
reallocator | (CxArrayReallocator* ) the array reallocator to use |
zero | success |
non-zero | failure |
#define CX_ARRAY_DECLARE | ( | type, | |
name ) CX_ARRAY_DECLARE_SIZED(type, name, size_t) |
Declares variables for an array that can be used with the convenience macros.
The size and capacity variables will have size_t
type. Use CX_ARRAY_DECLARE_SIZED() to specify a different type.
type | the type of the data |
name | the name of the array |
#define CX_ARRAY_DECLARE_SIZED | ( | type, | |
name, | |||
size_type ) |
Declares variables for an array that can be used with the convenience macros.
type | the type of the data |
name | the name of the array |
size_type | the type of the size (should be uint8_t, uint16_t, uint32_t, or size_t) |
#define cx_array_initialize | ( | array, | |
capacity ) |
Initializes an array with the given capacity.
The type of the capacity depends on the type used during declaration.
The memory for the array is allocated with stdlib malloc().
array | the name of the array |
capacity | the initial capacity |
#define cx_array_initialize_a | ( | allocator, | |
array, | |||
capacity ) |
Initializes an array with the given capacity using the specified allocator.
The memory for the array is allocated with stdlib malloc().
allocator | (CxAllocator* ) the allocator |
array | the name of the array |
capacity | the initial capacity |
#define cx_array_simple_add | ( | array, | |
elem ) cx_array_simple_add_a(cx_array_default_reallocator, array, elem) |
Convenience macro that uses cx_array_add() with a default layout and the default reallocator.
array | the name of the array (NOT a pointer or alias to the array) |
elem | the element to add (NOT a pointer, address is automatically taken) |
zero | success |
non-zero | failure |
#define cx_array_simple_add_a | ( | reallocator, | |
array, | |||
elem ) cx_array_simple_copy_a(reallocator, array, array##_size, &(elem), 1) |
Convenience macro that uses cx_array_add() with a default layout and the specified reallocator.
reallocator | (CxArrayReallocator* ) the array reallocator to use |
array | the name of the array (NOT a pointer or alias to the array) |
elem | the element to add (NOT a pointer, address is automatically taken) |
zero | success |
non-zero | failure |
#define cx_array_simple_add_sorted | ( | array, | |
elem, | |||
cmp_func ) cx_array_simple_add_sorted_a(NULL, array, elem, cmp_func) |
Convenience macro for cx_array_add_sorted() with a default layout and the default reallocator.
array | the name of the array (NOT a pointer or alias to the array) |
elem | the element to add (NOT a pointer, address is automatically taken) |
cmp_func | (cx_cmp_func ) the compare function for the elements |
zero | success |
non-zero | failure |
#define cx_array_simple_add_sorted_a | ( | reallocator, | |
array, | |||
elem, | |||
cmp_func ) |
Convenience macro for cx_array_add_sorted() with a default layout and the specified reallocator.
reallocator | (CxArrayReallocator* ) the array reallocator to use |
array | the name of the array (NOT a pointer or alias to the array) |
elem | the element to add (NOT a pointer, address is automatically taken) |
cmp_func | (cx_cmp_func ) the compare function for the elements |
zero | success |
non-zero | failure |
#define cx_array_simple_copy | ( | array, | |
index, | |||
src, | |||
count ) cx_array_simple_copy_a(NULL, array, index, src, count) |
Convenience macro that uses cx_array_copy() with a default layout and the default reallocator.
array | the name of the array (NOT a pointer or alias to the array) |
index | (size_t ) the index where the copied elements shall be placed |
src | (void* ) the source array |
count | (size_t ) the number of elements to copy |
zero | success |
non-zero | failure |
#define cx_array_simple_copy_a | ( | reallocator, | |
array, | |||
index, | |||
src, | |||
count ) |
Convenience macro that uses cx_array_copy() with a default layout and the specified reallocator.
reallocator | (CxArrayReallocator* ) the array reallocator to use |
array | the name of the array (NOT a pointer or alias to the array) |
index | (size_t ) the index where the copied elements shall be placed |
src | (void* ) the source array |
count | (size_t ) the number of elements to copy |
zero | success |
non-zero | failure |
#define cx_array_simple_insert_sorted | ( | array, | |
src, | |||
n, | |||
cmp_func ) cx_array_simple_insert_sorted_a(NULL, array, src, n, cmp_func) |
Convenience macro for cx_array_insert_sorted() with a default layout and the default reallocator.
array | the name of the array (NOT a pointer or alias to the array) |
src | (void* ) pointer to the source array |
n | (size_t ) number of elements in the source array |
cmp_func | (cx_cmp_func ) the compare function for the elements |
zero | success |
non-zero | failure |
#define cx_array_simple_insert_sorted_a | ( | reallocator, | |
array, | |||
src, | |||
n, | |||
cmp_func ) |
Convenience macro for cx_array_insert_sorted() with a default layout and the specified reallocator.
reallocator | (CxArrayReallocator* ) the array reallocator to use |
array | the name of the array (NOT a pointer or alias to the array) |
src | (void* ) pointer to the source array |
n | (size_t ) number of elements in the source array |
cmp_func | (cx_cmp_func ) the compare function for the elements |
zero | success |
non-zero | failure |
#define cx_array_simple_reserve | ( | array, | |
count ) cx_array_simple_reserve_a(NULL, array, count) |
Convenience macro that uses cx_array_reserve() with a default layout and the default reallocator.
array | the name of the array (NOT a pointer or alias to the array) |
count | (size_t ) the number of expected additional elements |
zero | success |
non-zero | failure |
#define cx_array_simple_reserve_a | ( | reallocator, | |
array, | |||
count ) |
Convenience macro that uses cx_array_reserve() with a default layout and the specified reallocator.
reallocator | (CxArrayReallocator* ) the array reallocator to use |
array | the name of the array (NOT a pointer or alias to the array) |
count | (size_t ) the number of expected additional elements |
zero | success |
non-zero | failure |
#define cxArrayListCreateSimple | ( | elem_size, | |
initial_capacity ) cxArrayListCreate(NULL, NULL, elem_size, initial_capacity) |
Allocates an array list for storing elements with elem_size
bytes each.
The list will use the cxDefaultAllocator and NO compare function. If you want to call functions that need a compare function, you have to set it immediately after creation or use cxArrayListCreate().
If elem_size
is CX_STORE_POINTERS, the created list stores pointers instead of copies of the added elements and the compare function will be automatically set to cx_cmp_ptr().
elem_size | (size_t ) the size of each element in bytes |
initial_capacity | (size_t ) the initial number of elements the array can store |
size_t cx_array_binary_search | ( | const void * | arr, |
size_t | size, | ||
size_t | elem_size, | ||
const void * | elem, | ||
cx_compare_func | cmp_func ) |
Searches an item in a sorted array.
If the array is not sorted with respect to the cmp_func
, the behavior is undefined.
arr | the array to search |
size | the size of the array |
elem_size | the size of one element |
elem | the element to find |
cmp_func | the compare function |
size
if the element cannot be found size_t cx_array_binary_search_inf | ( | const void * | arr, |
size_t | size, | ||
size_t | elem_size, | ||
const void * | elem, | ||
cx_compare_func | cmp_func ) |
Searches the largest lower bound in a sorted array.
In other words, this function returns the index of the largest element in arr
that is less or equal to elem
with respect to cmp_func
. When no such element exists, size
is returned.
If elem
is contained in the array, this is identical to cx_array_binary_search().
If the array is not sorted with respect to the cmp_func
, the behavior is undefined.
arr | the array to search |
size | the size of the array |
elem_size | the size of one element |
elem | the element to find |
cmp_func | the compare function |
size
size_t cx_array_binary_search_sup | ( | const void * | arr, |
size_t | size, | ||
size_t | elem_size, | ||
const void * | elem, | ||
cx_compare_func | cmp_func ) |
Searches the smallest upper bound in a sorted array.
In other words, this function returns the index of the smallest element in arr
that is greater or equal to elem
with respect to cmp_func
. When no such element exists, size
is returned.
If elem
is contained in the array, this is identical to cx_array_binary_search().
If the array is not sorted with respect to the cmp_func
, the behavior is undefined.
arr | the array to search |
size | the size of the array |
elem_size | the size of one element |
elem | the element to find |
cmp_func | the compare function |
size
int cx_array_copy | ( | void ** | target, |
void * | size, | ||
void * | capacity, | ||
unsigned | width, | ||
size_t | index, | ||
const void * | src, | ||
size_t | elem_size, | ||
size_t | elem_count, | ||
CxArrayReallocator * | reallocator ) |
Copies elements from one array to another.
The elements are copied to the target
array at the specified index
, overwriting possible elements. The index
does not need to be in range of the current array size
. If the new index plus the number of elements added would extend the array's size, the remaining capacity
is used.
If the capacity
is also insufficient to hold the new data, a reallocation attempt is made with the specified reallocator
. You can create your own reallocator by hand, use cx_array_default_reallocator, or use the convenience function cx_array_reallocator() to create a custom reallocator.
The width
in bytes refers to the size and capacity. Both must have the same width. Supported are 0, 1, 2, and 4, as well as 8 if running on a 64 bit architecture. If set to zero, the native word width is used.
target | a pointer to the target array |
size | a pointer to the size of the target array |
capacity | a pointer to the capacity of the target array |
width | the width in bytes for the size and capacity or zero for default |
index | the index where the copied elements shall be placed |
src | the source array |
elem_size | the size of one element |
elem_count | the number of elements to copy |
reallocator | the array reallocator to use (NULL defaults to cx_array_default_reallocator) |
zero | success |
non-zero | failure |
int cx_array_insert_sorted | ( | void ** | target, |
size_t * | size, | ||
size_t * | capacity, | ||
cx_compare_func | cmp_func, | ||
const void * | src, | ||
size_t | elem_size, | ||
size_t | elem_count, | ||
CxArrayReallocator * | reallocator ) |
Inserts a sorted array into another sorted array.
If either the target or the source array is not already sorted with respect to the specified cmp_func
, the behavior is undefined.
If the capacity is insufficient to hold the new data, a reallocation attempt is made. You can create your own reallocator by hand, use cx_array_default_reallocator, or use the convenience function cx_array_reallocator() to create a custom reallocator.
target | a pointer to the target array |
size | a pointer to the size of the target array |
capacity | a pointer to the capacity of the target array |
cmp_func | the compare function for the elements |
src | the source array |
elem_size | the size of one element |
elem_count | the number of elements to insert |
reallocator | the array reallocator to use (NULL defaults to cx_array_default_reallocator) |
zero | success |
non-zero | failure |
CxArrayReallocator cx_array_reallocator | ( | const struct cx_allocator_s * | allocator, |
const void * | stackmem ) |
Creates a new array reallocator.
When allocator
is NULL
, the stdlib default allocator will be used.
When stackmem
is not NULL
, the reallocator is supposed to be used only for the specific array that is initially located at stackmem
. When reallocation is needed, the reallocator checks, if the array is still located at stackmem
and copies the contents to the heap.
NULL
will return a reallocator that behaves like cx_array_default_reallocator.allocator | the allocator this reallocator shall be based on |
stackmem | the address of the array when the array is initially located on the stack or shall not reallocated in place |
int cx_array_reserve | ( | void ** | array, |
void * | size, | ||
void * | capacity, | ||
unsigned | width, | ||
size_t | elem_size, | ||
size_t | elem_count, | ||
CxArrayReallocator * | reallocator ) |
Reserves memory for additional elements.
This function checks if the capacity
of the array is sufficient to hold at least size
plus elem_count
elements. If not, a reallocation is performed with the specified reallocator
. You can create your own reallocator by hand, use cx_array_default_reallocator, or use the convenience function cx_array_reallocator() to create a custom reallocator.
This function can be useful to replace subsequent calls to cx_array_copy() with one single cx_array_reserve() and then - after guaranteeing a sufficient capacity - use simple memmove() or memcpy().
The width
in bytes refers to the size and capacity. Both must have the same width. Supported are 0, 1, 2, and 4, as well as 8 if running on a 64 bit architecture. If set to zero, the native word width is used.
array | a pointer to the target array |
size | a pointer to the size of the array |
capacity | a pointer to the capacity of the array |
width | the width in bytes for the size and capacity or zero for default |
elem_size | the size of one element |
elem_count | the number of expected additional elements |
reallocator | the array reallocator to use (NULL defaults to cx_array_default_reallocator) |
zero | success |
non-zero | failure |
void cx_array_swap | ( | void * | arr, |
size_t | elem_size, | ||
size_t | idx1, | ||
size_t | idx2 ) |
Swaps two array elements.
arr | the array |
elem_size | the element size |
idx1 | index of first element |
idx2 | index of second element |
CxList * cxArrayListCreate | ( | const CxAllocator * | allocator, |
cx_compare_func | comparator, | ||
size_t | elem_size, | ||
size_t | initial_capacity ) |
Allocates an array list for storing elements with elem_size
bytes each.
If elem_size
is CX_STORE_POINTERS, the created list stores pointers instead of copies of the added elements and the compare function will be automatically set to cx_cmp_ptr(), if none is given.
allocator | the allocator for allocating the list memory (if NULL , a default stdlib allocator will be used) |
comparator | the comparator for the elements (if NULL , and the list is not storing pointers, sort and find functions will not work) |
elem_size | the size of each element in bytes |
initial_capacity | the initial number of elements the array can store |