diff options
| author | Tyge Løvset <[email protected]> | 2021-01-04 10:39:08 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-01-04 10:39:08 +0100 |
| commit | 361ecbcdad468c64eebc13c6770a8ec8d681169a (patch) | |
| tree | c72e1d965da5dc729d9df2c180f3d40dbc316594 /docs/cmap_api.md | |
| parent | 3fce3fa270b7e3c268cd244543c0292412be62b9 (diff) | |
| download | STC-modified-361ecbcdad468c64eebc13c6770a8ec8d681169a.tar.gz STC-modified-361ecbcdad468c64eebc13c6770a8ec8d681169a.zip | |
Move and fix the advanced.c Viking example to cmap_api.md
Diffstat (limited to 'docs/cmap_api.md')
| -rw-r--r-- | docs/cmap_api.md | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 80198fdc..36dc829a 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -21,7 +21,7 @@ See [std::unordered_map](https://en.cppreference.com/w/cpp/container/unordered_m mappedFromRaw, mappedToRaw, RawMapped, keyEqualsRaw, keyHashRaw, keyDestroy, keyFromRaw, keyToRaw, RawKey) - + #define using_cmap_strkey(X, Mapped, mappedDestroy=c_default_del, mappedClone=c_default_clone) @@ -271,3 +271,78 @@ Output: 2: { 0, 100, 0} 1: { 100, 0, 0} ``` + +### Example 5 +Demonstrate a complex key type. +```c +#include <stdio.h> +#include <stc/cmap.h> +#include <stc/cstr.h> + +typedef struct Viking { + cstr_t name; + cstr_t country; +} Viking; + +void viking_del(Viking* vk) { + cstr_del(&vk->name); + cstr_del(&vk->country); +} + + +// Define Viking raw struct with hash, equals, and convertion functions between Viking and VikingRaw structs: + +typedef struct VikingRaw { + const char* name; + const char* country; +} VikingRaw; + +uint32_t vikingraw_hash(const VikingRaw* raw, size_t ignore) { + uint32_t hash = c_string_hash(raw->name) ^ (c_string_hash(raw->country) << 3); + return hash; +} +static inline int vikingraw_equals(const VikingRaw* rx, const VikingRaw* ry) { + return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; +} + +static inline Viking viking_fromRaw(VikingRaw raw) { // note: parameter is by value + Viking vk = {cstr_from(raw.name), cstr_from(raw.country)}; return vk; +} + +static inline VikingRaw viking_toRaw(Viking* vk) { + VikingRaw raw = {vk->name.str, vk->country.str}; return raw; +} + +// With this in place, we use the full using_cmap() macro to define {Viking -> int} hash map type: + +using_cmap(vk, Viking, int, c_default_del, c_default_clone, + vikingraw_equals, vikingraw_hash, + viking_del, viking_fromRaw, viking_toRaw, VikingRaw); + + +int main() { + cmap_vk vikings = cmap_vk_init(); + c_push_items(&vikings, cmap_vk, { + { {"Einar", "Norway"}, 20}, + { {"Olaf", "Denmark"}, 24}, + { {"Harald", "Iceland"}, 12}, + }); + + VikingRaw lookup = {"Einar", "Norway"}; + + cmap_vk_entry_t *e = cmap_vk_find(&vikings, lookup); + e->second += 3; // add 3 hp points + cmap_vk_emplace(&vikings, lookup, 0).first->second += 5; // add 5 more to Einar + + c_foreach (k, cmap_vk, vikings) { + printf("%s of %s has %d hp\n", k.ref->first.name.str, k.ref->first.country.str, k.ref->second); + } + cmap_vk_del(&vikings); +} +``` +Output: +``` +Olaf of Denmark has 24 hp +Einar of Norway has 28 hp +Harald of Iceland has 12 hp +``` |
