20#define ASSERT_OVERFLOW(element_size, capacity, data_size, alloc_size, message) \ 
   21    assert((data_size / element_size == capacity && alloc_size > data_size) && message); 
   44        const size_t capacity,
 
   45        const size_t allocator_size,
 
   46        const size_t ext_header_size);
 
   59        const void *
const value,
 
   71        const void *
const value,
 
   84    assert(opts && 
"non-null opts required!");
 
   85    assert(opts->
element_size && 
"'element_size' gt then zero required!");
 
 
  135    memcpy(clone, vector, alloc_size);
 
 
  143    assert(vector && *vector);
 
  147            (*vector)->allocator_size,
 
  148            (*vector)->ext_header_size);
 
 
  165    assert((vector->
ext_header_size != 0) && 
"trying to access extended header that wasn't alloc'd");
 
 
  220    assert((limit <= vector->capacity) && 
"Vector out of capacity bounds!");
 
  222    for (
size_t i = 0; i < limit; ++i)
 
  225        if (predicate(element, param))
 
 
  235        const void *
const value,
 
  244    assert((limit <= vector->capacity) && 
"Limit out of capacity bounds!");
 
  245    return binary_find(vector, value, 0, limit, cmp, param);
 
 
  250        const void *
const value,
 
  259    assert((limit <= vector->capacity) && 
"Limit out of capacity bounds!");
 
 
  274    assert((index < vector->capacity) && 
"Index out of capacity bounds!");
 
 
  282    assert((index < vector->capacity) && 
"Index out of capacity bounds!");
 
 
  290    assert((index < vector->capacity) && 
"Index out of capacity bounds!");
 
 
  300    assert((offset + length <= vector->capacity) && 
"`offset + length` exceeds vector's capacity!");
 
 
  310    assert((offset + length <= vector->capacity) && 
"`offset + length` exceeds vector's capacity!");
 
 
  320        const size_t part_offset,
 
  321        const size_t part_length)
 
  323    for (
size_t i = offset; i < length; ++i)
 
  325        char *src = (
char *)
vector_get(vector, i) + part_offset;
 
  326        memcpy(dest, src, part_length);
 
 
  338    assert((index < vector->capacity) && 
"Index out of capacity bounds!");
 
  339    assert((index + amount <= vector->capacity) && 
"`index + amount` exceedes vector's capacity.");
 
  341    size_t elements_set = 1;
 
  344    for (; (elements_set + elements_set) <= amount; elements_set += elements_set)
 
  346        void *dest = 
vector_get(vector, index + elements_set);
 
  350    for (; elements_set < amount; ++elements_set)
 
  352        void *dest = 
vector_get(vector, index + elements_set);
 
  353        vector_copy(vector, dest, index + elements_set - 1, 1);
 
 
  362    assert((offset < vector->capacity) && 
"Offset out of bounds.");
 
  363    assert(((ssize_t)offset + shift >= 0) && 
"Shifted range underflows allocated buffer");
 
  364    assert((offset + shift + length <= vector->capacity) && 
"Shifted range exceedes capacity");
 
 
  373    assert(index_a != index_b);
 
  374    assert(index_a < vector->capacity && index_b < vector->capacity);
 
 
  385    assert(limit && limit <= vector->capacity);
 
  388    for (
size_t i = 0; i < limit; ++i)
 
  390        int status = func(
vector_get(vector, i), param);
 
  391        if (status) 
return status;
 
 
  401    assert(limit && limit <= vector->capacity);
 
  404    for (
size_t i = 0; i < limit; ++i)
 
  406        int status = func(
vector_get(vector, i), acc, param);
 
  407        if (status) 
return status;
 
 
  417    assert(limit && limit <= vector->capacity);
 
 
  424void * __attribute__((weak)) 
vector_alloc(
const size_t alloc_size, 
void *
const param)
 
  427    return malloc(alloc_size);
 
  431void * __attribute__((weak)) 
vector_realloc(
void *ptr, 
const size_t alloc_size, 
void *
const param)
 
  434    return realloc(ptr, alloc_size);
 
  438void __attribute__((weak)) 
vector_free(
void *ptr, 
void *
const param)
 
  447    return (size + alignment - 1) / alignment * alignment;
 
 
  451ssize_t 
cmp_lex_asc(
const void *value, 
const void *element, 
void *param)
 
  453    return memcmp(value, element, (
size_t)param);
 
 
  457ssize_t 
cmp_lex_dsc(
const void *value, 
const void *element, 
void *param)
 
  459    return memcmp(element, value, (
size_t)param);
 
 
  468        const size_t capacity,
 
  469        const size_t allocator_size,
 
  470        const size_t ext_header_size)
 
  472    const size_t data_size = element_size * capacity;
 
  473    const size_t alloc_size = 
sizeof(
vector_t) + allocator_size + ext_header_size + data_size;
 
  474    ASSERT_OVERFLOW(element_size, capacity, data_size, alloc_size, 
"allocation size overflow!");
 
 
  482    return (
char*)vector->
memory;
 
 
  487        const void *
const value,
 
  498    const size_t middle = (start + end) / 2;
 
  499    void *middle_value = 
vector_get(vector, middle);
 
  501    if (0 == cmp(value, middle_value, param))
 
  506    if (0 < cmp(value, middle_value, param))
 
  508        return binary_find(vector, value, middle + 1, end, cmp, param);
 
  511    return binary_find(vector, value, start, middle, cmp, param);
 
 
  516        const void *
const value,
 
  527    const size_t middle = (start + end) / 2;
 
  528    void *middle_value = 
