summaryrefslogtreecommitdiffhomepage
path: root/docs/cmap_api.md
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-01-04 10:39:08 +0100
committerTyge Løvset <[email protected]>2021-01-04 10:39:08 +0100
commit361ecbcdad468c64eebc13c6770a8ec8d681169a (patch)
treec72e1d965da5dc729d9df2c180f3d40dbc316594 /docs/cmap_api.md
parent3fce3fa270b7e3c268cd244543c0292412be62b9 (diff)
downloadSTC-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.md77
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
+```