From 959eab1e1f590ba4e5b521f106ae48ff2e493421 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 13 Oct 2021 23:22:19 +0200 Subject: Maintenance update. template.h now includes cstr.h when i_key_str or i_val_str is defined. Minor optimizations. --- docs/cmap_api.md | 84 +++++++++++++++++++++++++------------------------- examples/new_map.c | 48 +++++++++++++++++------------ include/stc/cdeq.h | 2 +- include/stc/cpque.h | 22 ++++++------- include/stc/cstack.h | 7 +++-- include/stc/cvec.h | 6 ++-- include/stc/template.h | 4 +++ 7 files changed, 91 insertions(+), 82 deletions(-) diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 0146ff49..31dd3f63 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -123,28 +123,27 @@ void c_default_del(Type* val); // d int main() { // Create an unordered_map of three strings (that map to strings) - cmap_str u = cmap_str_init(); - c_apply_pair(cmap_str, emplace, &u, { - {"RED", "#FF0000"}, - {"GREEN", "#00FF00"}, - {"BLUE", "#0000FF"} - }); - - // Iterate and print keys and values of unordered map - c_foreach (n, cmap_str, u) { - printf("Key:[%s] Value:[%s]\n", n.ref->first.str, n.ref->second.str); - } - - // Add two new entries to the unordered map - cmap_str_emplace(&u, "BLACK", "#000000"); - cmap_str_emplace(&u, "WHITE", "#FFFFFF"); + c_auto (cmap_str, u) + { + c_apply_pair(cmap_str, emplace, &u, { + {"RED", "#FF0000"}, + {"GREEN", "#00FF00"}, + {"BLUE", "#0000FF"} + }); + + // Iterate and print keys and values of unordered map + c_foreach (n, cmap_str, u) { + printf("Key:[%s] Value:[%s]\n", n.ref->first.str, n.ref->second.str); + } - // Output values by key - printf("The HEX of color RED is:[%s]\n", cmap_str_at(&u, "RED")->str); - printf("The HEX of color BLACK is:[%s]\n", cmap_str_at(&u, "BLACK")->str); + // Add two new entries to the unordered map + cmap_str_emplace(&u, "BLACK", "#000000"); + cmap_str_emplace(&u, "WHITE", "#FFFFFF"); - cmap_str_del(&u); - return 0; + // Output values by key + printf("The HEX of color RED is:[%s]\n", cmap_str_at(&u, "RED")->str); + printf("The HEX of color BLACK is:[%s]\n", cmap_str_at(&u, "BLACK")->str); + } } ``` Output: @@ -170,22 +169,23 @@ int main() { uint32_t col = 0xcc7744ff; - cmap_id idnames = cmap_id_init(); - c_apply_pair(cmap_id, emplace, &idnames, { {100, "Red"}, {110, "Blue"} }); - - /* replace existing mapped value: */ - cmap_id_emplace_or_assign(&idnames, 110, "White"); - - /* insert a new constructed mapped string into map: */ - cmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); - - /* emplace/insert does nothing if key already exist: */ - cmap_id_emplace(&idnames, 100, "Green"); - - c_foreach (i, cmap_id, idnames) - printf("%d: %s\n", i.ref->first, i.ref->second.str); - - cmap_id_del(&idnames); + c_auto (cmap_id, idnames) + { + c_apply_pair(cmap_id, emplace, &idnames, { + {100, "Red"}, {110, "Blue"} + }); + // replace existing mapped value: + cmap_id_emplace_or_assign(&idnames, 110, "White"); + + // insert a new constructed mapped string into map: + cmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); + + // emplace/insert does nothing if key already exist: + cmap_id_emplace(&idnames, 100, "Green"); + + c_foreach (i, cmap_id, idnames) + printf("%d: %s\n", i.ref->first, i.ref->second.str); + } } ``` Output: @@ -338,8 +338,8 @@ static void Viking_del(Viking* v) { c_del(cstr, &v->name, &v->country); } -// Define a "raw" type that need no allocations, -// and define equals, hash, fromraw, toraw functions: +// Define a "raw" type that does not need allocations. +// Define equals, hash, fromraw, toraw functions: typedef struct { const char* name; @@ -360,10 +360,10 @@ static RViking Viking_toR(const Viking* v) #define i_key Viking #define i_val int -#define i_equ RViking_equals -#define i_hash RViking_hash #define i_keydel Viking_del #define i_keyraw RViking +#define i_equ RViking_equals +#define i_hash RViking_hash #define i_keyfrom Viking_fromR #define i_keyto Viking_toR #define i_tag vk @@ -377,11 +377,11 @@ int main() cmap_vk_insert(&vikings, (Viking){cstr_from("Einar"), cstr_from("Norway")}, 25); cmap_vk_insert(&vikings, (Viking){cstr_from("Olaf"), cstr_from("Denmark")}, 24); - // But emplace is simpler to use now - takes raw key argument + // Emplace is simpler to use now - takes rawkey argument cmap_vk_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); cmap_vk_emplace(&vikings, (RViking){"Einar", "Denmark"}, 21); - // Lookup also uses raw key type, so no need construct/destruct key: + // Lookup also uses rawkey args, no need construct/destruct key: printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, (RViking){"Einar", "Norway"})); // Print the status of the vikings. diff --git a/examples/new_map.c b/examples/new_map.c index 7ed192a3..1094fd91 100644 --- a/examples/new_map.c +++ b/examples/new_map.c @@ -15,6 +15,7 @@ struct MyStruct { // Point => int map struct Point { int x, y; } typedef Point; + int point_compare(const Point* a, const Point* b) { int c = c_default_compare(&a->x, &b->x); return c ? c : c_default_compare(&a->y, &b->y); @@ -39,24 +40,31 @@ int point_compare(const Point* a, const Point* b) { int main() { - cmap_int map = cmap_int_init(); - cmap_int_insert(&map, 123, 321); - cmap_int_del(&map); - - cmap_pnt pmap = cmap_pnt_init(); - cmap_pnt_insert(&pmap, (Point){42, 14}, 1); - cmap_pnt_insert(&pmap, (Point){32, 94}, 2); - cmap_pnt_insert(&pmap, (Point){62, 81}, 3); - c_foreach (i, cmap_pnt, pmap) - printf(" (%d,%d: %d)", i.ref->first.x, i.ref->first.y, i.ref->second); - puts(""); - cmap_pnt_del(&pmap); - - cmap_str smap = cmap_str_init(); - cmap_str_emplace(&smap, "Hello, friend", "this is the mapped value"); - cmap_str_del(&smap); - - cset_str sset = cset_str_init(); - cset_str_emplace(&sset, "Hello, friend"); - cset_str_del(&sset); + c_auto (cmap_int, map) + c_auto (cmap_pnt, pmap) + c_auto (cmap_str, smap) + c_auto (cset_str, sset) + { + cmap_int_insert(&map, 123, 321); + + c_apply_pair(cmap_pnt, insert, &pmap, { + {{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3} + }); + c_foreach (i, cmap_pnt, pmap) + printf(" (%d, %d: %d)", i.ref->first.x, i.ref->first.y, i.ref->second); + puts(""); + + c_apply_pair(cmap_str, emplace, &smap, { + {"Hello, friend", "long time no see"}, + {"So long, friend", "see you around"}, + }); + + c_apply(cset_str, emplace, &sset, { + "Hello, friend", + "Nice to see you again", + "So long, friend", + }); + c_foreach (i, cset_str, sset) + printf(" %s\n", i.ref->str); + } } \ No newline at end of file diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 8bfda771..0157f967 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -108,7 +108,7 @@ STC_INLINE cx_value_t* cx_memb(_emplace_front)(Self* self, i_valraw raw) { } STC_INLINE void cx_memb(_pop_back)(Self* self) { - size_t i = --cdeq_rep_(self)->size; i_valdel(&self->data[i]); + cx_value_t* p = &self->data[--cdeq_rep_(self)->size]; i_valdel(p); } STC_INLINE cx_value_t* cx_memb(_at)(const Self* self, size_t idx) { diff --git a/include/stc/cpque.h b/include/stc/cpque.h index b7a26360..0a06fc40 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -98,21 +98,17 @@ cx_memb(_push_back)(Self* self, cx_value_t value) { STC_INLINE void cx_memb(_pop_back)(Self* self) - { --self->size; i_valdel(&self->data[self->size]); } + { cx_value_t* p = &self->data[--self->size]; i_valdel(p); } /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp) STC_DEF void -cx_memb(_sift_down_)(cx_value_t* arr, size_t i, size_t n) { - size_t r = i, c = i << 1; - while (c <= n) { +cx_memb(_sift_down_)(cx_value_t* arr, size_t idx, size_t n) { + for (size_t r = idx, c = idx << 1; c <= n; c <<= 1) { c += (c < n && i_cmp(&arr[c], &arr[c + 1]) < 0); - if (i_cmp(&arr[r], &arr[c]) < 0) { - cx_value_t tmp = arr[r]; arr[r] = arr[c]; arr[r = c] = tmp; - } else - return; - c <<= 1; + if (i_cmp(&arr[r], &arr[c]) >= 0) return; + cx_value_t t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; } } @@ -143,10 +139,10 @@ cx_memb(_push)(Self* self, cx_value_t value) { if (self->size == self->capacity) cx_memb(_reserve)(self, self->size*3/2 + 4); cx_value_t *arr = self->data - 1; /* base 1 */ - size_t i = ++self->size; - for (; i > 1 && i_cmp(&arr[i >> 1], &value) < 0; i >>= 1) - arr[i] = arr[i >> 1]; - arr[i] = value; + size_t c = ++self->size; + for (; c > 1 && i_cmp(&arr[c >> 1], &value) < 0; c >>= 1) + arr[c] = arr[c >> 1]; + arr[c] = value; } #endif diff --git a/include/stc/cstack.h b/include/stc/cstack.h index 00d99fa1..3283eaf0 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -53,8 +53,9 @@ STC_INLINE Self cx_memb(_with_size)(size_t size, i_val fill) { } STC_INLINE void cx_memb(_clear)(Self* self) { - size_t i = self->size; self->size = 0; - while (i--) i_valdel(&self->data[i]); + cx_value_t *p = self->data + self->size; + while (p-- != self->data) i_valdel(p); + self->size = 0; } STC_INLINE void cx_memb(_del)(Self* self) @@ -73,7 +74,7 @@ STC_INLINE cx_value_t* cx_memb(_top)(const Self* self) { return &self->data[self->size - 1]; } STC_INLINE void cx_memb(_pop)(Self* self) - { --self->size; i_valdel(&self->data[self->size]); } + { cx_value_t* p = &self->data[--self->size]; i_valdel(p); } STC_INLINE void cx_memb(_reserve)(Self* self, size_t n) { if (n >= self->size) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index b8d0ac33..ff5b4399 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -108,7 +108,7 @@ STC_INLINE cx_value_t* cx_memb(_back)(const Self* self) STC_INLINE cx_value_t* cx_memb(_emplace_back)(Self* self, i_valraw raw) { return cx_memb(_push_back)(self, i_valfrom(raw)); } STC_INLINE void cx_memb(_pop_back)(Self* self) - { size_t i = --cvec_rep_(self)->size; i_valdel(&self->data[i]); } + { cx_value_t* p = &self->data[--cvec_rep_(self)->size]; i_valdel(p); } STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self) { return c_make(cx_iter_t){self->data}; } STC_INLINE cx_iter_t cx_memb(_end)(const Self* self) @@ -265,13 +265,13 @@ cx_memb(_reserve)(Self* self, size_t cap) { } STC_DEF void -cx_memb(_resize)(Self* self, size_t len, i_val null_val) { +cx_memb(_resize)(Self* self, size_t len, i_val fill) { if (len > cx_memb(_capacity)(*self)) cx_memb(_reserve)(self, len); struct cvec_rep* rep = cvec_rep_(self); size_t i, n = rep->size; for (i = len; i < n; ++i) i_valdel(&self->data[i]); - for (i = n; i < len; ++i) self->data[i] = null_val; + for (i = n; i < len; ++i) self->data[i] = fill; if (rep->cap) rep->size = len; } diff --git a/include/stc/template.h b/include/stc/template.h index 865e5b83..d72228aa 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -47,6 +47,10 @@ #error if i_keyraw or i_keyto defined, i_keyfrom a must be defined #endif +#if defined i_key_str || defined i_val_str + #include "cstr.h" +#endif + #ifdef i_cnt #define i_tag i_cnt #undef i_prefix -- cgit v1.2.3