Kaynağa Gözat

[lib.h] Adding a genery dynamic array lib

Vinicius Teshima 4 ay önce
ebeveyn
işleme
5f4cf0b06f
1 değiştirilmiş dosya ile 171 ekleme ve 1 silme
  1. 171 1
      src/lib.h

+ 171 - 1
src/lib.h

@@ -49,6 +49,7 @@ enum err {
     ERR_TOO_BIG,
     ERR_NULL_ARG,
     ERR_NOT_FOUND,
+    ERR_INDEX_TOO_LARGE,
     ERR_FAILED_OPEN,
     ERR_FAILED_CLOSE,
     ERR_FAILED_READ,
@@ -69,6 +70,7 @@ const char *err_to_name[] = {
     "ERR_TOO_BIG",
     "ERR_NULL_ARG",
     "ERR_NOT_FOUND",
+    "ERR_INDEX_TOO_LARGE",
     "ERR_FAILED_OPEN",
     "ERR_FAILED_CLOSE",
     "ERR_FAILED_READ",
@@ -101,6 +103,12 @@ typedef unsigned char u8;
 
 /* ------------------------------ END INT DEF ------------------------------ */
 
+void *malloc(u64 size);
+void *realloc(void *ptr, u64 new_size);
+void free(void *ptr);
+void *memcpy(void *dest, const void *src, u64 n);
+void *memset(void *s, int c, u64 n);
+
 /* ----------------------------- START LIB DEF ----------------------------- */
 
 # define LIB_SET_IF_NOT_NULL(var, err) \
@@ -249,13 +257,175 @@ struct str str_builder_to_str(const struct str_builder *str_bldr);
 # if defined(WANT_DYN_ARR) || defined(WANT_ALL)
 
 struct dyn_arr {
-    
+    void *data;
+    u64   size;
+    u64   cap;
+    u16   elem_size;
 };
 
+struct dyn_arr dyn_arr_create(u16 elem_size, enum err *out_err);
+
+enum err dyn_arr_append(struct dyn_arr *da, void *elem, enum err *out_err);
+enum err dyn_arr_prepend(struct dyn_arr *da, void *elem, enum err *out_err);
+enum err dyn_arr_insert(struct dyn_arr *da, void *elem, u64 index,
+                        enum err *out_err);
+void *dyn_arr_pop(struct dyn_arr *da, u64 index, enum err *out_err);
+void *dyn_arr_pop_last(struct dyn_arr *da, enum err *out_err);
+
+enum err dyn_arr_destroy(struct dyn_arr *da, enum err *out_err);
+
 
 #  if defined(IMP) || defined(IMP_STR)
 
+struct dyn_arr
+dyn_arr_create(u16 elem_size, enum err *out_err)
+{
+    struct dyn_arr empty = {0};
+    struct dyn_arr da = {0};
+
+    LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
+
+    da.size = 0;
+    da.cap  = 64;
+    da.elem_size = elem_size;
+    da.data = malloc(da.elem_size * da.cap);
+    if ( da.data == NULL ) {
+        LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
+        return empty;
+    }
+    memset(da.data, 0, elem_size * da.cap);
+
+
+    LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
+    return da;
+}
+
+enum err
+dyn_arr_insert(struct dyn_arr *da, void *elem, u64 index, enum err *out_err)
+{
+    u64 new_size = 0;
+    u64 i = 0;
+    u8 *data = NULL;
+
+    LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
+
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da,       out_err);
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
+
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem,     out_err);
+
+    new_size = da->size + 1;
+    if ( index >= new_size ) {
+        LIB_SET_IF_NOT_NULL(out_err, ERR_INDEX_TOO_LARGE);
+        return ERR_INDEX_TOO_LARGE;
+    }
+
+    if ( new_size >= da->cap ) {
+        da->cap *= 2;
+        da->data = realloc(da->data, da->cap);
+        if ( da->data == NULL ) {
+            LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
+            return ERR_FAILED_ALLOC;
+        }
+    }
+
+    data = (u8*) da->data;
+
+    if ( da->size > 0 ) {
+        for ( i = da->size-1; i > index; i-- ) {
+            memcpy((data + i), (data + i - 1), da->elem_size);
+        }
+    }
+
+    memcpy((data + index), elem, da->elem_size);
+
+    ++da->size;
+
+    LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
+    return ERR_OK;
+}
+
+enum err
+dyn_arr_append(struct dyn_arr *da, void *elem, enum err *out_err)
+{
+    LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
+
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da,       out_err);
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
 
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem,     out_err);
+
+    return dyn_arr_insert(da, elem, da->size, out_err);
+}
+
+enum err
+dyn_arr_prepend(struct dyn_arr *da, void *elem, enum err *out_err)
+{
+    LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
+
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da,       out_err);
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
+
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem,     out_err);
+
+    return dyn_arr_insert(da, elem, 0, out_err);
+}
+
+void *
+dyn_arr_pop(struct dyn_arr *da, u64 index, enum err *out_err)
+{
+    static u8 temp_mem[256] = {0};
+    u8 *data = NULL;
+    u64 i = 0;
+
+    LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
+
+    LIB_ARG_MUST_NOT_BE_NULL(da,       out_err, NULL);
+    LIB_ARG_MUST_NOT_BE_NULL(da->data, out_err, NULL);
+
+    if ( index >= da->size ) {
+        LIB_SET_IF_NOT_NULL(out_err, ERR_INDEX_TOO_LARGE);
+        return NULL;
+    }
+
+    data = (u8*) da->data;
+
+    memcpy(temp_mem, (data + index), da->elem_size);
+
+    for ( i = index; i < da->size-1; ++i ) {
+        memcpy((data + i), (data + i + 1), da->elem_size);
+    }
+
+    --da->size;
+
+    LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
+    return temp_mem;
+}
+
+void *
+dyn_arr_pop_last(struct dyn_arr *da, enum err *out_err)
+{
+    LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
+
+    LIB_ARG_MUST_NOT_BE_NULL(da,       out_err, NULL);
+    LIB_ARG_MUST_NOT_BE_NULL(da->data, out_err, NULL);
+
+    return dyn_arr_pop(da, da->size-1, out_err);
+}
+
+enum err
+dyn_arr_destroy(struct dyn_arr *da, enum err *out_err)
+{
+    LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
+
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da,       out_err);
+    LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
+
+    free(da->data);
+
+    LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
+    return ERR_OK;
+}
 
 #  endif /* defined(IMP) || defined(IMP_STR) */