From 691d951b93dbf2216e9e8dc089a147cfdae597ce Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 4 Sep 2020 14:23:08 +0200 Subject: Using X instead of tag as macro parameter name for readability. --- stc/carray.h | 104 ++++++++++++------------- stc/clist.h | 216 +++++++++++++++++++++++++-------------------------- stc/cmap.h | 246 +++++++++++++++++++++++++++++----------------------------- stc/cpqueue.h | 76 +++++++++--------- stc/cqueue.h | 50 ++++++------ stc/cstack.h | 46 +++++------ stc/cvec.h | 146 +++++++++++++++++----------------- 7 files changed, 442 insertions(+), 442 deletions(-) diff --git a/stc/carray.h b/stc/carray.h index 64d385a4..a167c58f 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -67,118 +67,118 @@ STC_INLINE size_t _carray3_size(const size_t* zdim) { return zdim[0] * zdim[-1]; } -#define declare_carray_common(D, tag, Value, valueDestroy) \ - typedef struct { Value *item, *end; } carray##D##tag##_iter_t; \ +#define declare_carray_common(D, X, Value, valueDestroy) \ + typedef struct { Value *item, *end; } carray##D##X##_iter_t; \ \ - STC_INLINE carray##D##tag##_iter_t \ - carray##D##tag##_begin(carray##D##tag* a) { \ - carray##D##tag##_iter_t it = {a->data, a->data + carray##D##_size(*a)}; return it; \ + STC_INLINE carray##D##X##_iter_t \ + carray##D##X##_begin(carray##D##X* a) { \ + carray##D##X##_iter_t it = {a->data, a->data + carray##D##_size(*a)}; return it; \ } \ STC_INLINE void \ - carray##D##tag##_next(carray##D##tag##_iter_t* it) { ++it->item; } \ + carray##D##X##_next(carray##D##X##_iter_t* it) { ++it->item; } \ \ STC_INLINE void \ - carray##D##tag##_destroy(carray##D##tag* self) { \ + carray##D##X##_destroy(carray##D##X* self) { \ if (self->_xdim & _carray_OWN) { \ - c_foreach (i, carray##D##tag, *self) \ + c_foreach (i, carray##D##X, *self) \ valueDestroy(i.item); \ free(self->data); \ } \ } #define declare_carray(...) c_MACRO_OVERLOAD(declare_carray, __VA_ARGS__) -#define declare_carray_2(tag, Value) \ - declare_carray_3(tag, Value, c_default_destroy) +#define declare_carray_2(X, Value) \ + declare_carray_3(X, Value, c_default_destroy) -#define declare_carray_3(tag, Value, valueDestroy) \ - typedef struct carray1##tag { \ +#define declare_carray_3(X, Value, valueDestroy) \ + typedef struct carray1##X { \ Value *data; \ size_t _xdim; \ - } carray1##tag; \ + } carray1##X; \ \ - typedef struct carray2##tag { \ + typedef struct carray2##X { \ Value *data; \ size_t _xdim, _yxdim; \ - } carray2##tag; \ + } carray2##X; \ \ - typedef struct carray3##tag { \ + typedef struct carray3##X { \ Value *data; \ size_t _xdim, _yxdim, _zdim; \ - } carray3##tag; \ + } carray3##X; \ \ - declare_carray_common(1, tag, Value, valueDestroy) \ - declare_carray_common(2, tag, Value, valueDestroy) \ - declare_carray_common(3, tag, Value, valueDestroy) \ + declare_carray_common(1, X, Value, valueDestroy) \ + declare_carray_common(2, X, Value, valueDestroy) \ + declare_carray_common(3, X, Value, valueDestroy) \ \ - STC_INLINE carray1##tag \ - carray1##tag##_make(size_t xdim, Value val) { \ + STC_INLINE carray1##X \ + carray1##X##_make(size_t xdim, Value val) { \ Value* m = c_new_n(Value, xdim); \ for (size_t i=0; idata + x; } \ + carray1##X##_at(carray1##X *a, size_t x) { return a->data + x; } \ \ - STC_INLINE carray1##tag \ - carray2##tag##_at1(carray2##tag *a, size_t y) { \ - carray1##tag sub = {a->data + y*carray2_xdim(*a), carray2_xdim(*a)}; \ + STC_INLINE carray1##X \ + carray2##X##_at1(carray2##X *a, size_t y) { \ + carray1##X sub = {a->data + y*carray2_xdim(*a), carray2_xdim(*a)}; \ return sub; \ } \ STC_INLINE Value* \ - carray2##tag##_at(carray2##tag *a, size_t y, size_t x) { \ + carray2##X##_at(carray2##X *a, size_t y, size_t x) { \ return a->data + y*carray2_xdim(*a) + x; \ } \ \ - STC_INLINE carray2##tag \ - carray3##tag##_at1(carray3##tag *a, size_t z) { \ - carray2##tag sub = {a->data + z*a->_yxdim, carray3_xdim(*a), a->_yxdim}; \ + STC_INLINE carray2##X \ + carray3##X##_at1(carray3##X *a, size_t z) { \ + carray2##X sub = {a->data + z*a->_yxdim, carray3_xdim(*a), a->_yxdim}; \ return sub; \ } \ - STC_INLINE carray1##tag \ - carray3##tag##_at2(carray3##tag *a, size_t z, size_t y) { \ - carray1##tag sub = {a->data + z*a->_yxdim + y*carray3_xdim(*a), carray3_xdim(*a)}; \ + STC_INLINE carray1##X \ + carray3##X##_at2(carray3##X *a, size_t z, size_t y) { \ + carray1##X sub = {a->data + z*a->_yxdim + y*carray3_xdim(*a), carray3_xdim(*a)}; \ return sub; \ } \ STC_INLINE Value* \ - carray3##tag##_at(carray3##tag *a, size_t z, size_t y, size_t x) { \ + carray3##X##_at(carray3##X *a, size_t z, size_t y, size_t x) { \ return a->data + z*a->_yxdim + y*carray3_xdim(*a) + x; \ } \ - typedef Value carray1##tag##_value_t; \ - typedef carray1##tag##_value_t carray2##tag##_value_t, carray3##tag##_value_t + typedef Value carray1##X##_value_t; \ + typedef carray1##X##_value_t carray2##X##_value_t, carray3##X##_value_t #endif diff --git a/stc/clist.h b/stc/clist.h index 530cd222..f5713e46 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -58,29 +58,29 @@ #define declare_clist(...) c_MACRO_OVERLOAD(declare_clist, __VA_ARGS__) -#define declare_clist_2(tag, Value) \ - declare_clist_3(tag, Value, c_default_destroy) -#define declare_clist_3(tag, Value, valueDestroy) \ - declare_clist_4(tag, Value, valueDestroy, c_default_compare) -#define declare_clist_4(tag, Value, valueDestroy, valueCompare) \ - declare_clist_7(tag, Value, valueDestroy, Value, \ +#define declare_clist_2(X, Value) \ + declare_clist_3(X, Value, c_default_destroy) +#define declare_clist_3(X, Value, valueDestroy) \ + declare_clist_4(X, Value, valueDestroy, c_default_compare) +#define declare_clist_4(X, Value, valueDestroy, valueCompare) \ + declare_clist_7(X, Value, valueDestroy, Value, \ valueCompare, c_default_to_raw, c_default_from_raw) #define declare_clist_str() declare_clist_7(str, cstr_t, cstr_destroy, const char*, \ cstr_compare_raw, cstr_to_raw, cstr_make) -#define declare_clist_types(tag, Value) \ - typedef struct clist_##tag##_node { \ - struct clist_##tag##_node *next; \ +#define declare_clist_types(X, Value) \ + typedef struct clist_##X##_node { \ + struct clist_##X##_node *next; \ Value value; \ - } clist_##tag##_node_t; \ + } clist_##X##_node_t; \ \ - typedef struct clist_##tag { \ - clist_##tag##_node_t *last; \ - } clist_##tag; \ + typedef struct clist_##X { \ + clist_##X##_node_t *last; \ + } clist_##X; \ \ typedef struct { \ - clist_##tag##_node_t *item, *end, **_last; \ - } clist_##tag##_iter_t + clist_##X##_node_t *item, *end, **_last; \ + } clist_##X##_iter_t #define clist_ini {NULL} #define clist_empty(list) ((list).last == NULL) @@ -89,151 +89,151 @@ declare_clist_types(void, int); STC_API size_t _clist_size(const clist_void* self); -#define declare_clist_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ +#define declare_clist_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ \ - declare_clist_types(tag, Value); \ - typedef Value clist_##tag##_value_t; \ - typedef RawValue clist_##tag##_rawvalue_t; \ - typedef clist_##tag##_rawvalue_t clist_##tag##_input_t; \ + declare_clist_types(X, Value); \ + typedef Value clist_##X##_value_t; \ + typedef RawValue clist_##X##_rawvalue_t; \ + typedef clist_##X##_rawvalue_t clist_##X##_input_t; \ \ - STC_INLINE clist_##tag \ - clist_##tag##_init(void) {clist_##tag x = clist_ini; return x;} \ + STC_INLINE clist_##X \ + clist_##X##_init(void) {clist_##X x = clist_ini; return x;} \ STC_INLINE bool \ - clist_##tag##_empty(clist_##tag ls) {return clist_empty(ls);} \ + clist_##X##_empty(clist_##X ls) {return clist_empty(ls);} \ STC_INLINE size_t \ - clist_##tag##_size(clist_##tag ls) {return _clist_size((const clist_void*) &ls);} \ + clist_##X##_size(clist_##X ls) {return _clist_size((const clist_void*) &ls);} \ STC_INLINE Value \ - clist_##tag##_value_from_raw(RawValue rawValue) {return valueFromRaw(rawValue);} \ + clist_##X##_value_from_raw(RawValue rawValue) {return valueFromRaw(rawValue);} \ \ STC_API void \ - clist_##tag##_destroy(clist_##tag* self); \ + clist_##X##_destroy(clist_##X* self); \ STC_INLINE void \ - clist_##tag##_clear(clist_##tag* self) {clist_##tag##_destroy(self);} \ + clist_##X##_clear(clist_##X* self) {clist_##X##_destroy(self);} \ \ STC_API void \ - clist_##tag##_push_n(clist_##tag *self, const clist_##tag##_input_t in[], size_t size); \ + clist_##X##_push_n(clist_##X *self, const clist_##X##_input_t in[], size_t size); \ STC_API void \ - clist_##tag##_push_back_v(clist_##tag* self, Value value); \ + clist_##X##_push_back_v(clist_##X* self, Value value); \ STC_INLINE void \ - clist_##tag##_push_back(clist_##tag* self, RawValue rawValue) { \ - clist_##tag##_push_back_v(self, valueFromRaw(rawValue)); \ + clist_##X##_push_back(clist_##X* self, RawValue rawValue) { \ + clist_##X##_push_back_v(self, valueFromRaw(rawValue)); \ } \ STC_API void \ - clist_##tag##_push_front_v(clist_##tag* self, Value value); \ + clist_##X##_push_front_v(clist_##X* self, Value value); \ STC_INLINE void \ - clist_##tag##_push_front(clist_##tag* self, RawValue rawValue) { \ - clist_##tag##_push_front_v(self, valueFromRaw(rawValue)); \ + clist_##X##_push_front(clist_##X* self, RawValue rawValue) { \ + clist_##X##_push_front_v(self, valueFromRaw(rawValue)); \ } \ STC_API void \ - clist_##tag##_pop_front(clist_##tag* self); \ + clist_##X##_pop_front(clist_##X* self); \ \ - STC_INLINE clist_##tag##_iter_t \ - clist_##tag##_before_begin(clist_##tag* self) { \ - clist_##tag##_iter_t it = {self->last, self->last, &self->last}; return it; \ + STC_INLINE clist_##X##_iter_t \ + clist_##X##_before_begin(clist_##X* self) { \ + clist_##X##_iter_t it = {self->last, self->last, &self->last}; return it; \ } \ - STC_INLINE clist_##tag##_iter_t \ - clist_##tag##_begin(clist_##tag* self) { \ - clist_##tag##_node_t *head = self->last ? self->last->next : NULL; \ - clist_##tag##_iter_t it = {head, NULL, &self->last}; return it; \ + STC_INLINE clist_##X##_iter_t \ + clist_##X##_begin(clist_##X* self) { \ + clist_##X##_node_t *head = self->last ? self->last->next : NULL; \ + clist_##X##_iter_t it = {head, NULL, &self->last}; return it; \ } \ - STC_INLINE clist_##tag##_iter_t \ - clist_##tag##_last(clist_##tag* self) { \ - clist_##tag##_iter_t it = {self->last, NULL, &self->last}; return it; \ + STC_INLINE clist_##X##_iter_t \ + clist_##X##_last(clist_##X* self) { \ + clist_##X##_iter_t it = {self->last, NULL, &self->last}; return it; \ } \ STC_INLINE void \ - clist_##tag##_next(clist_##tag##_iter_t* it) { \ + clist_##X##_next(clist_##X##_iter_t* it) { \ it->end = it->item == *it->_last ? it->item->next : NULL; \ it->item = it->item->next; \ } \ - STC_INLINE clist_##tag##_value_t* \ - clist_##tag##_itval(clist_##tag##_iter_t it) {return &it.item->value;} \ + STC_INLINE clist_##X##_value_t* \ + clist_##X##_itval(clist_##X##_iter_t it) {return &it.item->value;} \ \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_insert_after_v(clist_##tag* self, clist_##tag##_iter_t pos, Value value); \ - STC_INLINE clist_##tag##_iter_t \ - clist_##tag##_insert_after(clist_##tag* self, clist_##tag##_iter_t pos, RawValue rawValue) { \ - return clist_##tag##_insert_after_v(self, pos, valueFromRaw(rawValue)); \ + STC_API clist_##X##_iter_t \ + clist_##X##_insert_after_v(clist_##X* self, clist_##X##_iter_t pos, Value value); \ + STC_INLINE clist_##X##_iter_t \ + clist_##X##_insert_after(clist_##X* self, clist_##X##_iter_t pos, RawValue rawValue) { \ + return clist_##X##_insert_after_v(self, pos, valueFromRaw(rawValue)); \ } \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_erase_after(clist_##tag* self, clist_##tag##_iter_t pos); \ + STC_API clist_##X##_iter_t \ + clist_##X##_erase_after(clist_##X* self, clist_##X##_iter_t pos); \ \ STC_INLINE void \ - clist_##tag##_splice_after(clist_##tag* self, clist_##tag##_iter_t pos, clist_##tag* other) { \ + clist_##X##_splice_after(clist_##X* self, clist_##X##_iter_t pos, clist_##X* other) { \ _clist_splice_after((clist_void *) self, *(clist_void_iter_t *) &pos, (clist_void *) other); \ } \ STC_INLINE void \ - clist_##tag##_splice_front(clist_##tag* self, clist_##tag* other) { \ - clist_##tag##_splice_after(self, clist_##tag##_before_begin(self), other); \ + clist_##X##_splice_front(clist_##X* self, clist_##X* other) { \ + clist_##X##_splice_after(self, clist_##X##_before_begin(self), other); \ } \ STC_INLINE void \ - clist_##tag##_splice_back(clist_##tag* self, clist_##tag* other) { \ - clist_##tag##_splice_after(self, clist_##tag##_last(self), other); \ + clist_##X##_splice_back(clist_##X* self, clist_##X* other) { \ + clist_##X##_splice_after(self, clist_##X##_last(self), other); \ } \ \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_find_before(clist_##tag* self, clist_##tag##_iter_t prev, RawValue val); \ + STC_API clist_##X##_iter_t \ + clist_##X##_find_before(clist_##X* self, clist_##X##_iter_t prev, RawValue val); \ STC_API Value* \ - clist_##tag##_find(clist_##tag* self, RawValue val); \ + clist_##X##_find(clist_##X* self, RawValue val); \ STC_API size_t \ - clist_##tag##_remove(clist_##tag* self, RawValue val); \ + clist_##X##_remove(clist_##X* self, RawValue val); \ STC_API void \ - clist_##tag##_sort(clist_##tag* self); \ + clist_##X##_sort(clist_##X* self); \ \ STC_INLINE Value* \ - clist_##tag##_front(clist_##tag* self) {return &self->last->next->value;} \ + clist_##X##_front(clist_##X* self) {return &self->last->next->value;} \ STC_INLINE Value* \ - clist_##tag##_back(clist_##tag* self) {return &self->last->value;} \ + clist_##X##_back(clist_##X* self) {return &self->last->value;} \ \ - implement_clist_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) + implement_clist_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_clist_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ +#define implement_clist_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ \ STC_API void \ - clist_##tag##_destroy(clist_##tag* self) { \ + clist_##X##_destroy(clist_##X* self) { \ while (self->last) \ - clist_##tag##_pop_front(self); \ + clist_##X##_pop_front(self); \ } \ \ STC_API void \ - clist_##tag##_push_back_v(clist_##tag* self, Value value) { \ - _clist_insert_after(self, tag, self->last, value); \ + clist_##X##_push_back_v(clist_##X* self, Value value) { \ + _clist_insert_after(self, X, self->last, value); \ self->last = entry; \ } \ STC_API void \ - clist_##tag##_push_front_v(clist_##tag* self, Value value) { \ - _clist_insert_after(self, tag, self->last, value); \ + clist_##X##_push_front_v(clist_##X* self, Value value) { \ + _clist_insert_after(self, X, self->last, value); \ if (!self->last) self->last = entry; \ } \ STC_API void \ - clist_##tag##_push_n(clist_##tag *self, const clist_##tag##_input_t in[], size_t size) { \ - for (size_t i=0; ilast, valueDestroy); \ + clist_##X##_pop_front(clist_##X* self) { \ + _clist_erase_after(self, X, self->last, valueDestroy); \ } \ \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_insert_after_v(clist_##tag* self, clist_##tag##_iter_t pos, Value value) { \ - _clist_insert_after(self, tag, pos.item, value); \ + STC_API clist_##X##_iter_t \ + clist_##X##_insert_after_v(clist_##X* self, clist_##X##_iter_t pos, Value value) { \ + _clist_insert_after(self, X, pos.item, value); \ if (pos.item == self->last && pos.item != pos.end) self->last = entry; \ pos.item = entry; return pos; \ } \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_erase_after(clist_##tag* self, clist_##tag##_iter_t pos) { \ - _clist_erase_after(self, tag, pos.item, valueDestroy); \ - clist_##tag##_next(&pos); return pos; \ + STC_API clist_##X##_iter_t \ + clist_##X##_erase_after(clist_##X* self, clist_##X##_iter_t pos) { \ + _clist_erase_after(self, X, pos.item, valueDestroy); \ + clist_##X##_next(&pos); return pos; \ } \ \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_find_before(clist_##tag* self, clist_##tag##_iter_t prev, RawValue val) { \ - clist_##tag##_iter_t i = prev; \ + STC_API clist_##X##_iter_t \ + clist_##X##_find_before(clist_##X* self, clist_##X##_iter_t prev, RawValue val) { \ + clist_##X##_iter_t i = prev; \ if (i.item) i.item = i.item->next; \ - for (; i.item != i.end; clist_##tag##_next(&i)) { \ + for (; i.item != i.end; clist_##X##_next(&i)) { \ RawValue r = valueToRaw(&i.item->value); \ if (valueCompareRaw(&r, &val) == 0) \ return prev; \ @@ -244,43 +244,43 @@ STC_API size_t _clist_size(const clist_void* self); } \ \ STC_API Value* \ - clist_##tag##_find(clist_##tag* self, RawValue val) { \ - clist_##tag##_iter_t it = clist_##tag##_find_before(self, clist_##tag##_before_begin(self), val); \ + clist_##X##_find(clist_##X* self, RawValue val) { \ + clist_##X##_iter_t it = clist_##X##_find_before(self, clist_##X##_before_begin(self), val); \ return it.item ? &it.item->next->value : NULL; \ } \ \ STC_API size_t \ - clist_##tag##_remove(clist_##tag* self, RawValue val) { \ - clist_##tag##_iter_t it; size_t n = 0; \ - while ((it = clist_##tag##_find_before(self, clist_##tag##_before_begin(self), val)).item) \ - it = clist_##tag##_erase_after(self, it), ++n; \ + clist_##X##_remove(clist_##X* self, RawValue val) { \ + clist_##X##_iter_t it; size_t n = 0; \ + while ((it = clist_##X##_find_before(self, clist_##X##_before_begin(self), val)).item) \ + it = clist_##X##_erase_after(self, it), ++n; \ return n; \ } \ \ static inline int \ - clist_##tag##_sort_compare(const void* x, const void* y) { \ - RawValue a = valueToRaw(&((clist_##tag##_node_t *) x)->value); \ - RawValue b = valueToRaw(&((clist_##tag##_node_t *) y)->value); \ + clist_##X##_sort_compare(const void* x, const void* y) { \ + RawValue a = valueToRaw(&((clist_##X##_node_t *) x)->value); \ + RawValue b = valueToRaw(&((clist_##X##_node_t *) y)->value); \ return valueCompareRaw(&a, &b); \ } \ STC_API void \ - clist_##tag##_sort(clist_##tag* self) { \ - clist_void_node_t* last = _clist_mergesort((clist_void_node_t *) self->last->next, clist_##tag##_sort_compare); \ - self->last = (clist_##tag##_node_t *) last; \ + clist_##X##_sort(clist_##X* self) { \ + clist_void_node_t* last = _clist_mergesort((clist_void_node_t *) self->last->next, clist_##X##_sort_compare); \ + self->last = (clist_##X##_node_t *) last; \ } \ - typedef int clist_##tag##_dud + typedef int clist_##X##_dud -#define _clist_insert_after(self, tag, node, val) \ - clist_##tag##_node_t *entry = c_new (clist_##tag##_node_t), \ +#define _clist_insert_after(self, X, node, val) \ + clist_##X##_node_t *entry = c_new (clist_##X##_node_t), \ *next = self->last ? node->next : entry; \ entry->value = val; \ entry->next = next; \ if (node) node->next = entry /* +: set self->last based on node */ -#define _clist_erase_after(self, tag, node, valueDestroy) \ - clist_##tag##_node_t* del = node->next, *next = del->next; \ +#define _clist_erase_after(self, X, node, valueDestroy) \ + clist_##X##_node_t* del = node->next, *next = del->next; \ node->next = next; \ if (del == next) self->last = NULL; \ else if (self->last == del) self->last = node; \ @@ -368,7 +368,7 @@ _clist_mergesort(clist_void_node_t *list, int (*cmp)(const void*, const void*)) } #else -#define implement_clist_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) +#define implement_clist_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) #endif #endif diff --git a/stc/cmap.h b/stc/cmap.h index 44f39174..9b02849d 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -60,8 +60,8 @@ int main(void) { #define cset_ini cmap_ini #define cset_size(s) cmap_size(s) #define cset_bucket_count(s) cmap_bucket_count(s) -#define cmap_try_emplace(tag, self, k, v) do { \ - struct cmap_##tag##_result __r = cmap_##tag##_insert_key(self, k); \ +#define cmap_try_emplace(X, self, k, v) do { \ + struct cmap_##X##_result __r = cmap_##X##_insert_key(self, k); \ if (__r.inserted) __r.entry->value = v; \ } while (false) @@ -74,38 +74,38 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; #define declare_cmap(...) \ c_MACRO_OVERLOAD(declare_cmap, __VA_ARGS__) -#define declare_cmap_3(tag, Key, Value) \ - declare_cmap_4(tag, Key, Value, c_default_destroy) +#define declare_cmap_3(X, Key, Value) \ + declare_cmap_4(X, Key, Value, c_default_destroy) -#define declare_cmap_4(tag, Key, Value, valueDestroy) \ - declare_cmap_6(tag, Key, Value, valueDestroy, c_default_equals, c_default_hash16) +#define declare_cmap_4(X, Key, Value, valueDestroy) \ + declare_cmap_6(X, Key, Value, valueDestroy, c_default_equals, c_default_hash16) -#define declare_cmap_6(tag, Key, Value, valueDestroy, keyEquals, keyHash) \ - declare_cmap_10(tag, Key, Value, valueDestroy, keyEquals, keyHash, \ +#define declare_cmap_6(X, Key, Value, valueDestroy, keyEquals, keyHash) \ + declare_cmap_10(X, Key, Value, valueDestroy, keyEquals, keyHash, \ c_default_destroy, Key, c_default_to_raw, c_default_from_raw) -#define declare_cmap_10(tag, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ +#define declare_cmap_10(X, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw) \ - declare_CHASH(tag, cmap, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ + declare_CHASH(X, cmap, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw, Value, c_default_from_raw) /* cset: */ #define declare_cset(...) \ c_MACRO_OVERLOAD(declare_cset, __VA_ARGS__) -#define declare_cset_2(tag, Key) \ - declare_cset_4(tag, Key, c_default_equals, c_default_hash16) +#define declare_cset_2(X, Key) \ + declare_cset_4(X, Key, c_default_equals, c_default_hash16) -#define declare_cset_4(tag, Key, keyEquals, keyHash) \ - declare_cset_5(tag, Key, keyEquals, keyHash, c_default_destroy) +#define declare_cset_4(X, Key, keyEquals, keyHash) \ + declare_cset_5(X, Key, keyEquals, keyHash, c_default_destroy) -#define declare_cset_5(tag, Key, keyEquals, keyHash, keyDestroy) \ - declare_cset_8(tag, Key, keyEquals, keyHash, keyDestroy, \ +#define declare_cset_5(X, Key, keyEquals, keyHash, keyDestroy) \ + declare_cset_8(X, Key, keyEquals, keyHash, keyDestroy, \ Key, c_default_to_raw, c_default_from_raw) -#define declare_cset_8(tag, Key, keyEqualsRaw, keyHashRaw, keyDestroy, \ +#define declare_cset_8(X, Key, keyEqualsRaw, keyHashRaw, keyDestroy, \ RawKey, keyToRaw, keyFromRaw) \ - declare_CHASH(tag, cset, Key, Key, void, keyEqualsRaw, keyHashRaw, \ + declare_CHASH(X, cset, Key, Key, void, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw, void, c_default_from_raw) /* cset_str, cmap_str, cmap_strkey, cmap_strval: */ @@ -119,24 +119,24 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; #define declare_cmap_strkey(...) \ c_MACRO_OVERLOAD(declare_cmap_strkey, __VA_ARGS__) -#define declare_cmap_strkey_2(tag, Value) \ - declare_CHASH_strkey(tag, cmap, Value, c_default_destroy) +#define declare_cmap_strkey_2(X, Value) \ + declare_CHASH_strkey(X, cmap, Value, c_default_destroy) -#define declare_cmap_strkey_3(tag, Value, ValueDestroy) \ - declare_CHASH_strkey(tag, cmap, Value, ValueDestroy) +#define declare_cmap_strkey_3(X, Value, ValueDestroy) \ + declare_CHASH_strkey(X, cmap, Value, ValueDestroy) #define declare_cmap_strval(...) \ c_MACRO_OVERLOAD(declare_cmap_strval, __VA_ARGS__) -#define declare_cmap_strval_2(tag, Key) \ - declare_cmap_strval_4(tag, Key, c_default_equals, c_default_hash16) +#define declare_cmap_strval_2(X, Key) \ + declare_cmap_strval_4(X, Key, c_default_equals, c_default_hash16) -#define declare_cmap_strval_4(tag, Key, keyEquals, keyHash) \ - declare_CHASH(tag, cmap, Key, cstr_t, cstr_destroy, keyEquals, keyHash, \ +#define declare_cmap_strval_4(X, Key, keyEquals, keyHash) \ + declare_CHASH(X, cmap, Key, cstr_t, cstr_destroy, keyEquals, keyHash, \ c_default_destroy, Key, c_default_to_raw, c_default_from_raw, const char*, cstr_make) -#define declare_CHASH_strkey(tag, ctype, Value, valueDestroy) \ - declare_CHASH(tag, ctype, cstr_t, Value, valueDestroy, cstr_equals_raw, cstr_hash_raw, \ +#define declare_CHASH_strkey(X, ctype, Value, valueDestroy) \ + declare_CHASH(X, ctype, cstr_t, Value, valueDestroy, cstr_equals_raw, cstr_hash_raw, \ cstr_destroy, const char*, cstr_to_raw, cstr_make, Value, c_default_from_raw) #define CMAP_ONLY_cset(x) @@ -145,164 +145,164 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; #define CMAP_BOTH_cmap(x, y) x, y /* CHASH full: use 'void' for Value if ctype is cset */ -#define declare_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ +#define declare_CHASH(X, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw, RawValue, valueFromRaw) \ typedef struct { \ Key key; \ CMAP_ONLY_##ctype(Value value;) \ -} ctype##_##tag##_entry_t; \ +} ctype##_##X##_entry_t; \ \ STC_INLINE void \ -ctype##_##tag##_entry_destroy(ctype##_##tag##_entry_t* e) { \ +ctype##_##X##_entry_destroy(ctype##_##X##_entry_t* e) { \ keyDestroy(&e->key); \ CMAP_ONLY_##ctype(valueDestroy(&e->value);) \ } \ typedef struct { \ RawKey key; \ CMAP_ONLY_##ctype(RawValue value;) \ -} ctype##_##tag##_input_t; \ +} ctype##_##X##_input_t; \ \ -typedef Key ctype##_##tag##_key_t; \ -typedef Value ctype##_##tag##_value_t; \ -typedef RawKey ctype##_##tag##_rawkey_t; \ -typedef RawValue ctype##_##tag##_rawvalue_t; \ +typedef Key ctype##_##X##_key_t; \ +typedef Value ctype##_##X##_value_t; \ +typedef RawKey ctype##_##X##_rawkey_t; \ +typedef RawValue ctype##_##X##_rawvalue_t; \ \ -typedef struct ctype##_##tag { \ - ctype##_##tag##_entry_t* table; \ +typedef struct ctype##_##X { \ + ctype##_##X##_entry_t* table; \ uint8_t* _hashx; \ uint32_t size, bucket_count; \ float max_load_factor; \ float shrink_limit_factor; \ -} ctype##_##tag; \ +} ctype##_##X; \ \ typedef struct { \ - ctype##_##tag##_entry_t *item, *end; \ + ctype##_##X##_entry_t *item, *end; \ uint8_t* _hx; \ -} ctype##_##tag##_iter_t; \ +} ctype##_##X##_iter_t; \ \ -STC_INLINE ctype##_##tag \ -ctype##_##tag##_init(void) {ctype##_##tag m = cmap_ini; return m;} \ +STC_INLINE ctype##_##X \ +ctype##_##X##_init(void) {ctype##_##X m = cmap_ini; return m;} \ STC_INLINE bool \ -ctype##_##tag##_empty(ctype##_##tag m) {return m.size == 0;} \ +ctype##_##X##_empty(ctype##_##X m) {return m.size == 0;} \ STC_INLINE size_t \ -ctype##_##tag##_size(ctype##_##tag m) {return (size_t) m.size;} \ +ctype##_##X##_size(ctype##_##X m) {return (size_t) m.size;} \ STC_INLINE size_t \ -ctype##_##tag##_capacity(ctype##_##tag m) {return (size_t) (m.bucket_count * m.max_load_factor);} \ +ctype##_##X##_capacity(ctype##_##X m) {return (size_t) (m.bucket_count * m.max_load_factor);} \ STC_INLINE void \ -ctype##_##tag##_swap(ctype##_##tag* a, ctype##_##tag* b) {c_swap(ctype##_##tag, *a, *b);} \ +ctype##_##X##_swap(ctype##_##X* a, ctype##_##X* b) {c_swap(ctype##_##X, *a, *b);} \ STC_INLINE void \ -ctype##_##tag##_set_load_factors(ctype##_##tag* self, float max, float shrink) { \ +ctype##_##X##_set_load_factors(ctype##_##X* self, float max, float shrink) { \ self->max_load_factor = max; self->shrink_limit_factor = shrink; \ } \ -STC_API ctype##_##tag \ -ctype##_##tag##_with_capacity(size_t cap); \ +STC_API ctype##_##X \ +ctype##_##X##_with_capacity(size_t cap); \ STC_API void \ -ctype##_##tag##_push_n(ctype##_##tag* self, const ctype##_##tag##_input_t in[], size_t size); \ +ctype##_##X##_push_n(ctype##_##X* self, const ctype##_##X##_input_t in[], size_t size); \ STC_API void \ -ctype##_##tag##_destroy(ctype##_##tag* self); \ +ctype##_##X##_destroy(ctype##_##X* self); \ STC_API void \ -ctype##_##tag##_clear(ctype##_##tag* self); \ -STC_API ctype##_##tag##_entry_t* \ -ctype##_##tag##_find(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey); \ +ctype##_##X##_clear(ctype##_##X* self); \ +STC_API ctype##_##X##_entry_t* \ +ctype##_##X##_find(const ctype##_##X* self, ctype##_##X##_rawkey_t rawKey); \ \ -struct ctype##_##tag##_result {ctype##_##tag##_entry_t *entry; bool inserted;}; \ -STC_API struct ctype##_##tag##_result \ -ctype##_##tag##_insert_key(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey); \ +struct ctype##_##X##_result {ctype##_##X##_entry_t *entry; bool inserted;}; \ +STC_API struct ctype##_##X##_result \ +ctype##_##X##_insert_key(ctype##_##X* self, ctype##_##X##_rawkey_t rawKey); \ \ -STC_INLINE ctype##_##tag##_entry_t* /* like c++ std::map.insert(): */ \ -ctype##_##tag##_insert(ctype##_##tag* self, CMAP_BOTH_##ctype(ctype##_##tag##_rawkey_t rawKey, RawValue rawValue)) { \ - struct ctype##_##tag##_result res = ctype##_##tag##_insert_key(self, rawKey); \ +STC_INLINE ctype##_##X##_entry_t* /* like c++ std::map.insert(): */ \ +ctype##_##X##_insert(ctype##_##X* self, CMAP_BOTH_##ctype(ctype##_##X##_rawkey_t rawKey, RawValue rawValue)) { \ + struct ctype##_##X##_result res = ctype##_##X##_insert_key(self, rawKey); \ CMAP_ONLY_##ctype( if (res.inserted) res.entry->value = valueFromRaw(rawValue); ) \ return res.entry; \ } \ \ -STC_INLINE ctype##_##tag##_entry_t* /* like c++ std::map.insert_or_assign(): */ \ -ctype##_##tag##_put(ctype##_##tag* self, CMAP_BOTH_##ctype(ctype##_##tag##_rawkey_t rawKey, RawValue rawValue)) { \ - struct ctype##_##tag##_result res = ctype##_##tag##_insert_key(self, rawKey); \ +STC_INLINE ctype##_##X##_entry_t* /* like c++ std::map.insert_or_assign(): */ \ +ctype##_##X##_put(ctype##_##X* self, CMAP_BOTH_##ctype(ctype##_##X##_rawkey_t rawKey, RawValue rawValue)) { \ + struct ctype##_##X##_result res = ctype##_##X##_insert_key(self, rawKey); \ CMAP_ONLY_##ctype( if (!res.inserted) valueDestroy(&res.entry->value); \ res.entry->value = valueFromRaw(rawValue); ) \ return res.entry; \ } \ CMAP_ONLY_##ctype( \ -STC_INLINE ctype##_##tag##_entry_t* /* cmap_put_v(key, move(value)) */ \ -ctype##_##tag##_put_v(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Value value) { \ - struct ctype##_##tag##_result res = ctype##_##tag##_insert_key(self, rawKey); \ +STC_INLINE ctype##_##X##_entry_t* /* cmap_put_v(key, move(value)) */ \ +ctype##_##X##_put_v(ctype##_##X* self, ctype##_##X##_rawkey_t rawKey, Value value) { \ + struct ctype##_##X##_result res = ctype##_##X##_insert_key(self, rawKey); \ if (!res.inserted) valueDestroy(&res.entry->value); \ res.entry->value = value; \ return res.entry; \ } \ ) /* end CMAP_ONLY */ \ STC_API size_t \ -ctype##_##tag##_reserve(ctype##_##tag* self, size_t size); \ +ctype##_##X##_reserve(ctype##_##X* self, size_t size); \ STC_API bool \ -ctype##_##tag##_erase_entry(ctype##_##tag* self, ctype##_##tag##_entry_t* entry); \ +ctype##_##X##_erase_entry(ctype##_##X* self, ctype##_##X##_entry_t* entry); \ STC_API bool \ -ctype##_##tag##_erase(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey); \ +ctype##_##X##_erase(ctype##_##X* self, ctype##_##X##_rawkey_t rawKey); \ \ -STC_INLINE ctype##_##tag##_iter_t \ -ctype##_##tag##_begin(ctype##_##tag* self) { \ - ctype##_##tag##_iter_t it = {self->table, self->table + self->bucket_count, self->_hashx}; \ +STC_INLINE ctype##_##X##_iter_t \ +ctype##_##X##_begin(ctype##_##X* self) { \ + ctype##_##X##_iter_t it = {self->table, self->table + self->bucket_count, self->_hashx}; \ if (it._hx) while (*it._hx == 0) ++it.item, ++it._hx; \ return it; \ } \ STC_INLINE void \ -ctype##_##tag##_next(ctype##_##tag##_iter_t* it) { \ +ctype##_##X##_next(ctype##_##X##_iter_t* it) { \ while ((++it->item, *++it->_hx == 0)) ; \ } \ -CMAP_ONLY_##ctype( STC_INLINE ctype##_##tag##_value_t* \ -ctype##_##tag##_itval(ctype##_##tag##_iter_t it) {return &it.item->value;} ) \ +CMAP_ONLY_##ctype( STC_INLINE ctype##_##X##_value_t* \ +ctype##_##X##_itval(ctype##_##X##_iter_t it) {return &it.item->value;} ) \ \ STC_API uint32_t c_default_hash16(const void *data, size_t len); \ STC_API uint32_t c_default_hash32(const void* data, size_t len); \ \ -implement_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ +implement_CHASH(X, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw, RawValue, valueFromRaw) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ +#define implement_CHASH(X, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw, RawValue, valueFromRaw) \ -STC_API ctype##_##tag \ -ctype##_##tag##_with_capacity(size_t cap) { \ - ctype##_##tag h = ctype##_ini; \ - ctype##_##tag##_reserve(&h, cap); \ +STC_API ctype##_##X \ +ctype##_##X##_with_capacity(size_t cap) { \ + ctype##_##X h = ctype##_ini; \ + ctype##_##X##_reserve(&h, cap); \ return h; \ } \ STC_API void \ -ctype##_##tag##_push_n(ctype##_##tag* self, const ctype##_##tag##_input_t in[], size_t size) { \ - for (size_t i=0; isize == 0) return; \ - ctype##_##tag##_entry_t* e = self->table, *end = e + self->bucket_count; \ + ctype##_##X##_entry_t* e = self->table, *end = e + self->bucket_count; \ uint8_t *hx = self->_hashx; \ - for (; e != end; ++e) if (*hx++) ctype##_##tag##_entry_destroy(e); \ + for (; e != end; ++e) if (*hx++) ctype##_##X##_entry_destroy(e); \ } \ \ -STC_API void ctype##_##tag##_destroy(ctype##_##tag* self) { \ - ctype##_##tag##_wipe_(self); \ +STC_API void ctype##_##X##_destroy(ctype##_##X* self) { \ + ctype##_##X##_wipe_(self); \ free(self->_hashx); \ free(self->table); \ } \ \ -STC_API void ctype##_##tag##_clear(ctype##_##tag* self) { \ - ctype##_##tag##_wipe_(self); \ +STC_API void ctype##_##X##_clear(ctype##_##X* self) { \ + ctype##_##X##_wipe_(self); \ self->size = 0; \ memset(self->_hashx, 0, self->bucket_count); \ } \ \ STC_API size_t \ -ctype##_##tag##_bucket(const ctype##_##tag* self, const ctype##_##tag##_rawkey_t* rawKeyPtr, uint32_t* hxPtr) { \ - uint32_t hash = keyHashRaw(rawKeyPtr, sizeof(ctype##_##tag##_rawkey_t)); \ +ctype##_##X##_bucket(const ctype##_##X* self, const ctype##_##X##_rawkey_t* rawKeyPtr, uint32_t* hxPtr) { \ + uint32_t hash = keyHashRaw(rawKeyPtr, sizeof(ctype##_##X##_rawkey_t)); \ uint32_t sx, hx = (hash & chash_HASH) | chash_USED; \ size_t cap = self->bucket_count; \ size_t idx = chash_reduce(hash, cap); \ uint8_t* hashx = self->_hashx; \ while ((sx = hashx[idx])) { \ if (sx == hx) { \ - ctype##_##tag##_rawkey_t r = keyToRaw(&self->table[idx].key); \ + ctype##_##X##_rawkey_t r = keyToRaw(&self->table[idx].key); \ if (keyEqualsRaw(&r, rawKeyPtr)) break; \ } \ if (++idx == cap) idx = 0; \ @@ -311,25 +311,25 @@ ctype##_##tag##_bucket(const ctype##_##tag* self, const ctype##_##tag##_rawkey_t return idx; \ } \ \ -STC_API ctype##_##tag##_entry_t* \ -ctype##_##tag##_find(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \ +STC_API ctype##_##X##_entry_t* \ +ctype##_##X##_find(const ctype##_##X* self, ctype##_##X##_rawkey_t rawKey) { \ if (self->size == 0) return NULL; \ uint32_t hx; \ - size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \ + size_t idx = ctype##_##X##_bucket(self, &rawKey, &hx); \ return self->_hashx[idx] ? &self->table[idx] : NULL; \ } \ \ -STC_INLINE void ctype##_##tag##_reserve_expand(ctype##_##tag* self) { \ +STC_INLINE void ctype##_##X##_reserve_expand(ctype##_##X* self) { \ if (self->size + 1 >= self->bucket_count * self->max_load_factor) \ - ctype##_##tag##_reserve(self, 5 + self->size * 3 / 2); \ + ctype##_##X##_reserve(self, 5 + self->size * 3 / 2); \ } \ \ -STC_API struct ctype##_##tag##_result \ -ctype##_##tag##_insert_key(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \ - ctype##_##tag##_reserve_expand(self); \ +STC_API struct ctype##_##X##_result \ +ctype##_##X##_insert_key(ctype##_##X* self, ctype##_##X##_rawkey_t rawKey) { \ + ctype##_##X##_reserve_expand(self); \ uint32_t hx; \ - size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \ - struct ctype##_##tag##_result res = {&self->table[idx], !self->_hashx[idx]}; \ + size_t idx = ctype##_##X##_bucket(self, &rawKey, &hx); \ + struct ctype##_##X##_result res = {&self->table[idx], !self->_hashx[idx]}; \ if (res.inserted) { \ res.entry->key = keyFromRaw(rawKey); \ self->_hashx[idx] = (uint8_t) hx; \ @@ -339,25 +339,25 @@ ctype##_##tag##_insert_key(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) } \ \ STC_API size_t \ -ctype##_##tag##_reserve(ctype##_##tag* self, size_t newcap) { \ +ctype##_##X##_reserve(ctype##_##X* self, size_t newcap) { \ size_t oldcap = self->bucket_count; \ if (self->size > newcap) return oldcap; \ newcap = (size_t) (newcap / self->max_load_factor) | 1; \ - ctype##_##tag tmp = { \ - c_new_n(ctype##_##tag##_entry_t, newcap), \ + ctype##_##X tmp = { \ + c_new_n(ctype##_##X##_entry_t, newcap), \ (uint8_t *) calloc(newcap + 1, sizeof(uint8_t)), \ self->size, (uint32_t) newcap, \ self->max_load_factor, self->shrink_limit_factor \ }; \ /* Rehash: */ \ - tmp._hashx[newcap] = 0xff; c_swap(ctype##_##tag, *self, tmp); \ - ctype##_##tag##_entry_t* e = tmp.table, *slot = self->table; \ + tmp._hashx[newcap] = 0xff; c_swap(ctype##_##X, *self, tmp); \ + ctype##_##X##_entry_t* e = tmp.table, *slot = self->table; \ uint8_t* hashx = self->_hashx; \ uint32_t hx; \ for (size_t i = 0; i < oldcap; ++i, ++e) \ if (tmp._hashx[i]) { \ - ctype##_##tag##_rawkey_t r = keyToRaw(&e->key); \ - size_t idx = ctype##_##tag##_bucket(self, &r, &hx); \ + ctype##_##X##_rawkey_t r = keyToRaw(&e->key); \ + size_t idx = ctype##_##X##_bucket(self, &r, &hx); \ slot[idx] = *e, \ hashx[idx] = (uint8_t) hx; \ } \ @@ -367,20 +367,20 @@ ctype##_##tag##_reserve(ctype##_##tag* self, size_t newcap) { \ } \ \ STC_API bool \ -ctype##_##tag##_erase_entry(ctype##_##tag* self, ctype##_##tag##_entry_t* entry) { \ +ctype##_##X##_erase_entry(ctype##_##X* self, ctype##_##X##_entry_t* entry) { \ size_t i = chash_entry_index(*self, entry), j = i, k, cap = self->bucket_count; \ - ctype##_##tag##_entry_t* slot = self->table; \ + ctype##_##X##_entry_t* slot = self->table; \ uint8_t* hashx = self->_hashx; \ - ctype##_##tag##_rawkey_t r; \ + ctype##_##X##_rawkey_t r; \ if (! hashx[i]) \ return false; \ - ctype##_##tag##_entry_destroy(&slot[i]); \ + ctype##_##X##_entry_destroy(&slot[i]); \ do { /* deletion from hash table without tombstone */ \ if (++j == cap) j = 0; /* ++j; j %= cap; is slow */ \ if (! hashx[j]) \ break; \ r = keyToRaw(&slot[j].key); \ - k = chash_reduce(keyHashRaw(&r, sizeof(ctype##_##tag##_rawkey_t)), cap); \ + k = chash_reduce(keyHashRaw(&r, sizeof(ctype##_##X##_rawkey_t)), cap); \ if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ \ slot[i] = slot[j], hashx[i] = hashx[j], i = j; \ } while (true); \ @@ -390,16 +390,16 @@ ctype##_##tag##_erase_entry(ctype##_##tag* self, ctype##_##tag##_entry_t* entry) } \ \ STC_API bool \ -ctype##_##tag##_erase(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \ +ctype##_##X##_erase(ctype##_##X* self, ctype##_##X##_rawkey_t rawKey) { \ if (self->size == 0) \ return false; \ - if (self->size < self->bucket_count * self->shrink_limit_factor && self->bucket_count * sizeof(ctype##_##tag##_entry_t) > 1024) \ - ctype##_##tag##_reserve(self, self->size * 6 / 5); \ + if (self->size < self->bucket_count * self->shrink_limit_factor && self->bucket_count * sizeof(ctype##_##X##_entry_t) > 1024) \ + ctype##_##X##_reserve(self, self->size * 6 / 5); \ uint32_t hx; \ - size_t i = ctype##_##tag##_bucket(self, &rawKey, &hx); \ - return ctype##_##tag##_erase_entry(self, self->table + i); \ + size_t i = ctype##_##X##_bucket(self, &rawKey, &hx); \ + return ctype##_##X##_erase_entry(self, self->table + i); \ } \ -typedef int ctype##_##tag##_dud +typedef int ctype##_##X##_dud /* https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/ */ @@ -417,7 +417,7 @@ STC_API uint32_t c_default_hash32(const void* data, size_t len) { } #else -#define implement_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ +#define implement_CHASH(X, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \ keyDestroy, RawKey, keyToRaw, keyFromRaw) #endif diff --git a/stc/cpqueue.h b/stc/cpqueue.h index 8873b0cd..4cdc3f37 100644 --- a/stc/cpqueue.h +++ b/stc/cpqueue.h @@ -50,52 +50,52 @@ #include "cvec.h" -#define declare_cpqueue(tag, ctype, cmpOpr) /* cmpOpr: < or > */ \ +#define declare_cpqueue(X, ctype, cmpOpr) /* cmpOpr: < or > */ \ \ -typedef struct ctype cpqueue_##tag; \ -typedef ctype##_value_t cpqueue_##tag##_value_t; \ -typedef ctype##_rawvalue_t cpqueue_##tag##_rawvalue_t; \ -typedef ctype##_input_t cpqueue_##tag##_input_t; \ -STC_INLINE cpqueue_##tag \ -cpqueue_##tag##_init() {return ctype##_init();} \ +typedef struct ctype cpqueue_##X; \ +typedef ctype##_value_t cpqueue_##X##_value_t; \ +typedef ctype##_rawvalue_t cpqueue_##X##_rawvalue_t; \ +typedef ctype##_input_t cpqueue_##X##_input_t; \ +STC_INLINE cpqueue_##X \ +cpqueue_##X##_init() {return ctype##_init();} \ STC_INLINE size_t \ -cpqueue_##tag##_size(cpqueue_##tag pq) {return ctype##_size(pq);} \ +cpqueue_##X##_size(cpqueue_##X pq) {return ctype##_size(pq);} \ STC_INLINE bool \ -cpqueue_##tag##_empty(cpqueue_##tag pq) {return ctype##_empty(pq);} \ +cpqueue_##X##_empty(cpqueue_##X pq) {return ctype##_empty(pq);} \ STC_INLINE void \ -cpqueue_##tag##_destroy(cpqueue_##tag* self) {ctype##_destroy(self);} \ +cpqueue_##X##_destroy(cpqueue_##X* self) {ctype##_destroy(self);} \ STC_API void \ -cpqueue_##tag##_build(cpqueue_##tag* self); \ +cpqueue_##X##_build(cpqueue_##X* self); \ STC_API void \ -cpqueue_##tag##_erase(cpqueue_##tag* self, size_t i); \ -STC_INLINE const cpqueue_##tag##_value_t* \ -cpqueue_##tag##_top(const cpqueue_##tag* self) {return &self->data[0];} \ +cpqueue_##X##_erase(cpqueue_##X* self, size_t i); \ +STC_INLINE const cpqueue_##X##_value_t* \ +cpqueue_##X##_top(const cpqueue_##X* self) {return &self->data[0];} \ STC_INLINE void \ -cpqueue_##tag##_pop(cpqueue_##tag* self) {cpqueue_##tag##_erase(self, 0);} \ +cpqueue_##X##_pop(cpqueue_##X* self) {cpqueue_##X##_erase(self, 0);} \ STC_API void \ -cpqueue_##tag##_push_v(cpqueue_##tag* self, cpqueue_##tag##_value_t value); \ +cpqueue_##X##_push_v(cpqueue_##X* self, cpqueue_##X##_value_t value); \ STC_INLINE void \ -cpqueue_##tag##_push(cpqueue_##tag* self, cpqueue_##tag##_rawvalue_t rawValue) { \ - cpqueue_##tag##_push_v(self, ctype##_value_from_raw(rawValue)); \ +cpqueue_##X##_push(cpqueue_##X* self, cpqueue_##X##_rawvalue_t rawValue) { \ + cpqueue_##X##_push_v(self, ctype##_value_from_raw(rawValue)); \ } \ STC_API void \ -cpqueue_##tag##_push_n(cpqueue_##tag *self, const cpqueue_##tag##_input_t in[], size_t size); \ +cpqueue_##X##_push_n(cpqueue_##X *self, const cpqueue_##X##_input_t in[], size_t size); \ \ -implement_cpqueue(tag, ctype, cmpOpr) +implement_cpqueue(X, ctype, cmpOpr) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_cpqueue(tag, ctype, cmpOpr) \ +#define implement_cpqueue(X, ctype, cmpOpr) \ \ STC_INLINE void \ -_cpqueue_##tag##_sift_down(cpqueue_##tag##_value_t* arr, size_t i, size_t n) { \ +_cpqueue_##X##_sift_down(cpqueue_##X##_value_t* arr, size_t i, size_t n) { \ size_t r = i, c = i << 1; \ while (c <= n) { \ if (c < n && ctype##_value_compare(&arr[c], &arr[c + 1]) cmpOpr 0) \ ++c; \ if (ctype##_value_compare(&arr[r], &arr[c]) cmpOpr 0) { \ - cpqueue_##tag##_value_t t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; \ + cpqueue_##X##_value_t tmp = arr[r]; arr[r] = arr[c]; arr[r = c] = tmp; \ } else \ return; \ c <<= 1; \ @@ -103,39 +103,39 @@ _cpqueue_##tag##_sift_down(cpqueue_##tag##_value_t* arr, size_t i, size_t n) { \ } \ \ STC_API void \ -cpqueue_##tag##_build(cpqueue_##tag* self) { \ - size_t n = cpqueue_##tag##_size(*self); \ - cpqueue_##tag##_value_t *arr = self->data - 1; \ +cpqueue_##X##_build(cpqueue_##X* self) { \ + size_t n = cpqueue_##X##_size(*self); \ + cpqueue_##X##_value_t *arr = self->data - 1; \ for (size_t k = n >> 1; k != 0; --k) \ - _cpqueue_##tag##_sift_down(arr, k, n); \ + _cpqueue_##X##_sift_down(arr, k, n); \ } \ \ STC_API void \ -cpqueue_##tag##_erase(cpqueue_##tag* self, size_t i) { \ - size_t n = cpqueue_##tag##_size(*self) - 1; \ +cpqueue_##X##_erase(cpqueue_##X* self, size_t i) { \ + size_t n = cpqueue_##X##_size(*self) - 1; \ self->data[i] = self->data[n]; \ ctype##_pop_back(self); \ - _cpqueue_##tag##_sift_down(self->data - 1, i + 1, n); \ + _cpqueue_##X##_sift_down(self->data - 1, i + 1, n); \ } \ \ STC_API void \ -cpqueue_##tag##_push_v(cpqueue_##tag* self, cpqueue_##tag##_value_t value) { \ +cpqueue_##X##_push_v(cpqueue_##X* self, cpqueue_##X##_value_t value) { \ ctype##_push_back(self, value); /* sift-up the value */ \ - size_t n = cpqueue_##tag##_size(*self), c = n; \ - cpqueue_##tag##_value_t *arr = self->data - 1; \ + size_t n = cpqueue_##X##_size(*self), c = n; \ + cpqueue_##X##_value_t *arr = self->data - 1; \ for (; c > 1 && ctype##_value_compare(&arr[c >> 1], &value) cmpOpr 0; c >>= 1) \ arr[c] = arr[c >> 1]; \ if (c != n) arr[c] = value; \ } \ STC_API void \ -cpqueue_##tag##_push_n(cpqueue_##tag *self, const cpqueue_##tag##_input_t in[], size_t size) { \ - ctype##_reserve(self, cpqueue_##tag##_size(*self) + size); \ - for (size_t i=0; idata) _cvec_size(*self) = 0; \ } \ STC_INLINE void \ -cvec_##tag##_pop_back(cvec_##tag* self) { \ +cvec_##X##_pop_back(cvec_##X* self) { \ valueDestroy(&self->data[_cvec_size(*self) - 1]); \ --_cvec_size(*self); \ } \ STC_INLINE Value* \ -cvec_##tag##_front(cvec_##tag* self) {return self->data;} \ +cvec_##X##_front(cvec_##X* self) {return self->data;} \ STC_INLINE Value* \ -cvec_##tag##_back(cvec_##tag* self) {return self->data + _cvec_size(*self) - 1;} \ +cvec_##X##_back(cvec_##X* self) {return self->data + _cvec_size(*self) - 1;} \ STC_INLINE Value* \ -cvec_##tag##_at(cvec_##tag* self, size_t i) {return self->data + i;} \ +cvec_##X##_at(cvec_##X* self, size_t i) {return self->data + i;} \ STC_INLINE void \ -cvec_##tag##_swap(cvec_##tag* a, cvec_##tag* b) { \ +cvec_##X##_swap(cvec_##X* a, cvec_##X* b) { \ c_swap(Value*, a->data, b->data); \ } \ STC_INLINE void \ -cvec_##tag##_sort(cvec_##tag* self) { \ - qsort(self->data, cvec_size(*self), sizeof(Value), (_cvec_cmp) cvec_##tag##_value_compare); \ +cvec_##X##_sort(cvec_##X* self) { \ + qsort(self->data, cvec_size(*self), sizeof(Value), (_cvec_cmp) cvec_##X##_value_compare); \ } \ STC_INLINE void \ -cvec_##tag##_sort_with(cvec_##tag* self, int(*cmp)(const Value*, const Value*)) { \ +cvec_##X##_sort_with(cvec_##X* self, int(*cmp)(const Value*, const Value*)) { \ qsort(self->data, cvec_size(*self), sizeof(Value), (_cvec_cmp) cmp); \ } \ \ typedef struct { \ Value *item, *end; \ -} cvec_##tag##_iter_t; \ +} cvec_##X##_iter_t; \ \ -STC_INLINE cvec_##tag##_iter_t \ -cvec_##tag##_begin(cvec_##tag* vec) { \ - cvec_##tag##_iter_t it = {vec->data, vec->data + cvec_size(*vec)}; \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_begin(cvec_##X* vec) { \ + cvec_##X##_iter_t it = {vec->data, vec->data + cvec_size(*vec)}; \ return it; \ } \ STC_INLINE void \ -cvec_##tag##_next(cvec_##tag##_iter_t* it) { ++it->item; } \ -STC_INLINE cvec_##tag##_value_t* \ -cvec_##tag##_itval(cvec_##tag##_iter_t it) {return it.item;} \ +cvec_##X##_next(cvec_##X##_iter_t* it) { ++it->item; } \ +STC_INLINE cvec_##X##_value_t* \ +cvec_##X##_itval(cvec_##X##_iter_t it) {return it.item;} \ \ -implement_cvec_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) +implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_cvec_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ +#define implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ \ STC_API void \ -cvec_##tag##_push_n(cvec_##tag *self, const cvec_##tag##_input_t in[], size_t size) { \ - cvec_##tag##_reserve(self, cvec_size(*self) + size); \ +cvec_##X##_push_n(cvec_##X *self, const cvec_##X##_input_t in[], size_t size) { \ + cvec_##X##_reserve(self, cvec_size(*self) + size); \ _cvec_size(*self) += size; \ for (size_t i=0; idata[i] = valueFromRaw(in[i]); \ } \ \ STC_API void \ -cvec_##tag##_destroy(cvec_##tag* self) { \ +cvec_##X##_destroy(cvec_##X* self) { \ Value* p = self->data; \ size_t i = 0, n = cvec_size(*self); \ for (; i < n; ++p, ++i) valueDestroy(p); \ @@ -172,7 +172,7 @@ cvec_##tag##_destroy(cvec_##tag* self) { \ } \ \ STC_API void \ -cvec_##tag##_reserve(cvec_##tag* self, size_t cap) { \ +cvec_##X##_reserve(cvec_##X* self, size_t cap) { \ size_t len = cvec_size(*self); \ if (cap >= len) { \ size_t* rep = (size_t *) realloc(_cvec_alloced(self->data), 2 * sizeof(size_t) + cap * sizeof(Value)); \ @@ -182,33 +182,33 @@ cvec_##tag##_reserve(cvec_##tag* self, size_t cap) { \ } \ } \ STC_API void \ -cvec_##tag##_resize(cvec_##tag* self, size_t size, Value null_val) { \ - cvec_##tag##_reserve(self, size); \ +cvec_##X##_resize(cvec_##X* self, size_t size, Value null_val) { \ + cvec_##X##_reserve(self, size); \ for (size_t i=cvec_size(*self); idata[i] = null_val; \ if (self->data) _cvec_size(*self) = size; \ } \ \ STC_API void \ -cvec_##tag##_push_back_v(cvec_##tag* self, Value value) { \ +cvec_##X##_push_back_v(cvec_##X* self, Value value) { \ size_t len = cvec_size(*self); \ if (len == cvec_capacity(*self)) \ - cvec_##tag##_reserve(self, 4 + len * 3 / 2); \ + cvec_##X##_reserve(self, 4 + len * 3 / 2); \ self->data[cvec_size(*self)] = value; \ ++_cvec_size(*self); \ } \ \ STC_API void \ -cvec_##tag##_insert_v(cvec_##tag* self, size_t pos, Value value) { \ +cvec_##X##_insert_v(cvec_##X* self, size_t pos, Value value) { \ size_t len = cvec_size(*self); \ if (len == cvec_capacity(*self)) \ - cvec_##tag##_reserve(self, 4 + len * 3 / 2); \ + cvec_##X##_reserve(self, 4 + len * 3 / 2); \ memmove(&self->data[pos + 1], &self->data[pos], (len - pos) * sizeof(Value)); \ self->data[pos] = value; \ ++_cvec_size(*self); \ } \ \ STC_API void \ -cvec_##tag##_erase(cvec_##tag* self, size_t pos, size_t size) { \ +cvec_##X##_erase(cvec_##X* self, size_t pos, size_t size) { \ size_t len = cvec_size(*self); \ if (len) { \ Value* p = &self->data[pos], *start = p, *end = p + size; \ @@ -219,7 +219,7 @@ cvec_##tag##_erase(cvec_##tag* self, size_t pos, size_t size) { \ } \ \ STC_API size_t \ -cvec_##tag##_find(const cvec_##tag* self, RawValue rawValue) { \ +cvec_##X##_find(const cvec_##X* self, RawValue rawValue) { \ const Value *p = self->data, *end = p + cvec_size(*self); \ for (; p != end; ++p) { \ RawValue r = valueToRaw(p); \ @@ -229,7 +229,7 @@ cvec_##tag##_find(const cvec_##tag* self, RawValue rawValue) { \ } \ \ STC_API int \ -cvec_##tag##_value_compare(const Value* x, const Value* y) { \ +cvec_##X##_value_compare(const Value* x, const Value* y) { \ RawValue rx = valueToRaw(x); \ RawValue ry = valueToRaw(y); \ return valueCompareRaw(&rx, &ry); \ @@ -237,7 +237,7 @@ cvec_##tag##_value_compare(const Value* x, const Value* y) { \ typedef int cvec_##taq##_dud #else -#define implement_cvec_7(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw) +#define implement_cvec_7(X, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw) #endif #if defined(_WIN32) && defined(_DLL) -- cgit v1.2.3