123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- // https://github.com/skogorev/vc_vector
- #include "vc_vector.h"
- #include <stdlib.h>
- #include <string.h>
- #define GROWTH_FACTOR 1.5
- #define DEFAULT_COUNT_OF_ELEMENTS 8
- #define MINIMUM_COUNT_OF_ELEMENTS 2
- // ----------------------------------------------------------------------------
- // vc_vector structure
- // struct vc_vector {
- // size_t count;
- // size_t element_size;
- // size_t reserved_size;
- // char* data;
- // vc_vector_deleter* deleter;
- // };
- // ----------------------------------------------------------------------------
- // Auxiliary methods
- bool vc_vector_realloc(vc_vector* vector, size_t new_count) {
- const size_t new_size = new_count * vector->element_size;
- char* new_data = (char*)realloc(vector->data, new_size);
- if (!new_data) {
- return false;
- }
- vector->reserved_size = new_size;
- vector->data = new_data;
- return true;
- }
- // [first_index, last_index)
- void vc_vector_call_deleter(vc_vector* vector, size_t first_index, size_t last_index) {
- size_t i;
- for (i = first_index; i < last_index; ++i) {
- vector->deleter(vc_vector_at(vector, i));
- }
- }
- void vc_vector_call_deleter_all(vc_vector* vector) {
- vc_vector_call_deleter(vector, 0, vc_vector_count(vector));
- }
- // ----------------------------------------------------------------------------
- // Control
- vc_vector* vc_vector_create(size_t count_elements, size_t size_of_element, vc_vector_deleter* deleter) {
- vc_vector* v = (vc_vector*)malloc(sizeof(vc_vector));
- if (v != NULL) {
- v->data = NULL;
- v->count = 0;
- v->element_size = size_of_element;
- v->deleter = deleter;
- if (count_elements < MINIMUM_COUNT_OF_ELEMENTS) {
- count_elements = DEFAULT_COUNT_OF_ELEMENTS;
- }
- if (size_of_element < 1 ||
- !vc_vector_realloc(v, count_elements)) {
- free(v);
- v = NULL;
- }
- }
- return v;
- }
- vc_vector* vc_vector_create_copy(const vc_vector* vector) {
- vc_vector* new_vector = vc_vector_create(vector->reserved_size / vector->count,
- vector->element_size,
- vector->deleter);
- if (!new_vector) {
- return new_vector;
- }
- if (memcpy(vector->data,
- new_vector->data,
- new_vector->element_size * vector->count) == NULL) {
- vc_vector_release(new_vector);
- new_vector = NULL;
- return new_vector;
- }
- new_vector->count = vector->count;
- return new_vector;
- }
- void vc_vector_release(vc_vector* vector) {
- if (vector->deleter != NULL) {
- vc_vector_call_deleter_all(vector);
- }
- if (vector->reserved_size != 0) {
- free(vector->data);
- }
- free(vector);
- }
- bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2) {
- const size_t size_vector1 = vc_vector_size(vector1);
- if (size_vector1 != vc_vector_size(vector2)) {
- return false;
- }
- return memcmp(vector1->data, vector2->data, size_vector1) == 0;
- }
- float vc_vector_get_growth_factor() {
- return GROWTH_FACTOR;
- }
- size_t vc_vector_get_default_count_of_elements() {
- return DEFAULT_COUNT_OF_ELEMENTS;
- }
- size_t vc_vector_struct_size() {
- return sizeof(vc_vector);
- }
- // ----------------------------------------------------------------------------
- // Element access
- void* vc_vector_at(vc_vector* vector, size_t index) {
- return vector->data + index * vector->element_size;
- }
- void* vc_vector_front(vc_vector* vector) {
- return vector->data;
- }
- void* vc_vector_back(vc_vector* vector) {
- return vector->data + (vector->count - 1) * vector->element_size;
- }
- void* vc_vector_data(vc_vector* vector) {
- return vector->data;
- }
- // ----------------------------------------------------------------------------
- // Iterators
- void* vc_vector_begin(vc_vector* vector) {
- return vector->data;
- }
- void* vc_vector_end(vc_vector* vector) {
- return vector->data + vector->element_size * vector->count;
- }
- void* vc_vector_next(vc_vector* vector, void* i) {
- return (char *)i + vector->element_size;
- }
- // ----------------------------------------------------------------------------
- // Capacity
- bool vc_vector_empty(vc_vector* vector) {
- return vector->count == 0;
- }
- size_t vc_vector_count(const vc_vector* vector) {
- return vector->count;
- }
- size_t vc_vector_size(const vc_vector* vector) {
- return vector->count * vector->element_size;
- }
- size_t vc_vector_max_count(const vc_vector* vector) {
- return vector->reserved_size / vector->element_size;
- }
- size_t vc_vector_max_size(const vc_vector* vector) {
- return vector->reserved_size;
- }
- bool vc_vector_reserve_count(vc_vector* vector, size_t new_count) {
- size_t new_size;
- if (new_count < vector->count) {
- return false;
- }
- new_size = vector->element_size * new_count;
- if (new_size == vector->reserved_size) {
- return true;
- }
- return vc_vector_realloc(vector, new_count);
- }
- bool vc_vector_reserve_size(vc_vector* vector, size_t new_size) {
- return vc_vector_reserve_count(vector, new_size / vector->element_size);
- }
- // ----------------------------------------------------------------------------
- // Modifiers
- void vc_vector_clear(vc_vector* vector) {
- if (vector->deleter != NULL) {
- vc_vector_call_deleter_all(vector);
- }
- vector->count = 0;
- }
- bool vc_vector_insert(vc_vector* vector, size_t index, const void* value) {
- if (vc_vector_max_count(vector) < vector->count + 1) {
- if (!vc_vector_realloc(vector, vc_vector_max_count(vector) * GROWTH_FACTOR)) {
- return false;
- }
- }
- if (!memmove(vc_vector_at(vector, index + 1),
- vc_vector_at(vector, index),
- vector->element_size * (vector->count - index))) {
- return false;
- }
- if (memcpy(vc_vector_at(vector, index),
- value,
- vector->element_size) == NULL) {
- return false;
- }
- ++vector->count;
- return true;
- }
- bool vc_vector_erase(vc_vector* vector, size_t index) {
- if (vector->deleter != NULL) {
- vector->deleter(vc_vector_at(vector, index));
- }
- if (!memmove(vc_vector_at(vector, index),
- vc_vector_at(vector, index + 1),
- vector->element_size * (vector->count - index))) {
- return false;
- }
- vector->count--;
- return true;
- }
- bool vc_vector_erase_range(vc_vector* vector, size_t first_index, size_t last_index) {
- if (vector->deleter != NULL) {
- vc_vector_call_deleter(vector, first_index, last_index);
- }
- if (!memmove(vc_vector_at(vector, first_index),
- vc_vector_at(vector, last_index),
- vector->element_size * (vector->count - last_index))) {
- return false;
- }
- vector->count -= last_index - first_index;
- return true;
- }
- bool vc_vector_append(vc_vector* vector, const void* values, size_t count) {
- const size_t count_new = count + vc_vector_count(vector);
- if (vc_vector_max_count(vector) < count_new) {
- size_t max_count_to_reserved = vc_vector_max_count(vector) * GROWTH_FACTOR;
- while (count_new > max_count_to_reserved) {
- max_count_to_reserved *= GROWTH_FACTOR;
- }
- if (!vc_vector_realloc(vector, max_count_to_reserved)) {
- return false;
- }
- }
- if (memcpy(vector->data + vector->count * vector->element_size,
- values,
- vector->element_size * count) == NULL) {
- return false;
- }
- vector->count = count_new;
- return true;
- }
- bool vc_vector_push_back(vc_vector* vector, const void* value) {
- if (!vc_vector_append(vector, value, 1)) {
- return false;
- }
- return true;
- }
- bool vc_vector_pop_back(vc_vector* vector) {
- if (vector->deleter != NULL) {
- vector->deleter(vc_vector_back(vector));
- }
- vector->count--;
- return true;
- }
- bool vc_vector_replace(vc_vector* vector, size_t index, const void* value) {
- if (vector->deleter != NULL) {
- vector->deleter(vc_vector_at(vector, index));
- }
- return memcpy(vc_vector_at(vector, index),
- value,
- vector->element_size) != NULL;
- }
- bool vc_vector_replace_multiple(vc_vector* vector, size_t index, const void* values, size_t count) {
- if (vector->deleter != NULL) {
- vc_vector_call_deleter(vector, index, index + count);
- }
- return memcpy(vc_vector_at(vector, index),
- values,
- vector->element_size * count) != NULL;
- }
|