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,
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.