diff --git a/src/guf_dict.h b/src/guf_dict.h index d9dae4e..134477c 100755 --- a/src/guf_dict.h +++ b/src/guf_dict.h @@ -127,6 +127,8 @@ GUF_DICT_KWRDS GUF_DICT_NAME *GUF_CAT(GUF_DICT_NAME, _try_init)(GUF_DICT_NAME *h GUF_DICT_KWRDS GUF_DICT_NAME *GUF_CAT(GUF_DICT_NAME, _init)(GUF_DICT_NAME *ht, guf_allocator *alloc); GUF_DICT_KWRDS void GUF_CAT(GUF_DICT_NAME, _free)(GUF_DICT_NAME *ht, void *ctx); +GUF_DICT_KWRDS GUF_DICT_NAME *GUF_CAT(GUF_DICT_NAME, _copy)(GUF_DICT_NAME *dst, const GUF_DICT_NAME *src, void *ctx); +GUF_DICT_KWRDS GUF_DICT_NAME *GUF_CAT(GUF_DICT_NAME, _move)(GUF_DICT_NAME *dst, GUF_DICT_NAME *src, void *ctx); GUF_DICT_KWRDS void GUF_CAT(GUF_DICT_NAME, _try_insert)(GUF_DICT_NAME *ht, GUF_DICT_KEY_T *key, GUF_DICT_VAL_T *val, guf_cpy_opt key_opt, guf_cpy_opt val_opt, guf_err *err); GUF_DICT_KWRDS void GUF_CAT(GUF_DICT_NAME, _insert)(GUF_DICT_NAME *ht, GUF_DICT_KEY_T *key, GUF_DICT_VAL_T *val, guf_cpy_opt key_opt, guf_cpy_opt val_opt); @@ -173,10 +175,10 @@ GUF_DICT_KWRDS size_t GUF_CAT(GUF_DICT_NAME, _memory_usage)(const GUF_DICT_NAME GUF_DICT_KWRDS bool GUF_CAT(GUF_DICT_NAME, _valid)(const GUF_DICT_NAME *ht); GUF_DICT_KWRDS bool GUF_CAT(GUF_DICT_NAME, _debug_valid_size)(const GUF_DICT_NAME *ht); - // #define GUF_DICT_IMPL /* DEBUGGGGGGGGG */ #if defined(GUF_DICT_IMPL) || defined(GUF_DICT_IMPL_STATIC) +#include #include "guf_assert.h" #include "guf_math.h" @@ -282,8 +284,6 @@ GUF_DICT_KWRDS size_t GUF_CAT(GUF_DICT_NAME, _memory_usage)(const GUF_DICT_NAME return mem_kv_indices + mem_kv_elems; } - - GUF_DICT_KWRDS void GUF_CAT(GUF_DICT_NAME, _free)(GUF_DICT_NAME *ht, void *ctx) { (void)ctx; @@ -302,6 +302,69 @@ GUF_DICT_KWRDS void GUF_CAT(GUF_DICT_NAME, _free)(GUF_DICT_NAME *ht, void *ctx) ht->max_probelen = 0; } +GUF_DICT_KWRDS GUF_DICT_NAME *GUF_CAT(GUF_DICT_NAME, _copy)(GUF_DICT_NAME *dst, const GUF_DICT_NAME *src, void *ctx) +{ + (void)ctx; + GUF_ASSERT_RELEASE(dst); + GUF_ASSERT_RELEASE(GUF_CAT(GUF_DICT_NAME, _valid)(src)); + GUF_ASSERT_RELEASE(dst != src); + + dst->kv_indices = NULL; + dst->kv_indices_cap = dst->max_probelen = dst->num_tombstones = 0; + dst->kv_elems.allocator = NULL; + dst->kv_elems.data = NULL; + dst->kv_elems.capacity = dst->kv_elems.size = 0; + + GUF_DICT_KV_DBUF *kv_elems_cpy = GUF_CAT(GUF_DICT_KV_DBUF, _copy)(&dst->kv_elems, &src->kv_elems, NULL); + if (!kv_elems_cpy) { + return NULL; + } + + if (src->kv_indices) { + GUF_ASSERT(src->kv_indices_cap > 0); + const ptrdiff_t num_bytes = src->kv_indices_cap * sizeof(src->kv_indices[0]); + dst->kv_indices = src->kv_elems.allocator->alloc(num_bytes, src->kv_elems.allocator->ctx); + if (!dst->kv_indices) { + GUF_CAT(GUF_DICT_KV_DBUF, _free)(&dst->kv_elems, NULL); + return NULL; + } + memcpy(dst->kv_indices, src->kv_indices, num_bytes); + dst->kv_indices_cap = src->kv_indices_cap; + } else { + dst->kv_indices = NULL; + } + + dst->max_probelen = src->max_probelen; + dst->num_tombstones = src->num_tombstones; + + GUF_ASSERT(dst->kv_elems.size == src->kv_elems.size && dst->kv_elems.capacity == src->kv_elems.capacity && dst->kv_elems.allocator == src->kv_elems.allocator); + GUF_ASSERT(dst->kv_indices_cap == src->kv_indices_cap); + return dst; +} + +GUF_DICT_KWRDS GUF_DICT_NAME *GUF_CAT(GUF_DICT_NAME, _move)(GUF_DICT_NAME *dst, GUF_DICT_NAME *src, void *ctx) +{ + (void)ctx; + GUF_ASSERT_RELEASE(dst); + GUF_ASSERT_RELEASE(GUF_CAT(GUF_DICT_NAME, _valid)(src)); + GUF_ASSERT_RELEASE(dst != src); + + dst->kv_elems = src->kv_elems; + dst->kv_indices = src->kv_indices; + dst->kv_indices_cap = src->kv_indices_cap; + dst->max_probelen = src->max_probelen; + dst->num_tombstones = src->num_tombstones; + + src->kv_indices = NULL; + src->kv_indices_cap = src->max_probelen = src->num_tombstones = 0; + + src->kv_elems.allocator = NULL; + src->kv_elems.data = NULL; + src->kv_elems.capacity = src->kv_elems.size = 0; + + return dst; +} + GUF_DICT_KWRDS ptrdiff_t GUF_CAT(GUF_DICT_NAME, _size)(const GUF_DICT_NAME *ht) { GUF_ASSERT_RELEASE(GUF_CAT(GUF_DICT_NAME, _valid)(ht)); diff --git a/src/guf_str.h b/src/guf_str.h index 06fa039..1198515 100644 --- a/src/guf_str.h +++ b/src/guf_str.h @@ -87,6 +87,8 @@ GUF_STR_KWRDS guf_str guf_str_try_new(guf_str_view str_view, guf_allocator *allo GUF_STR_KWRDS guf_str guf_str_new(guf_str_view str_view, guf_allocator *alloc); GUF_STR_KWRDS void guf_str_free(guf_str *str, void *ctx); +GUF_STR_KWRDS guf_str *guf_str_copy(guf_str *dst, const guf_str *src, void *ctx); +GUF_STR_KWRDS guf_str *guf_str_move(guf_str *dst, guf_str *src, void *ctx); // TODO: GUF_STR_KWRDS guf_str guf_str_try_new_substr(guf_str_view str_view, ptrdiff_t pos, ptrdiff_t len, guf_allocator *alloc, guf_err *err); @@ -550,6 +552,53 @@ GUF_STR_KWRDS void guf_str_free(guf_str *str, void *ctx) } } +GUF_STR_KWRDS guf_str *guf_str_copy(guf_str *dst, const guf_str *src, void *ctx) +{ + (void)ctx; + GUF_ASSERT_RELEASE(dst); + GUF_ASSERT_RELEASE(guf_str_is_valid(src)); + + guf_str_init_empty(dst, src->allocator); + GUF_ASSERT(guf_str_is_short_internal_(dst)); + + if (!guf_str_is_short_internal_(src)) { + const size_t src_cap_with_null = guf_str_cap_internal_(src) + 1; + char *dst_cstr = src->allocator->alloc(src_cap_with_null, src->allocator->ctx); + if (!dst_cstr) { + *dst = guf_str_new_uninitialised(); + return NULL; + } + dst->data.lng.c_str = dst_cstr; + dst->data.lng.capacity = src->data.lng.capacity; + dst->data.lng.size = src->data.lng.size; + } else { + dst->data.shrt.size = src->data.shrt.size; + } + + const size_t src_len_with_null = guf_str_len_internal_(src) + 1; + GUF_ASSERT(src_len_with_null == (guf_str_len_internal_(dst) + 1)); + GUF_ASSERT(guf_str_is_short(dst) == guf_str_is_short(src)); + + const char *src_cstr = guf_str_const_cstr(src); + char *dst_cstr = guf_str_cstr(dst); + GUF_ASSERT(src_cstr && dst_cstr); + memcpy(dst_cstr, src_cstr, src_len_with_null); + + GUF_ASSERT(guf_str_is_valid(dst)); + return dst; +} + +GUF_STR_KWRDS guf_str *guf_str_move(guf_str *dst, guf_str *src, void *ctx) +{ + (void)ctx; + GUF_ASSERT_RELEASE(dst); + GUF_ASSERT_RELEASE(guf_str_is_valid(src)); + *dst = *src; + *src = guf_str_new_uninitialised(); + return dst; +} + + GUF_STR_KWRDS guf_str *guf_str_try_append_char(guf_str *str, char c, ptrdiff_t times, guf_err *err)