vector_get(vector, middle);
 
  530    if (0 == cmp(value, middle_value, param))
 
  535    if (0 < cmp(value, middle_value, param))
 
 
void * vector_realloc(void *const ptr, size_t alloc_size, void *const param)
Reallocates already allocated memory chunk in order to change allocation size.
void * vector_alloc(const size_t alloc_size, void *const param)
Allocates memory chunk of alloc_size.
void vector_free(void *const ptr, void *const param)
Free allocation that was previously allocated.
int(* foreach_t)(const void *const element, void *const param)
Callback determines an operation for vector_foreach.
int(* transform_t)(void *const element, void *const param)
Callback determines an operation for vector_transform.
bool(* predicate_t)(const void *const element, void *const param)
Predicate, tells if traversed element matches user's criteria.
int(* aggregate_t)(const void *const element, void *const acc, void *const param)
Callback determines an operation for vector_aggregate.
ssize_t(* compare_t)(const void *const value, const void *const element, void *const param)
Compare, used to define traversal order.
int vector_transform(vector_t *const vector, const size_t limit, const transform_t func, void *const param)
Perform mutable transformation on each element of the vector.
int vector_aggregate(const vector_t *const vector, const size_t limit, const aggregate_t func, void *const acc, void *const param)
Perform immutable accamulating action on each element of the vector.
void vector_shift(vector_t *const vector, const size_t offset, const size_t length, const ssize_t shift)
Shift range of elements.
void vector_part_copy(const vector_t *const vector, char *dest, const size_t offset, const size_t length, const size_t part_offset, const size_t part_length)
Partial copying.
void vector_spread(vector_t *const vector, const size_t index, const size_t amount)
Duplicates existing element across range.
void * vector_get(const vector_t *const vector, const size_t index)
Returns pointer for the element at index.
int vector_foreach(const vector_t *const vector, const size_t limit, const foreach_t func, void *const param)
Perform immutable action on each element of the vector.
void vector_move(const vector_t *const vector, char *dest, const size_t offset, const size_t length)
Moves range of the vector elements to another location.
void vector_set(vector_t *const vector, const size_t index, const void *const value)
Sets element at given index to a value.
void vector_copy(const vector_t *const vector, char *const dest, const size_t offset, const size_t length)
Copy element range to other location.
char * vector_data(const vector_t *const vector)
Gives a pointer to a location where elements' data begins.
void vector_swap(vector_t *const vector, const size_t index_a, const size_t index_b)
Swaps values of elements designated by indicies.
void vector_set_zero(vector_t *const vector, const size_t index)
Sets element at given index to a zero value.
size_t vector_data_offset(const vector_t *const vector)
Compute offset from vector_t::memory to first element.
size_t vector_ext_header_size(const vector_t *const vector)
Retrieves extended header size.
void * vector_get_ext_header(const vector_t *const vector)
Provides a location where user can put a header for the derived class.
vector_status_t vector_resize(vector_t **const vector, const size_t capacity, const vector_status_t error)
Performs allocation resize.
vector_t * vector_clone(const vector_t *const vector)
Duplicates a vector.
void vector_destroy(vector_t *const vector)
Deallocates vector.
vector_t * vector_create_(const vector_opts_t *const opts)
Vector contructor.
size_t vector_capacity_bytes(const vector_t *const vector)
Reports current capacity of the vector in bytes.
size_t vector_element_size(const vector_t *const vector)
Reports current element size.
size_t vector_capacity(const vector_t *const vector)
Reports current capacity of the vector.
alloc_opts_t vector_alloc_opts(const vector_t *const vector)
Access allocator options.
void * vector_linear_find(const vector_t *const vector, const size_t limit, const predicate_t predicate, void *param)
Simple linear search for unordered data.
void * vector_binary_find(const vector_t *const vector, const void *const value, const size_t limit, const compare_t cmp, void *param)
Run binary search on the vector.
ssize_t vector_binary_find_index(const vector_t *const vector, const void *const value, const size_t limit, const compare_t cmp, void *const param)
Run binary search on the vector.
ssize_t cmp_lex_asc(const void *value, const void *element, void *param)
Performs comparison in lexicographical ascending order.
size_t calc_aligned_size(const size_t size, const size_t alignment)
Function calculates size of the element while respecting requirement for alignment.
ssize_t cmp_lex_dsc(const void *value, const void *element, void *param)
Performs comparison in lexicographical descending order.
size_t size
Size of the allocator data.
void * data
User defined allocator structure.
size_t element_size
Size of the underling element type.
alloc_opts_t alloc_opts
optional allocator
size_t initial_cap
Amount of elements that will be preallocated.
size_t ext_header_size
Size of the extention header.
Vector control structure type.
size_t allocator_size
Size of the allocator.
char memory[]
Beginning of the vector's memory region.
size_t capacity
Current amount of allocated elements.
size_t ext_header_size
Size of the extention header.
size_t element_size
Size of the underling element type.
static ssize_t binary_find_index(const vector_t *const vector, const void *const value, const size_t start, const size_t end, const compare_t cmp, void *param)
Performs binary search on a vectors range.
static size_t calculate_alloc_size(const size_t element_size, const size_t capacity, const size_t allocator_size, const size_t ext_header_size)
Calculates allocation size for the vector.
static void * get_allocator(const vector_t *const vector)
Access allocator region of the vector.
static void * binary_find(const vector_t *const vector, const void *const value, const size_t start, const size_t end, const compare_t cmp, void *const param)
Performs binary search on a vectors range.
Public interface of the vector.
vector_status_t
Status enum that indicates errors of operations that may fail.