From 900295256d825fc323149cd223c49787f32a3696 Mon Sep 17 00:00:00 2001 From: tylov Date: Thu, 20 Jul 2023 15:09:10 +0200 Subject: Moved examples to sub-directories. Added cotask1.c cotask2.c examples. --- misc/examples/hashmaps/vikings.c | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 misc/examples/hashmaps/vikings.c (limited to 'misc/examples/hashmaps/vikings.c') diff --git a/misc/examples/hashmaps/vikings.c b/misc/examples/hashmaps/vikings.c new file mode 100644 index 00000000..d6125854 --- /dev/null +++ b/misc/examples/hashmaps/vikings.c @@ -0,0 +1,59 @@ +#define i_implement +#include + +typedef struct Viking { + cstr name; + cstr country; +} Viking; + +void Viking_drop(Viking* vk) { + cstr_drop(&vk->name); + cstr_drop(&vk->country); +} + +// Define Viking lookup struct with hash, cmp, and convertion functions between Viking and RViking structs: + +typedef struct RViking { + const char* name; + const char* country; +} RViking; + +static inline int RViking_cmp(const RViking* rx, const RViking* ry) { + int c = strcmp(rx->name, ry->name); + return c ? c : strcmp(rx->country, ry->country); +} + +static inline Viking Viking_from(RViking raw) { // note: parameter is by value + return c_LITERAL(Viking){cstr_from(raw.name), cstr_from(raw.country)}; +} + +static inline RViking Viking_toraw(const Viking* vp) { + return c_LITERAL(RViking){cstr_str(&vp->name), cstr_str(&vp->country)}; +} + +// With this in place, we define the Viking => int hash map type: +#define i_type Vikings +#define i_keyclass Viking // key type +#define i_rawclass RViking // lookup type +#define i_keyfrom Viking_from +#define i_opt c_no_clone +#define i_hash(rp) cstrhash(rp->name) ^ cstrhash(rp->country) +#define i_val int // mapped type +#include + +int main(void) +{ + Vikings vikings = {0}; + Vikings_emplace(&vikings, c_LITERAL(RViking){"Einar", "Norway"}, 20); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Olaf", "Denmark"}, 24); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Harald", "Iceland"}, 12); + Vikings_emplace(&vikings, c_LITERAL(RViking){"Björn", "Sweden"}, 10); + + Vikings_value* v = Vikings_get_mut(&vikings, c_LITERAL(RViking){"Einar", "Norway"}); + v->second += 3; // add 3 hp points to Einar + + c_forpair (vk, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", cstr_str(&_.vk->name), cstr_str(&_.vk->country), *_.hp); + } + Vikings_drop(&vikings); +} -- cgit v1.2.3 From 493c34e9c2de0587f38681340db8f2735e72d7dd Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 5 Sep 2023 18:10:14 +0200 Subject: Renamed (half)internal functions: cfasthash() => stc_hash() cstrhash() => stc_strhash() cnextpow2() => stc_nextpow2() --- docs/cmap_api.md | 15 ++++++++------- docs/cstr_api.md | 5 +++-- include/stc/ccommon.h | 16 ++++++++-------- include/stc/cmap.h | 2 +- include/stc/crawstr.h | 4 ++-- include/stc/cstr.h | 6 +++--- include/stc/csview.h | 6 +++--- include/stc/priv/cqueue_imp.h | 2 +- misc/examples/hashmaps/vikings.c | 2 +- 9 files changed, 30 insertions(+), 28 deletions(-) (limited to 'misc/examples/hashmaps/vikings.c') diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 0fbd9b7a..8e29efe1 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -72,7 +72,7 @@ cmap_X_result cmap_X_push(cmap_X* self, cmap_X_value entry); cmap_X_result cmap_X_emplace(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // no change if rkey in map cmap_X_result cmap_X_emplace_or_assign(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // always update mapped -cmap_X_result cmap_X_emplace_key(cmap_X* self, i_keyraw rkey); // see example 1. +cmap_X_result cmap_X_emplace_key(cmap_X* self, i_keyraw rkey); // see example 1. int cmap_X_erase(cmap_X* self, i_keyraw rkey); // return 0 or 1 cmap_X_iter cmap_X_erase_at(cmap_X* self, cmap_X_iter it); // return iter after it @@ -86,13 +86,14 @@ cmap_X_iter cmap_X_advance(cmap_X_iter it, cmap_X_ssize n); cmap_X_value cmap_X_value_clone(cmap_X_value val); cmap_X_raw cmap_X_value_toraw(cmap_X_value* pval); ``` -Helpers: +Free helper functions: ```c -uint64_t cbytehash(const void *data, intptr_t len); // base hash function -uint64_t cstrhash(const char *str); // string hash funcion, uses strlen() -uint64_t c_default_hash(const X *obj); // macro, calls cbytehash(obj, sizeof *obj) +uint64_t stc_hash(const void *data, intptr_t len); // base hash function +uint64_t stc_strhash(const char *str); // string hash funcion, uses strlen() +uint64_t stc_nextpow2(intptr_t i); // get next power of 2 >= i -// equalto template parameter functions: +// hash/equal template default functions: +uint64_t c_default_hash(const X *obj); // macro, calls stc_hash(obj, sizeof *obj) bool c_default_eq(const i_keyraw* a, const i_keyraw* b); // *a == *b bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // !memcmp(a, b, sizeof *a) ``` @@ -381,7 +382,7 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_keyraw RViking #define i_keyfrom Viking_from #define i_opt c_no_clone // disable map cloning -#define i_hash(rp) (cstrhash(rp->name) ^ cstrhash(rp->country)) +#define i_hash(rp) (stc_strhash(rp->name) ^ stc_strhash(rp->country)) #define i_val int #include diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 397634ec..69512a9e 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -142,8 +142,9 @@ Note that all methods with arguments `(..., const char* str, intptr_t n)`, `n` m ```c int cstr_cmp(const cstr* s1, const cstr* s2); bool cstr_eq(const cstr* s1, const cstr* s2); -bool cstr_hash(const cstr* self); -char* cstrnstrn(const char* str, const char* search, intptr_t slen, intptr_t nlen); +uint64_t cstr_hash(const cstr* self); + +char* stc_strnstrn(const char* str, const char* search, intptr_t slen, intptr_t nlen); ``` ## Types diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 8363fbe5..d074701f 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -103,7 +103,7 @@ typedef long long _llong; #define c_default_less(x, y) (*(x) < *(y)) #define c_default_eq(x, y) (*(x) == *(y)) #define c_memcmp_eq(x, y) (memcmp(x, y, sizeof *(x)) == 0) -#define c_default_hash(x) cbytehash(x, c_sizeof(*(x))) +#define c_default_hash(x) stc_hash(x, c_sizeof(*(x))) #define c_default_clone(v) (v) #define c_default_toraw(vp) (*(vp)) @@ -124,7 +124,7 @@ typedef long long _llong; // Non-owning c-string "class" typedef const char* ccharptr; #define ccharptr_cmp(xp, yp) strcmp(*(xp), *(yp)) -#define ccharptr_hash(p) cstrhash(*(p)) +#define ccharptr_hash(p) stc_strhash(*(p)) #define ccharptr_clone(s) (s) #define ccharptr_drop(p) ((void)p) @@ -138,7 +138,7 @@ typedef const char* ccharptr; #define c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k))) -STC_INLINE uint64_t cbytehash(const void* key, intptr_t len) { +STC_INLINE uint64_t stc_hash(const void* key, intptr_t len) { uint32_t u4; uint64_t u8; switch (len) { case 8: memcpy(&u8, key, 8); return u8*0xc6a4a7935bd1e99d; @@ -156,11 +156,11 @@ STC_INLINE uint64_t cbytehash(const void* key, intptr_t len) { return h ^ c_ROTL(h, 26); } -STC_INLINE uint64_t cstrhash(const char *str) - { return cbytehash(str, c_strlen(str)); } +STC_INLINE uint64_t stc_strhash(const char *str) + { return stc_hash(str, c_strlen(str)); } -STC_INLINE char* cstrnstrn(const char *str, const char *needle, - intptr_t slen, const intptr_t nlen) { +STC_INLINE char* stc_strnstrn(const char *str, const char *needle, + intptr_t slen, const intptr_t nlen) { if (!nlen) return (char *)str; if (nlen > slen) return NULL; slen -= nlen; @@ -172,7 +172,7 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, return NULL; } -STC_INLINE intptr_t cnextpow2(intptr_t n) { +STC_INLINE intptr_t stc_nextpow2(intptr_t n) { n--; n |= n >> 1, n |= n >> 2; n |= n >> 4, n |= n >> 8; diff --git a/include/stc/cmap.h b/include/stc/cmap.h index deee1f59..c069fbd8 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -414,7 +414,7 @@ _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t _newcap) { if (_newcap != self->size && _newcap <= _oldbucks) return true; intptr_t _newbucks = (intptr_t)((float)_newcap / (i_max_load_factor)) + 4; - _newbucks = cnextpow2(_newbucks); + _newbucks = stc_nextpow2(_newbucks); _cx_Self m = { (_cx_value *)i_malloc(_newbucks*c_sizeof(_cx_value)), (struct chash_slot *)i_calloc(_newbucks + 1, c_sizeof(struct chash_slot)), diff --git a/include/stc/crawstr.h b/include/stc/crawstr.h index a244397d..9dbdb6f7 100644 --- a/include/stc/crawstr.h +++ b/include/stc/crawstr.h @@ -45,7 +45,7 @@ STC_INLINE bool crawstr_equals(crawstr rs, const char* str) { } STC_INLINE intptr_t crawstr_find(crawstr rs, const char* search) { - char* res = cstrnstrn(rs.str, search, rs.size, c_strlen(search)); + char* res = strstr(rs.str, search); return res ? (res - rs.str) : c_NPOS; } @@ -98,7 +98,7 @@ STC_INLINE bool crawstr_eq(const crawstr* x, const crawstr* y) { return x->size == y->size && !c_memcmp(x->str, y->str, x->size); } STC_INLINE uint64_t crawstr_hash(const crawstr *self) - { return cbytehash(self->str, self->size); } + { return stc_hash(self->str, self->size); } #endif // CRAWSTR_H_INCLUDED #undef i_static diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 51519d82..d2faeb62 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -450,12 +450,12 @@ bool cstr_valid_utf8(const cstr* self) STC_DEF uint64_t cstr_hash(const cstr *self) { csview sv = cstr_sv(self); - return cbytehash(sv.buf, sv.size); + return stc_hash(sv.buf, sv.size); } STC_DEF intptr_t cstr_find_sv(const cstr* self, csview search) { csview sv = cstr_sv(self); - char* res = cstrnstrn(sv.buf, search.buf, sv.size, search.size); + char* res = stc_strnstrn(sv.buf, search.buf, sv.size, search.size); return res ? (res - sv.buf) : c_NPOS; } @@ -588,7 +588,7 @@ STC_DEF cstr cstr_replace_sv(csview in, csview search, csview repl, int32_t coun intptr_t from = 0; char* res; if (!count) count = INT32_MAX; if (search.size) - while (count-- && (res = cstrnstrn(in.buf + from, search.buf, in.size - from, search.size))) { + while (count-- && (res = stc_strnstrn(in.buf + from, search.buf, in.size - from, search.size))) { const intptr_t pos = (res - in.buf); cstr_append_n(&out, in.buf + from, pos - from); cstr_append_n(&out, repl.buf, repl.size); diff --git a/include/stc/csview.h b/include/stc/csview.h index 005f27de..f41acf4f 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -165,12 +165,12 @@ STC_DEF csview_iter csview_advance(csview_iter it, intptr_t pos) { } STC_DEF intptr_t csview_find_sv(csview sv, csview search) { - char* res = cstrnstrn(sv.buf, search.buf, sv.size, search.size); + char* res = stc_strnstrn(sv.buf, search.buf, sv.size, search.size); return res ? (res - sv.buf) : c_NPOS; } STC_DEF uint64_t csview_hash(const csview *self) - { return cbytehash(self->buf, self->size); } + { return stc_hash(self->buf, self->size); } STC_DEF csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n) { if (pos < 0) { @@ -197,7 +197,7 @@ STC_DEF csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2) { STC_DEF csview csview_token(csview sv, const char* sep, intptr_t* start) { intptr_t sep_size = c_strlen(sep); csview slice = {sv.buf + *start, sv.size - *start}; - const char* res = cstrnstrn(slice.buf, sep, slice.size, sep_size); + const char* res = stc_strnstrn(slice.buf, sep, slice.size, sep_size); csview tok = {slice.buf, res ? (res - slice.buf) : slice.size}; *start += tok.size + sep_size; return tok; diff --git a/include/stc/priv/cqueue_imp.h b/include/stc/priv/cqueue_imp.h index 2ad9c811..18c1bb15 100644 --- a/include/stc/priv/cqueue_imp.h +++ b/include/stc/priv/cqueue_imp.h @@ -54,7 +54,7 @@ STC_DEF bool _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t n) { if (n <= self->capmask) return true; - intptr_t oldcap = self->capmask + 1, newcap = cnextpow2(n + 1); + intptr_t oldcap = self->capmask + 1, newcap = stc_nextpow2(n + 1); _cx_value* d = (_cx_value *)i_realloc(self->data, newcap*c_sizeof *self->data); if (!d) return false; diff --git a/misc/examples/hashmaps/vikings.c b/misc/examples/hashmaps/vikings.c index d6125854..cef17a04 100644 --- a/misc/examples/hashmaps/vikings.c +++ b/misc/examples/hashmaps/vikings.c @@ -37,7 +37,7 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_rawclass RViking // lookup type #define i_keyfrom Viking_from #define i_opt c_no_clone -#define i_hash(rp) cstrhash(rp->name) ^ cstrhash(rp->country) +#define i_hash(rp) stc_strhash(rp->name) ^ stc_strhash(rp->country) #define i_val int // mapped type #include -- cgit v1.2.3