From 423d46bdae07ceee0af94e5cc12f335afabbcbb8 Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Fri, 24 May 2024 13:06:19 -0300 Subject: src/vector.{c,h}: Improve code and tests --- src/vector.c | 130 ++++++++++++++++++++--------------------------------------- src/vector.h | 15 ++++--- 2 files changed, 50 insertions(+), 95 deletions(-) (limited to 'src') diff --git a/src/vector.c b/src/vector.c index 65f004f..77a6a8a 100644 --- a/src/vector.c +++ b/src/vector.c @@ -11,6 +11,7 @@ #include "logerr.h" #include "catalog.h" #include "i18n.h" +#include "math.h" #include "vector.h" @@ -18,8 +19,7 @@ struct Vector { void **values; size_t capacity; - size_t back_count; - size_t front_count; + size_t count; const size_t max_capacity; const size_t multiplier; const size_t value_size; @@ -41,20 +41,19 @@ vector_new_with( const size_t max_capacity, const size_t multiplier, const size_t value_size, - struct Vector **const out + const struct Vector **const out ) { int rc = -1; struct Vector v = { .values = NULL, .capacity = capacity, - .back_count = 0U, - .front_count = 0U, + .count = 0U, .max_capacity = max_capacity, .multiplier = multiplier, .value_size = value_size, }; - struct Vector *restrict vref = NULL; + struct Vector *restrict ret = NULL; assert(capacity > 0); if (capacity > max_capacity) { @@ -74,19 +73,19 @@ vector_new_with( goto out; } - vref = malloc(sizeof(*vref)); - if (vref == NULL) { - logerr("malloc(%ld): %s\n", sizeof(vref), strerror(errno)); + ret = malloc(sizeof(*ret)); + if (ret == NULL) { + logerr("malloc(%ld): %s\n", sizeof(ret), strerror(errno)); goto out; } - memcpy(vref, &v, sizeof(v)); + memcpy(ret, &v, sizeof(v)); - *out = vref; + *out = ret; rc = 0; out: if (rc) { - if (vref != NULL) { - free(vref); + if (ret != NULL) { + free(ret); } if (v.values != NULL) { free(v.values); @@ -96,7 +95,7 @@ out: } int -vector_new(const size_t value_size, struct Vector **const out) { +vector_new(const size_t value_size, const struct Vector **const out) { return vector_new_with( VECTOR_DEFAULT_CAPACITY, VECTOR_MAX_CAPACITY, @@ -115,9 +114,22 @@ vector_free(const struct Vector *const v) { size_t vector_count(const struct Vector *const v) { - const size_t count = v->back_count + v->front_count; - assert(count <= v->capacity); - return count; + return v->count; +} + +static size_t +next_capacity(const struct Vector *const v) { + size_t ret; + if (mul_size(v->capacity, v->multiplier, &ret)) { + return v->max_capacity; + } + + return ret; +} + +static int +next_size(const struct Vector *const v, const size_t capacity, size_t *const out) { + return mul_size(v->value_size, capacity, out); } int @@ -136,20 +148,12 @@ out: return rc; } -static size_t -next_capacity(const struct Vector *const v) { - if (v->capacity > v->max_capacity / v->multiplier) { - return v->max_capacity; - } else { - return v->capacity * v->multiplier; - } -} - int -vector_push_back(struct Vector *const v, void *const value) { +vector_push_back(const struct Vector *const v, const void *const value) { int rc = -1; void *new_values = NULL; + struct Vector *const v_mut = (struct Vector *const)v; const size_t count = vector_count(v); if (count == v->capacity) { @@ -164,50 +168,17 @@ vector_push_back(struct Vector *const v, void *const value) { } const size_t new_capacity = next_capacity(v); - const size_t new_size = new_capacity * v->value_size; - new_values = realloc(v->values, new_size); - if (new_values == NULL) { - logerr( - "realloc(v->values, %ld): %s\n", - new_size, - strerror(errno) - ); - goto out; - } - v->capacity = new_capacity; - v->values = new_values; - } - - v->values[v->back_count] = value; - v->back_count++; - rc = 0; -out: - if (rc) { - if (new_values != NULL) { - free(new_values); - } - } - return rc; -} - -int -vector_push_front(struct Vector *const v, void *const value) { - int rc = -1; - - void *new_values = NULL; - - const size_t count = vector_count(v); - if (count == v->capacity) { - if (count == v->max_capacity) { + size_t new_size; + if (next_size(v, new_capacity, &new_size)) { logerr( _(MSG_ERR_VECTOR_MAX_CAPACITY), v->max_capacity, strerror(EOVERFLOW) ); + rc = EOVERFLOW; + goto out; } - const size_t new_capacity = next_capacity(v); - const size_t new_size = new_capacity * v->value_size; new_values = realloc(v->values, new_size); if (new_values == NULL) { logerr( @@ -217,12 +188,12 @@ vector_push_front(struct Vector *const v, void *const value) { ); goto out; } - v->capacity = new_capacity; - // FIXME: copy, but leaving things at the beginning + v_mut->capacity = new_capacity; + v_mut->values = new_values; } - v->values[v->front_count] = value; - v->front_count++; + memcpy(&v->values[v->count], value, v->value_size); + v_mut->count++; rc = 0; out: if (rc) { @@ -234,25 +205,10 @@ out: } int -vector_pop_back(struct Vector *const v, const void **const out) { +vector_pop_back(const struct Vector *const v, const void **const out) { int rc = -1; - const size_t count = vector_count(v); - if (count == 0) { - logerr(_(MSG_ERR_VECTOR_UNDERFLOW)); - goto out; - } - - *out = v->values[v->back_count - 1]; // FIXME: can become negative! - v->back_count--; - rc = 0; -out: - return rc; -} - -int -vector_pop_front(struct Vector *const v, const void **const out) { - int rc = -1; + struct Vector *const v_mut = (struct Vector *const)v; const size_t count = vector_count(v); if (count == 0) { @@ -260,8 +216,8 @@ vector_pop_front(struct Vector *const v, const void **const out) { goto out; } - *out = v->values[v->front_count - 1]; // FIXME: can become negative! - v->front_count--; + v_mut->count--; + *out = v->values[v->count]; rc = 0; out: return rc; diff --git a/src/vector.h b/src/vector.h index cc3c96a..7d83594 100644 --- a/src/vector.h +++ b/src/vector.h @@ -1,29 +1,28 @@ struct Vector; - -int -vector_new(const size_t value_size, struct Vector **out); - int vector_new_with( const size_t capacity, const size_t max_capacity, const size_t multiplier, const size_t value_size, - struct Vector **out + const struct Vector **const out ); +int +vector_new(const size_t value_size, const struct Vector **const out); + void vector_free(const struct Vector *const v); size_t -vector_count(const struct Vector *v); +vector_count(const struct Vector *const v); int vector_nth(const struct Vector *const v, const size_t idx, const void **const out); int -vector_push_back(struct Vector *const v, void *const value); +vector_push_back(const struct Vector *const v, const void *const value); int -vector_pop_back(struct Vector *const v, const void **const out); +vector_pop_back(const struct Vector *const v, const void **const out); -- cgit v1.2.3