summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/cmap_api.md48
-rw-r--r--examples/vikings.c37
-rw-r--r--include/stc/template.h14
3 files changed, 47 insertions, 52 deletions
diff --git a/docs/cmap_api.md b/docs/cmap_api.md
index 717e7677..9a4a2ef1 100644
--- a/docs/cmap_api.md
+++ b/docs/cmap_api.md
@@ -264,8 +264,8 @@ Output:
1: { 100, 0, 0 }
```
-### Example 5
-Advanced 1: Key type is struct.
+### Example 5: Advanced
+Key type is struct.
```c
#include <stc/cstr.h>
@@ -300,10 +300,10 @@ static inline void Viking_drop(Viking* vk) {
#define i_key_bind Viking
#define i_val int
/*
- i_key_bind auto-binds:
+ i_key_bind makes these defines, unless they are already defined:
#define i_cmp Viking_cmp
#define i_hash Viking_hash
- #define i_keyfrom Viking_clone
+ #define i_keyclone Viking_clone
#define i_keydrop Viking_drop
*/
#include <stc/cmap.h>
@@ -338,8 +338,8 @@ Einar of Norway has 25 hp
Harald of Iceland has 12 hp
```
-### Example 6
-Advanced 2: In example 5 we needed to construct a lookup key which allocated strings, and then had to free it after.
+### Example 6: More advanced
+In example 5 we needed to construct a lookup key which allocated strings, and then had to free it after.
In this example we use rawtype feature to make it even simpler to use. Note that we must use the emplace() methods
to add "raw" type entries (otherwise compile error):
```c
@@ -354,7 +354,7 @@ static inline void Viking_drop(Viking* v) {
c_drop(cstr, &v->name, &v->country);
}
-// Define Viking raw struct with hash, equalto, and convertion functions between Viking and RViking structs:
+// Define Viking raw struct with cmp, hash, and convertion functions between Viking and RViking structs:
typedef struct RViking {
const char* name;
@@ -366,14 +366,10 @@ static inline int RViking_cmp(const RViking* rx, const RViking* ry) {
return c ? c : strcmp(rx->country, ry->country);
}
-static inline Viking Viking_clone(RViking v) {
- v.name = cstr_clone(v.name), v.country = cstr_clone(v.country);
- return vk;
-}
-
static inline Viking Viking_from(RViking raw) {
return (Viking){cstr_from(raw.name), cstr_from(raw.country)};
}
+
static inline RViking Viking_toraw(const Viking* vp) {
return (RViking){cstr_str(&vp->name), cstr_str(&vp->country)};
}
@@ -382,35 +378,33 @@ static inline RViking Viking_toraw(const Viking* vp) {
#define i_type Vikings
#define i_key_bind Viking
#define i_keyraw RViking
-#define i_keyfrom Viking_from // optional to enable emplace funcs.
+#define i_keyfrom Viking_from
#define i_hash(rp) (c_strhash(rp->name) ^ c_strhash(rp->country))
#define i_val int
/*
- i_key_bind macro auto-binds these functions:
- #define i_hash RViking_hash
+ i_key_bind makes these defines, unless they are already defined:
#define i_cmp RViking_cmp
- #define i_keyclone Viking_clone
- #define i_keyto Viking_toraw // because i_keyraw type is defined
+ //#define i_hash RViking_hash // already defined above.
+ #define i_keyclone c_derived_keyclone // because i_keyfrom is defined.
+ #define i_keyto Viking_toraw // because i_keyraw type is defined
#define i_keydrop Viking_drop
*/
#include <stc/cmap.h>
int main()
{
- c_auto (Vikings, vikings) {
- c_forarray (Vikings_raw, v, {
- {{"Einar", "Norway"}, 20},
- {{"Olaf", "Denmark"}, 24},
- {{"Harald", "Iceland"}, 12}
- }) Vikings_emplace(&vikings, v->first, v->second);
-
- Vikings_emplace_or_assign(&vikings, (RViking){"Bjorn", "Sweden"}, 10);
+ c_auto (Vikings, vikings)
+ {
+ Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20);
+ Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24);
+ Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12);
+ Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10);
Vikings_value *v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"});
if (v) v->second += 3; // add 3 hp points to Einar
- c_forpair (vik, health, Vikings, vikings) {
- printf("%s of %s has %d hp\n", cstr_str(&_.vik->name), cstr_str(&_.vik->country), *_.health);
+ c_forpair (vk, hp, Vikings, vikings) {
+ printf("%s of %s has %d hp\n", cstr_str(&_.vk->name), cstr_str(&_.vk->country), *_.hp);
}
}
}
diff --git a/examples/vikings.c b/examples/vikings.c
index 667c4426..b5b3417b 100644
--- a/examples/vikings.c
+++ b/examples/vikings.c
@@ -25,10 +25,7 @@ static inline int RViking_cmp(const RViking* rx, const RViking* ry) {
static inline Viking Viking_from(RViking raw) { // note: parameter is by value
return c_make(Viking){cstr_from(raw.name), cstr_from(raw.country)};
}
-static inline Viking Viking_clone(Viking vk) { // note: parameter is by value
- vk.name = cstr_clone(vk.name), vk.country = cstr_clone(vk.country);
- return vk;
-}
+
static inline RViking Viking_toraw(const Viking* vp) {
return c_make(RViking){cstr_str(&vp->name), cstr_str(&vp->country)};
}
@@ -37,36 +34,32 @@ static inline RViking Viking_toraw(const Viking* vp) {
#define i_type Vikings
#define i_key_bind Viking // key type
#define i_keyraw RViking // lookup type
-#define i_keyfrom Viking_from // convert from lookup type (enables emplace)
+#define i_keyfrom Viking_from
#define i_hash(rp) c_strhash(rp->name) ^ c_strhash(rp->country)
#define i_val int // mapped type
-// i_key_bind auto-binds these functions (unless they are defined by i_...):
+
+// i_key_bind makes up these defines, unless they are already defined:
// i_cmp => RViking_cmp
-// i_hash => RViking_hash
-// i_keyclone => Viking_clone
-// i_keyto => Viking_toraw // because i_keyraw is defined
+// //i_hash => RViking_hash // already defined.
+// i_keyclone => c_derived_keyclone // because i_keyfrom is defined
+// i_keyto => Viking_toraw // because i_keyraw is defined
// i_keydrop => Viking_drop
+
#include <stc/cmap.h>
int main()
{
c_auto (Vikings, vikings) {
- c_forarray (Vikings_raw, v, {
- {{"Einar", "Norway"}, 20},
- {{"Olaf", "Denmark"}, 24},
- {{"Harald", "Iceland"}, 12},
- }) Vikings_emplace(&vikings, c_pair(v));
-
- RViking bjorn = {"Bjorn", "Sweden"};
- Vikings_emplace_or_assign(&vikings, bjorn, 10);
+ Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20);
+ Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24);
+ Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12);
+ Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10);
- RViking einar = {"Einar", "Norway"};
- Vikings_value* v = Vikings_get_mut(&vikings, einar);
+ Vikings_value* v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"});
v->second += 3; // add 3 hp points to Einar
- Vikings_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar
- c_forpair (vik, hp, Vikings, vikings) {
- printf("%s of %s has %d hp\n", cstr_str(&_.vik->name), cstr_str(&_.vik->country), *_.hp);
+ c_forpair (vk, hp, Vikings, vikings) {
+ printf("%s of %s has %d hp\n", cstr_str(&_.vk->name), cstr_str(&_.vk->country), *_.hp);
}
}
}
diff --git a/include/stc/template.h b/include/stc/template.h
index d7289ba7..e77aa781 100644
--- a/include/stc/template.h
+++ b/include/stc/template.h
@@ -95,6 +95,7 @@
#define i_key_bind cstr
#define i_keyraw crawstr
#define i_keyfrom cstr_from
+ #define i_keyclone cstr_clone
#ifndef i_tag
#define i_tag str
#endif
@@ -103,6 +104,7 @@
#define i_keyraw csview
#define i_keyfrom cstr_from_sv
#define i_keyto cstr_sv
+ #define i_keyclone cstr_clone
#define i_eq csview_eq
#ifndef i_tag
#define i_tag ssv
@@ -116,7 +118,9 @@
#ifdef i_key_bind
#define i_key i_key_bind
- #ifndef i_keyclone
+ #if !defined i_keyclone && defined i_keyfrom
+ #define i_keyclone c_derived_keyclone
+ #elif !defined i_keyclone
#define i_keyclone c_paste(i_key, _clone)
#endif
#if !defined i_keyto && defined i_keyraw
@@ -189,20 +193,24 @@
#define i_val_bind cstr
#define i_valraw crawstr
#define i_valfrom cstr_from
+ #define i_valclone cstr_clone
#elif defined i_val_ssv
#define i_val_bind cstr
#define i_valraw csview
#define i_valfrom cstr_from_sv
#define i_valto cstr_sv
+ #define i_valclone cstr_clone
#elif defined i_val_arcbox
#define i_val_bind i_val_arcbox
#define i_valraw c_paste(i_val_arcbox, _value)
- #define i_valto c_paste(i_val, _toval)
+ #define i_valto c_paste(i_val, _toval)
#endif
#ifdef i_val_bind
#define i_val i_val_bind
- #ifndef i_valclone
+ #if !defined i_valclone && defined i_valfrom
+ #define i_valclone c_derived_valclone
+ #elif !defined i_valclone
#define i_valclone c_paste(i_val, _clone)
#endif
#if !defined i_valto && defined i_valraw