summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/osm/utils.h20
-rw-r--r--src/vector.c115
2 files changed, 127 insertions, 8 deletions
diff --git a/include/osm/utils.h b/include/osm/utils.h
index 5a53f41..441cce2 100644
--- a/include/osm/utils.h
+++ b/include/osm/utils.h
@@ -1,6 +1,8 @@
#ifndef OSM_UTILS_H
#define OSM_UTILS_H
+#include <stdbool.h>
+
// Vector utilities
/**
@@ -11,27 +13,30 @@ typedef struct {
void *data;
} Vector;
+/**
+ * Get an initialized vector struct
+ */
Vector vect_init(unsigned int elsz);
/**
* Add an element to an arbitrary index in the vector
*/
-void vect_add(Vector *vec, unsigned int index);
+bool vect_add(Vector *vec, unsigned int index, void *el);
/**
* Remove an element from an arbitrary index in the vector
*/
-void vect_remove(Vector *vec, unsigned int index);
+bool vect_remove(Vector *vec, unsigned int index);
/**
* Push an element to the end of the vector
*/
-void vect_push(Vector *vec, void *el);
+bool vect_push(Vector *vec, void *el);
/**
* Pop an element from the end of the vector
*/
-void vect_pop(Vector *vec);
+bool vect_pop(Vector *vec);
/**
* Get an element from the vector
@@ -41,7 +46,12 @@ void *vect_get(Vector *vec, unsigned int index);
/**
* Set an element inside the vector
*/
-void *vect_set(Vector *vec, unsigned int index, void *el);
+bool vect_set(Vector *vec, unsigned int index, void *el);
+
+/**
+ * Clear all data in a vector
+ */
+void vect_clear(Vector *vec);
/**
* Remove all associated data from the vector
diff --git a/src/vector.c b/src/vector.c
index 72b2a4f..33e3e85 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -55,7 +55,7 @@ void _vect_grow(Vector *vec)
*/
void _vect_shrink(Vector *vec)
{
- if (vec->size == 1)
+ if (vec->size / 2 < VECT_INIT_CAP)
{
return;
}
@@ -66,9 +66,13 @@ void _vect_shrink(Vector *vec)
/**
* Push a new element to the end of the vector
+ * Returns false if the vector was invalid
*/
-void vect_push(Vector *vec, void *el)
+bool vect_push(Vector *vec, void *el)
{
+ if (vec->elsz == 0 || vec->size == 0)
+ return false;
+
memcpy(vec->data + (vec->count * vec->elsz), el, vec->elsz);
vec->count++;
@@ -76,21 +80,124 @@ void vect_push(Vector *vec, void *el)
{
_vect_grow(vec);
}
+
+ return true;
}
/**
* Pop an element off of the end of the vector
+ * Returns true if an element was removed, false if there was no element to remove.
*/
-void vect_pop(Vector *vec)
+bool vect_pop(Vector *vec)
{
+ if (vec->count < 1)
+ return false;
+
vec->count--;
if (vec->count < vec->size / 3)
{
_vect_shrink(vec);
}
+
+ return true;
+}
+
+/**
+ * Get an element from the vector
+ * Returns NULL if the index is invalid
+ */
+void *vect_get(Vector *vec, unsigned int index)
+{
+ if (index >= vec->count)
+ return NULL;
+
+ return vec->data + (index * vec->elsz);
+}
+
+/**
+ * Set an element in the vector
+ * If the index is outside the vector, returns false.
+ */
+bool vect_set(Vector *vec, unsigned int index, void *el)
+{
+ if (index >= vec->count)
+ return false;
+
+ memcpy(vec->data + (index * vec->elsz), el, vec->elsz);
+ return true;
+}
+
+/**
+ * Remove an element from the given position in the vector
+ * Returns false if the index was invalid
+ * O(n)
+ */
+bool vect_remove(Vector *vec, unsigned int index)
+{
+ if (index >= vec->count)
+ return false;
+
+ if (index == vec->count - 1)
+ {
+ return vect_pop(vec);
+ }
+
+ char *curr = vec->data + (vec->elsz * index);
+ char *next = vec->data + (vec->elsz * (index + 1));
+
+ for(int i = 0; i < vec->elsz * (vec->count - (index + 1)); i++)
+ {
+ *(curr + i) = *(next + i);
+ }
+
+ return vect_pop(vec);
+}
+
+/**
+ * Add an element into the vector
+ * Returns false if the index is invalid
+ * O(n)
+ */
+bool vect_insert(Vector *vec, unsigned int index, void *el)
+{
+ if (index > vec->count)
+ return false;
+
+ if (index == vec->count)
+ return vect_push(vec, el);
+
+ char *curr = vec->data + (vec->elsz * index);
+ char *next = vec->data + (vec->elsz * (index + 1));
+
+ for (int i = vec->elsz * (vec->count - (index + 1)); i > 0; i--)
+ {
+ *(next + i - 1) = *(curr + i - 1);
+ }
+
+ vec->count++;
+
+ if (vec->size == vec->count)
+ {
+ _vect_grow(vec);
+ }
+
+ return true;
+}
+
+/**
+ * Clear all data from the vector
+ */
+void vect_clear(Vector *vec)
+{
+ int elsz = vec->elsz;
+ vect_end(vec);
+ *vec = vect_init(elsz);
}
+/**
+ * Free associated data of the vector
+ */
void vect_end(Vector *vec)
{
vec->size = 0;
@@ -99,3 +206,5 @@ void vect_end(Vector *vec)
free(vec->data);
vec->data = NULL;
}
+
+