summaryrefslogtreecommitdiff
path: root/src/vector.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vector.c')
-rw-r--r--src/vector.c130
1 files changed, 43 insertions, 87 deletions
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;