summaryrefslogtreecommitdiffhomepage
path: root/docs/cmap_api.md
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-12-19 12:21:44 +0100
committerTyge Løvset <[email protected]>2021-12-19 12:21:44 +0100
commit92b950333c6c7002bdbf1b60af44a249dc0cef9c (patch)
tree4b1acfcdba0bd940f829c53910587e27b5e0af90 /docs/cmap_api.md
parent183a89859ba9914ee0546e4482b40be199e52292 (diff)
downloadSTC-modified-92b950333c6c7002bdbf1b60af44a249dc0cef9c.tar.gz
STC-modified-92b950333c6c7002bdbf1b60af44a249dc0cef9c.zip
First commit for Version 3 of STC. Main changes are consistent rename of '_del' to '_drop' and '_compare' to '_cmp'.
Also i_key_ref (earlier i_key_sptr) and i_val_ref replaced by more general i_key_bind/i_val_bind.
Diffstat (limited to 'docs/cmap_api.md')
-rw-r--r--docs/cmap_api.md161
1 files changed, 86 insertions, 75 deletions
diff --git a/docs/cmap_api.md b/docs/cmap_api.md
index 0fec365c..e2cb668f 100644
--- a/docs/cmap_api.md
+++ b/docs/cmap_api.md
@@ -21,13 +21,13 @@ See the c++ class [std::unordered_map](https://en.cppreference.com/w/cpp/contain
#define i_val // value: REQUIRED
#define i_cmp // three-way compare two i_keyraw*: REQUIRED IF i_keyraw is non-integral type
#define i_equ // equality comparison two i_keyraw*: ALTERNATIVE to i_cmp
-#define i_keydel // destroy key func - defaults to empty destruct
+#define i_keydrop // destroy key func - defaults to empty destruct
#define i_keyraw // convertion "raw" type - defaults to i_key
-#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
+#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
-#define i_valdel // destroy value func - defaults to empty destruct
+#define i_valdrop // destroy value func - defaults to empty destruct
#define i_valraw // convertion "raw" type - defaults to i_val
-#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy
+#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy
#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy
#define i_tag // defaults to i_key
#include <stc/cmap.h>
@@ -47,7 +47,7 @@ void cmap_X_max_load_factor(cmap_X* self, float max_load);
bool cmap_X_reserve(cmap_X* self, size_t size);
void cmap_X_shrink_to_fit(cmap_X* self);
void cmap_X_swap(cmap_X* a, cmap_X* b);
-void cmap_X_del(cmap_X* self); // destructor
+void cmap_X_drop(cmap_X* self); // destructor
size_t cmap_X_size(cmap_X map);
size_t cmap_X_capacity(cmap_X map); // buckets * max_load_factor
@@ -207,15 +207,15 @@ typedef struct { int x, y, z; } Vec3i;
int main()
{
// Define map with defered destruct
- c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_del(&vecs))
+ c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs))
{
cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1);
cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2);
cmap_vi_insert(&vecs, (Vec3i){ 0, 0, 100}, 3);
cmap_vi_insert(&vecs, (Vec3i){100, 100, 100}, 4);
- c_foreach (i, cmap_vi, vecs)
- printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second);
+ c_forpair (vec, num, cmap_vi, vecs)
+ printf("{ %3d, %3d, %3d }: %d\n", _.vec.x, _.vec.y, _.vec.z, _.num);
}
}
```
@@ -240,15 +240,15 @@ typedef struct { int x, y, z; } Vec3i;
int main()
{
- c_autovar (cmap_iv vecs = cmap_iv_init(), cmap_iv_del(&vecs))
+ c_auto (cmap_iv, vecs) // shorthand for c_autovar with _init(), _drop().
{
cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0});
cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0});
cmap_iv_insert(&vecs, 3, (Vec3i){ 0, 0, 100});
cmap_iv_insert(&vecs, 4, (Vec3i){100, 100, 100});
- c_foreach (i, cmap_iv, vecs)
- printf("%d: { %3d, %3d, %3d }\n", i.ref->first, i.ref->second.x, i.ref->second.y, i.ref->second.z);
+ c_forpair (num, vec, cmap_iv, vecs)
+ printf("%d: { %3d, %3d, %3d }\n", _.num_, _.vec.x, _.vec.y, _.vec.z);
}
}
```
@@ -270,45 +270,56 @@ typedef struct {
cstr country;
} Viking;
-static bool Viking_equalto(const Viking* a, const Viking* b) {
+#define Viking_init() ((Viking){cstr_null, cstr_null})
+
+static inline bool RViking_equalto(const Viking* a, const Viking* b) {
return cstr_equals_s(a->name, b->name) && cstr_equals_s(a->country, b->country);
}
-static uint32_t Viking_hash(const Viking* a, int ignored) {
+static inline uint32_t RViking_hash(const Viking* a, int ignored) {
return c_strhash(a->name.str) ^ (c_strhash(a->country.str) >> 15);
}
-static void Viking_del(Viking* v) {
- c_del(cstr, &v->name, &v->country);
+static inline Viking Viking_clone(Viking v) {
+ v.name = cstr_clone(v.name);
+ v.country = cstr_clone(v.country);
+}
+
+void inline Viking_drop(Viking* vk) {
+ cstr_drop(&vk->name);
+ cstr_drop(&vk->country);
}
-#define i_key Viking
+#define i_type Vikings
+#define i_key_bind Viking
#define i_val int
-#define i_equ Viking_equalto
-#define i_hash Viking_hash
-#define i_del Viking_del
-#define i_tag vk
+// i_key_bind auto-binds:
+// #define i_equ RViking_equalto
+// #define i_hash RViking_hash
+// #define i_keyfrom Viking_clone
+// #define i_drop Viking_drop
#include <stc/cmap.h>
int main()
{
// Use a HashMap to store the vikings' health points.
- cmap_vk vikings = cmap_vk_init();
-
- cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25);
- cmap_vk_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24);
- cmap_vk_insert(&vikings, (Viking){cstr_new("Harald"), cstr_new("Iceland")}, 12);
- cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Denmark")}, 21);
-
- Viking lookup = (Viking){cstr_new("Einar"), cstr_new("Norway")};
- printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, lookup));
- Viking_del(&lookup);
-
- // Print the status of the vikings.
- c_foreach (i, cmap_vk, vikings) {
- printf("%s of %s has %d hp\n", i.ref->first.name.str, i.ref->first.country.str, i.ref->second);
+ c_auto (Vikings, vikings) // uses Vikings_init(), Vikings_drop()
+ {
+ Vikings_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25);
+ Vikings_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24);
+ Vikings_insert(&vikings, (Viking){cstr_new("Harald"), cstr_new("Iceland")}, 12);
+ Vikings_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Denmark")}, 21);
+
+ c_auto (Viking, lookup) {
+ lookup = (Viking){cstr_new("Einar"), cstr_new("Norway")};
+ printf("Lookup: Einar of Norway has %d hp\n\n", *Vikings_at(&vikings, lookup));
+ }
+
+ // Print the status of the vikings.
+ c_forpair (viking, hp, Vikings, vikings) {
+ printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.hp);
+ }
}
- cmap_vk_del(&vikings);
}
```
Output:
@@ -326,65 +337,65 @@ to add "raw" type entries (otherwise compile error):
```c
#include <stc/cstr.h>
-typedef struct {
+typedef struct Viking {
cstr name;
cstr country;
} Viking;
-static void Viking_del(Viking* v) {
- c_del(cstr, &v->name, &v->country);
+static inline void Viking_drop(Viking* v) {
+ c_drop(cstr, &v->name, &v->country);
}
-// Define a "raw" type that does not need allocations.
-// Define equals, hash, fromraw, toraw functions:
+// Define Viking raw struct with hash, equalto, and convertion functions between Viking and RViking structs:
-typedef struct {
+typedef struct RViking {
const char* name;
const char* country;
} RViking;
-static bool RViking_equalto(const RViking* r1, const RViking* r2)
- { return !strcmp(r1->name, r2->name) && !strcmp(r1->country, r2->country); }
-
-static uint32_t RViking_hash(const RViking* r, int ignored)
- { return c_strhash(r->name) ^ (c_strhash(r->country) >> 15); }
-
-static Viking Viking_fromR(RViking r)
- { return (Viking){cstr_from(r.name), cstr_from(r.country)}; }
+static inline uint64_t RViking_hash(const RViking* raw, size_t ignore) {
+ uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15);
+ return hash;
+}
+static inline bool RViking_equalto(const RViking* rx, const RViking* ry) {
+ return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0;
+}
-static RViking Viking_toR(const Viking* v)
- { return (RViking){v->name.str, v->country.str}; }
+static inline Viking Viking_from(RViking raw) {
+ return (Viking){cstr_from(raw.name), cstr_from(raw.country)};
+}
+static inline RViking Viking_toraw(const Viking* vk) {
+ return (RViking){vk->name.str, vk->country.str};
+}
-#define i_key Viking
-#define i_val int
-#define i_keydel Viking_del
-#define i_keyraw RViking
-#define i_equ RViking_equalto
-#define i_hash RViking_hash
-#define i_keyfrom Viking_fromR
-#define i_keyto Viking_toR
-#define i_tag vk
+// With this in place, we define the Viking => int hash map type:
+#define i_type Vikings
+#define i_key_bind Viking
+#define i_val int
+#define i_keyraw RViking
+// i_key_bind macro will make these functions auto-bind:
+// #define i_hash RViking_hash
+// #define i_equ RViking_equalto
+// #define i_keyfrom Viking_from // uses _from because i_keyraw is defined
+// #define i_keyto Viking_toraw
+// #define i_keydrop Viking_drop
#include <stc/cmap.h>
int main()
{
- c_auto (cmap_vk, vikings) // RAII
- {
- // Insert works as before, takes a constructed Viking object
- cmap_vk_insert(&vikings, (Viking){cstr_new("Einar"), cstr_new("Norway")}, 25);
- cmap_vk_insert(&vikings, (Viking){cstr_new("Olaf"), cstr_new("Denmark")}, 24);
-
- // 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);
+ c_auto (Vikings, vikings) {
+ c_apply_pair(Vikings, emplace, &vikings, {
+ {{"Einar", "Norway"}, 20},
+ {{"Olaf", "Denmark"}, 24},
+ {{"Harald", "Iceland"}, 12},
+ });
+ Vikings_emplace_or_assign(&vikings, (RViking){"Bjorn", "Sweden"}, 10);
- // 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"}));
+ Vikings_value *einar = Vikings_find(&vikings, (RViking){"Einar", "Norway"}).ref;
+ if (einar) einar->second += 3; // add 3 hp points to Einar
- // Print the status of the vikings.
- c_foreach (i, cmap_vk, vikings) {
- printf("%s of %s has %d hp\n", i.ref->first.name.str,
- i.ref->first.country.str, i.ref->second);
+ c_forpair (viking, health, Vikings, vikings) {
+ printf("%s of %s has %d hp\n", _.viking.name.str, _.viking.country.str, _.health);
}
}
}