summaryrefslogtreecommitdiffhomepage
path: root/include/stc/cmap.h
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-09-05 23:12:53 +0200
committerTyge Løvset <[email protected]>2021-09-05 23:12:53 +0200
commit44c64073662500684008c87e3a87f33b04e53c13 (patch)
tree6a927fe91e6d2eee073cdce5d30ff87f5e709ce6 /include/stc/cmap.h
parentb2dc4c367030232068338b9e7b3faee03c2db0a8 (diff)
downloadSTC-modified-44c64073662500684008c87e3a87f33b04e53c13.tar.gz
STC-modified-44c64073662500684008c87e3a87f33b04e53c13.zip
New usage style. only cvec is functional. see vec_test_new.c
Diffstat (limited to 'include/stc/cmap.h')
-rw-r--r--include/stc/cmap.h393
1 files changed, 141 insertions, 252 deletions
diff --git a/include/stc/cmap.h b/include/stc/cmap.h
index 68a5fd4b..39d9fce8 100644
--- a/include/stc/cmap.h
+++ b/include/stc/cmap.h
@@ -51,276 +51,170 @@ int main(void) {
#include <stdlib.h>
#include <string.h>
-#define using_cmap(...) c_MACRO_OVERLOAD(using_cmap, __VA_ARGS__)
-#define using_cmap_3(X, Key, Mapped) \
- using_cmap_5(X, Key, Mapped, c_default_equals, c_default_hash)
-#define using_cmap_5(X, Key, Mapped, keyEquals, keyHash) \
- using_cmap_7(X, Key, Mapped, keyEquals, keyHash, \
- c_default_del, c_default_fromraw)
-#define using_cmap_6(X, Key, Mapped, keyEquals, keyHash, mappedDel) \
- using_cmap_7(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, c_no_clone)
-#define using_cmap_7(X, Key, Mapped, keyEquals, keyHash, mappedDel, mappedClone) \
- using_cmap_10(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, mappedClone, c_default_toraw, Mapped, c_true)
-#define using_cmap_10(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- using_cmap_14(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- c_default_del, c_default_fromraw, c_default_toraw, Key, defTypes)
-#define using_cmap_14(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-
-#define using_cmap_keydef(...) c_MACRO_OVERLOAD(using_cmap_keydef, __VA_ARGS__)
-
-#define using_cmap_keydef_7(X, Key, Mapped, keyEquals, keyHash, keyDel, keyClone) \
- using_cmap_keydef_10(X, Key, Mapped, keyEquals, keyHash, \
- keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_cmap_keydef_10(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- c_default_del, c_default_fromraw, c_default_toraw, Mapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define using_cmap_str() \
- _c_using_chash(cmap_str, cmap_, cstr, cstr, c_rawstr_equals, c_rawstr_hash, \
- cstr_del, cstr_from, cstr_str, const char*, \
- cstr_del, cstr_from, cstr_str, const char*, c_true)
-
-
-#define using_cmap_strkey(...) c_MACRO_OVERLOAD(using_cmap_strkey, __VA_ARGS__)
-
-#define using_cmap_strkey_2(X, Mapped) \
- using_cmap_strkey_4(X, Mapped, c_default_del, c_default_fromraw)
-#define using_cmap_strkey_3(X, Mapped, mappedDel) \
- using_cmap_strkey_4(X, Mapped, mappedDel, c_no_clone)
-#define using_cmap_strkey_4(X, Mapped, mappedDel, mappedClone) \
- using_cmap_strkey_7(X, Mapped, mappedDel, mappedClone, c_default_toraw, Mapped, c_true)
-#define using_cmap_strkey_7(X, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- _c_using_chash_strkey(X, cmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes)
-#define _c_using_chash_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- _c_using_chash(C##X, C, cstr, Mapped, c_rawstr_equals, c_rawstr_hash, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- cstr_del, cstr_from, cstr_str, const char*, defTypes)
-
-
-#define using_cmap_strval(...) c_MACRO_OVERLOAD(using_cmap_strval, __VA_ARGS__)
-
-#define using_cmap_strval_2(X, Key) \
- using_cmap_strval_4(X, Key, c_default_equals, c_default_hash)
-#define using_cmap_strval_4(X, Key, keyEquals, keyHash) \
- using_cmap_strval_6(X, Key, keyEquals, keyHash, c_default_del, c_default_fromraw)
-#define using_cmap_strval_5(X, Key, keyEquals, keyHash, keyDel) \
- using_cmap_strval_6(X, Key, keyEquals, keyHash, keyDel, c_no_clone)
-#define using_cmap_strval_6(X, Key, keyEquals, keyHash, keyDel, keyClone) \
- using_cmap_strval_9(X, Key, keyEquals, keyHash, keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_cmap_strval_9(X, Key, keyEqualsRaw, keyHashRaw, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cmap_##X, cmap_, Key, cstr, keyEqualsRaw, keyHashRaw, \
- cstr_del, cstr_from, cstr_str, const char*, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define SET_ONLY_cmap_(...)
-#define MAP_ONLY_cmap_(...) __VA_ARGS__
#define KEY_REF_cmap_(vp) (&(vp)->first)
-#ifndef CMAP_SIZE_T
-#define CMAP_SIZE_T uint32_t
-#endif
#define _cmap_inits {NULL, NULL, 0, 0, 0.85f}
-typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; \
+typedef struct {size_t idx; uint_fast8_t hx; } chash_bucket_t; \
STC_API uint64_t c_default_hash(const void *data, size_t len);
STC_INLINE uint64_t c_string_hash(const char *s)
- {return c_default_hash(s, strlen(s));}
+ { return c_default_hash(s, strlen(s)); }
STC_INLINE uint64_t c_default_hash32(const void* data, size_t ignored)
- {return *(const uint32_t *)data * 0xc6a4a7935bd1e99d;}
+ { return *(const uint32_t *)data * 0xc6a4a7935bd1e99d; }
STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored)
- {return *(const uint64_t *)data * 0xc6a4a7935bd1e99d;}
+ { return *(const uint64_t *)data * 0xc6a4a7935bd1e99d; }
-#define _c_chash_types(CX, C, Key, Mapped) \
- typedef Key CX##_key_t; \
- typedef Mapped CX##_mapped_t; \
- typedef CMAP_SIZE_T CX##_size_t; \
-\
- typedef SET_ONLY_##C( CX##_key_t ) \
- MAP_ONLY_##C( struct CX##_value_t ) \
- CX##_value_t; \
-\
- typedef struct { \
- CX##_value_t *ref; \
- bool inserted; \
- } CX##_result_t; \
-\
- typedef struct { \
- CX##_value_t *ref; \
- uint8_t* _hx; \
- } CX##_iter_t; \
-\
- typedef struct { \
- CX##_value_t* table; \
- uint8_t* _hashx; \
- CX##_size_t size, bucket_count; \
- float max_load_factor; \
- } CX
-#define _c_using_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- defTypes( _c_chash_types(CX, C, Key, Mapped); ) \
+ defTypes( _c_chash_types(Self, C, i_KEY, i_VAL); ) \
\
- MAP_ONLY_##C( struct CX##_value_t { \
- CX##_key_t first; \
- CX##_mapped_t second; \
+ MAP_ONLY_##C( struct cx_value_t { \
+ cx_key_t first; \
+ cx_mapped_t second; \
}; ) \
\
- typedef RawKey CX##_rawkey_t; \
- typedef RawMapped CX##_rawmapped_t; \
- typedef SET_ONLY_##C( RawKey ) \
- MAP_ONLY_##C( struct { RawKey first; \
- RawMapped second; } ) \
- CX##_rawvalue_t; \
+ typedef i_KEYRAW cx_rawkey_t; \
+ typedef i_VALRAW cx_memb(_rawmapped_t); \
+ typedef SET_ONLY_##C( i_KEYRAW ) \
+ MAP_ONLY_##C( struct { i_KEYRAW first; \
+ i_VALRAW second; } ) \
+ cx_rawvalue_t; \
\
- STC_API CX CX##_with_capacity(size_t cap); \
- STC_API CX CX##_clone(CX map); \
- STC_API void CX##_del(CX* self); \
- STC_API void CX##_clear(CX* self); \
- STC_API void CX##_reserve(CX* self, size_t capacity); \
- STC_API chash_bucket_t CX##_bucket_(const CX* self, const CX##_rawkey_t* rkeyptr); \
- STC_API CX##_result_t CX##_insert_entry_(CX* self, RawKey rkey); \
- STC_API void CX##_erase_entry(CX* self, CX##_value_t* val); \
+ STC_API Self cx_memb(_with_capacity)(size_t cap); \
+ STC_API Self cx_memb(_clone)(Self map); \
+ STC_API void cx_memb(_del)(Self* self); \
+ STC_API void cx_memb(_clear)(Self* self); \
+ STC_API void cx_memb(_reserve)(Self* self, size_t capacity); \
+ STC_API chash_bucket_t cx_memb(_bucket_)(const Self* self, const cx_rawkey_t* rkeyptr); \
+ STC_API cx_result_t cx_memb(_insert_entry_)(Self* self, i_KEYRAW rkey); \
+ STC_API void cx_memb(_erase_entry)(Self* self, cx_value_t* val); \
\
- STC_INLINE CX CX##_init(void) {return c_make(CX)_cmap_inits;} \
- STC_INLINE void CX##_shrink_to_fit(CX* self) {CX##_reserve(self, self->size);} \
- STC_INLINE void CX##_max_load_factor(CX* self, float ml) {self->max_load_factor = ml;} \
- STC_INLINE bool CX##_empty(CX m) {return m.size == 0;} \
- STC_INLINE size_t CX##_size(CX m) {return m.size;} \
- STC_INLINE size_t CX##_bucket_count(CX map) {return map.bucket_count;} \
- STC_INLINE size_t CX##_capacity(CX map) \
- {return (size_t) (map.bucket_count * map.max_load_factor);} \
- STC_INLINE void CX##_swap(CX *map1, CX *map2) {c_swap(CX, *map1, *map2);} \
- STC_INLINE bool CX##_contains(const CX* self, RawKey rkey) \
- {return self->size && self->_hashx[CX##_bucket_(self, &rkey).idx];} \
+ STC_INLINE Self cx_memb(_init)(void) { return c_make(Self)_cmap_inits; } \
+ STC_INLINE void cx_memb(_shrink_to_fit)(Self* self) {cx_memb(_reserve)(self, self->size); } \
+ STC_INLINE void cx_memb(_max_load_factor)(Self* self, float ml) {self->max_load_factor = ml; } \
+ STC_INLINE bool cx_memb(_empty)(Self m) { return m.size == 0; } \
+ STC_INLINE size_t cx_memb(_size)(Self m) { return m.size; } \
+ STC_INLINE size_t cx_memb(_bucket_count)(Self map) { return map.bucket_count; } \
+ STC_INLINE size_t cx_memb(_capacity)(Self map) \
+ { return (size_t) (map.bucket_count * map.max_load_factor); } \
+ STC_INLINE void cx_memb(_swap)(Self *map1, Self *map2) {c_swap(Self, *map1, *map2); } \
+ STC_INLINE bool cx_memb(_contains)(const Self* self, i_KEYRAW rkey) \
+ { return self->size && self->_hashx[cx_memb(_bucket_)(self, &rkey).idx]; } \
\
STC_INLINE void \
- CX##_value_clone(CX##_value_t* _dst, CX##_value_t* _val) { \
- *KEY_REF_##C(_dst) = keyFromRaw(keyToRaw(KEY_REF_##C(_val))); \
- MAP_ONLY_##C( _dst->second = mappedFromRaw(mappedToRaw(&_val->second)); ) \
+ cx_memb(_value_clone)(cx_value_t* _dst, cx_value_t* _val) { \
+ *KEY_REF_##C(_dst) = i_KEYFROM(i_KEYTO(KEY_REF_##C(_val))); \
+ MAP_ONLY_##C( _dst->second = i_VALFROM(i_VALTO(&_val->second)); ) \
} \
\
- STC_INLINE CX##_rawvalue_t \
- CX##_value_toraw(CX##_value_t* val) { \
- return SET_ONLY_##C( keyToRaw(val) ) \
- MAP_ONLY_##C( c_make(CX##_rawvalue_t){keyToRaw(&val->first), mappedToRaw(&val->second)} ); \
+ STC_INLINE cx_rawvalue_t \
+ cx_memb(_value_toraw)(cx_value_t* val) { \
+ return SET_ONLY_##C( i_KEYTO(val) ) \
+ MAP_ONLY_##C( c_make(cx_rawvalue_t){i_KEYTO(&val->first), i_VALTO(&val->second)} ); \
} \
\
STC_INLINE void \
- CX##_value_del(CX##_value_t* _val) { \
- keyDel(KEY_REF_##C(_val)); \
- MAP_ONLY_##C( mappedDel(&_val->second); ) \
+ cx_memb(_value_del)(cx_value_t* _val) { \
+ i_KEYDEL(KEY_REF_##C(_val)); \
+ MAP_ONLY_##C( i_VALDEL(&_val->second); ) \
} \
\
- STC_INLINE CX##_result_t \
- CX##_emplace(CX* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \
- CX##_result_t _res = CX##_insert_entry_(self, rkey); \
+ STC_INLINE cx_result_t \
+ cx_memb(_emplace)(Self* self, i_KEYRAW rkey MAP_ONLY_##C(, i_VALRAW rmapped)) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, rkey); \
if (_res.inserted) { \
- *KEY_REF_##C(_res.ref) = keyFromRaw(rkey); \
- MAP_ONLY_##C(_res.ref->second = mappedFromRaw(rmapped);) \
+ *KEY_REF_##C(_res.ref) = i_KEYFROM(rkey); \
+ MAP_ONLY_##C(_res.ref->second = i_VALFROM(rmapped);) \
} \
return _res; \
} \
\
STC_INLINE void \
- CX##_emplace_items(CX* self, const CX##_rawvalue_t arr[], size_t n) { \
- for (size_t i=0; i<n; ++i) SET_ONLY_##C( CX##_emplace(self, arr[i]); ) \
- MAP_ONLY_##C( CX##_emplace(self, arr[i].first, arr[i].second); ) \
+ cx_memb(_emplace_items)(Self* self, const cx_rawvalue_t arr[], size_t n) { \
+ for (size_t i=0; i<n; ++i) SET_ONLY_##C( cx_memb(_emplace)(self, arr[i]); ) \
+ MAP_ONLY_##C( cx_memb(_emplace)(self, arr[i].first, arr[i].second); ) \
} \
\
- STC_INLINE CX##_result_t \
- CX##_insert(CX* self, Key _key MAP_ONLY_##C(, Mapped _mapped)) { \
- CX##_result_t _res = CX##_insert_entry_(self, keyToRaw(&_key)); \
+ STC_INLINE cx_result_t \
+ cx_memb(_insert)(Self* self, i_KEY _key MAP_ONLY_##C(, i_VAL _mapped)) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, i_KEYTO(&_key)); \
if (_res.inserted) {*KEY_REF_##C(_res.ref) = _key; MAP_ONLY_##C( _res.ref->second = _mapped; )} \
- else {keyDel(&_key); MAP_ONLY_##C( mappedDel(&_mapped); )} \
+ else {i_KEYDEL(&_key); MAP_ONLY_##C( i_VALDEL(&_mapped); )} \
return _res; \
} \
\
MAP_ONLY_##C( \
- STC_INLINE CX##_result_t \
- CX##_insert_or_assign(CX* self, Key _key, Mapped _mapped) { \
- CX##_result_t _res = CX##_insert_entry_(self, keyToRaw(&_key)); \
+ STC_INLINE cx_result_t \
+ cx_memb(_insert_or_assign)(Self* self, i_KEY _key, i_VAL _mapped) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, i_KEYTO(&_key)); \
if (_res.inserted) _res.ref->first = _key; \
- else {keyDel(&_key); mappedDel(&_res.ref->second);} \
+ else {i_KEYDEL(&_key); i_VALDEL(&_res.ref->second); } \
_res.ref->second = _mapped; return _res; \
} \
\
- STC_INLINE CX##_result_t \
- CX##_put(CX* self, Key k, Mapped m) { /* shorter, like operator[] */ \
- return CX##_insert_or_assign(self, k, m); \
+ STC_INLINE cx_result_t \
+ cx_memb(_put)(Self* self, i_KEY k, i_VAL m) { /* shorter, like operator[] */ \
+ return cx_memb(_insert_or_assign)(self, k, m); \
} \
\
- STC_INLINE CX##_result_t \
- CX##_emplace_or_assign(CX* self, RawKey rkey, RawMapped rmapped) { \
- CX##_result_t _res = CX##_insert_entry_(self, rkey); \
- if (_res.inserted) _res.ref->first = keyFromRaw(rkey); \
- else mappedDel(&_res.ref->second); \
- _res.ref->second = mappedFromRaw(rmapped); return _res; \
+ STC_INLINE cx_result_t \
+ cx_memb(_emplace_or_assign)(Self* self, i_KEYRAW rkey, i_VALRAW rmapped) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, rkey); \
+ if (_res.inserted) _res.ref->first = i_KEYFROM(rkey); \
+ else i_VALDEL(&_res.ref->second); \
+ _res.ref->second = i_VALFROM(rmapped); return _res; \
} \
\
- STC_INLINE CX##_mapped_t* \
- CX##_at(const CX* self, RawKey rkey) { \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
+ STC_INLINE cx_mapped_t* \
+ cx_memb(_at)(const Self* self, i_KEYRAW rkey) { \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
return &self->table[b.idx].second; \
}) \
\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawKey rkey) { \
- CX##_iter_t it = {NULL}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_find)(const Self* self, i_KEYRAW rkey) { \
+ cx_iter_t it = {NULL}; \
if (self->size == 0) return it; \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
if (*(it._hx = self->_hashx+b.idx)) it.ref = self->table+b.idx; \
return it; \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_get(const CX* self, RawKey rkey) \
- {return CX##_find(self, rkey).ref;} \
+ STC_INLINE cx_value_t* \
+ cx_memb(_get)(const Self* self, i_KEYRAW rkey) \
+ { return cx_memb(_find)(self, rkey).ref; } \
\
- STC_INLINE CX##_iter_t \
- CX##_begin(const CX* self) { \
- CX##_iter_t it = {self->table, self->_hashx}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_begin)(const Self* self) { \
+ cx_iter_t it = {self->table, self->_hashx}; \
if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; \
return it; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_end(const CX* self) \
- {return c_make(CX##_iter_t){self->table + self->bucket_count};} \
+ STC_INLINE cx_iter_t \
+ cx_memb(_end)(const Self* self) \
+ { return c_make(cx_iter_t){self->table + self->bucket_count}; } \
\
STC_INLINE void \
- CX##_next(CX##_iter_t* it) \
- {while ((++it->ref, *++it->_hx == 0)) ;} \
+ cx_memb(_next)(cx_iter_t* it) \
+ {while ((++it->ref, *++it->_hx == 0)) ; } \
\
STC_INLINE size_t \
- CX##_erase(CX* self, RawKey rkey) { \
+ cx_memb(_erase)(Self* self, i_KEYRAW rkey) { \
if (self->size == 0) return 0; \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
- return self->_hashx[b.idx] ? CX##_erase_entry(self, self->table + b.idx), 1 : 0; \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
+ return self->_hashx[b.idx] ? cx_memb(_erase_entry)(self, self->table + b.idx), 1 : 0; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_erase_at(CX* self, CX##_iter_t it) { \
- CX##_erase_entry(self, it.ref); \
- if (*it._hx == 0) CX##_next(&it); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_erase_at)(Self* self, cx_iter_t it) { \
+ cx_memb(_erase_entry)(self, it.ref); \
+ if (*it._hx == 0) cx_memb(_next)(&it); \
return it; \
} \
\
- _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey) \
+ _c_implement_chash(Self, C, i_KEY, i_VAL, i_EQU, i_HASH, \
+ i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW, \
+ i_KEYDEL, i_KEYFROM, i_KEYTO, i_KEYRAW) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -329,63 +223,63 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored)
#ifdef c_umul128
STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \
- {uint64_t l, h; c_umul128(x, n, &l, &h); return h;}
+ {uint64_t l, h; c_umul128(x, n, &l, &h); return h; }
#endif
#define fastrange_uint32_t(x, n) ((size_t) (((uint32_t)(x)*(uint64_t)(n)) >> 32))
#define chash_index_(h, entryPtr) ((entryPtr) - (h).table)
-#define _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey) \
- STC_DEF CX \
- CX##_with_capacity(size_t cap) { \
- CX h = _cmap_inits; \
- CX##_reserve(&h, cap); \
+#define _c_implement_chash(Self, C, i_KEY, i_VAL, i_EQU, i_HASH, \
+ i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW, \
+ i_KEYDEL, i_KEYFROM, i_KEYTO, i_KEYRAW) \
+ STC_DEF Self \
+ cx_memb(_with_capacity)(size_t cap) { \
+ Self h = _cmap_inits; \
+ cx_memb(_reserve)(&h, cap); \
return h; \
} \
\
- STC_INLINE void CX##_wipe_(CX* self) { \
+ STC_INLINE void cx_memb(_wipe_)(Self* self) { \
if (self->size == 0) return; \
- CX##_value_t* e = self->table, *end = e + self->bucket_count; \
+ cx_value_t* e = self->table, *end = e + self->bucket_count; \
uint8_t *hx = self->_hashx; \
- for (; e != end; ++e) if (*hx++) CX##_value_del(e); \
+ for (; e != end; ++e) if (*hx++) cx_memb(_value_del)(e); \
} \
\
- STC_DEF void CX##_del(CX* self) { \
- CX##_wipe_(self); \
+ STC_DEF void cx_memb(_del)(Self* self) { \
+ cx_memb(_wipe_)(self); \
c_free(self->_hashx); \
c_free((void *) self->table); \
} \
\
- STC_DEF void CX##_clear(CX* self) { \
- CX##_wipe_(self); \
+ STC_DEF void cx_memb(_clear)(Self* self) { \
+ cx_memb(_wipe_)(self); \
self->size = 0; \
memset(self->_hashx, 0, self->bucket_count); \
} \
\
STC_DEF chash_bucket_t \
- CX##_bucket_(const CX* self, const CX##_rawkey_t* rkeyptr) { \
- const uint64_t _hash = keyHashRaw(rkeyptr, sizeof *rkeyptr); \
+ cx_memb(_bucket_)(const Self* self, const cx_rawkey_t* rkeyptr) { \
+ const uint64_t _hash = i_HASH(rkeyptr, sizeof *rkeyptr); \
uint_fast8_t _hx; size_t _cap = self->bucket_count; \
chash_bucket_t b = {c_SELECT(fastrange,CMAP_SIZE_T)(_hash, _cap), (uint_fast8_t)(_hash | 0x80)}; \
const uint8_t* _hashx = self->_hashx; \
while ((_hx = _hashx[b.idx])) { \
if (_hx == b.hx) { \
- CX##_rawkey_t _raw = keyToRaw(KEY_REF_##C(self->table + b.idx)); \
- if (keyEqualsRaw(&_raw, rkeyptr)) break; \
+ cx_rawkey_t _raw = i_KEYTO(KEY_REF_##C(self->table + b.idx)); \
+ if (i_EQU(&_raw, rkeyptr)) break; \
} \
if (++b.idx == _cap) b.idx = 0; \
} \
return b; \
} \
\
- STC_DEF CX##_result_t \
- CX##_insert_entry_(CX* self, RawKey rkey) { \
- if (self->size + 1 >= (CX##_size_t) (self->bucket_count * self->max_load_factor)) \
- CX##_reserve(self, 8 + (self->size*13ull >> 3)); \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
- CX##_result_t res = {&self->table[b.idx], !self->_hashx[b.idx]}; \
+ STC_DEF cx_result_t \
+ cx_memb(_insert_entry_)(Self* self, i_KEYRAW rkey) { \
+ if (self->size + 1 >= (cx_memb(_size_t)) (self->bucket_count * self->max_load_factor)) \
+ cx_memb(_reserve)(self, 8 + (self->size*13ull >> 3)); \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
+ cx_result_t res = {&self->table[b.idx], !self->_hashx[b.idx]}; \
if (res.inserted) { \
self->_hashx[b.idx] = b.hx; \
++self->size; \
@@ -393,39 +287,39 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \
return res; \
} \
\
- STC_DEF CX \
- CX##_clone(CX m) { \
- CX clone = { \
- c_new_n(CX##_value_t, m.bucket_count), \
+ STC_DEF Self \
+ cx_memb(_clone)(Self m) { \
+ Self clone = { \
+ c_new_n(cx_value_t, m.bucket_count), \
(uint8_t *) memcpy(c_malloc(m.bucket_count + 1), m._hashx, m.bucket_count + 1), \
m.size, m.bucket_count, \
m.max_load_factor \
}; \
- CX##_value_t *e = m.table, *end = e + m.bucket_count, *dst = clone.table; \
+ cx_value_t *e = m.table, *end = e + m.bucket_count, *dst = clone.table; \
for (uint8_t *hx = m._hashx; e != end; ++hx, ++e, ++dst) \
- if (*hx) CX##_value_clone(dst, e); \
+ if (*hx) cx_memb(_value_clone)(dst, e); \
return clone; \
} \
\
STC_DEF void \
- CX##_reserve(CX* self, size_t _newcap) { \
+ cx_memb(_reserve)(Self* self, size_t _newcap) { \
if (_newcap < self->size) return; \
size_t _oldcap = self->bucket_count; \
_newcap = (size_t) (2 + _newcap / self->max_load_factor) | 1; \
- CX _tmp = { \
- c_new_n(CX##_value_t, _newcap), \
+ Self _tmp = { \
+ c_new_n(cx_value_t, _newcap), \
(uint8_t *) c_calloc(_newcap + 1, sizeof(uint8_t)), \
- self->size, (CX##_size_t) _newcap, \
+ self->size, (cx_memb(_size_t)) _newcap, \
self->max_load_factor \
}; \
/* Rehash: */ \
- _tmp._hashx[_newcap] = 0xff; c_swap(CX, *self, _tmp); \
- CX##_value_t* e = _tmp.table, *_slot = self->table; \
+ _tmp._hashx[_newcap] = 0xff; c_swap(Self, *self, _tmp); \
+ cx_value_t* e = _tmp.table, *_slot = self->table; \
uint8_t* _hashx = self->_hashx; \
for (size_t i = 0; i < _oldcap; ++i, ++e) \
if (_tmp._hashx[i]) { \
- CX##_rawkey_t _raw = keyToRaw(KEY_REF_##C(e)); \
- chash_bucket_t b = CX##_bucket_(self, &_raw); \
+ cx_rawkey_t _raw = i_KEYTO(KEY_REF_##C(e)); \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &_raw); \
memcpy((void *) &_slot[b.idx], e, sizeof *e); \
_hashx[b.idx] = (uint8_t) b.hx; \
} \
@@ -434,17 +328,17 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \
} \
\
STC_DEF void \
- CX##_erase_entry(CX* self, CX##_value_t* _val) { \
+ cx_memb(_erase_entry)(Self* self, cx_value_t* _val) { \
size_t i = chash_index_(*self, _val), j = i, k, _cap = self->bucket_count; \
- CX##_value_t* _slot = self->table; \
+ cx_value_t* _slot = self->table; \
uint8_t* _hashx = self->_hashx; \
- CX##_value_del(&_slot[i]); \
+ cx_memb(_value_del)(&_slot[i]); \
for (;;) { /* delete without leaving tombstone */ \
if (++j == _cap) j = 0; \
if (! _hashx[j]) \
break; \
- CX##_rawkey_t _raw = keyToRaw(KEY_REF_##C(_slot+j)); \
- k = c_SELECT(fastrange,CMAP_SIZE_T)(keyHashRaw(&_raw, sizeof _raw), _cap); \
+ cx_rawkey_t _raw = i_KEYTO(KEY_REF_##C(_slot+j)); \
+ k = c_SELECT(fastrange,CMAP_SIZE_T)(i_HASH(&_raw, sizeof _raw), _cap); \
if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ \
memcpy((void *) &_slot[i], &_slot[j], sizeof *_slot), _hashx[i] = _hashx[j], i = j; \
} \
@@ -457,7 +351,7 @@ 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;}
+ for (; p != end; p += 8) {memcpy(&k, p, 8); h ^= m*k; }
switch (len & 7) {
case 7: h ^= (uint64_t) p[6] << 48;
case 6: h ^= (uint64_t) p[5] << 40;
@@ -470,10 +364,5 @@ STC_DEF uint64_t c_default_hash(const void *key, size_t len) {
return h ^ (h >> 15);
}
-#else
-#define _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey)
#endif
-
#endif