From 9d776ddba802e7faab32a0d7ae5a8b57979d4341 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 1 Aug 2020 17:52:40 +0200 Subject: Fixed namings in cstr.h and restruct. in cmap: added cmap_try_emplace() macro. --- stc/clist.h | 2 +- stc/cmap.h | 74 ++++++++++++++++++++++++++++++------------------------------- stc/cstr.h | 24 ++++++++++---------- stc/cvec.h | 2 +- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/stc/clist.h b/stc/clist.h index c27f254c..2ba55c4f 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -65,7 +65,7 @@ #define declare_clist_4(tag, Value, valueDestroy, valueCompare) \ declare_clist_6(tag, Value, valueDestroy, Value, valueCompare, c_default_to_raw) #define declare_clist_str() \ - declare_clist_6(str, cstr_t, cstr_destroy, const char*, cstr_compareRaw, cstr_getRaw) + declare_clist_6(str, cstr_t, cstr_destroy, const char*, cstr_compare_raw, cstr_to_raw) #define declare_clist_types(tag, Value) \ typedef struct clistnode_##tag { \ diff --git a/stc/cmap.h b/stc/cmap.h index 3f416145..555d4c28 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -55,8 +55,12 @@ int main(void) { #define cmap_init {NULL, NULL, 0, 0, 0.85f, 0.15f} #define cmap_size(m) ((size_t) (m).size) -#define cset_init cmap_init -#define cset_size(s) cmap_size(s) +#define cset_init cmap_init +#define cset_size(s) cmap_size(s) +#define cmap_try_emplace(self, tag, k, v) do { \ + struct cmap_##tag##_result __r = cmap_##tag##_insert_key(self, k); \ + if (__r.inserted) __r.entry->value = v; \ +} while (false) /* https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction */ #define chash_reduce(x, N) ((uint32_t) (((uint64_t) (x) * (N)) >> 32)) @@ -98,12 +102,12 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; #define declare_cset_8(tag, Key, keyEqualsRaw, keyHashRaw, keyDestroy, \ RawKey, keyGetRaw, keyInitRaw) \ - declare_CHASH(tag, cset, Key, void, void, keyEqualsRaw, keyHashRaw, \ + declare_CHASH(tag, cset, Key, Key, void, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyGetRaw, keyInitRaw) /* cset_str, cmap_str: */ #define declare_cset_str() \ - declare_CHASH_STR(str, cset, void, void) + declare_CHASH_STR(str, cset, cstr_t, void) #define declare_cmap_str(...) \ c_MACRO_OVERLOAD(declare_cmap_str, __VA_ARGS__) @@ -115,8 +119,8 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; declare_CHASH_STR(tag, cmap, Value, ValueDestroy) #define declare_CHASH_STR(tag, ctype, Value, valueDestroy) \ - declare_CHASH(tag, ctype, cstr_t, Value, valueDestroy, cstr_equalsRaw, cstr_hashRaw, \ - cstr_destroy, const char*, cstr_getRaw, cstr_make) + declare_CHASH(tag, ctype, cstr_t, Value, valueDestroy, cstr_equals_raw, cstr_hash_raw, \ + cstr_destroy, const char*, cstr_to_raw, cstr_make) #define OPT_1_cset(x) #define OPT_2_cset(x, y) x @@ -174,13 +178,10 @@ ctype##_##tag##_set_load_factors(ctype##_##tag* self, float max, float shrink) { } \ STC_API ctype##_##tag##_entry_t* \ ctype##_##tag##_find(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey); \ -STC_FORCE_INLINE ctype##_##tag##_entry_t* /* alias */ \ -ctype##_##tag##_get(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) \ - {return ctype##_##tag##_find(self, rawKey);} \ -STC_API ctype##_##tag##_entry_t* /* similar to c++ std::map.insert_or_assign(): */ \ +STC_API ctype##_##tag##_entry_t* /* like c++ std::map.insert_or_assign(), or operator[]: */ \ ctype##_##tag##_put(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t rawKey, Value value)); \ -OPT_1_##ctype(STC_API ctype##_##tag##_entry_t* /* similar to c++ std::map.operator[](): */ \ -ctype##_##tag##_insert(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Value initValue);) \ +OPT_1_##ctype(STC_API ctype##_##tag##_entry_t* /* like c++ std::map.insert(): */ \ +ctype##_##tag##_insert(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Value value);) \ STC_INLINE void \ ctype##_##tag##_swap(ctype##_##tag* a, ctype##_##tag* b) { c_swap(ctype##_##tag, *a, *b); } \ STC_API size_t \ @@ -260,43 +261,42 @@ ctype##_##tag##_find(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) return self->_hashx[idx] ? &self->table[idx] : NULL; \ } \ \ -static inline void ctype##_##tag##_reserve_expand(ctype##_##tag* self) { \ +STC_INLINE void ctype##_##tag##_reserve_expand(ctype##_##tag* self) { \ if (self->size + 1 >= self->bucket_count * self->max_load_factor) \ ctype##_##tag##_reserve(self, 5 + self->size * 3 / 2); \ } \ \ -STC_API ctype##_##tag##_entry_t* \ -ctype##_##tag##_put(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t rawKey, Value value)) { \ +struct ctype##_##tag##_result {ctype##_##tag##_entry_t *entry; bool inserted;}; \ +STC_INLINE struct ctype##_##tag##_result \ +ctype##_##tag##_insert_key(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \ ctype##_##tag##_reserve_expand(self); \ uint32_t hx; \ size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \ - ctype##_##tag##_entry_t* e = &self->table[idx]; \ - if (self->_hashx[idx]) \ - OPT_1_##ctype(valueDestroy(&e->value)) ; \ - else { \ - e->key = keyInitRaw(rawKey); \ + struct ctype##_##tag##_result res = {&self->table[idx], !self->_hashx[idx]}; \ + if (res.inserted) { \ + res.entry->key = keyInitRaw(rawKey); \ self->_hashx[idx] = (uint8_t) hx; \ ++self->size; \ } \ - OPT_1_##ctype(e->value = value;) \ - return e; \ + return res; \ } \ \ -OPT_1_##ctype( \ STC_API ctype##_##tag##_entry_t* \ -ctype##_##tag##_insert(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Value initValue) { \ - ctype##_##tag##_reserve_expand(self); \ - uint32_t hx; \ - size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \ - ctype##_##tag##_entry_t* e = &self->table[idx]; \ - if (! self->_hashx[idx]) { \ - e->key = keyInitRaw(rawKey); \ - self->_hashx[idx] = (uint8_t) hx; \ - ++self->size; \ - e->value = initValue; \ - } \ - return e; \ -}) \ +ctype##_##tag##_put(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t rawKey, Value value)) { \ + struct ctype##_##tag##_result res = ctype##_##tag##_insert_key(self, rawKey); \ + OPT_1_##ctype( \ + if (!res.inserted) valueDestroy(&res.entry->value); \ + res.entry->value = value; \ + ) \ + return res.entry; \ +} \ + \ +STC_API ctype##_##tag##_entry_t* \ +ctype##_##tag##_insert(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t rawKey, Value value)) { \ + struct ctype##_##tag##_result res = ctype##_##tag##_insert_key(self, rawKey); \ + OPT_1_##ctype( if (res.inserted) res.entry->value = value; ) \ + return res.entry; \ +} \ \ STC_API size_t \ ctype##_##tag##_reserve(ctype##_##tag* self, size_t newcap) { \ @@ -309,8 +309,8 @@ ctype##_##tag##_reserve(ctype##_##tag* self, size_t newcap) { \ self->size, (uint32_t) newcap, \ self->max_load_factor, self->shrink_limit_factor \ }; \ + /* Rehash: */ \ ctype##_##tag##_swap(self, &tmp); \ - \ ctype##_##tag##_entry_t* e = tmp.table, *slot = self->table; \ uint8_t* hashx = self->_hashx; \ uint32_t hx; \ diff --git a/stc/cstr.h b/stc/cstr.h index 35049094..42411980 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -128,7 +128,7 @@ cstr_append(cstr_t* self, const char* str) { return cstr_append_n(self, str, strlen(str)); } STC_INLINE cstr_t* -cstr_appendS(cstr_t* self, cstr_t s) { +cstr_append_s(cstr_t* self, cstr_t s) { return cstr_append_n(self, s.str, cstr_size(s)); } STC_INLINE cstr_t* @@ -165,7 +165,7 @@ cstr_equals(cstr_t s1, const char* str) { return strcmp(s1.str, str) == 0; } STC_INLINE bool -cstr_equalsS(cstr_t s1, cstr_t s2) { +cstr_equals_s(cstr_t s1, cstr_t s2) { return strcmp(s1.str, s2.str) == 0; } STC_INLINE int @@ -173,7 +173,7 @@ cstr_compare(const void* s1, const void* s2) { return strcmp(((const cstr_t*)s1)->str, ((const cstr_t*)s2)->str); } STC_INLINE size_t -cstr_findN(cstr_t s, size_t pos, const char* needle, size_t n) { +cstr_find_n(cstr_t s, size_t pos, const char* needle, size_t n) { char* res = cstr_strnstr(s, pos, needle, n); return res ? res - s.str : cstr_npos; } @@ -183,12 +183,12 @@ cstr_find(cstr_t s, size_t pos, const char* needle) { return res ? res - s.str : cstr_npos; } -/* CVec / cmap API functions: */ +/* cvec/cmap API functions: */ -#define cstr_getRaw(x) ((x)->str) -#define cstr_compareRaw(x, y) strcmp(*(x), *(y)) -#define cstr_equalsRaw(x, y) (strcmp(*(x), *(y)) == 0) -STC_INLINE uint32_t cstr_hashRaw(const char* const* sPtr, size_t ignored) { +#define cstr_to_raw(x) ((x)->str) +#define cstr_compare_raw(x, y) strcmp(*(x), *(y)) +#define cstr_equals_raw(x, y) (strcmp(*(x), *(y)) == 0) +STC_INLINE uint32_t cstr_hash_raw(const char* const* sPtr, size_t ignored) { uint32_t hash = 5381, c; /* djb2 */ const char* tmp = *sPtr; while (c = *tmp++) hash = ((hash << 5) + hash) ^ c; @@ -274,7 +274,7 @@ cstr_append_n(cstr_t* self, const char* str, size_t len) { return self; } -STC_INLINE void _cstr_internalMove(cstr_t* self, size_t pos1, size_t pos2) { +STC_INLINE void _cstr_internal_move(cstr_t* self, size_t pos1, size_t pos2) { if (pos1 == pos2) return; size_t len = cstr_size(*self), newlen = len + pos2 - pos1; @@ -287,17 +287,17 @@ STC_INLINE void _cstr_internalMove(cstr_t* self, size_t pos1, size_t pos2) { STC_API void cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n) { char* xstr = (char *) memcpy(n > c_max_alloca ? malloc(n) : alloca(n), str, n); - _cstr_internalMove(self, pos, pos + n); + _cstr_internal_move(self, pos, pos + n); memcpy(&self->str[pos], xstr, n); if (n > c_max_alloca) free(xstr); } STC_API size_t cstr_replace_n(cstr_t* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2) { - size_t pos2 = cstr_findN(*self, pos, str1, n1); + size_t pos2 = cstr_find_n(*self, pos, str1, n1); if (pos2 == cstr_npos) return cstr_npos; char* xstr2 = (char *) memcpy(n2 > c_max_alloca ? malloc(n2) : alloca(n2), str2, n2); - _cstr_internalMove(self, pos2 + n1, pos2 + n2); + _cstr_internal_move(self, pos2 + n1, pos2 + n2); memcpy(&self->str[pos2], xstr2, n2); if (n2 > c_max_alloca) free(xstr2); return pos2; diff --git a/stc/cvec.h b/stc/cvec.h index c4824353..96d990b4 100644 --- a/stc/cvec.h +++ b/stc/cvec.h @@ -42,7 +42,7 @@ #define declare_cvec_4(tag, Value, valueDestroy, valueCompare) \ declare_cvec_6(tag, Value, valueDestroy, valueCompare, Value, c_default_to_raw) #define declare_cvec_str() \ - declare_cvec_6(str, cstr_t, cstr_destroy, cstr_compareRaw, const char*, cstr_getRaw) + declare_cvec_6(str, cstr_t, cstr_destroy, cstr_compare_raw, const char*, cstr_to_raw) #define declare_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \ -- cgit v1.2.3