|
|
@@ -1 +1,126 @@
|
|
|
#include <ds/vector.h>
|
|
|
+#include <ds/err.h>
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
+extern func_malloc ds_malloc;
|
|
|
+extern func_free ds_free;
|
|
|
+
|
|
|
+struct _ds_vector {
|
|
|
+ int size;
|
|
|
+ int cap;
|
|
|
+ ds_data_t *ptr;
|
|
|
+ func_destroyer destroyer;
|
|
|
+};
|
|
|
+
|
|
|
+ds_vector_t*ds_vector_new(func_destroyer destroyer)
|
|
|
+{
|
|
|
+ ds_vector_t * vec = (ds_vector_t*) ds_malloc(sizeof(ds_vector_t));
|
|
|
+ if (!vec) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ vec->cap = DS_DEF_ARRAY_SIZE;
|
|
|
+ vec->size = 0;
|
|
|
+ vec->ptr = (ds_data_t*)ds_malloc(sizeof(ds_data_t) * vec->cap);
|
|
|
+ if (!vec->ptr) {
|
|
|
+ ds_free(vec);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ memset(vec->ptr, 0, sizeof(ds_data_t) * vec->cap);
|
|
|
+ vec->destroyer = destroyer ? destroyer : ds_cb_default_destroyer;
|
|
|
+
|
|
|
+ return vec;
|
|
|
+}
|
|
|
+
|
|
|
+int ds_vector_append(ds_vector_t * vec, ds_data_t data)
|
|
|
+{
|
|
|
+ if(vec->size >= vec->cap - 1) {
|
|
|
+ int old_cap = vec->cap;
|
|
|
+ vec->cap += DS_DEF_ARRAY_SIZE;
|
|
|
+ ds_data_t *new_ptr = (ds_data_t*) ds_malloc ( sizeof(ds_data_t) * vec->cap);
|
|
|
+ if (!new_ptr){
|
|
|
+ vec->cap = old_cap;
|
|
|
+ return DS_ERR_MEM;
|
|
|
+ }
|
|
|
+ memcpy(new_ptr, vec->ptr, sizeof(ds_data_t) * vec->size);
|
|
|
+ ds_free(vec->ptr);
|
|
|
+ vec->ptr = new_ptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ vec->ptr[vec->size++] = data;
|
|
|
+ return DS_ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int ds_vector_get(ds_vector_t * vec, int pos, ds_data_t *ret)
|
|
|
+{
|
|
|
+ if(!vec || !ret) return DS_ERR_PARAMS;
|
|
|
+ if(pos < 0 || pos >= vec->size) return DS_ERR_PARAMS;
|
|
|
+
|
|
|
+ *ret = vec->ptr[pos];
|
|
|
+ return DS_ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+int ds_vector_set(ds_vector_t * vec, int pos, ds_data_t data)
|
|
|
+{
|
|
|
+ if(!vec) return DS_ERR_MEM;
|
|
|
+ if(pos < 0 || pos >= vec->size) return DS_ERR_MEM;
|
|
|
+
|
|
|
+ if(vec->ptr[pos]) {
|
|
|
+ vec->destroyer(vec->ptr[pos]);
|
|
|
+ }
|
|
|
+
|
|
|
+ vec->ptr[pos] = data;
|
|
|
+ return DS_ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+int ds_vector_poptail(ds_vector_t * vec, ds_data_t *ret)
|
|
|
+{
|
|
|
+ if(!vec || !ret) return DS_ERR_PARAMS;
|
|
|
+ if(vec->size <= 0) return DS_ERR_EMPTY;
|
|
|
+
|
|
|
+ *ret = vec->ptr[vec->size--];
|
|
|
+ return DS_ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+void ds_vector_destroy(ds_vector_t * vec)
|
|
|
+{
|
|
|
+ if (!vec) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // release userdata
|
|
|
+ for(int i = 0; i < vec->size; i++) {
|
|
|
+ if ( vec->ptr[i]) {
|
|
|
+ vec->destroyer(vec->ptr[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ds_free(vec->ptr);
|
|
|
+ ds_free(vec);
|
|
|
+}
|
|
|
+
|
|
|
+void ds_vector_foreach(ds_vector_t * vec, func_each fn)
|
|
|
+{
|
|
|
+ if(!vec || !fn) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int i = 0; i < vec->size; i++) {
|
|
|
+ if(fn) {
|
|
|
+ if(!fn(vec->ptr[i])) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline int ds_vector_size(ds_vector_t * vec)
|
|
|
+{
|
|
|
+ return vec->size;
|
|
|
+}
|
|
|
+
|
|
|
+inline int ds_vector_cap(ds_vector_t * vec)
|
|
|
+{
|
|
|
+ return vec->cap;
|
|
|
+}
|