summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--examples/mapmap.c61
-rw-r--r--include/stc/ccommon.h2
-rw-r--r--include/stc/cmap.h31
-rw-r--r--include/stc/cstr.h2
4 files changed, 46 insertions, 50 deletions
diff --git a/examples/mapmap.c b/examples/mapmap.c
index 44cf7da5..184a7a7d 100644
--- a/examples/mapmap.c
+++ b/examples/mapmap.c
@@ -1,39 +1,46 @@
-
-#include <stdio.h>
-#include <stc/cstr.h>
-
// unordered_map<string, unordered_map<string, string>>:
#define i_key_str
#define i_val_str
-#include <stc/cmap.h>
+#define i_tag sect
+#include <stc/csmap.h>
#define i_key_str
-#define i_val cmap_str
-#define i_valdel cmap_str_del
-#define i_tag cfg
-#include <stc/cmap.h>
+#define i_val csmap_sect
+#define i_valdel csmap_sect_del
+#define i_tag conf
+#include <stc/csmap.h>
-int main(void)
+void add(csmap_conf* map, const char* section, const char* entry, const char* value)
{
- c_auto (cmap_cfg, cfg)
- {
- cmap_cfg_insert(&cfg, cstr_from("user"), cmap_str_init());
- cmap_cfg_insert(&cfg, cstr_from("group"), cmap_str_init());
- cmap_cfg_insert(&cfg, cstr_from("admin"), cmap_str_init());
-
- cmap_str_emplace(cmap_cfg_at(&cfg, "user"), "name", "Joe");
- cmap_str_emplace(cmap_cfg_at(&cfg, "user"), "groups", "proj1,proj3");
- cmap_str_emplace(cmap_cfg_at(&cfg, "group"), "proj1", "Energy");
- cmap_str_emplace(cmap_cfg_at(&cfg, "group"), "proj2", "Windy");
- cmap_str_emplace(cmap_cfg_at(&cfg, "group"), "proj3", "Oil");
- cmap_str_emplace(cmap_cfg_at(&cfg, "admin"), "employees", "2302");
+ csmap_sect *smap = &csmap_conf_insert(map, cstr_from(section), csmap_sect_init()).ref->second;
+ csmap_sect_emplace_or_assign(smap, entry, value);
+}
- cmap_str_emplace_or_assign(cmap_cfg_at(&cfg, "group"), "proj2", "Wind"); // Update
+bool contains(csmap_conf* map, const char* section, const char* entry)
+{
+ csmap_conf_value_t *val = csmap_conf_get(map, section);
+ return val && csmap_sect_get(&val->second, entry);
+}
- c_foreach (i, cmap_cfg, cfg)
- c_foreach (j, cmap_str, i.ref->second)
- printf("%s: %s - %s (%u)\n", i.ref->first.str, j.ref->first.str, j.ref->second.str,
- i.ref->second.bucket_count);
+int main(void)
+{
+ c_auto (csmap_conf, map)
+ {
+ add(&map, "user", "name", "Joe");
+ add(&map, "user", "groups", "proj1,proj3");
+ add(&map, "group", "proj1", "Energy");
+ add(&map, "group", "proj2", "Windy");
+ add(&map, "group", "proj3", "Oil");
+ add(&map, "admin", "employees", "2302");
+ add(&map, "group", "proj2", "Wind"); // Update
+
+ printf("contains: %d\n", contains(&map, "group", "employees"));
+ printf("contains: %d\n", contains(&map, "admin", "name"));
+ printf("contains: %d\n", contains(&map, "admin", "employees"));
+
+ c_foreach (i, csmap_conf, map)
+ c_foreach (j, csmap_sect, i.ref->second)
+ printf("%s: %s - %s\n", i.ref->first.str, j.ref->first.str, j.ref->second.str);
}
} \ No newline at end of file
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index e3ccfffd..5480d9f2 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -111,7 +111,7 @@
#define c_default_del(ptr) ((void) (ptr))
-STC_API uint64_t c_default_hash(const void *key, size_t len);
+STC_INLINE uint64_t c_default_hash(const void *key, size_t len);
#define c_default_hash32(data, len_is_4) \
((*(const uint32_t*)data * 0xc6a4a7935bd1e99d) >> 15)
#define c_default_hash64(data, len_is_8) \
diff --git a/include/stc/cmap.h b/include/stc/cmap.h
index 3a860f39..1dc1fd90 100644
--- a/include/stc/cmap.h
+++ b/include/stc/cmap.h
@@ -213,34 +213,23 @@ cx_memb(_erase_at)(Self* self, cx_iter_t it) {
/* -------------------------- IMPLEMENTATION ------------------------- */
-#if !defined(STC_HEADER) && !defined(CMAP_H_INCLUDED) || defined(i_imp) && i_imp == 2
-
-STC_DEF uint64_t c_default_hash(const void *key, size_t len) {
- const uint64_t m = 0xb5ad4eceda1ce2a9;
- uint64_t k, h = m + len;
- const uint8_t *p = (const uint8_t *)key, *end = p + (len & ~7ull);
- for (; p != end; p += 8) { memcpy(&k, p, 8); h ^= m*k; }
- switch (len & 7) {
- case 7: h ^= (uint64_t) p[6] << 48; /* @fallthrough@ */
- case 6: h ^= (uint64_t) p[5] << 40; /* @fallthrough@ */
- case 5: h ^= (uint64_t) p[4] << 32; /* @fallthrough@ */
- case 4: h ^= (uint64_t) p[3] << 24; /* @fallthrough@ */
- case 3: h ^= (uint64_t) p[2] << 16; /* @fallthrough@ */
- case 2: h ^= (uint64_t) p[1] << 8; /* @fallthrough@ */
- case 1: h ^= (uint64_t) p[0]; h *= m;
- }
- return h ^ (h >> 15);
-}
-#endif // NON-TEMPLATED
-
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp)
#ifndef CMAP_H_INCLUDED
+#define _c_rotl(x, k) (x << (k) | x >> (8*sizeof(x) - (k)))
+STC_INLINE uint64_t c_default_hash(const void *key, size_t len) {
+ const char* str = (const char*)key;
+ uint64_t h = 0xb5ad4eceda1ce2a9;
+ for (size_t i = 0; i < len; ++i)
+ h ^= (_c_rotl(h, 4) ^ (h << 13)) + str[i];
+ return h;
+}
+
//STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n)
// { uint64_t lo, hi; c_umul128(x, n, &lo, &hi); return hi; }
#define fastrange_uint32_t(x, n) (uint32_t)((uint32_t)(x)*(uint64_t)(n) >> 32)
#define chash_index_(h, entryPtr) ((entryPtr) - (h).table)
-#endif
+#endif // CMAP_H_INCLUDED
STC_DEF Self
cx_memb(_with_capacity)(size_t cap) {
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index 23830d75..98b95e3d 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -68,11 +68,11 @@ STC_API char* c_strnstrn(const char* s, const char* needle, size_t sle
STC_API int c_strncasecmp(const char* s1, const char* s2, size_t nmax);
STC_INLINE cstr cstr_init() { return cstr_null; }
+#define cstr_str(self) (self)->str
#define cstr_lit(literal) \
cstr_from_n(literal, sizeof c_make(strlit_t){literal} - 1)
STC_INLINE cstr cstr_from(const char* str)
{ return cstr_from_n(str, strlen(str)); }
-STC_INLINE const char* cstr_str(const cstr* self) { return self->str; }
STC_INLINE char* cstr_data(cstr* self) { return self->str; }
STC_INLINE size_t cstr_size(cstr s) { return _cstr_rep(&s)->size; }
STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; }