From 94c816fbed2882f7dc0127f05f4ee74ffdccc21b Mon Sep 17 00:00:00 2001 From: Tyge Date: Thu, 23 Apr 2020 17:09:17 +0200 Subject: Fixed bugs with use of "Raw" types, and updated EXAMPLE.md accordingly. --- stc/cdefs.h | 2 +- stc/cmap.h | 21 +++++++++++++-------- stc/cstring.h | 6 ++++-- stc/cvector.h | 9 ++++++--- 4 files changed, 24 insertions(+), 14 deletions(-) (limited to 'stc') diff --git a/stc/cdefs.h b/stc/cdefs.h index 3aa8136e..b201dd59 100644 --- a/stc/cdefs.h +++ b/stc/cdefs.h @@ -47,7 +47,7 @@ #define c_swap(T, x, y) { T __t = x; x = y; y = __t; } #define c_defaultInitRaw(x) (x) -#define c_defaultGetRaw(x) (x) +#define c_defaultGetRaw(ptr) (*(ptr)) #define c_noCompare(x, y) 0 #define c_defaultCompare(x, y) (*(x) == *(y) ? 0 : *(x) < *(y) ? -1 : 1) #define c_defaultEquals(x, y) (memcmp(x, y, sizeof(*(y))) == 0) diff --git a/stc/cmap.h b/stc/cmap.h index abf520eb..b5accb30 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -140,12 +140,13 @@ cmap_##tag##_setShrinkLimitFactor(CMap_##tag* self, double limit) { \ } \ \ static inline size_t \ -cmap_##tag##_bucket(CMap_##tag* self, cmap_##tag##_rawkey_t* const rawKey, uint32_t* hxPtr) { \ - uint32_t hash = keyHashRaw(rawKey, sizeof(cmap_##tag##_rawkey_t)), hx = (hash & cmapentry_HASH) | cmapentry_USED; \ +cmap_##tag##_bucket(CMap_##tag* self, cmap_##tag##_rawkey_t* const rawKeyPtr, uint32_t* hxPtr) { \ + uint32_t hash = keyHashRaw(rawKeyPtr, sizeof(cmap_##tag##_rawkey_t)), hx = (hash & cmapentry_HASH) | cmapentry_USED; \ size_t cap = cvector_capacity(self->_table); \ size_t idx = cmap_reduce(hash, cap); \ CMapEntry_##tag* slot = self->_table.data; \ - while (slot[idx].hashx && (slot[idx].hashx != hx || !keyEqualsRaw((RawKey* const) keyGetRaw(&slot[idx].key), rawKey))) { \ + cmap_##tag##_rawkey_t r; \ + while (slot[idx].hashx && (slot[idx].hashx != hx || !keyEqualsRaw((r = keyGetRaw(&slot[idx].key), &r), rawKeyPtr))) { \ if (++idx == cap) idx = 0; \ } \ *hxPtr = hx; \ @@ -183,12 +184,13 @@ cmap_##tag##_put(CMap_##tag* self, cmap_##tag##_rawkey_t rawKey, Value value) { e->value = value; \ return e; \ } \ -/* \ + \ static inline CMapEntry_##tag* \ cmap_##tag##_insert(CMap_##tag* self, CMapEntry_##tag entry) { \ cmap_##tag##_expand(self); \ uint32_t hx; \ - size_t idx = cmap_##tag##_bucket(self, (RawKey* const) keyGetRaw(&entry.key), &hx); \ + cmap_##tag##_rawkey_t r = keyGetRaw(&entry.key); \ + size_t idx = cmap_##tag##_bucket(self, &r, &hx); \ CMapEntry_##tag* e = &self->_table.data[idx]; \ if (e->hashx) \ valueDestroy(&e->value); \ @@ -200,7 +202,7 @@ cmap_##tag##_insert(CMap_##tag* self, CMapEntry_##tag entry) { \ e->value = entry.value; \ return e; \ } \ -*/ \ + \ static inline size_t \ cmap_##tag##_reserve(CMap_##tag* self, size_t size) { \ size_t oldcap = cvector_capacity(self->_table), newcap = 1 + (size / 2) * 2; \ @@ -212,9 +214,10 @@ cmap_##tag##_reserve(CMap_##tag* self, size_t size) { \ \ CMapEntry_##tag* e = vec.data, *slot = self->_table.data; \ uint32_t hx; \ + cmap_##tag##_rawkey_t r; \ for (size_t i = 0; i < oldcap; ++i, ++e) \ if (e->hashx) \ - slot[ cmap_##tag##_bucket(self, (RawKey* const) keyGetRaw(&e->key), &hx) ] = *e; \ + slot[ cmap_##tag##_bucket(self, (r = keyGetRaw(&e->key), &r), &hx) ] = *e; \ free(_cvector_alloced(vec.data)); /* not cvector_destroy() here */ \ return newcap; \ } \ @@ -231,11 +234,13 @@ cmap_##tag##_erase(CMap_##tag* self, cmap_##tag##_rawkey_t rawKey) { \ CMapEntry_##tag* slot = self->_table.data; \ if (! slot[i].hashx) \ return false; \ + cmap_##tag##_rawkey_t r; \ do { /* deletion from hash table without tombstone */ \ if (++j == cap) j = 0; /* j %= cap; is slow */ \ if (! slot[j].hashx) \ break; \ - k = cmap_reduce(keyHashRaw((RawKey* const) keyGetRaw(&slot[j].key), sizeof(cmap_##tag##_rawkey_t)), cap); \ + k = cmap_reduce(keyHashRaw((r = keyGetRaw(&slot[j].key), &r), \ + sizeof(cmap_##tag##_rawkey_t)), cap); \ if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ \ slot[i] = slot[j], i = j; \ } while (true); \ diff --git a/stc/cstring.h b/stc/cstring.h index 454ff48c..99ab4e81 100644 --- a/stc/cstring.h +++ b/stc/cstring.h @@ -293,9 +293,11 @@ cstring_temp(const char* str) { /* CVector / CMap API functions: */ -#define cstring_getRaw(x) (&(x)->str) +#define cstring_getRaw(x) ((x)->str) #define cstring_compareRaw(x, y) strcmp(*(x), *(y)) #define cstring_equalsRaw(x, y) (strcmp(*(x), *(y)) == 0) -static inline uint32_t cstring_hashRaw(const char* const* str, size_t ignored) { return c_defaultHash(*str, strlen(*str)); } +static inline uint32_t cstring_hashRaw(const char* const* sPtr, size_t ignored) { + return c_defaultHash(*sPtr, strlen(*sPtr)); +} #endif diff --git a/stc/cvector.h b/stc/cvector.h index 069a335e..4bbc55cf 100644 --- a/stc/cvector.h +++ b/stc/cvector.h @@ -47,7 +47,7 @@ extern void qsort(void *base, size_t nitems, size_t size, int (*compar)(const vo #define declare_CVector_6(tag, Value, valueDestroy, valueCompare, ValueRaw, valueGetRaw) \ - \ +typedef ValueRaw cvector_##tag##_rawvalue_t; \ typedef struct CVector_##tag { \ Value* data; \ } CVector_##tag; \ @@ -118,7 +118,9 @@ cvector_##tag##_erase(CVector_##tag* self, size_t pos, size_t size) { \ \ static inline int \ cvector_##tag##_sortCompare(const void* x, const void* y) { \ - return valueCompare(valueGetRaw((const Value *) x), valueGetRaw((const Value *) y)); \ + cvector_##tag##_rawvalue_t rx = valueGetRaw((const Value *) x); \ + cvector_##tag##_rawvalue_t ry = valueGetRaw((const Value *) y); \ + return valueCompare(&rx, &ry); \ } \ \ static inline void \ @@ -130,8 +132,9 @@ cvector_##tag##_sort(CVector_##tag* self) { \ static inline size_t \ cvector_##tag##_find(CVector_##tag cv, ValueRaw rawValue) { \ size_t n = cvector_size(cv); \ + cvector_##tag##_rawvalue_t r; \ for (size_t i = 0; i < n; ++i) { \ - if (valueCompare(valueGetRaw(&cv.data[i]), &rawValue) == 0) return i; \ + if (valueCompare((r = valueGetRaw(&cv.data[i]), &r), &rawValue) == 0) return i; \ } \ return c_npos; \ } \ -- cgit v1.2.3