From bb998d5bf71cd0e23b941150dc78a1504aacff80 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 8 Apr 2021 14:44:43 +0200 Subject: Big change set to simplify the internal templating implementations. Shorter and more readable code. Removed C_X_itval() as they are no longer needed. API is to use *it.ref --- docs/cdeq_api.md | 1 - docs/cmap_api.md | 1 - docs/cqueue_api.md | 1 - docs/cset_api.md | 1 - docs/csmap_api.md | 1 - docs/csset_api.md | 1 - docs/cstack_api.md | 1 - docs/cstr_api.md | 1 - docs/cvec_api.md | 1 - stc/carray.h | 140 +++++++++--------- stc/cdeq.h | 284 ++++++++++++++++++------------------ stc/clist.h | 275 +++++++++++++++++------------------ stc/cmap.h | 301 +++++++++++++++++++------------------- stc/cpque.h | 99 ++++++------- stc/cqueue.h | 75 ++++------ stc/cset.h | 8 +- stc/csmap.h | 415 ++++++++++++++++++++++++++--------------------------- stc/csset.h | 8 +- stc/cstack.h | 73 ++++------ stc/cstr.h | 1 - stc/cvec.h | 280 ++++++++++++++++++------------------ 21 files changed, 962 insertions(+), 1006 deletions(-) diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 21f8b5c8..03843fcf 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -82,7 +82,6 @@ void cdeq_X_sort_range(cdeq_X_iter_t i1, cdeq_X_iter_t i2, cdeq_X_iter_t cdeq_X_begin(const cdeq_X* self); cdeq_X_iter_t cdeq_X_end(const cdeq_X* self); void cdeq_X_next(cdeq_X_iter_t* it); -cdeq_X_value_t* cdeq_X_itval(cdeq_X_iter_t it); size_t cdeq_X_index(const cdeq_X deq, cdeq_X_iter_t it); cdeq_X_value_t cdeq_X_value_clone(cdeq_X_value_t val); diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 77c8d765..aec048e6 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -72,7 +72,6 @@ void cmap_X_erase_entry(cmap_X* self, cmap_X_value_t* entry); cmap_X_iter_t cmap_X_begin(const cmap_X* self); cmap_X_iter_t cmap_X_end(const cmap_X* self); void cmap_X_next(cmap_X_iter_t* it); -cmap_X_mapped_t* cmap_X_itval(cmap_X_iter_t it); cmap_X_value_t cmap_X_value_clone(cmap_X_value_t val); ``` diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index a99f7176..2d9b113c 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -39,7 +39,6 @@ void cqueue_X_pop(cqueue_X* self); cqueue_X_iter_t cqueue_X_begin(const cqueue_X* self); cqueue_X_iter_t cqueue_X_end(const cqueue_X* self); void cqueue_X_next(cqueue_X_iter_t* it); -cqueue_X_value_t* cqueue_X_itval(cqueue_X_iter_t it); cqueue_X_value_t cqueue_X_value_clone(cqueue_X_value_t val); ``` diff --git a/docs/cset_api.md b/docs/cset_api.md index 26515a11..dfdad074 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -52,7 +52,6 @@ void cset_X_erase_entry(cset_X* self, cset_X_value_t* entry); cset_X_iter_t cset_X_begin(const cset_X* self); cset_X_iter_t cset_X_end(const cset_X* self); void cset_X_next(cset_X_iter_t* it); -cset_X_value_t* cset_X_itval(cset_X_iter_t it); cset_X_value_t cset_X_value_clone(cset_X_value_t val); ``` diff --git a/docs/csmap_api.md b/docs/csmap_api.md index dcde885f..a8912463 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -70,7 +70,6 @@ csmap_X_iter_t csmap_X_erase_at(csmap_X* self, csmap_X_iter_t pos); csmap_X_iter_t csmap_X_begin(const csmap_X* self); csmap_X_iter_t csmap_X_end(const csmap_X* self); void csmap_X_next(csmap_X_iter_t* it); -csmap_X_mapped_t* csmap_X_itval(csmap_X_iter_t it); csmap_X_value_t csmap_X_value_clone(csmap_X_value_t val); ``` diff --git a/docs/csset_api.md b/docs/csset_api.md index accc81d9..002752f7 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -49,7 +49,6 @@ csset_X_iter_t csset_X_erase_at(csset_X* self, csset_X_iter_t pos); csset_X_iter_t csset_X_begin(const csset_X* self); csset_X_iter_t csset_X_end(const csset_X* self); void csset_X_next(csset_X_iter_t* it); -csset_X_value_t* csset_X_itval(csset_X_iter_t it); csset_X_value_t csset_X_value_clone(csset_X_value_t val); ``` diff --git a/docs/cstack_api.md b/docs/cstack_api.md index 85e23455..06163518 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -39,7 +39,6 @@ void cstack_X_pop(cstack_X* self); cstack_X_iter_t cstack_X_begin(const cstack_X* self); cstack_X_iter_t cstack_X_end(const cstack_X* self); void cstack_X_next(cstack_X_iter_t* it); -cstack_X_value_t* cstack_X_itval(cstack_X_iter_t it); cstack_X_value_t cstack_X_value_clone(cstack_X_value_t val); ``` diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 5bc07b7d..58f4a1bf 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -77,7 +77,6 @@ char* cstr_back(cstr* self); cstr_iter_t cstr_begin(cstr* self); cstr_iter_t cstr_end(cstr* self); void cstr_next(cstr_iter_t* it); -char* cstr_itval(cstr_iter_t it); bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) bool cstr_getdelim(cstr *self, int delim, FILE *stream); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 50223e00..6f495cae 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -84,7 +84,6 @@ void cvec_X_sort_range(cvec_X_iter_t i1, cvec_X_iter_t i2, cvec_X_iter_t cvec_X_begin(const cvec_X* self); cvec_X_iter_t cvec_X_end(const cvec_X* self); void cvec_X_next(cvec_X_iter_t* it); -cvec_X_value_t* cvec_X_itval(cvec_X_iter_t it); size_t cvec_X_index(const cvec_X vec, cvec_X_iter_t it); cvec_X_value_t cvec_X_value_clone(cvec_X_value_t val); diff --git a/stc/carray.h b/stc/carray.h index f1c90b1d..c3b60663 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -55,108 +55,116 @@ int main() { #define using_carray2(...) c_MACRO_OVERLOAD(using_carray2, __VA_ARGS__) #define using_carray2_2(X, Value) \ - using_carray2_4(X, Value, c_trivial_del, c_trivial_fromraw) - + _c_using_carray2(carray2##X, Value, c_trivial_del, c_trivial_fromraw) +#define using_carray2_3(X, Value, valueDel) \ + _c_using_carray2(carray2##X, Value, valueDel, c_no_clone) #define using_carray2_4(X, Value, valueDel, valueClone) \ + _c_using_carray2(carray2##X, Value, valueDel, valueClone) + +#define _c_using_carray2(CX, Value, valueDel, valueClone) \ \ - typedef Value carray2##X##_value_t; \ - typedef struct { carray2##X##_value_t **at; size_t xdim, ydim; } carray2##X; \ - typedef struct { carray2##X##_value_t *ref; } carray2##X##_iter_t; \ + typedef Value CX##_value_t; \ + typedef struct { CX##_value_t **at; size_t xdim, ydim; } CX; \ + typedef struct { CX##_value_t *ref; } CX##_iter_t; \ \ - STC_API carray2##X carray2##X##_from(carray2##X##_value_t* block, size_t xdim, size_t ydim); \ - STC_API carray2##X carray2##X##_init(size_t xdim, size_t ydim, Value value); \ - STC_API carray2##X carray2##X##_clone(carray2##X src); \ + STC_API CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim); \ + STC_API CX CX##_init(size_t xdim, size_t ydim, Value value); \ + STC_API CX CX##_clone(CX src); \ \ - STC_INLINE size_t carray2##X##_size(carray2##X arr) { return arr.xdim*arr.ydim; } \ - STC_INLINE carray2##X##_value_t *carray2##X##_data(carray2##X* self) { return *self->at; } \ - STC_INLINE carray2##X##_value_t *carray2##X##_at(carray2##X* self, size_t x, size_t y) { \ + STC_INLINE size_t CX##_size(CX arr) { return arr.xdim*arr.ydim; } \ + STC_INLINE CX##_value_t *CX##_data(CX* self) { return *self->at; } \ + STC_INLINE CX##_value_t *CX##_at(CX* self, size_t x, size_t y) { \ return *self->at + self->ydim*x + y; \ } \ - STC_INLINE carray2##X##_value_t *carray2##X##_release(carray2##X* self) { \ - carray2##X##_value_t *t = *self->at; c_free(self->at); self->at = NULL; return t; \ + STC_INLINE CX##_value_t *CX##_release(CX* self) { \ + CX##_value_t *t = *self->at; c_free(self->at); self->at = NULL; return t; \ } \ \ - STC_INLINE carray2##X##_iter_t carray2##X##_begin(const carray2##X* self) { \ - carray2##X##_iter_t it = {*self->at}; return it; \ + STC_INLINE CX##_iter_t CX##_begin(const CX* self) { \ + CX##_iter_t it = {*self->at}; return it; \ } \ - STC_INLINE carray2##X##_iter_t carray2##X##_end(const carray2##X* self) { \ - carray2##X##_iter_t it = {*self->at + carray2##X##_size(*self)}; return it; \ + STC_INLINE CX##_iter_t CX##_end(const CX* self) { \ + CX##_iter_t it = {*self->at + CX##_size(*self)}; return it; \ } \ - STC_INLINE void carray2##X##_next(carray2##X##_iter_t* it) { ++it->ref; } \ + STC_INLINE void CX##_next(CX##_iter_t* it) { ++it->ref; } \ \ - _c_implement_carray2_4(X, Value, valueDel, valueClone) \ - STC_API void carray2##X##_del(carray2##X* self) + _c_implement_carray2(CX, Value, valueDel, valueClone) \ + STC_API void CX##_del(CX* self) // carray3: #define using_carray3(...) c_MACRO_OVERLOAD(using_carray3, __VA_ARGS__) #define using_carray3_2(X, Value) \ - using_carray3_4(X, Value, c_trivial_del, c_trivial_fromraw) - + _c_using_carray3(carray3##X, Value, c_trivial_del, c_trivial_fromraw) +#define using_carray3_3(X, Value, valueDel) \ + _c_using_carray3(carray3##X, Value, valueDel, c_no_clone) #define using_carray3_4(X, Value, valueDel, valueClone) \ + _c_using_carray3(carray3##X, Value, valueDel, valueClone) + +#define _c_using_carray3(CX, Value, valueDel, valueClone) \ \ - typedef Value carray3##X##_value_t; \ - typedef struct { carray3##X##_value_t ***at; size_t xdim, ydim, zdim; } carray3##X; \ - typedef struct { carray3##X##_value_t *ref; } carray3##X##_iter_t; \ + typedef Value CX##_value_t; \ + typedef struct { CX##_value_t ***at; size_t xdim, ydim, zdim; } CX; \ + typedef struct { CX##_value_t *ref; } CX##_iter_t; \ \ - STC_API carray3##X carray3##X##_from(carray3##X##_value_t* block, size_t xdim, size_t ydim, size_t zdim); \ - STC_API carray3##X carray3##X##_init(size_t xdim, size_t ydim, size_t zdim, Value value); \ - STC_API carray3##X carray3##X##_clone(carray3##X src); \ + STC_API CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim, size_t zdim); \ + STC_API CX CX##_init(size_t xdim, size_t ydim, size_t zdim, Value value); \ + STC_API CX CX##_clone(CX src); \ \ - STC_INLINE size_t carray3##X##_size(carray3##X arr) { return arr.xdim*arr.ydim*arr.zdim; } \ - STC_INLINE carray3##X##_value_t *carray3##X##_data(carray3##X* self) { return **self->at; } \ - STC_INLINE carray3##X##_value_t *carray3##X##_at(carray3##X* self, size_t x, size_t y, size_t z) { \ + STC_INLINE size_t CX##_size(CX arr) { return arr.xdim*arr.ydim*arr.zdim; } \ + STC_INLINE CX##_value_t *CX##_data(CX* self) { return **self->at; } \ + STC_INLINE CX##_value_t *CX##_at(CX* self, size_t x, size_t y, size_t z) { \ return **self->at + self->zdim*(self->ydim*x + y) + z; \ } \ - STC_INLINE carray3##X##_value_t *carray3##X##_release(carray3##X* self) { \ - carray3##X##_value_t *t = **self->at; c_free(self->at); self->at = NULL; return t; \ + STC_INLINE CX##_value_t *CX##_release(CX* self) { \ + CX##_value_t *t = **self->at; c_free(self->at); self->at = NULL; return t; \ } \ \ - STC_INLINE carray3##X##_iter_t carray3##X##_begin(const carray3##X* self) { \ - carray3##X##_iter_t it = {**self->at}; return it; \ + STC_INLINE CX##_iter_t CX##_begin(const CX* self) { \ + CX##_iter_t it = {**self->at}; return it; \ } \ - STC_INLINE carray3##X##_iter_t carray3##X##_end(const carray3##X* self) { \ - carray3##X##_iter_t it = {**self->at + carray3##X##_size(*self)}; return it; \ + STC_INLINE CX##_iter_t CX##_end(const CX* self) { \ + CX##_iter_t it = {**self->at + CX##_size(*self)}; return it; \ } \ - STC_INLINE void carray3##X##_next(carray3##X##_iter_t* it) { ++it->ref; } \ + STC_INLINE void CX##_next(CX##_iter_t* it) { ++it->ref; } \ \ - _c_implement_carray3_4(X, Value, valueDel, valueClone) \ - STC_API void carray3##X##_del(carray3##X* self) + _c_implement_carray3(CX, Value, valueDel, valueClone) \ + STC_API void CX##_del(CX* self) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define _c_implement_carray2_4(X, Value, valueDel, valueClone) \ +#define _c_implement_carray2(CX, Value, valueDel, valueClone) \ \ - STC_DEF carray2##X carray2##X##_from(carray2##X##_value_t* block, size_t xdim, size_t ydim) { \ + STC_DEF CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim) { \ size_t n = xdim * ydim; \ - carray2##X _arr = {c_new_2(carray2##X##_value_t*, xdim), xdim, ydim}; \ + CX _arr = {c_new_2(CX##_value_t*, xdim), xdim, ydim}; \ for (size_t x = 0; x < xdim; ++x, block += ydim) \ _arr.at[x] = block; \ return _arr; \ } \ \ - STC_DEF carray2##X carray2##X##_init(size_t xdim, size_t ydim, Value value) { \ + STC_DEF CX CX##_init(size_t xdim, size_t ydim, Value value) { \ size_t n = xdim*ydim; \ - carray2##X _arr = carray2##X##_from(c_new_2(carray2##X##_value_t, n), xdim, ydim); \ - for (carray2##X##_value_t* p = _arr.at[0], *e = p + n; p != e; ++p) \ + CX _arr = CX##_from(c_new_2(CX##_value_t, n), xdim, ydim); \ + for (CX##_value_t* p = _arr.at[0], *e = p + n; p != e; ++p) \ *p = value; \ return _arr; \ } \ \ - STC_DEF carray2##X carray2##X##_clone(carray2##X src) { \ + STC_DEF CX CX##_clone(CX src) { \ size_t n = src.xdim*src.ydim; \ - carray2##X _arr = carray2##X##_from(c_new_2(carray2##X##_value_t, n), src.xdim, src.ydim); \ - for (carray2##X##_value_t* p = _arr.at[0], *q = src.at[0], *e = p + n; p != e; ++p, ++q) \ + CX _arr = CX##_from(c_new_2(CX##_value_t, n), src.xdim, src.ydim); \ + for (CX##_value_t* p = _arr.at[0], *q = src.at[0], *e = p + n; p != e; ++p, ++q) \ *p = valueClone(*q); \ return _arr; \ } \ \ - STC_DEF void carray2##X##_del(carray2##X* self) { \ + STC_DEF void CX##_del(CX* self) { \ if (!self->at) return; \ - for (carray2##X##_value_t* p = self->at[0], *e = p + self->xdim*self->ydim; p != e; ++p) \ + for (CX##_value_t* p = self->at[0], *e = p + self->xdim*self->ydim; p != e; ++p) \ valueDel(p); \ c_free(self->at[0]); /* data */ \ c_free(self->at); \ @@ -164,44 +172,44 @@ int main() { // carray3 impl. -#define _c_implement_carray3_4(X, Value, valueDel, valueClone) \ +#define _c_implement_carray3(CX, Value, valueDel, valueClone) \ \ - STC_DEF carray3##X carray3##X##_from(carray3##X##_value_t* block, size_t xdim, size_t ydim, size_t zdim) { \ - carray3##X _arr = {c_new_2(carray3##X##_value_t**, xdim*(ydim + 1)), xdim, ydim, zdim}; \ - carray3##X##_value_t** p = (carray3##X##_value_t**) &_arr.at[xdim]; \ + STC_DEF CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim, size_t zdim) { \ + CX _arr = {c_new_2(CX##_value_t**, xdim*(ydim + 1)), xdim, ydim, zdim}; \ + CX##_value_t** p = (CX##_value_t**) &_arr.at[xdim]; \ for (size_t x = 0, y; x < xdim; ++x, p += ydim) \ for (_arr.at[x] = p, y = 0; y < ydim; ++y, block += zdim) \ _arr.at[x][y] = block; \ return _arr; \ } \ \ - STC_DEF carray3##X carray3##X##_init(size_t xdim, size_t ydim, size_t zdim, Value value) { \ + STC_DEF CX CX##_init(size_t xdim, size_t ydim, size_t zdim, Value value) { \ size_t n = xdim*ydim*zdim; \ - carray3##X _arr = carray3##X##_from(c_new_2(carray3##X##_value_t, n), xdim, ydim, zdim); \ - for (carray3##X##_value_t* p = **_arr.at, *e = p + n; p != e; ++p) \ + CX _arr = CX##_from(c_new_2(CX##_value_t, n), xdim, ydim, zdim); \ + for (CX##_value_t* p = **_arr.at, *e = p + n; p != e; ++p) \ *p = value; \ return _arr; \ } \ \ - STC_DEF carray3##X carray3##X##_clone(carray3##X src) { \ - size_t n = carray3##X##_size(src); \ - carray3##X _arr = carray3##X##_from(c_new_2(carray3##X##_value_t, n), src.xdim, src.ydim, src.zdim); \ - for (carray3##X##_value_t* p = **_arr.at, *q = **src.at, *e = p + n; p != e; ++p, ++q) \ + STC_DEF CX CX##_clone(CX src) { \ + size_t n = CX##_size(src); \ + CX _arr = CX##_from(c_new_2(CX##_value_t, n), src.xdim, src.ydim, src.zdim); \ + for (CX##_value_t* p = **_arr.at, *q = **src.at, *e = p + n; p != e; ++p, ++q) \ *p = valueClone(*q); \ return _arr; \ } \ \ - STC_DEF void carray3##X##_del(carray3##X* self) { \ + STC_DEF void CX##_del(CX* self) { \ if (!self->at) return; \ - for (carray3##X##_value_t* p = **self->at, *e = p + carray3##X##_size(*self); p != e; ++p) \ + for (CX##_value_t* p = **self->at, *e = p + CX##_size(*self); p != e; ++p) \ valueDel(p); \ c_free(self->at[0][0]); /* data */ \ c_free(self->at); /* pointers */ \ } #else -#define _c_implement_carray2_4(X, Value, valueDel, valueClone) -#define _c_implement_carray3_4(X, Value, valueDel, valueClone) +#define _c_implement_carray2(CX, Value, valueDel, valueClone) +#define _c_implement_carray3(CX, Value, valueDel, valueClone) #endif #endif diff --git a/stc/cdeq.h b/stc/cdeq.h index bb77f04c..9f535eb1 100644 --- a/stc/cdeq.h +++ b/stc/cdeq.h @@ -36,181 +36,181 @@ using_cdeq_5(X, Value, valueCompare, valueDel, c_no_clone) #define using_cdeq_5(X, Value, valueCompare, valueDel, valueClone) \ using_cdeq_7(X, Value, valueCompare, valueDel, valueClone, c_trivial_toraw, Value) +#define using_cdeq_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + _c_using_cdeq(cdeq_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #define using_cdeq_str() \ - using_cdeq_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) + _c_using_cdeq(cdeq_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) -#define typedefs_cdeq(X, Value, RawValue) \ - typedef Value cdeq_##X##_value_t; \ - typedef RawValue cdeq_##X##_rawvalue_t; \ - typedef struct { cdeq_##X##_value_t *ref; } cdeq_##X##_iter_t; \ +#define typedefs_cdeq(CX, Value, RawValue) \ + typedef Value CX##_value_t; \ + typedef RawValue CX##_rawvalue_t; \ + typedef struct { CX##_value_t *ref; } CX##_iter_t; \ typedef struct { \ - cdeq_##X##_value_t *base, *data; \ - } cdeq_##X + CX##_value_t *base, *data; \ + } CX struct cdeq_rep { size_t size, cap; void* base[]; }; #define cdeq_rep_(self) c_container_of((self)->base, struct cdeq_rep, base) typedef int (*c_cmp_fn)(const void*, const void*); -#define using_cdeq_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ - typedefs_cdeq(X, Value, RawValue); \ +#define _c_using_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + typedefs_cdeq(CX, Value, RawValue); \ \ - STC_API cdeq_##X \ - cdeq_##X##_init(void); \ + STC_API CX \ + CX##_init(void); \ STC_INLINE bool \ - cdeq_##X##_empty(cdeq_##X deq) {return !cdeq_rep_(&deq)->size;} \ + CX##_empty(CX deq) {return !cdeq_rep_(&deq)->size;} \ STC_INLINE size_t \ - cdeq_##X##_size(cdeq_##X deq) {return cdeq_rep_(&deq)->size;} \ + CX##_size(CX deq) {return cdeq_rep_(&deq)->size;} \ STC_INLINE size_t \ - cdeq_##X##_capacity(cdeq_##X deq) {return cdeq_rep_(&deq)->cap;} \ + CX##_capacity(CX deq) {return cdeq_rep_(&deq)->cap;} \ + STC_INLINE Value \ + CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ STC_INLINE Value \ - cdeq_##X##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ - STC_INLINE cdeq_##X##_value_t \ - cdeq_##X##_value_clone(cdeq_##X##_value_t val) {return valueFromRaw(valueToRaw(&val));} \ + CX##_value_clone(Value val) {return valueFromRaw(valueToRaw(&val));} \ STC_API void \ - cdeq_##X##_clear(cdeq_##X* self); \ + CX##_clear(CX* self); \ STC_API void \ - cdeq_##X##_del(cdeq_##X* self); \ + CX##_del(CX* self); \ STC_API void \ - _cdeq_##X##_expand(cdeq_##X* self, size_t n, bool at_front); \ + CX##_expand_(CX* self, size_t n, bool at_front); \ STC_API void \ - cdeq_##X##_resize(cdeq_##X* self, size_t size, Value fill_val); \ + CX##_resize(CX* self, size_t size, Value fill_val); \ STC_INLINE void \ - cdeq_##X##_reserve(cdeq_##X* self, size_t n) { \ - _cdeq_##X##_expand(self, (n - cdeq_rep_(self)->size)*0.65, false); \ + CX##_reserve(CX* self, size_t n) { \ + CX##_expand_(self, (n - cdeq_rep_(self)->size)*0.65, false); \ } \ STC_INLINE void \ - cdeq_##X##_swap(cdeq_##X* a, cdeq_##X* b) {c_swap(cdeq_##X, *a, *b);} \ + CX##_swap(CX* a, CX* b) {c_swap(CX, *a, *b);} \ \ - STC_INLINE cdeq_##X \ - cdeq_##X##_with_size(size_t size, Value null_val) { \ - cdeq_##X x = cdeq_##X##_init(); \ - cdeq_##X##_resize(&x, size, null_val); \ + STC_INLINE CX \ + CX##_with_size(size_t size, Value null_val) { \ + CX x = CX##_init(); \ + CX##_resize(&x, size, null_val); \ return x; \ } \ - STC_INLINE cdeq_##X \ - cdeq_##X##_with_capacity(size_t size) { \ - cdeq_##X x = cdeq_##X##_init(); \ - _cdeq_##X##_expand(&x, size, false); \ + STC_INLINE CX \ + CX##_with_capacity(size_t size) { \ + CX x = CX##_init(); \ + CX##_expand_(&x, size, false); \ return x; \ } \ - STC_API cdeq_##X \ - cdeq_##X##_clone(cdeq_##X deq); \ + STC_API CX \ + CX##_clone(CX deq); \ \ STC_INLINE void \ - cdeq_##X##_shrink_to_fit(cdeq_##X *self) { \ - cdeq_##X x = cdeq_##X##_clone(*self); \ - cdeq_##X##_del(self); *self = x; \ + CX##_shrink_to_fit(CX *self) { \ + CX x = CX##_clone(*self); \ + CX##_del(self); *self = x; \ } \ \ STC_API void \ - cdeq_##X##_emplace_n(cdeq_##X *self, const cdeq_##X##_rawvalue_t arr[], size_t n); \ + CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t n); \ STC_API void \ - cdeq_##X##_push_back(cdeq_##X* self, Value value); \ + CX##_push_back(CX* self, Value value); \ STC_INLINE void \ - cdeq_##X##_emplace_back(cdeq_##X* self, RawValue raw) { \ - cdeq_##X##_push_back(self, valueFromRaw(raw)); \ + CX##_emplace_back(CX* self, RawValue raw) { \ + CX##_push_back(self, valueFromRaw(raw)); \ } \ STC_INLINE void \ - cdeq_##X##_pop_back(cdeq_##X* self) { \ + CX##_pop_back(CX* self) { \ valueDel(&self->data[--cdeq_rep_(self)->size]); \ } \ \ STC_API void \ - cdeq_##X##_push_front(cdeq_##X* self, Value value); \ + CX##_push_front(CX* self, Value value); \ STC_INLINE void \ - cdeq_##X##_emplace_front(cdeq_##X* self, RawValue raw) { \ - cdeq_##X##_push_front(self, valueFromRaw(raw)); \ + CX##_emplace_front(CX* self, RawValue raw) { \ + CX##_push_front(self, valueFromRaw(raw)); \ } \ STC_INLINE void \ - cdeq_##X##_pop_front(cdeq_##X* self) { \ + CX##_pop_front(CX* self) { \ valueDel(self->data++); \ --cdeq_rep_(self)->size; \ } \ \ - STC_API cdeq_##X##_iter_t \ - cdeq_##X##_insert_range_p(cdeq_##X* self, cdeq_##X##_value_t* pos, const cdeq_##X##_value_t* pfirst, const cdeq_##X##_value_t* pfinish); \ + STC_API CX##_iter_t \ + CX##_insert_range_p(CX* self, CX##_value_t* pos, const CX##_value_t* pfirst, const CX##_value_t* pfinish); \ \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_insert_range(cdeq_##X* self, cdeq_##X##_iter_t pos, cdeq_##X##_iter_t first, cdeq_##X##_iter_t finish) { \ - return cdeq_##X##_insert_range_p(self, pos.ref, first.ref, finish.ref); \ + STC_INLINE CX##_iter_t \ + CX##_insert_range(CX* self, CX##_iter_t pos, CX##_iter_t first, CX##_iter_t finish) { \ + return CX##_insert_range_p(self, pos.ref, first.ref, finish.ref); \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_insert_at(cdeq_##X* self, cdeq_##X##_iter_t pos, Value value) { \ - return cdeq_##X##_insert_range_p(self, pos.ref, &value, &value + 1); \ + STC_INLINE CX##_iter_t \ + CX##_insert_at(CX* self, CX##_iter_t pos, Value value) { \ + return CX##_insert_range_p(self, pos.ref, &value, &value + 1); \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_insert(cdeq_##X* self, size_t idx, Value value) { \ - return cdeq_##X##_insert_range_p(self, self->data + idx, &value, &value + 1); \ + STC_INLINE CX##_iter_t \ + CX##_insert(CX* self, size_t idx, Value value) { \ + return CX##_insert_range_p(self, self->data + idx, &value, &value + 1); \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_emplace_at(cdeq_##X* self, cdeq_##X##_iter_t pos, RawValue raw) { \ - return cdeq_##X##_insert_at(self, pos, valueFromRaw(raw)); \ + STC_INLINE CX##_iter_t \ + CX##_emplace_at(CX* self, CX##_iter_t pos, RawValue raw) { \ + return CX##_insert_at(self, pos, valueFromRaw(raw)); \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_emplace(cdeq_##X* self, size_t idx, RawValue raw) { \ - return cdeq_##X##_insert(self, idx, valueFromRaw(raw)); \ + STC_INLINE CX##_iter_t \ + CX##_emplace(CX* self, size_t idx, RawValue raw) { \ + return CX##_insert(self, idx, valueFromRaw(raw)); \ } \ \ - STC_API cdeq_##X##_iter_t \ - cdeq_##X##_erase_range_p(cdeq_##X* self, cdeq_##X##_value_t* first, cdeq_##X##_value_t* finish); \ + STC_API CX##_iter_t \ + CX##_erase_range_p(CX* self, CX##_value_t* first, CX##_value_t* finish); \ \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_erase_range(cdeq_##X* self, cdeq_##X##_iter_t first, cdeq_##X##_iter_t finish) { \ - return cdeq_##X##_erase_range_p(self, first.ref, finish.ref); \ + STC_INLINE CX##_iter_t \ + CX##_erase_range(CX* self, CX##_iter_t first, CX##_iter_t finish) { \ + return CX##_erase_range_p(self, first.ref, finish.ref); \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_erase_at(cdeq_##X* self, cdeq_##X##_iter_t pos) { \ - return cdeq_##X##_erase_range_p(self, pos.ref, pos.ref + 1); \ + STC_INLINE CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos) { \ + return CX##_erase_range_p(self, pos.ref, pos.ref + 1); \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_erase(cdeq_##X* self, size_t idx, size_t n) { \ - return cdeq_##X##_erase_range_p(self, self->data + idx, self->data + idx + n); \ + STC_INLINE CX##_iter_t \ + CX##_erase(CX* self, size_t idx, size_t n) { \ + return CX##_erase_range_p(self, self->data + idx, self->data + idx + n); \ } \ \ - STC_INLINE cdeq_##X##_value_t* \ - cdeq_##X##_front(const cdeq_##X* self) {return self->data;} \ - STC_INLINE cdeq_##X##_value_t* \ - cdeq_##X##_back(const cdeq_##X* self) {return self->data + cdeq_rep_(self)->size - 1;} \ - STC_INLINE cdeq_##X##_value_t* \ - cdeq_##X##_at(const cdeq_##X* self, size_t i) { \ + STC_INLINE CX##_value_t* \ + CX##_front(const CX* self) {return self->data;} \ + STC_INLINE CX##_value_t* \ + CX##_back(const CX* self) {return self->data + cdeq_rep_(self)->size - 1;} \ + STC_INLINE CX##_value_t* \ + CX##_at(const CX* self, size_t i) { \ assert(i < cdeq_rep_(self)->size); \ return self->data + i; \ } \ \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_begin(const cdeq_##X* self) { \ - cdeq_##X##_iter_t it = {self->data}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_begin(const CX* self) { \ + CX##_iter_t it = {self->data}; return it; \ } \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_end(const cdeq_##X* self) { \ - cdeq_##X##_iter_t it = {self->data + cdeq_rep_(self)->size}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_end(const CX* self) { \ + CX##_iter_t it = {self->data + cdeq_rep_(self)->size}; return it; \ } \ STC_INLINE void \ - cdeq_##X##_next(cdeq_##X##_iter_t* it) {++it->ref;} \ - STC_INLINE cdeq_##X##_value_t* \ - cdeq_##X##_itval(cdeq_##X##_iter_t it) {return it.ref;} \ + CX##_next(CX##_iter_t* it) {++it->ref;} \ STC_INLINE size_t \ - cdeq_##X##_index(cdeq_##X deq, cdeq_##X##_iter_t it) {return it.ref - deq.data;} \ + CX##_index(CX deq, CX##_iter_t it) {return it.ref - deq.data;} \ \ - STC_API cdeq_##X##_iter_t \ - cdeq_##X##_find_in_range(cdeq_##X##_iter_t first, cdeq_##X##_iter_t finish, RawValue raw); \ - STC_INLINE cdeq_##X##_iter_t \ - cdeq_##X##_find(const cdeq_##X* self, RawValue raw) { \ - return cdeq_##X##_find_in_range(cdeq_##X##_begin(self), cdeq_##X##_end(self), raw); \ + STC_API CX##_iter_t \ + CX##_find_in_range(CX##_iter_t first, CX##_iter_t finish, RawValue raw); \ + STC_INLINE CX##_iter_t \ + CX##_find(const CX* self, RawValue raw) { \ + return CX##_find_in_range(CX##_begin(self), CX##_end(self), raw); \ } \ STC_API int \ - cdeq_##X##_value_compare(const cdeq_##X##_value_t* x, const cdeq_##X##_value_t* y); \ + CX##_value_compare(const CX##_value_t* x, const CX##_value_t* y); \ STC_INLINE void \ - cdeq_##X##_sort_range(cdeq_##X##_iter_t i1, cdeq_##X##_iter_t i2, \ - int(*cmp)(const cdeq_##X##_value_t*, const cdeq_##X##_value_t*)) { \ - qsort(i1.ref, i2.ref - i1.ref, sizeof(cdeq_##X##_value_t), (c_cmp_fn) cmp); \ + CX##_sort_range(CX##_iter_t i1, CX##_iter_t i2, \ + int(*cmp)(const CX##_value_t*, const CX##_value_t*)) { \ + qsort(i1.ref, i2.ref - i1.ref, sizeof(CX##_value_t), (c_cmp_fn) cmp); \ } \ STC_INLINE void \ - cdeq_##X##_sort(cdeq_##X* self) { \ - cdeq_##X##_sort_range(cdeq_##X##_begin(self), cdeq_##X##_end(self), cdeq_##X##_value_compare); \ + CX##_sort(CX* self) { \ + CX##_sort_range(CX##_begin(self), CX##_end(self), CX##_value_compare); \ } \ - _c_implement_cdeq_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ - typedef cdeq_##X cdeq_##X##_t + _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + typedef CX CX##_t /* -------------------------- IMPLEMENTATION ------------------------- */ @@ -221,40 +221,40 @@ static struct cdeq_rep _cdeq_inits = {0, 0}; static inline double _minf(double x, double y) {return x < y ? x : y;} static inline double _maxf(double x, double y) {return x > y ? x : y;} -#define _c_implement_cdeq_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ +#define _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ \ - STC_DEF cdeq_##X \ - cdeq_##X##_init(void) { \ - cdeq_##X##_value_t *b = (cdeq_##X##_value_t *) _cdeq_inits.base; \ - cdeq_##X deq = {b, b}; return deq; \ + STC_DEF CX \ + CX##_init(void) { \ + CX##_value_t *b = (CX##_value_t *) _cdeq_inits.base; \ + CX deq = {b, b}; return deq; \ } \ \ STC_DEF void \ - cdeq_##X##_emplace_n(cdeq_##X *self, const cdeq_##X##_rawvalue_t arr[], size_t n) { \ + CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t n) { \ if (!n) return; \ - _cdeq_##X##_expand(self, n, false); \ - cdeq_##X##_value_t* p = self->data + cdeq_rep_(self)->size; \ + CX##_expand_(self, n, false); \ + CX##_value_t* p = self->data + cdeq_rep_(self)->size; \ for (size_t i=0; i < n; ++i) *p++ = valueFromRaw(arr[i]); \ cdeq_rep_(self)->size += n; \ } \ \ STC_DEF void \ - cdeq_##X##_clear(cdeq_##X* self) { \ + CX##_clear(CX* self) { \ struct cdeq_rep* rep = cdeq_rep_(self); if (rep->cap) { \ - for (cdeq_##X##_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \ + for (CX##_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \ valueDel(p); \ rep->size = 0; \ } \ } \ STC_DEF void \ - cdeq_##X##_del(cdeq_##X* self) { \ - cdeq_##X##_clear(self); \ + CX##_del(CX* self) { \ + CX##_clear(self); \ if (cdeq_rep_(self)->cap) \ c_free(cdeq_rep_(self)); \ } \ \ STC_DEF void \ - _cdeq_##X##_expand(cdeq_##X* self, size_t n, bool at_front) { \ + CX##_expand_(CX* self, size_t n, bool at_front) { \ struct cdeq_rep* rep = cdeq_rep_(self); \ size_t len = rep->size, cap = rep->cap; \ size_t nfront = self->data - self->base, nback = cap - (nfront + len); \ @@ -265,20 +265,20 @@ static inline double _maxf(double x, double y) {return x > y ? x : y;} rep = (struct cdeq_rep*) c_realloc(rep->cap ? rep : NULL, \ sizeof(struct cdeq_rep) + cap*sizeof(Value)); \ rep->size = len, rep->cap = cap; \ - self->base = (cdeq_##X##_value_t *) rep->base; \ + self->base = (CX##_value_t *) rep->base; \ self->data = self->base + nfront; \ - _cdeq_##X##_expand(self, n, at_front); \ + CX##_expand_(self, n, at_front); \ return; \ } \ size_t unused = cap - (len + n); \ size_t pos = at_front ? _maxf(unused*0.5, (float) unused - nback) + n \ : _minf(unused*0.5, nfront); \ - self->data = (cdeq_##X##_value_t *) memmove(self->base + pos, self->data, len*sizeof(Value)); \ + self->data = (CX##_value_t *) memmove(self->base + pos, self->data, len*sizeof(Value)); \ } \ \ STC_DEF void \ - cdeq_##X##_resize(cdeq_##X* self, size_t size, Value null_val) { \ - _cdeq_##X##_expand(self, size, false); \ + CX##_resize(CX* self, size_t size, Value null_val) { \ + CX##_expand_(self, size, false); \ size_t i, n = cdeq_rep_(self)->size; \ for (i=size; idata + i); \ for (i=n; idata[i] = null_val; \ @@ -286,33 +286,33 @@ static inline double _maxf(double x, double y) {return x > y ? x : y;} } \ \ STC_DEF void \ - cdeq_##X##_push_front(cdeq_##X* self, Value value) { \ + CX##_push_front(CX* self, Value value) { \ if (self->data == self->base) \ - _cdeq_##X##_expand(self, 1, true); \ + CX##_expand_(self, 1, true); \ *--self->data = value; \ ++cdeq_rep_(self)->size; \ } \ STC_DEF void \ - cdeq_##X##_push_back(cdeq_##X* self, Value value) { \ + CX##_push_back(CX* self, Value value) { \ if (_cdeq_nfront(self) + cdeq_rep_(self)->size == cdeq_rep_(self)->cap) \ - _cdeq_##X##_expand(self, 1, false); \ + CX##_expand_(self, 1, false); \ self->data[cdeq_rep_(self)->size++] = value; \ } \ \ - STC_DEF cdeq_##X \ - cdeq_##X##_clone(cdeq_##X deq) { \ + STC_DEF CX \ + CX##_clone(CX deq) { \ size_t len = cdeq_rep_(&deq)->size; \ - cdeq_##X out = cdeq_##X##_with_capacity(len); \ - cdeq_##X##_insert_range_p(&out, out.data, deq.data, deq.data + len); \ + CX out = CX##_with_capacity(len); \ + CX##_insert_range_p(&out, out.data, deq.data, deq.data + len); \ return out; \ } \ \ - STC_DEF cdeq_##X##_iter_t \ - cdeq_##X##_insert_range_p(cdeq_##X* self, cdeq_##X##_value_t* pos, \ - const cdeq_##X##_value_t* first, const cdeq_##X##_value_t* finish) { \ + STC_DEF CX##_iter_t \ + CX##_insert_range_p(CX* self, CX##_value_t* pos, \ + const CX##_value_t* first, const CX##_value_t* finish) { \ size_t n = finish - first, idx = pos - self->data, size = cdeq_rep_(self)->size; \ bool at_front = (idx*2 < size); \ - _cdeq_##X##_expand(self, n, at_front); \ + CX##_expand_(self, n, at_front); \ if (at_front) { \ memmove(self->data - n, self->data, idx*sizeof(Value)); \ pos = (self->data -= n) + idx; \ @@ -320,28 +320,28 @@ static inline double _maxf(double x, double y) {return x > y ? x : y;} pos = self->data + idx; \ memmove(pos + n, pos, (size - idx)*sizeof(Value)); \ } \ - cdeq_##X##_iter_t it = {pos}; \ + CX##_iter_t it = {pos}; \ if (n) cdeq_rep_(self)->size += n; \ while (first != finish) \ *pos++ = valueFromRaw(valueToRaw(first++)); \ return it; \ } \ \ - STC_DEF cdeq_##X##_iter_t \ - cdeq_##X##_erase_range_p(cdeq_##X* self, cdeq_##X##_value_t* first, cdeq_##X##_value_t* finish) { \ + STC_DEF CX##_iter_t \ + CX##_erase_range_p(CX* self, CX##_value_t* first, CX##_value_t* finish) { \ intptr_t len = finish - first; \ if (len > 0) { \ - cdeq_##X##_value_t* p = first, *end = self->data + cdeq_rep_(self)->size; \ + CX##_value_t* p = first, *end = self->data + cdeq_rep_(self)->size; \ while (p != finish) valueDel(p++); \ if (first == self->data) self->data += len; \ else memmove(first, finish, (end - finish) * sizeof(Value)); \ cdeq_rep_(self)->size -= len; \ } \ - cdeq_##X##_iter_t it = {first}; return it; \ + CX##_iter_t it = {first}; return it; \ } \ \ - STC_DEF cdeq_##X##_iter_t \ - cdeq_##X##_find_in_range(cdeq_##X##_iter_t i1, cdeq_##X##_iter_t i2, RawValue raw) { \ + STC_DEF CX##_iter_t \ + CX##_find_in_range(CX##_iter_t i1, CX##_iter_t i2, RawValue raw) { \ for (; i1.ref != i2.ref; ++i1.ref) { \ RawValue r = valueToRaw(i1.ref); \ if (valueCompareRaw(&raw, &r) == 0) return i1; \ @@ -349,14 +349,14 @@ static inline double _maxf(double x, double y) {return x > y ? x : y;} return i2; \ } \ STC_DEF int \ - cdeq_##X##_value_compare(const cdeq_##X##_value_t* x, const cdeq_##X##_value_t* y) { \ + CX##_value_compare(const CX##_value_t* x, const CX##_value_t* y) { \ RawValue rx = valueToRaw(x); \ RawValue ry = valueToRaw(y); \ return valueCompareRaw(&rx, &ry); \ } #else -#define _c_implement_cdeq_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) +#define _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #endif #endif diff --git a/stc/clist.h b/stc/clist.h index 027f5e9c..5a972304 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -56,6 +56,7 @@ #include #define using_clist(...) c_MACRO_OVERLOAD(using_clist, __VA_ARGS__) + #define using_clist_2(X, Value) \ using_clist_3(X, Value, c_default_compare) #define using_clist_3(X, Value, valueCompare) \ @@ -64,174 +65,176 @@ using_clist_5(X, Value, valueCompare, valueDel, c_no_clone) #define using_clist_5(X, Value, valueCompare, valueDel, valueClone) \ using_clist_7(X, Value, valueCompare, valueDel, valueClone, c_trivial_toraw, Value) +#define using_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + _c_using_clist(clist_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #define using_clist_str() \ - using_clist_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) + _c_using_clist(clist_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) -#define using_clist_types(X, Value) \ - typedef Value clist_##X##_value_t; \ +#define _c_using_clist_types(CX, Value) \ + typedef Value CX##_value_t; \ \ - typedef struct clist_##X##_node { \ - struct clist_##X##_node* next; \ - clist_##X##_value_t value; \ - } clist_##X##_node_t; \ + typedef struct CX##_node { \ + struct CX##_node* next; \ + CX##_value_t value; \ + } CX##_node_t; \ \ typedef struct { \ - clist_##X##_node_t* last; \ - } clist_##X; \ + CX##_node_t* last; \ + } CX; \ \ typedef struct { \ - clist_##X##_node_t* const *_last, *_prev; \ - clist_##X##_value_t* ref; \ - } clist_##X##_iter_t + CX##_node_t* const *_last, *_prev; \ + CX##_value_t* ref; \ + } CX##_iter_t -using_clist_types(void, int); -STC_API size_t _clist_size(const clist_void* self); -#define _clist_node(X, vp) c_container_of(vp, clist_##X##_node_t, value) +_c_using_clist_types(clist_VOID, int); +STC_API size_t _clist_size(const clist_VOID* self); +#define _clist_node(CX, vp) c_container_of(vp, CX##_node_t, value) -#define using_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ +#define _c_using_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ \ - using_clist_types(X, Value); \ - typedef RawValue clist_##X##_rawvalue_t; \ + _c_using_clist_types(CX, Value); \ + typedef RawValue CX##_rawvalue_t; \ \ - STC_INLINE clist_##X \ - clist_##X##_init(void) {clist_##X lst = {NULL}; return lst;} \ + STC_INLINE CX \ + CX##_init(void) {CX lst = {NULL}; return lst;} \ STC_INLINE bool \ - clist_##X##_empty(clist_##X lst) {return lst.last == NULL;} \ + CX##_empty(CX lst) {return lst.last == NULL;} \ STC_INLINE size_t \ - clist_##X##_count(clist_##X lst) {return _clist_size((const clist_void*) &lst);} \ + CX##_count(CX lst) {return _clist_size((const clist_VOID*) &lst);} \ STC_INLINE Value \ - clist_##X##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ - STC_INLINE clist_##X##_value_t \ - clist_##X##_value_clone(clist_##X##_value_t val) {return valueFromRaw(valueToRaw(&val));} \ + CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ + STC_INLINE CX##_value_t \ + CX##_value_clone(CX##_value_t val) {return valueFromRaw(valueToRaw(&val));} \ \ STC_API void \ - clist_##X##_del(clist_##X* self); \ - STC_API clist_##X \ - clist_##X##_clone(clist_##X list); \ + CX##_del(CX* self); \ + STC_API CX \ + CX##_clone(CX list); \ STC_INLINE void \ - clist_##X##_clear(clist_##X* self) {clist_##X##_del(self);} \ + CX##_clear(CX* self) {CX##_del(self);} \ \ STC_API void \ - clist_##X##_emplace_n(clist_##X *self, const clist_##X##_rawvalue_t arr[], size_t size); \ + CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t size); \ STC_API void \ - clist_##X##_push_back(clist_##X* self, Value value); \ + CX##_push_back(CX* self, Value value); \ STC_INLINE void \ - clist_##X##_emplace_back(clist_##X* self, RawValue raw) { \ - clist_##X##_push_back(self, valueFromRaw(raw)); \ + CX##_emplace_back(CX* self, RawValue raw) { \ + CX##_push_back(self, valueFromRaw(raw)); \ } \ STC_API void \ - clist_##X##_push_front(clist_##X* self, Value value); \ + CX##_push_front(CX* self, Value value); \ STC_INLINE void \ - clist_##X##_emplace_front(clist_##X* self, RawValue raw) { \ - clist_##X##_push_front(self, valueFromRaw(raw)); \ + CX##_emplace_front(CX* self, RawValue raw) { \ + CX##_push_front(self, valueFromRaw(raw)); \ } \ \ - STC_API clist_##X##_node_t* \ - _clist_##X##_erase_after(clist_##X* self, clist_##X##_node_t* node); \ + STC_API CX##_node_t* \ + CX##_erase_after_(CX* self, CX##_node_t* node); \ \ STC_INLINE void \ - clist_##X##_pop_front(clist_##X* self) { \ - _clist_##X##_erase_after(self, self->last); \ + CX##_pop_front(CX* self) { \ + CX##_erase_after_(self, self->last); \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_begin(const clist_##X* self) { \ - clist_##X##_value_t* head = self->last ? &self->last->next->value : NULL; \ - clist_##X##_iter_t it = {&self->last, self->last, head}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_begin(const CX* self) { \ + CX##_value_t* head = self->last ? &self->last->next->value : NULL; \ + CX##_iter_t it = {&self->last, self->last, head}; return it; \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_end(const clist_##X* self) { \ - clist_##X##_iter_t it = {&self->last, NULL, NULL}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_end(const CX* self) { \ + CX##_iter_t it = {&self->last, NULL, NULL}; return it; \ } \ STC_INLINE void \ - clist_##X##_next(clist_##X##_iter_t* it) { \ - clist_##X##_node_t* node = it->_prev = _clist_node(X, it->ref); \ + CX##_next(CX##_iter_t* it) { \ + CX##_node_t* node = it->_prev = _clist_node(CX, it->ref); \ it->ref = (node == *it->_last ? NULL : &node->next->value); \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_fwd(clist_##X##_iter_t it, size_t n) { \ - while (n-- && it.ref) clist_##X##_next(&it); \ + STC_INLINE CX##_iter_t \ + CX##_fwd(CX##_iter_t it, size_t n) { \ + while (n-- && it.ref) CX##_next(&it); \ return it; \ } \ \ - STC_API clist_##X##_iter_t \ - clist_##X##_insert(clist_##X* self, clist_##X##_iter_t pos, Value value); \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_emplace(clist_##X* self, clist_##X##_iter_t pos, RawValue raw) { \ - return clist_##X##_insert(self, pos, valueFromRaw(raw)); \ + STC_API CX##_iter_t \ + CX##_insert(CX* self, CX##_iter_t pos, Value value); \ + STC_INLINE CX##_iter_t \ + CX##_emplace(CX* self, CX##_iter_t pos, RawValue raw) { \ + return CX##_insert(self, pos, valueFromRaw(raw)); \ } \ - STC_API clist_##X##_iter_t \ - clist_##X##_erase_at(clist_##X* self, clist_##X##_iter_t pos); \ - STC_API clist_##X##_iter_t \ - clist_##X##_erase_range(clist_##X* self, clist_##X##_iter_t pos, clist_##X##_iter_t finish); \ + STC_API CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos); \ + STC_API CX##_iter_t \ + CX##_erase_range(CX* self, CX##_iter_t pos, CX##_iter_t finish); \ \ STC_API void \ - clist_##X##_splice(clist_##X* self, clist_##X##_iter_t pos, clist_##X* other); \ - STC_API clist_##X \ - clist_##X##_split(clist_##X* self, clist_##X##_iter_t pos1, clist_##X##_iter_t pos2); \ + CX##_splice(CX* self, CX##_iter_t pos, CX* other); \ + STC_API CX \ + CX##_split(CX* self, CX##_iter_t pos1, CX##_iter_t pos2); \ \ STC_INLINE void \ - clist_##X##_splice_range(clist_##X* self, clist_##X##_iter_t pos, \ - clist_##X* other, clist_##X##_iter_t pos1, clist_##X##_iter_t pos2) { \ - clist_##X tmp = clist_##X##_split(other, pos1, pos2); \ - clist_##X##_splice(self, pos, &tmp); \ + CX##_splice_range(CX* self, CX##_iter_t pos, \ + CX* other, CX##_iter_t pos1, CX##_iter_t pos2) { \ + CX tmp = CX##_split(other, pos1, pos2); \ + CX##_splice(self, pos, &tmp); \ } \ \ STC_API size_t \ - clist_##X##_remove(clist_##X* self, RawValue val); \ + CX##_remove(CX* self, RawValue val); \ STC_API void \ - clist_##X##_sort(clist_##X* self); \ - STC_API clist_##X##_iter_t \ - clist_##X##_find_in_range(const clist_##X* self, clist_##X##_iter_t first, clist_##X##_iter_t finish, RawValue val); \ + CX##_sort(CX* self); \ + STC_API CX##_iter_t \ + CX##_find_in_range(const CX* self, CX##_iter_t first, CX##_iter_t finish, RawValue val); \ \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_find(const clist_##X* self, RawValue val) { \ - return clist_##X##_find_in_range(self, clist_##X##_begin(self), clist_##X##_end(self), val); \ + STC_INLINE CX##_iter_t \ + CX##_find(const CX* self, RawValue val) { \ + return CX##_find_in_range(self, CX##_begin(self), CX##_end(self), val); \ } \ STC_INLINE Value* \ - clist_##X##_front(const clist_##X* self) {return &self->last->next->value;} \ + CX##_front(const CX* self) {return &self->last->next->value;} \ STC_INLINE Value* \ - clist_##X##_back(const clist_##X* self) {return &self->last->value;} \ + CX##_back(const CX* self) {return &self->last->value;} \ \ - _c_implement_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ - typedef clist_##X clist_##X##_t + _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + typedef CX CX##_t /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define _c_implement_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ +#define _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ \ - STC_DEF clist_##X \ - clist_##X##_clone(clist_##X list) { \ - clist_##X out = clist_##X##_init(); \ - c_foreach_3 (i, clist_##X, list) \ - clist_##X##_emplace_back(&out, valueToRaw(i.ref)); \ + STC_DEF CX \ + CX##_clone(CX list) { \ + CX out = CX##_init(); \ + c_foreach_3 (i, CX, list) \ + CX##_emplace_back(&out, valueToRaw(i.ref)); \ return out; \ } \ STC_DEF void \ - clist_##X##_del(clist_##X* self) { \ - while (self->last) _clist_##X##_erase_after(self, self->last); \ + CX##_del(CX* self) { \ + while (self->last) CX##_erase_after_(self, self->last); \ } \ \ STC_DEF void \ - clist_##X##_push_back(clist_##X* self, Value value) { \ - _c_clist_insert_after(self, X, self->last, value); \ + CX##_push_back(CX* self, Value value) { \ + _c_clist_insert_after(self, CX, self->last, value); \ self->last = entry; \ } \ STC_DEF void \ - clist_##X##_push_front(clist_##X* self, Value value) { \ - _c_clist_insert_after(self, X, self->last, value); \ + CX##_push_front(CX* self, Value value) { \ + _c_clist_insert_after(self, CX, self->last, value); \ if (!self->last) self->last = entry; \ } \ STC_DEF void \ - clist_##X##_emplace_n(clist_##X *self, const clist_##X##_rawvalue_t arr[], size_t n) { \ - for (size_t i=0; ilast; \ - _c_clist_insert_after(self, X, node, value); \ + STC_DEF CX##_iter_t \ + CX##_insert(CX* self, CX##_iter_t pos, Value value) { \ + CX##_node_t* node = pos.ref ? pos._prev : self->last; \ + _c_clist_insert_after(self, CX, node, value); \ if (!self->last || !pos.ref) { \ pos._prev = self->last ? self->last : entry; \ self->last = entry; \ @@ -240,35 +243,35 @@ STC_API size_t _clist_size(const clist_void* self); return pos; \ } \ \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_erase_at(clist_##X* self, clist_##X##_iter_t pos) { \ - clist_##X##_node_t *node = _clist_node(X, pos.ref); \ + STC_DEF CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos) { \ + CX##_node_t *node = _clist_node(CX, pos.ref); \ pos.ref = (node == self->last) ? NULL : &node->next->value; \ - _clist_##X##_erase_after(self, pos._prev); \ + CX##_erase_after_(self, pos._prev); \ return pos; \ } \ \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_erase_range(clist_##X* self, clist_##X##_iter_t first, clist_##X##_iter_t finish) { \ - clist_##X##_node_t *node = first.ref ? first._prev : NULL, \ - *done = finish.ref ? _clist_node(X, finish.ref) : NULL; \ + STC_DEF CX##_iter_t \ + CX##_erase_range(CX* self, CX##_iter_t first, CX##_iter_t finish) { \ + CX##_node_t *node = first.ref ? first._prev : NULL, \ + *done = finish.ref ? _clist_node(CX, finish.ref) : NULL; \ while (node && node->next != done) \ - node = _clist_##X##_erase_after(self, node); \ + node = CX##_erase_after_(self, node); \ return finish; \ } \ \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_find_in_range(const clist_##X* self, clist_##X##_iter_t first, clist_##X##_iter_t finish, RawValue val) { \ - c_foreach_4 (i, clist_##X, first, finish) { \ + STC_DEF CX##_iter_t \ + CX##_find_in_range(const CX* self, CX##_iter_t first, CX##_iter_t finish, RawValue val) { \ + c_foreach_4 (i, CX, first, finish) { \ RawValue r = valueToRaw(i.ref); \ if (valueCompareRaw(&r, &val) == 0) return i; \ } \ - return clist_##X##_end(self); \ + return CX##_end(self); \ } \ \ - STC_DEF clist_##X##_node_t* \ - _clist_##X##_erase_after(clist_##X* self, clist_##X##_node_t* node) { \ - clist_##X##_node_t* del = node->next, *next = del->next; \ + STC_DEF CX##_node_t* \ + CX##_erase_after_(CX* self, CX##_node_t* node) { \ + CX##_node_t* del = node->next, *next = del->next; \ node->next = next; \ if (del == next) self->last = node = NULL; \ else if (self->last == del) self->last = node, node = NULL; \ @@ -277,14 +280,14 @@ STC_API size_t _clist_size(const clist_void* self); } \ \ STC_DEF size_t \ - clist_##X##_remove(clist_##X* self, RawValue val) { \ + CX##_remove(CX* self, RawValue val) { \ size_t n = 0; \ - clist_##X##_node_t* prev = self->last, *node; \ + CX##_node_t* prev = self->last, *node; \ while (prev) { \ node = prev->next; \ RawValue r = valueToRaw(&node->value); \ if (valueCompareRaw(&r, &val) == 0) \ - prev = _clist_##X##_erase_after(self, prev), ++n; \ + prev = CX##_erase_after_(self, prev), ++n; \ else \ prev = (node == self->last ? NULL : node); \ } \ @@ -292,11 +295,11 @@ STC_API size_t _clist_size(const clist_void* self); } \ \ STC_DEF void \ - clist_##X##_splice(clist_##X* self, clist_##X##_iter_t pos, clist_##X* other) { \ + CX##_splice(CX* self, CX##_iter_t pos, CX* other) { \ if (!self->last) \ self->last = other->last; \ else if (other->last) { \ - clist_##X##_node_t *p = pos.ref ? pos._prev : self->last, *next = p->next; \ + CX##_node_t *p = pos.ref ? pos._prev : self->last, *next = p->next; \ p->next = other->last->next; \ other->last->next = next; \ if (!pos.ref) self->last = other->last; \ @@ -304,41 +307,41 @@ STC_API size_t _clist_size(const clist_void* self); other->last = NULL; \ } \ \ - STC_DEF clist_##X \ - clist_##X##_split(clist_##X* self, clist_##X##_iter_t pos1, clist_##X##_iter_t pos2) { \ - clist_##X list = {NULL}; \ + STC_DEF CX \ + CX##_split(CX* self, CX##_iter_t pos1, CX##_iter_t pos2) { \ + CX list = {NULL}; \ if (pos1.ref == pos2.ref) return list; \ - clist_##X##_node_t *p1 = pos1._prev, \ + CX##_node_t *p1 = pos1._prev, \ *p2 = pos2.ref ? pos2._prev : self->last; \ - p1->next = p2->next, p2->next = _clist_node(X, pos1.ref); \ + p1->next = p2->next, p2->next = _clist_node(CX, pos1.ref); \ if (self->last == p2) self->last = (p1 == p2) ? NULL : p1; \ list.last = p2; \ return list; \ } \ \ STC_INLINE int \ - 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); \ + CX##_sort_compare(const void* x, const void* y) { \ + RawValue a = valueToRaw(&((CX##_node_t *) x)->value); \ + RawValue b = valueToRaw(&((CX##_node_t *) y)->value); \ return valueCompareRaw(&a, &b); \ } \ STC_DEF void \ - clist_##X##_sort(clist_##X* self) { \ + CX##_sort(CX* self) { \ if (self->last) \ - self->last = (clist_##X##_node_t *) _clist_mergesort((clist_void_node_t *) self->last->next, clist_##X##_sort_compare); \ + self->last = (CX##_node_t *) _clist_mergesort((clist_VOID_node_t *) self->last->next, CX##_sort_compare); \ } -#define _c_clist_insert_after(self, X, node, val) \ - clist_##X##_node_t *entry = c_new_1 (clist_##X##_node_t); \ +#define _c_clist_insert_after(self, CX, node, val) \ + CX##_node_t *entry = c_new_1 (CX##_node_t); \ if (node) entry->next = node->next, node->next = entry; \ else entry->next = entry; \ entry->value = val /* +: set self->last based on node */ STC_DEF size_t -_clist_size(const clist_void* self) { - const clist_void_node_t *i = self->last; +_clist_size(const clist_VOID* self) { + const clist_VOID_node_t *i = self->last; if (!i) return 0; size_t n = 1; while ((i = i->next) != self->last) ++n; @@ -348,9 +351,9 @@ _clist_size(const clist_void* self) { /* Singly linked list Mergesort implementation by Simon Tatham. O(n*log n). * https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html */ -STC_DEF clist_void_node_t * -_clist_mergesort(clist_void_node_t *list, int (*cmp)(const void*, const void*)) { - clist_void_node_t *p, *q, *e, *tail, *oldhead; +STC_DEF clist_VOID_node_t * +_clist_mergesort(clist_VOID_node_t *list, int (*cmp)(const void*, const void*)) { + clist_VOID_node_t *p, *q, *e, *tail, *oldhead; int insize = 1, nmerges, psize, qsize, i; while (1) { @@ -397,7 +400,7 @@ _clist_mergesort(clist_void_node_t *list, int (*cmp)(const void*, const void*)) } #else -#define _c_implement_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) +#define _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #endif #endif diff --git a/stc/cmap.h b/stc/cmap.h index fe9b7bdd..4dea5566 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -69,16 +69,16 @@ typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; #define using_cmap_9(X, Key, Mapped, keyEquals, keyHash, \ mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ - _using_CHASH(X, cmap_, Key, Mapped, keyEquals, keyHash, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - c_trivial_del, c_trivial_fromraw, c_trivial_toraw, Key) + _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEquals, keyHash, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + c_trivial_del, c_trivial_fromraw, c_trivial_toraw, Key) #define using_cmap_13(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \ mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_CHASH(X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) + _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) #define using_cmap_keydef(...) c_MACRO_OVERLOAD(using_cmap_keydef, __VA_ARGS__) @@ -88,15 +88,15 @@ typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; #define using_cmap_keydef_9(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \ keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_CHASH(X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \ - c_trivial_del, c_trivial_fromraw, c_trivial_toraw, Mapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) + _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + c_trivial_del, c_trivial_fromraw, c_trivial_toraw, Mapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) /* cmap_str, cmap_strkey, cmap_strval: */ #define using_cmap_str() \ - _using_CHASH(str, cmap_, cstr_t, cstr_t, cstr_equals_raw, cstr_hash_raw, \ - cstr_del, cstr_from, cstr_c_str, const char*, \ - cstr_del, cstr_from, cstr_c_str, const char*) + _c_using_chash(cmap_str, cmap_, cstr_t, cstr_t, cstr_equals_raw, cstr_hash_raw, \ + cstr_del, cstr_from, cstr_c_str, const char*, \ + cstr_del, cstr_from, cstr_c_str, const char*) #define using_cmap_strkey(...) \ c_MACRO_OVERLOAD(using_cmap_strkey, __VA_ARGS__) @@ -106,14 +106,14 @@ typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; #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_CHASH_strkey(X, cmap_, Mapped, mappedDel, mappedClone, c_trivial_toraw, Mapped) + _c_using_chash_strkey(X, cmap_, Mapped, mappedDel, mappedClone, c_trivial_toraw, Mapped) #define using_cmap_strkey_6(X, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ - _using_CHASH_strkey(X, cmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) + _c_using_chash_strkey(X, cmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) -#define _using_CHASH_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ - _using_CHASH(X, C, cstr_t, Mapped, cstr_equals_raw, cstr_hash_raw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - cstr_del, cstr_from, cstr_c_str, const char*) +#define _c_using_chash_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \ + _c_using_chash(C##X, C, cstr_t, Mapped, cstr_equals_raw, cstr_hash_raw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + cstr_del, cstr_from, cstr_c_str, const char*) #define using_cmap_strval(...) \ c_MACRO_OVERLOAD(using_cmap_strval, __VA_ARGS__) @@ -128,9 +128,9 @@ typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; using_cmap_strval_8(X, Key, keyEquals, keyHash, keyDel, keyClone, c_trivial_toraw, Key) #define using_cmap_strval_8(X, Key, keyEqualsRaw, keyHashRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_CHASH(X, cmap_, Key, cstr_t, keyEqualsRaw, keyHashRaw, \ - cstr_del, cstr_from, cstr_c_str, const char*, \ - keyDel, keyFromRaw, keyToRaw, RawKey) + _c_using_chash(cmap_##X, cmap_, Key, cstr_t, keyEqualsRaw, keyHashRaw, \ + cstr_del, cstr_from, cstr_c_str, const char*, \ + keyDel, keyFromRaw, keyToRaw, RawKey) #define SET_ONLY_cmap_(...) #define MAP_ONLY_cmap_(...) __VA_ARGS__ @@ -139,97 +139,97 @@ typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; #define CMAP_SIZE_T uint32_t #endif -#define _using_CHASH(X, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) \ - typedef Key C##X##_key_t; \ - typedef Mapped C##X##_mapped_t; \ - typedef RawKey C##X##_rawkey_t; \ - typedef RawMapped C##X##_rawmapped_t; \ - typedef CMAP_SIZE_T C##X##_size_t; \ +#define _c_using_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + typedef Key CX##_key_t; \ + typedef Mapped CX##_mapped_t; \ + typedef RawKey CX##_rawkey_t; \ + typedef RawMapped CX##_rawmapped_t; \ + typedef CMAP_SIZE_T CX##_size_t; \ \ typedef SET_ONLY_##C( Key ) \ MAP_ONLY_##C( struct {Key first; \ Mapped second;} ) \ - C##X##_value_t; \ + CX##_value_t; \ \ typedef SET_ONLY_##C( RawKey ) \ MAP_ONLY_##C( struct {RawKey first; \ RawMapped second;} ) \ - C##X##_rawvalue_t; \ + CX##_rawvalue_t; \ \ typedef struct { \ - C##X##_value_t *ref; \ + CX##_value_t *ref; \ bool inserted; \ - } C##X##_result_t; \ + } CX##_result_t; \ \ typedef struct { \ - C##X##_value_t* table; \ + CX##_value_t* table; \ uint8_t* _hashx; \ - C##X##_size_t size, bucket_count; \ + CX##_size_t size, bucket_count; \ float min_load_factor; \ float max_load_factor; \ - } C##X; \ + } CX; \ \ typedef struct { \ - C##X##_value_t *ref; \ + CX##_value_t *ref; \ uint8_t* _hx; \ - } C##X##_iter_t; \ + } CX##_iter_t; \ \ - STC_INLINE C##X \ - C##X##_init(void) {C##X m = _cmap_inits; return m;} \ + STC_INLINE CX \ + CX##_init(void) {CX m = _cmap_inits; return m;} \ STC_INLINE bool \ - C##X##_empty(C##X m) {return m.size == 0;} \ + CX##_empty(CX m) {return m.size == 0;} \ STC_INLINE size_t \ - C##X##_size(C##X m) {return (size_t) m.size;} \ - STC_INLINE C##X##_value_t \ - C##X##_value_clone(C##X##_value_t val) { \ + CX##_size(CX m) {return (size_t) m.size;} \ + STC_INLINE CX##_value_t \ + CX##_value_clone(CX##_value_t val) { \ *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \ MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \ return val; \ } \ STC_INLINE void \ - C##X##_value_del(C##X##_value_t* val) { \ + CX##_value_del(CX##_value_t* val) { \ keyDel(KEY_REF_##C(val)); \ MAP_ONLY_##C( mappedDel(&val->second); ) \ } \ STC_INLINE size_t \ - C##X##_bucket_count(C##X map) {return (size_t) map.bucket_count;} \ + CX##_bucket_count(CX map) {return (size_t) map.bucket_count;} \ STC_INLINE size_t \ - C##X##_capacity(C##X map) {return (size_t) (map.bucket_count*map.max_load_factor);} \ + CX##_capacity(CX map) {return (size_t) (map.bucket_count*map.max_load_factor);} \ STC_INLINE void \ - C##X##_swap(C##X *map1, C##X *map2) {c_swap(C##X, *map1, *map2);} \ + CX##_swap(CX *map1, CX *map2) {c_swap(CX, *map1, *map2);} \ STC_INLINE void \ - C##X##_set_load_factors(C##X* self, float min_load, float max_load) { \ + CX##_set_load_factors(CX* self, float min_load, float max_load) { \ self->min_load_factor = min_load; \ self->max_load_factor = max_load; \ } \ - STC_API C##X \ - C##X##_with_capacity(size_t cap); \ - STC_API C##X \ - C##X##_clone(C##X map); \ + STC_API CX \ + CX##_with_capacity(size_t cap); \ + STC_API CX \ + CX##_clone(CX map); \ STC_API void \ - C##X##_reserve(C##X* self, size_t capacity); \ + CX##_reserve(CX* self, size_t capacity); \ STC_API void \ - C##X##_del(C##X* self); \ + CX##_del(CX* self); \ STC_API void \ - C##X##_clear(C##X* self); \ + CX##_clear(CX* self); \ \ - STC_API C##X##_result_t \ - C##X##_insert_entry_(C##X* self, RawKey rkey); \ + STC_API CX##_result_t \ + CX##_insert_entry_(CX* self, RawKey rkey); \ STC_API chash_bucket_t \ - C##X##_bucket_(const C##X* self, const C##X##_rawkey_t* rkeyptr); \ + CX##_bucket_(const CX* self, const CX##_rawkey_t* rkeyptr); \ \ - STC_API C##X##_iter_t \ - C##X##_find(const C##X* self, RawKey rkey); \ + STC_API CX##_iter_t \ + CX##_find(const CX* self, RawKey rkey); \ STC_INLINE bool \ - C##X##_contains(const C##X* self, RawKey rkey) { \ - return self->size && self->_hashx[C##X##_bucket_(self, &rkey).idx]; \ + CX##_contains(const CX* self, RawKey rkey) { \ + return self->size && self->_hashx[CX##_bucket_(self, &rkey).idx]; \ } \ \ - STC_INLINE C##X##_result_t \ - C##X##_emplace(C##X* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \ - C##X##_result_t res = C##X##_insert_entry_(self, rkey); \ + 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); \ if (res.inserted) { \ *KEY_REF_##C(res.ref) = keyFromRaw(rkey); \ MAP_ONLY_##C(res.ref->second = mappedFromRaw(rmapped);) \ @@ -237,81 +237,78 @@ typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; return res; \ } \ STC_INLINE void \ - C##X##_emplace_n(C##X* self, const C##X##_rawvalue_t arr[], size_t n) { \ - for (size_t i=0; isecond = mapped; )} \ else {keyDel(&key); MAP_ONLY_##C( mappedDel(&mapped); )} \ return res; \ } \ \ MAP_ONLY_##C( \ - STC_INLINE C##X##_result_t \ - C##X##_insert_or_assign(C##X* self, Key key, Mapped mapped) { \ - C##X##_result_t res = C##X##_insert_entry_(self, keyToRaw(&key)); \ + 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)); \ if (res.inserted) res.ref->first = key; \ else {keyDel(&key); mappedDel(&res.ref->second);} \ res.ref->second = mapped; return res; \ } \ - STC_INLINE C##X##_result_t \ - C##X##_put(C##X* self, Key k, Mapped m) { /* shorter, like operator[] */ \ - return C##X##_insert_or_assign(self, k, m); \ + 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 C##X##_result_t \ - C##X##_emplace_or_assign(C##X* self, RawKey rkey, RawMapped rmapped) { \ - C##X##_result_t res = C##X##_insert_entry_(self, rkey); \ + 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 C##X##_mapped_t* \ - C##X##_at(const C##X* self, RawKey rkey) { \ - chash_bucket_t b = C##X##_bucket_(self, &rkey); \ + STC_INLINE CX##_mapped_t* \ + CX##_at(const CX* self, RawKey rkey) { \ + chash_bucket_t b = CX##_bucket_(self, &rkey); \ assert(self->_hashx[b.idx]); \ return &self->table[b.idx].second; \ }) \ \ - STC_INLINE C##X##_iter_t \ - C##X##_begin(const C##X* self) { \ - C##X##_iter_t it = {self->table, self->_hashx}; \ + STC_INLINE CX##_iter_t \ + CX##_begin(const CX* self) { \ + CX##_iter_t it = {self->table, self->_hashx}; \ if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; \ return it; \ } \ - STC_INLINE C##X##_iter_t \ - C##X##_end(const C##X* self) {\ - C##X##_iter_t it = {self->table + self->bucket_count}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_end(const CX* self) {\ + CX##_iter_t it = {self->table + self->bucket_count}; return it; \ } \ STC_INLINE void \ - C##X##_next(C##X##_iter_t* it) { \ + CX##_next(CX##_iter_t* it) { \ while ((++it->ref, *++it->_hx == 0)) ; \ } \ - STC_INLINE C##X##_mapped_t* \ - C##X##_itval(C##X##_iter_t it) {return SET_ONLY_##C( it.ref ) \ - MAP_ONLY_##C( &it.ref->second );} \ \ STC_API void \ - C##X##_erase_entry(C##X* self, C##X##_value_t* val); \ + CX##_erase_entry(CX* self, CX##_value_t* val); \ STC_INLINE size_t \ - C##X##_erase(C##X* self, RawKey rkey) { \ + CX##_erase(CX* self, RawKey rkey) { \ if (self->size == 0) return 0; \ - chash_bucket_t b = C##X##_bucket_(self, &rkey); \ - return self->_hashx[b.idx] ? C##X##_erase_entry(self, self->table + b.idx), 1 : 0; \ + chash_bucket_t b = CX##_bucket_(self, &rkey); \ + return self->_hashx[b.idx] ? CX##_erase_entry(self, self->table + b.idx), 1 : 0; \ } \ - STC_INLINE C##X##_iter_t \ - C##X##_erase_at(C##X* self, C##X##_iter_t pos) { \ - C##X##_erase_entry(self, pos.ref); \ - C##X##_next(&pos); return pos; \ + STC_INLINE CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos) { \ + CX##_erase_entry(self, pos.ref); \ + CX##_next(&pos); return pos; \ } \ \ - _implement_CHASH(X, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) \ - typedef C##X C##X##_t + _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + typedef CX CX##_t STC_API uint64_t c_default_hash(const void *data, size_t len); STC_INLINE uint64_t c_default_hash32(const void* data, size_t ignored) @@ -329,37 +326,37 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) {uint64_t l,h; c_um #endif #define chash_index_(h, entryPtr) ((entryPtr) - (h).table) -#define _implement_CHASH(X, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) \ - STC_DEF C##X \ - C##X##_with_capacity(size_t cap) { \ - C##X h = _cmap_inits; \ - C##X##_reserve(&h, cap); \ +#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); \ return h; \ } \ \ - STC_INLINE void C##X##_wipe_(C##X* self) { \ + STC_INLINE void CX##_wipe_(CX* self) { \ if (self->size == 0) return; \ - C##X##_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++) C##X##_value_del(e); \ + for (; e != end; ++e) if (*hx++) CX##_value_del(e); \ } \ \ - STC_DEF void C##X##_del(C##X* self) { \ - C##X##_wipe_(self); \ + STC_DEF void CX##_del(CX* self) { \ + CX##_wipe_(self); \ c_free(self->_hashx); \ c_free(self->table); \ } \ \ - STC_DEF void C##X##_clear(C##X* self) { \ - C##X##_wipe_(self); \ + STC_DEF void CX##_clear(CX* self) { \ + CX##_wipe_(self); \ self->size = 0; \ memset(self->_hashx, 0, self->bucket_count); \ } \ \ STC_DEF chash_bucket_t \ - C##X##_bucket_(const C##X* self, const C##X##_rawkey_t* rkeyptr) { \ + CX##_bucket_(const CX* self, const CX##_rawkey_t* rkeyptr) { \ const uint64_t hash = keyHashRaw(rkeyptr, sizeof(RawKey)); \ uint_fast8_t sx; size_t cap = self->bucket_count; \ chash_bucket_t b = {_c_SELECT(fastrange,CMAP_SIZE_T)(hash, cap), (uint_fast8_t)(hash | 0x80)}; \ @@ -374,24 +371,24 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) {uint64_t l,h; c_um return b; \ } \ \ - STC_DEF C##X##_iter_t \ - C##X##_find(const C##X* self, RawKey rkey) { \ - C##X##_iter_t it = {NULL}; \ + STC_DEF CX##_iter_t \ + CX##_find(const CX* self, RawKey rkey) { \ + CX##_iter_t it = {NULL}; \ if (self->size == 0) return it; \ - chash_bucket_t b = C##X##_bucket_(self, &rkey); \ + chash_bucket_t b = CX##_bucket_(self, &rkey); \ if (*(it._hx = self->_hashx+b.idx)) it.ref = self->table+b.idx; \ return it; \ } \ \ - STC_INLINE void C##X##_reserve_expand_(C##X* self) { \ + STC_INLINE void CX##_reserve_expand_(CX* self) { \ if (self->size + 1 >= self->bucket_count*self->max_load_factor) \ - C##X##_reserve(self, 5 + self->size * 3 / 2); \ + CX##_reserve(self, 5 + self->size * 3 / 2); \ } \ - STC_DEF C##X##_result_t \ - C##X##_insert_entry_(C##X* self, RawKey rkey) { \ - C##X##_reserve_expand_(self); \ - chash_bucket_t b = C##X##_bucket_(self, &rkey); \ - C##X##_result_t res = {&self->table[b.idx], !self->_hashx[b.idx]}; \ + STC_DEF CX##_result_t \ + CX##_insert_entry_(CX* self, RawKey rkey) { \ + CX##_reserve_expand_(self); \ + chash_bucket_t b = CX##_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; \ @@ -399,38 +396,38 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) {uint64_t l,h; c_um return res; \ } \ \ - STC_DEF C##X \ - C##X##_clone(C##X m) { \ - C##X clone = { \ - c_new_2(C##X##_value_t, m.bucket_count), \ + STC_DEF CX \ + CX##_clone(CX m) { \ + CX clone = { \ + c_new_2(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.min_load_factor, m.max_load_factor \ }; \ - C##X##_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) *dst = C##X##_value_clone(*e); \ + if (*hx) *dst = CX##_value_clone(*e); \ return clone; \ } \ \ STC_DEF void \ - C##X##_reserve(C##X* self, size_t newcap) { \ + CX##_reserve(CX* self, size_t newcap) { \ if (newcap < self->size) return; \ size_t oldcap = self->bucket_count; \ newcap = (size_t) (newcap / self->max_load_factor) | 1; \ - C##X tmp = { \ - c_new_2 (C##X##_value_t, newcap), \ + CX tmp = { \ + c_new_2 (CX##_value_t, newcap), \ (uint8_t *) c_calloc(newcap + 1, sizeof(uint8_t)), \ - self->size, (C##X##_size_t) newcap, \ + self->size, (CX##_size_t) newcap, \ self->min_load_factor, self->max_load_factor \ }; \ /* Rehash: */ \ - tmp._hashx[newcap] = 0xff; c_swap(C##X, *self, tmp); \ - C##X##_value_t* e = tmp.table, *slot = self->table; \ + tmp._hashx[newcap] = 0xff; c_swap(CX, *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]) { \ RawKey r = keyToRaw(KEY_REF_##C(e)); \ - chash_bucket_t b = C##X##_bucket_(self, &r); \ + chash_bucket_t b = CX##_bucket_(self, &r); \ slot[b.idx] = *e, \ hashx[b.idx] = (uint8_t) b.hx; \ } \ @@ -439,11 +436,11 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) {uint64_t l,h; c_um } \ \ STC_DEF void \ - C##X##_erase_entry(C##X* self, C##X##_value_t* val) { \ + CX##_erase_entry(CX* self, CX##_value_t* val) { \ size_t i = chash_index_(*self, val), j = i, k, cap = self->bucket_count; \ - C##X##_value_t* slot = self->table; \ + CX##_value_t* slot = self->table; \ uint8_t* hashx = self->_hashx; \ - C##X##_value_del(&slot[i]); \ + CX##_value_del(&slot[i]); \ for (;;) { /* delete without leaving tombstone */ \ if (++j == cap) j = 0; \ if (! hashx[j]) \ @@ -455,7 +452,7 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) {uint64_t l,h; c_um } \ hashx[i] = 0, k = --self->size; \ if (k < cap*self->min_load_factor && k > 512) \ - C##X##_reserve(self, k*1.2); \ + CX##_reserve(self, k*1.2); \ } STC_DEF uint64_t c_default_hash(const void *key, size_t len) { @@ -476,9 +473,9 @@ STC_DEF uint64_t c_default_hash(const void *key, size_t len) { } #else -#define _implement_CHASH(X, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) +#define _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) #endif #endif diff --git a/stc/cpque.h b/stc/cpque.h index 8e08724f..28e8113f 100644 --- a/stc/cpque.h +++ b/stc/cpque.h @@ -52,62 +52,52 @@ #define using_cpque(...) c_MACRO_OVERLOAD(using_cpque, __VA_ARGS__) #define using_cpque_2(X, ctype) \ - using_cpque_3(X, ctype, ctype##_value_compare) - + _c_using_cpque(cpque_##X, ctype, ctype##_value_compare) #define using_cpque_3(X, ctype, valueCompare) \ - typedef ctype##_t cpque_##X; \ - typedef ctype##_value_t cpque_##X##_value_t; \ - typedef ctype##_rawvalue_t cpque_##X##_rawvalue_t; \ + _c_using_cpque(cpque_##X, ctype, valueCompare) + +#define _c_using_cpque(CX, ctype, valueCompare) \ + typedef ctype##_t CX; \ + typedef ctype##_value_t CX##_value_t; \ + typedef ctype##_rawvalue_t CX##_rawvalue_t; \ \ - STC_INLINE cpque_##X \ - cpque_##X##_init(void) {return ctype##_init();} \ - STC_INLINE cpque_##X \ - cpque_##X##_clone(cpque_##X pq) {return ctype##_clone(pq);} \ - STC_INLINE cpque_##X##_value_t \ - cpque_##X##_value_clone(cpque_##X##_value_t val) {return ctype##_value_clone(val);} \ - STC_INLINE void \ - cpque_##X##_clear(cpque_##X* self) {ctype##_clear(self);} \ - STC_INLINE void \ - cpque_##X##_del(cpque_##X* self) {ctype##_del(self);} \ + STC_INLINE CX CX##_init(void) {return ctype##_init();} \ + STC_INLINE CX CX##_clone(CX pq) {return ctype##_clone(pq);} \ + STC_INLINE CX##_value_t CX##_value_clone(CX##_value_t val) \ + {return ctype##_value_clone(val);} \ + STC_INLINE void CX##_clear(CX* self) {ctype##_clear(self);} \ + STC_INLINE void CX##_del(CX* self) {ctype##_del(self);} \ \ - STC_INLINE size_t \ - cpque_##X##_size(cpque_##X pq) {return ctype##_size(pq);} \ - STC_INLINE bool \ - cpque_##X##_empty(cpque_##X pq) {return ctype##_empty(pq);} \ - STC_API void \ - cpque_##X##_make_heap(cpque_##X* self); \ - STC_API void \ - cpque_##X##_erase_at(cpque_##X* self, size_t i); \ - STC_INLINE const cpque_##X##_value_t* \ - cpque_##X##_top(const cpque_##X* self) {return &self->data[0];} \ - STC_INLINE void \ - cpque_##X##_pop(cpque_##X* self) {cpque_##X##_erase_at(self, 0);} \ - STC_API void \ - cpque_##X##_push(cpque_##X* self, cpque_##X##_value_t value); \ - STC_INLINE void \ - cpque_##X##_emplace(cpque_##X* self, cpque_##X##_rawvalue_t raw) { \ - cpque_##X##_push(self, ctype##_value_fromraw(raw)); \ - } \ - STC_API void \ - cpque_##X##_emplace_n(cpque_##X *self, const cpque_##X##_rawvalue_t arr[], size_t size); \ + STC_INLINE size_t CX##_size(CX pq) {return ctype##_size(pq);} \ + STC_INLINE bool CX##_empty(CX pq) {return ctype##_empty(pq);} \ + \ + STC_API void CX##_make_heap(CX* self); \ + STC_API void CX##_erase_at(CX* self, size_t i); \ + STC_INLINE \ + const CX##_value_t* CX##_top(const CX* self) {return &self->data[0];} \ + STC_INLINE void CX##_pop(CX* self) {CX##_erase_at(self, 0);} \ + \ + STC_API void CX##_push(CX* self, CX##_value_t value); \ + STC_INLINE void CX##_emplace(CX* self, CX##_rawvalue_t raw) \ + {CX##_push(self, ctype##_value_fromraw(raw));} \ + STC_API void CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t size); \ \ - _c_implement_cpque(X, ctype, valueCompare) \ - typedef cpque_##X cpque_##X##_t + _c_implement_cpque(CX, ctype, valueCompare) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define _c_implement_cpque(X, ctype, valueCompare) \ +#define _c_implement_cpque(CX, ctype, valueCompare) \ \ STC_INLINE void \ - _cpque_##X##_sift_down(cpque_##X##_value_t* arr, size_t i, size_t n) { \ + CX##_sift_down_(CX##_value_t* arr, size_t i, size_t n) { \ size_t r = i, c = i << 1; \ while (c <= n) { \ c += (c < n && valueCompare(&arr[c], &arr[c + 1]) < 0); \ if (valueCompare(&arr[r], &arr[c]) < 0) { \ - cpque_##X##_value_t tmp = arr[r]; arr[r] = arr[c]; arr[r = c] = tmp; \ + CX##_value_t tmp = arr[r]; arr[r] = arr[c]; arr[r = c] = tmp; \ } else \ return; \ c <<= 1; \ @@ -115,37 +105,38 @@ } \ \ STC_API void \ - cpque_##X##_make_heap(cpque_##X* self) { \ - size_t n = cpque_##X##_size(*self); \ - cpque_##X##_value_t *arr = self->data - 1; \ + CX##_make_heap(CX* self) { \ + size_t n = CX##_size(*self); \ + CX##_value_t *arr = self->data - 1; \ for (size_t k = n >> 1; k != 0; --k) \ - _cpque_##X##_sift_down(arr, k, n); \ + CX##_sift_down_(arr, k, n); \ } \ \ STC_API void \ - cpque_##X##_erase_at(cpque_##X* self, size_t i) { \ - size_t n = cpque_##X##_size(*self) - 1; \ + CX##_erase_at(CX* self, size_t i) { \ + size_t n = CX##_size(*self) - 1; \ self->data[i] = self->data[n]; \ ctype##_pop_back(self); \ - _cpque_##X##_sift_down(self->data - 1, i + 1, n); \ + CX##_sift_down_(self->data - 1, i + 1, n); \ } \ \ STC_API void \ - cpque_##X##_push(cpque_##X* self, cpque_##X##_value_t value) { \ + CX##_push(CX* self, CX##_value_t value) { \ ctype##_push_back(self, value); /* sift-up the value */ \ - size_t n = cpque_##X##_size(*self), c = n; \ - cpque_##X##_value_t *arr = self->data - 1; \ + size_t n = CX##_size(*self), c = n; \ + CX##_value_t *arr = self->data - 1; \ for (; c > 1 && valueCompare(&arr[c >> 1], &value) < 0; c >>= 1) \ arr[c] = arr[c >> 1]; \ if (c != n) arr[c] = value; \ } \ STC_API void \ - cpque_##X##_emplace_n(cpque_##X *self, const cpque_##X##_rawvalue_t arr[], size_t size) { \ - for (size_t i=0; inodes, struct csmap_rep, nodes) -#define _using_AATREE(X, C, Key, Mapped, keyCompareRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) \ - typedef Key C##X##_key_t; \ - typedef Mapped C##X##_mapped_t; \ - typedef RawKey C##X##_rawkey_t; \ - typedef RawMapped C##X##_rawmapped_t; \ - typedef CSMAP_SIZE_T C##X##_size_t; \ -\ - typedef SET_ONLY_##C( C##X##_key_t ) \ - MAP_ONLY_##C( struct {C##X##_key_t first; \ - C##X##_mapped_t second;} ) \ - C##X##_value_t; \ +#define _c_using_aatree(CX, C, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + typedef Key CX##_key_t; \ + typedef Mapped CX##_mapped_t; \ + typedef RawKey CX##_rawkey_t; \ + typedef RawMapped CX##_rawmapped_t; \ + typedef CSMAP_SIZE_T CX##_size_t; \ +\ + typedef SET_ONLY_##C( CX##_key_t ) \ + MAP_ONLY_##C( struct {CX##_key_t first; \ + CX##_mapped_t second;} ) \ + CX##_value_t; \ \ typedef SET_ONLY_##C( RawKey ) \ MAP_ONLY_##C( struct {RawKey first; \ RawMapped second;} ) \ - C##X##_rawvalue_t; \ + CX##_rawvalue_t; \ \ typedef struct { \ - C##X##_value_t *ref; \ + CX##_value_t *ref; \ bool inserted; \ - } C##X##_result_t; \ + } CX##_result_t; \ \ - typedef struct C##X##_node { \ - C##X##_size_t link[2]; \ + typedef struct CX##_node { \ + CX##_size_t link[2]; \ int8_t level; \ - C##X##_value_t value; \ - } C##X##_node_t; \ + CX##_value_t value; \ + } CX##_node_t; \ \ typedef struct { \ - C##X##_node_t* nodes; \ - } C##X; \ + CX##_node_t* nodes; \ + } CX; \ \ typedef struct { \ - C##X##_value_t *ref; \ - C##X##_node_t *_d; \ + CX##_value_t *ref; \ + CX##_node_t *_d; \ int _top; \ - C##X##_size_t _tn, _st[48]; \ - } C##X##_iter_t; \ + CX##_size_t _tn, _st[48]; \ + } CX##_iter_t; \ \ - STC_API C##X C##X##_init(void); \ - STC_API C##X C##X##_clone(C##X tree); \ + STC_API CX CX##_init(void); \ + STC_API CX CX##_clone(CX tree); \ \ STC_API void \ - C##X##_reserve(C##X* self, size_t cap); \ - STC_INLINE C##X \ - C##X##_with_capacity(size_t size) { \ - C##X x = C##X##_init(); \ - C##X##_reserve(&x, size); \ + CX##_reserve(CX* self, size_t cap); \ + STC_INLINE CX \ + CX##_with_capacity(size_t size) { \ + CX x = CX##_init(); \ + CX##_reserve(&x, size); \ return x; \ } \ STC_INLINE bool \ - C##X##_empty(C##X tree) {return _csmap_rep(&tree)->size == 0;} \ + CX##_empty(CX tree) {return _csmap_rep(&tree)->size == 0;} \ STC_INLINE size_t \ - C##X##_size(C##X tree) {return _csmap_rep(&tree)->size;} \ + CX##_size(CX tree) {return _csmap_rep(&tree)->size;} \ STC_INLINE size_t \ - C##X##_capacity(C##X tree) {return _csmap_rep(&tree)->cap;} \ + CX##_capacity(CX tree) {return _csmap_rep(&tree)->cap;} \ STC_API void \ - C##X##_del(C##X* self); \ + CX##_del(CX* self); \ STC_INLINE void \ - C##X##_clear(C##X* self) {C##X##_del(self); *self = C##X##_init();} \ + CX##_clear(CX* self) {CX##_del(self); *self = CX##_init();} \ STC_INLINE void \ - C##X##_swap(C##X* a, C##X* b) {c_swap(C##X, *a, *b);} \ + CX##_swap(CX* a, CX* b) {c_swap(CX, *a, *b);} \ \ STC_INLINE void \ - C##X##_value_del(C##X##_value_t* val) { \ + CX##_value_del(CX##_value_t* val) { \ keyDel(KEY_REF_##C(val)); \ MAP_ONLY_##C( mappedDel(&val->second); ) \ } \ - STC_INLINE C##X##_value_t \ - C##X##_value_clone(C##X##_value_t val) { \ + STC_INLINE CX##_value_t \ + CX##_value_clone(CX##_value_t val) { \ *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \ MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \ return val; \ } \ \ - STC_API C##X##_value_t* \ - C##X##_find_it(const C##X* self, RawKey rkey, C##X##_iter_t* out); \ + STC_API CX##_value_t* \ + CX##_find_it(const CX* self, RawKey rkey, CX##_iter_t* out); \ \ - STC_API C##X##_iter_t \ - C##X##_lower_bound(const C##X* self, RawKey rkey); \ + STC_API CX##_iter_t \ + CX##_lower_bound(const CX* self, RawKey rkey); \ \ - STC_INLINE C##X##_iter_t \ - C##X##_find(const C##X* self, RawKey rkey) { \ - C##X##_iter_t it; \ - C##X##_find_it(self, rkey, &it); \ + STC_INLINE CX##_iter_t \ + CX##_find(const CX* self, RawKey rkey) { \ + CX##_iter_t it; \ + CX##_find_it(self, rkey, &it); \ return it; \ } \ \ STC_INLINE bool \ - C##X##_contains(const C##X* self, RawKey rkey) { \ - C##X##_iter_t it; \ - return C##X##_find_it(self, rkey, &it) != NULL; \ + CX##_contains(const CX* self, RawKey rkey) { \ + CX##_iter_t it; \ + return CX##_find_it(self, rkey, &it) != NULL; \ } \ \ - STC_API C##X##_result_t \ - C##X##_insert_entry_(C##X* self, RawKey rkey); \ + STC_API CX##_result_t \ + CX##_insert_entry_(CX* self, RawKey rkey); \ \ - STC_INLINE C##X##_result_t \ - C##X##_emplace(C##X* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \ - C##X##_result_t res = C##X##_insert_entry_(self, rkey); \ + 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); \ if (res.inserted) { \ *KEY_REF_##C(res.ref) = keyFromRaw(rkey); \ MAP_ONLY_##C(res.ref->second = mappedFromRaw(rmapped);) \ @@ -241,134 +241,131 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; return res; \ } \ STC_INLINE void \ - C##X##_emplace_n(C##X* self, const C##X##_rawvalue_t arr[], size_t n) { \ - for (size_t i=0; isecond = mapped; )} \ else {keyDel(&key); MAP_ONLY_##C( mappedDel(&mapped); )} \ return res; \ } \ \ MAP_ONLY_##C( \ - STC_INLINE C##X##_result_t \ - C##X##_insert_or_assign(C##X* self, Key key, Mapped mapped) { \ - C##X##_result_t res = C##X##_insert_entry_(self, keyToRaw(&key)); \ + 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)); \ if (res.inserted) res.ref->first = key; \ else {keyDel(&key); mappedDel(&res.ref->second);} \ res.ref->second = mapped; return res; \ } \ - STC_INLINE C##X##_result_t \ - C##X##_put(C##X* self, Key k, Mapped m) { \ - return C##X##_insert_or_assign(self, k, m); \ + STC_INLINE CX##_result_t \ + CX##_put(CX* self, Key k, Mapped m) { \ + return CX##_insert_or_assign(self, k, m); \ } \ - STC_INLINE C##X##_result_t \ - C##X##_emplace_or_assign(C##X* self, RawKey rkey, RawMapped rmapped) { \ - C##X##_result_t res = C##X##_insert_entry_(self, rkey); \ + 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 C##X##_mapped_t* \ - C##X##_at(const C##X* self, RawKey rkey) { \ - C##X##_iter_t it; \ - return &C##X##_find_it(self, rkey, &it)->second; \ + STC_INLINE CX##_mapped_t* \ + CX##_at(const CX* self, RawKey rkey) { \ + CX##_iter_t it; \ + return &CX##_find_it(self, rkey, &it)->second; \ }) \ \ - STC_API C##X##_value_t* C##X##_front(const C##X* self); \ - STC_API C##X##_value_t* C##X##_back(const C##X* self); \ - STC_API void C##X##_next(C##X##_iter_t* it); \ + STC_API CX##_value_t* CX##_front(const CX* self); \ + STC_API CX##_value_t* CX##_back(const CX* self); \ + STC_API void CX##_next(CX##_iter_t* it); \ \ - STC_INLINE C##X##_iter_t \ - C##X##_begin(const C##X* self) { \ - C##X##_iter_t it = {NULL, self->nodes, 0, (C##X##_size_t) _csmap_rep(self)->root}; \ - if (it._tn) C##X##_next(&it); \ + STC_INLINE CX##_iter_t \ + CX##_begin(const CX* self) { \ + CX##_iter_t it = {NULL, self->nodes, 0, (CX##_size_t) _csmap_rep(self)->root}; \ + if (it._tn) CX##_next(&it); \ return it; \ } \ - STC_INLINE C##X##_iter_t \ - C##X##_end(const C##X* self) {\ - C##X##_iter_t it = {NULL}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_end(const CX* self) {\ + CX##_iter_t it = {NULL}; return it; \ } \ - STC_INLINE C##X##_mapped_t* \ - C##X##_itval(C##X##_iter_t it) {return SET_ONLY_##C( it.ref ) \ - MAP_ONLY_##C( &it.ref->second );} \ STC_API int \ - C##X##_erase(C##X* self, RawKey rkey); \ + CX##_erase(CX* self, RawKey rkey); \ \ - STC_API C##X##_iter_t \ - C##X##_erase_at(C##X* self, C##X##_iter_t pos); \ + STC_API CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos); \ \ - _implement_AATREE(X, C, Key, Mapped, keyCompareRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) \ - typedef C##X C##X##_t + _c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + typedef CX CX##_t /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) static struct csmap_rep _smap_inits = {0, 0, 0, 0}; -#define _implement_AATREE(X, C, Key, Mapped, keyCompareRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) \ - STC_DEF C##X \ - C##X##_init(void) { \ - C##X tree = {(C##X##_node_t *) _smap_inits.nodes}; \ +#define _c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) \ + STC_DEF CX \ + CX##_init(void) { \ + CX tree = {(CX##_node_t *) _smap_inits.nodes}; \ return tree; \ } \ \ - STC_DEF C##X##_value_t* \ - C##X##_front(const C##X* self) { \ - C##X##_node_t *d = self->nodes; \ - C##X##_size_t tn = (C##X##_size_t) _csmap_rep(self)->root; \ + STC_DEF CX##_value_t* \ + CX##_front(const CX* self) { \ + CX##_node_t *d = self->nodes; \ + CX##_size_t tn = (CX##_size_t) _csmap_rep(self)->root; \ while (d[tn].link[0]) tn = d[tn].link[0]; \ return &d[tn].value; \ } \ - STC_DEF C##X##_value_t* \ - C##X##_back(const C##X* self) { \ - C##X##_node_t *d = self->nodes; \ - C##X##_size_t tn = (C##X##_size_t) _csmap_rep(self)->root; \ + STC_DEF CX##_value_t* \ + CX##_back(const CX* self) { \ + CX##_node_t *d = self->nodes; \ + CX##_size_t tn = (CX##_size_t) _csmap_rep(self)->root; \ while (d[tn].link[1]) tn = d[tn].link[1]; \ return &d[tn].value; \ } \ \ STC_DEF void \ - C##X##_reserve(C##X* self, size_t cap) { \ + CX##_reserve(CX* self, size_t cap) { \ struct csmap_rep* rep = _csmap_rep(self); \ - C##X##_size_t oldcap = rep->cap; \ + CX##_size_t oldcap = rep->cap; \ if (cap > oldcap) { \ rep = (struct csmap_rep*) c_realloc(oldcap ? rep : NULL, \ - sizeof(struct csmap_rep) + (cap + 1)*sizeof(C##X##_node_t)); \ + sizeof(struct csmap_rep) + (cap + 1)*sizeof(CX##_node_t)); \ if (oldcap == 0) \ - memset(rep, 0, sizeof(struct csmap_rep) + sizeof(C##X##_node_t)); \ + memset(rep, 0, sizeof(struct csmap_rep) + sizeof(CX##_node_t)); \ rep->cap = cap; \ - self->nodes = (C##X##_node_t *) rep->nodes; \ + self->nodes = (CX##_node_t *) rep->nodes; \ } \ } \ \ - STC_DEF C##X##_size_t \ - C##X##_node_new_(C##X* self, int level) { \ + STC_DEF CX##_size_t \ + CX##_node_new_(CX* self, int level) { \ size_t tn; struct csmap_rep *rep = _csmap_rep(self); \ if (rep->disp) { \ tn = rep->disp; \ rep->disp = self->nodes[tn].link[1]; \ } else { \ - if ((tn = rep->head + 1) > rep->cap) C##X##_reserve(self, 4 + tn*3/2); \ + if ((tn = rep->head + 1) > rep->cap) CX##_reserve(self, 4 + tn*3/2); \ ++_csmap_rep(self)->head; /* do after reserve */ \ } \ - C##X##_node_t* dn = &self->nodes[tn]; \ + CX##_node_t* dn = &self->nodes[tn]; \ dn->link[0] = dn->link[1] = 0; dn->level = level; \ - return (C##X##_size_t) tn; \ + return (CX##_size_t) tn; \ } \ \ - STC_DEF C##X##_value_t* \ - C##X##_find_it(const C##X* self, RawKey rkey, C##X##_iter_t* out) { \ - C##X##_size_t tn = _csmap_rep(self)->root; \ - C##X##_node_t *d = out->_d = self->nodes; \ + STC_DEF CX##_value_t* \ + CX##_find_it(const CX* self, RawKey rkey, CX##_iter_t* out) { \ + CX##_size_t tn = _csmap_rep(self)->root; \ + CX##_node_t *d = out->_d = self->nodes; \ out->_top = 0; \ while (tn) { \ int c; RawKey rx = keyToRaw(KEY_REF_##C(&d[tn].value)); \ @@ -382,12 +379,12 @@ static struct csmap_rep _smap_inits = {0, 0, 0, 0}; return (out->ref = NULL); \ } \ \ - STC_DEF C##X##_iter_t \ - C##X##_lower_bound(const C##X* self, RawKey rkey) { \ - C##X##_iter_t it; \ - C##X##_find_it(self, rkey, &it); \ + STC_DEF CX##_iter_t \ + CX##_lower_bound(const CX* self, RawKey rkey) { \ + CX##_iter_t it; \ + CX##_find_it(self, rkey, &it); \ if (!it.ref && it._top) { \ - C##X##_size_t tn = it._st[--it._top]; \ + CX##_size_t tn = it._st[--it._top]; \ it._tn = it._d[tn].link[1]; \ it.ref = &it._d[tn].value; \ } \ @@ -395,8 +392,8 @@ static struct csmap_rep _smap_inits = {0, 0, 0, 0}; } \ \ STC_DEF void \ - C##X##_next(C##X##_iter_t *it) { \ - C##X##_size_t tn = it->_tn; \ + CX##_next(CX##_iter_t *it) { \ + CX##_size_t tn = it->_tn; \ if (it->_top || tn) { \ while (tn) { \ it->_st[it->_top++] = tn; \ @@ -409,20 +406,20 @@ static struct csmap_rep _smap_inits = {0, 0, 0, 0}; it->ref = NULL; \ } \ \ - static C##X##_size_t \ - C##X##_skew_(C##X##_node_t *d, C##X##_size_t tn) { \ + static CX##_size_t \ + CX##_skew_(CX##_node_t *d, CX##_size_t tn) { \ if (tn && d[d[tn].link[0]].level == d[tn].level) { \ - C##X##_size_t tmp = d[tn].link[0]; \ + CX##_size_t tmp = d[tn].link[0]; \ d[tn].link[0] = d[tmp].link[1]; \ d[tmp].link[1] = tn; \ tn = tmp; \ } \ return tn; \ } \ - static C##X##_size_t \ - C##X##_split_(C##X##_node_t *d, C##X##_size_t tn) { \ + static CX##_size_t \ + CX##_split_(CX##_node_t *d, CX##_size_t tn) { \ if (d[d[d[tn].link[1]].link[1]].level == d[tn].level) { \ - C##X##_size_t tmp = d[tn].link[1]; \ + CX##_size_t tmp = d[tn].link[1]; \ d[tn].link[1] = d[tmp].link[0]; \ d[tmp].link[0] = tn; \ tn = tmp; \ @@ -431,10 +428,10 @@ static struct csmap_rep _smap_inits = {0, 0, 0, 0}; return tn; \ } \ \ - static inline C##X##_size_t \ - C##X##_insert_entry_i_(C##X* self, C##X##_size_t tn, const C##X##_rawkey_t* rkey, C##X##_result_t* res) { \ - C##X##_size_t up[64], it = tn; \ - C##X##_node_t* d = self->nodes; \ + static inline CX##_size_t \ + CX##_insert_entry_i_(CX* self, CX##_size_t tn, const CX##_rawkey_t* rkey, CX##_result_t* res) { \ + CX##_size_t up[64], it = tn; \ + CX##_node_t* d = self->nodes; \ int c, top = 0, dir = 0; \ while (it) { \ up[top++] = it; \ @@ -443,50 +440,50 @@ static struct csmap_rep _smap_inits = {0, 0, 0, 0}; dir = (c == -1); \ it = d[it].link[dir]; \ } \ - it = C##X##_node_new_(self, 1); d = self->nodes; \ + it = CX##_node_new_(self, 1); d = self->nodes; \ res->ref = &d[it].value, res->inserted = true; \ if (top == 0) return it; \ d[up[top - 1]].link[dir] = it; \ while (top--) { \ if (top) dir = (d[up[top - 1]].link[1] == up[top]); \ - up[top] = C##X##_skew_(d, up[top]); \ - up[top] = C##X##_split_(d, up[top]); \ + up[top] = CX##_skew_(d, up[top]); \ + up[top] = CX##_split_(d, up[top]); \ if (top) d[up[top - 1]].link[dir] = up[top]; \ } \ return up[0]; \ } \ \ - STC_DEF C##X##_result_t \ - C##X##_insert_entry_(C##X* self, RawKey rkey) { \ - C##X##_result_t res = {NULL, false}; \ - C##X##_size_t tn = C##X##_insert_entry_i_(self, (C##X##_size_t) _csmap_rep(self)->root, &rkey, &res); \ + STC_DEF CX##_result_t \ + CX##_insert_entry_(CX* self, RawKey rkey) { \ + CX##_result_t res = {NULL, false}; \ + CX##_size_t tn = CX##_insert_entry_i_(self, (CX##_size_t) _csmap_rep(self)->root, &rkey, &res); \ _csmap_rep(self)->root = tn; \ _csmap_rep(self)->size += res.inserted; \ return res; \ } \ \ - static C##X##_size_t \ - C##X##_erase_r_(C##X##_node_t *d, C##X##_size_t tn, const C##X##_rawkey_t* rkey, int *erased) { \ + static CX##_size_t \ + CX##_erase_r_(CX##_node_t *d, CX##_size_t tn, const CX##_rawkey_t* rkey, int *erased) { \ if (tn == 0) return 0; \ RawKey raw = keyToRaw(KEY_REF_##C(&d[tn].value)); \ - C##X##_size_t tx; int c = keyCompareRaw(&raw, rkey); \ + CX##_size_t tx; int c = keyCompareRaw(&raw, rkey); \ if (c != 0) \ - d[tn].link[c == -1] = C##X##_erase_r_(d, d[tn].link[c == -1], rkey, erased); \ + d[tn].link[c == -1] = CX##_erase_r_(d, d[tn].link[c == -1], rkey, erased); \ else { \ - if (!*erased) {C##X##_value_del(&d[tn].value); *erased = 1;} \ + if (!*erased) {CX##_value_del(&d[tn].value); *erased = 1;} \ if (d[tn].link[0] && d[tn].link[1]) { \ tx = d[tn].link[0]; \ while (d[tx].link[1]) \ tx = d[tx].link[1]; \ d[tn].value = d[tx].value; /* move */ \ raw = keyToRaw(KEY_REF_##C(&d[tn].value)); \ - d[tn].link[0] = C##X##_erase_r_(d, d[tn].link[0], &raw, erased); \ + d[tn].link[0] = CX##_erase_r_(d, d[tn].link[0], &raw, erased); \ } else { /* unlink node */ \ tx = tn; \ tn = d[tn].link[ d[tn].link[0] == 0 ]; \ /* move it to disposed nodes list */ \ struct csmap_rep *rep = c_container_of(d, struct csmap_rep, nodes); \ - d[tx].link[1] = (C##X##_size_t) rep->disp; \ + d[tx].link[1] = (CX##_size_t) rep->disp; \ rep->disp = tx; \ } \ } \ @@ -494,70 +491,70 @@ static struct csmap_rep _smap_inits = {0, 0, 0, 0}; if (d[d[tn].link[0]].level < d[tn].level - 1 || d[tx].level < d[tn].level - 1) { \ if (d[tx].level > --d[tn].level) \ d[tx].level = d[tn].level; \ - tn = C##X##_skew_(d, tn); \ - tx = d[tn].link[1] = C##X##_skew_(d, d[tn].link[1]); \ - d[tx].link[1] = C##X##_skew_(d, d[tx].link[1]); \ - tn = C##X##_split_(d, tn); \ - d[tn].link[1] = C##X##_split_(d, d[tn].link[1]); \ + tn = CX##_skew_(d, tn); \ + tx = d[tn].link[1] = CX##_skew_(d, d[tn].link[1]); \ + d[tx].link[1] = CX##_skew_(d, d[tx].link[1]); \ + tn = CX##_split_(d, tn); \ + d[tn].link[1] = CX##_split_(d, d[tn].link[1]); \ } \ return tn; \ } \ \ STC_DEF int \ - C##X##_erase(C##X* self, RawKey rkey) { \ + CX##_erase(CX* self, RawKey rkey) { \ int erased = 0; \ - C##X##_size_t root = C##X##_erase_r_(self->nodes, (C##X##_size_t) _csmap_rep(self)->root, &rkey, &erased); \ + CX##_size_t root = CX##_erase_r_(self->nodes, (CX##_size_t) _csmap_rep(self)->root, &rkey, &erased); \ if (erased) {_csmap_rep(self)->root = root; --_csmap_rep(self)->size;} \ return erased; \ } \ \ - STC_DEF C##X##_iter_t \ - C##X##_erase_at(C##X* self, C##X##_iter_t pos) { \ - RawKey raw = keyToRaw(KEY_REF_##C(pos.ref)); C##X##_next(&pos); \ + STC_DEF CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos) { \ + RawKey raw = keyToRaw(KEY_REF_##C(pos.ref)); CX##_next(&pos); \ RawKey nxt = keyToRaw(KEY_REF_##C(pos.ref)); \ - C##X##_erase(self, raw); \ - C##X##_find_it(self, nxt, &pos); \ + CX##_erase(self, raw); \ + CX##_find_it(self, nxt, &pos); \ return pos; \ } \ \ - static C##X##_size_t \ - C##X##_clone_r_(C##X* self, const C##X##_node_t* src, C##X##_size_t sn) { \ + static CX##_size_t \ + CX##_clone_r_(CX* self, const CX##_node_t* src, CX##_size_t sn) { \ if (sn == 0) return 0; \ - C##X##_size_t tx, tn = C##X##_node_new_(self, src[sn].level); \ - self->nodes[tn].value = C##X##_value_clone(src[sn].value); \ - tx = C##X##_clone_r_(self, src, src[sn].link[0]); self->nodes[tn].link[0] = tx; \ - tx = C##X##_clone_r_(self, src, src[sn].link[1]); self->nodes[tn].link[1] = tx; \ + CX##_size_t tx, tn = CX##_node_new_(self, src[sn].level); \ + self->nodes[tn].value = CX##_value_clone(src[sn].value); \ + tx = CX##_clone_r_(self, src, src[sn].link[0]); self->nodes[tn].link[0] = tx; \ + tx = CX##_clone_r_(self, src, src[sn].link[1]); self->nodes[tn].link[1] = tx; \ return tn; \ } \ - STC_DEF C##X \ - C##X##_clone(C##X tree) { \ - C##X clone = C##X##_with_capacity(_csmap_rep(&tree)->size); \ - C##X##_size_t root = C##X##_clone_r_(&clone, tree.nodes, (C##X##_size_t) _csmap_rep(&tree)->root); \ + STC_DEF CX \ + CX##_clone(CX tree) { \ + CX clone = CX##_with_capacity(_csmap_rep(&tree)->size); \ + CX##_size_t root = CX##_clone_r_(&clone, tree.nodes, (CX##_size_t) _csmap_rep(&tree)->root); \ _csmap_rep(&clone)->root = root; \ _csmap_rep(&clone)->size = _csmap_rep(&tree)->size; \ return clone; \ } \ \ static void \ - C##X##_del_r_(C##X##_node_t* d, C##X##_size_t tn) { \ + CX##_del_r_(CX##_node_t* d, CX##_size_t tn) { \ if (tn) { \ - C##X##_del_r_(d, d[tn].link[0]); \ - C##X##_del_r_(d, d[tn].link[1]); \ - C##X##_value_del(&d[tn].value); \ + CX##_del_r_(d, d[tn].link[0]); \ + CX##_del_r_(d, d[tn].link[1]); \ + CX##_value_del(&d[tn].value); \ } \ } \ STC_DEF void \ - C##X##_del(C##X* self) { \ + CX##_del(CX* self) { \ if (_csmap_rep(self)->root) { \ - C##X##_del_r_(self->nodes, (C##X##_size_t) _csmap_rep(self)->root); \ + CX##_del_r_(self->nodes, (CX##_size_t) _csmap_rep(self)->root); \ c_free(_csmap_rep(self)); \ } \ } #else -#define _implement_AATREE(X, C, Key, Mapped, keyCompareRaw, \ - mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ - keyDel, keyFromRaw, keyToRaw, RawKey) +#define _c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, \ + mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \ + keyDel, keyFromRaw, keyToRaw, RawKey) #endif #endif diff --git a/stc/csset.h b/stc/csset.h index 9f2711c3..774a451a 100644 --- a/stc/csset.h +++ b/stc/csset.h @@ -59,13 +59,11 @@ int main(void) { using_csset_7(X, Key, keyCompare, keyDel, keyClone, c_trivial_toraw, Key) #define using_csset_7(X, Key, keyCompareRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \ - _using_AATREE(X, csset_, Key, Key, keyCompareRaw, \ - @@, @@, @@, void, \ - keyDel, keyFromRaw, keyToRaw, RawKey) + _c_using_aatree(csset_##X, csset_, Key, Key, keyCompareRaw, \ + @@, @@, @@, void, keyDel, keyFromRaw, keyToRaw, RawKey) -/* csset_str: */ #define using_csset_str() \ - _using_AATREE_strkey(str, csset_, cstr_t, @@, @@, @@, void) + _c_using_aatree_strkey(str, csset_, cstr_t, @@, @@, @@, void) #define SET_ONLY_csset_(...) __VA_ARGS__ #define MAP_ONLY_csset_(...) diff --git a/stc/cstack.h b/stc/cstack.h index f0a248cb..cc5372ec 100644 --- a/stc/cstack.h +++ b/stc/cstack.h @@ -46,50 +46,37 @@ #include "cvec.h" #define using_cstack(X, ctype) \ - typedef ctype##_t cstack_##X; \ - typedef ctype##_value_t cstack_##X##_value_t; \ - typedef ctype##_rawvalue_t cstack_##X##_rawvalue_t; \ + _c_using_cstack(cstack_##X, ctype) + +#define _c_using_cstack(CX, ctype) \ + typedef ctype##_t CX; \ + typedef ctype##_value_t CX##_value_t; \ + typedef ctype##_rawvalue_t CX##_rawvalue_t; \ + typedef ctype##_iter_t CX##_iter_t; \ +\ + STC_INLINE CX CX##_init(void) {return ctype##_init();} \ + STC_INLINE CX CX##_clone(CX st) {return ctype##_clone(st);} \ + STC_INLINE CX##_value_t CX##_value_clone(CX##_value_t val) \ + {return ctype##_value_clone(val);} \ + STC_INLINE void CX##_clear(CX* self) {ctype##_clear(self);} \ + STC_INLINE void CX##_del(CX* self) {ctype##_del(self);} \ +\ + STC_INLINE size_t CX##_size(CX st) {return ctype##_size(st);} \ + STC_INLINE bool CX##_empty(CX st) {return ctype##_empty(st);} \ + STC_INLINE CX##_value_t* CX##_top(const CX* self) {return ctype##_back(self);} \ \ - STC_INLINE cstack_##X \ - cstack_##X##_init(void) {return ctype##_init();} \ - STC_INLINE cstack_##X \ - cstack_##X##_clone(cstack_##X st) {return ctype##_clone(st);} \ - STC_INLINE cstack_##X##_value_t \ - cstack_##X##_value_clone(cstack_##X##_value_t val) {return ctype##_value_clone(val);} \ - STC_INLINE void \ - cstack_##X##_clear(cstack_##X* self) {ctype##_clear(self);} \ - STC_INLINE void \ - cstack_##X##_del(cstack_##X* self) {ctype##_del(self);} \ - STC_INLINE size_t \ - cstack_##X##_size(cstack_##X st) {return ctype##_size(st);} \ - STC_INLINE bool \ - cstack_##X##_empty(cstack_##X st) {return ctype##_empty(st);} \ - STC_INLINE cstack_##X##_value_t* \ - cstack_##X##_top(const cstack_##X* self) {return ctype##_back(self);} \ - STC_INLINE void \ - cstack_##X##_pop(cstack_##X* self) {ctype##_pop_back(self);} \ - STC_INLINE void \ - cstack_##X##_push(cstack_##X* self, ctype##_value_t value) { \ - ctype##_push_back(self, value); \ - } \ - STC_INLINE void \ - cstack_##X##_emplace(cstack_##X* self, cstack_##X##_rawvalue_t raw) { \ - ctype##_emplace_back(self, raw); \ - } \ - STC_INLINE void \ - cstack_##X##_emplace_n(cstack_##X *self, const cstack_##X##_rawvalue_t arr[], size_t size) { \ - ctype##_emplace_n(self, arr, size); \ - } \ - typedef ctype##_iter_t cstack_##X##_iter_t; \ - STC_INLINE cstack_##X##_iter_t \ - cstack_##X##_begin(const cstack_##X* self) {return ctype##_begin(self);} \ - STC_INLINE cstack_##X##_iter_t \ - cstack_##X##_end(const cstack_##X* self) {return ctype##_end(self);} \ - STC_INLINE void \ - cstack_##X##_next(cstack_##X##_iter_t* it) {ctype##_next(it);} \ - STC_INLINE cstack_##X##_value_t* \ - cstack_##X##_itval(cstack_##X##_iter_t it) {return ctype##_itval(it);} \ + STC_INLINE void CX##_pop(CX* self) {ctype##_pop_back(self);} \ + STC_INLINE void CX##_push(CX* self, ctype##_value_t value) \ + {ctype##_push_back(self, value);} \ + STC_INLINE void CX##_emplace(CX* self, CX##_rawvalue_t raw) \ + {ctype##_emplace_back(self, raw);} \ + STC_INLINE void CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t n) \ + {ctype##_emplace_n(self, arr, n);} \ \ - typedef cstack_##X cstack_##X##_t + STC_INLINE CX##_iter_t CX##_begin(const CX* self) {return ctype##_begin(self);} \ + STC_INLINE CX##_iter_t CX##_end(const CX* self) {return ctype##_end(self);} \ + STC_INLINE void CX##_next(CX##_iter_t* it) {ctype##_next(it);} \ + \ + typedef CX CX##_t #endif diff --git a/stc/cstr.h b/stc/cstr.h index 88fc71a4..ed069d4a 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -110,7 +110,6 @@ cstr_end(cstr_t* self) { cstr_iter_t it = {self->str + _cstr_rep(self)->size}; return it; } STC_INLINE void cstr_next(cstr_iter_t* it) { ++it->ref; } -STC_INLINE char* cstr_itval(cstr_iter_t it) {return it.ref;} STC_INLINE cstr_t* cstr_assign(cstr_t* self, const char* str) { diff --git a/stc/cvec.h b/stc/cvec.h index 4c1dcb8a..5177ad9c 100644 --- a/stc/cvec.h +++ b/stc/cvec.h @@ -36,223 +36,223 @@ using_cvec_5(X, Value, valueCompare, valueDel, c_no_clone) #define using_cvec_5(X, Value, valueCompare, valueDel, valueClone) \ using_cvec_7(X, Value, valueCompare, valueDel, valueClone, c_trivial_toraw, Value) +#define using_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #define using_cvec_str() \ - using_cvec_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) + _c_using_cvec(cvec_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) -#define typedefs_cvec(X, Value, RawValue) \ - typedef Value cvec_##X##_value_t; \ - typedef RawValue cvec_##X##_rawvalue_t; \ - typedef struct { cvec_##X##_value_t *ref; } cvec_##X##_iter_t; \ +#define typedefs_cvec(CX, Value, RawValue) \ + typedef Value CX##_value_t; \ + typedef RawValue CX##_rawvalue_t; \ + typedef struct { CX##_value_t *ref; } CX##_iter_t; \ typedef struct { \ - cvec_##X##_value_t* data; \ - } cvec_##X + CX##_value_t* data; \ + } CX struct cvec_rep { size_t size, cap; void* data[]; }; #define _cvec_rep(self) c_container_of((self)->data, struct cvec_rep, data) typedef int (*c_cmp_fn)(const void*, const void*); -#define using_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ - typedefs_cvec(X, Value, RawValue); \ +#define _c_using_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + typedefs_cvec(CX, Value, RawValue); \ \ - STC_API cvec_##X \ - cvec_##X##_init(void); \ + STC_API CX \ + CX##_init(void); \ STC_INLINE size_t \ - cvec_##X##_size(cvec_##X vec) { return _cvec_rep(&vec)->size; } \ + CX##_size(CX vec) { return _cvec_rep(&vec)->size; } \ STC_INLINE size_t \ - cvec_##X##_capacity(cvec_##X vec) { return _cvec_rep(&vec)->cap; } \ + CX##_capacity(CX vec) { return _cvec_rep(&vec)->cap; } \ STC_INLINE bool \ - cvec_##X##_empty(cvec_##X vec) {return !_cvec_rep(&vec)->size;} \ + CX##_empty(CX vec) {return !_cvec_rep(&vec)->size;} \ STC_INLINE Value \ - cvec_##X##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ - STC_INLINE cvec_##X##_value_t \ - cvec_##X##_value_clone(cvec_##X##_value_t val) {return valueFromRaw(valueToRaw(&val));} \ + CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ + STC_INLINE CX##_value_t \ + CX##_value_clone(CX##_value_t val) {return valueFromRaw(valueToRaw(&val));} \ STC_INLINE void \ - cvec_##X##_clear(cvec_##X* self); \ + CX##_clear(CX* self); \ STC_API void \ - cvec_##X##_del(cvec_##X* self); \ + CX##_del(CX* self); \ STC_API void \ - cvec_##X##_reserve(cvec_##X* self, size_t cap); \ + CX##_reserve(CX* self, size_t cap); \ STC_API void \ - cvec_##X##_resize(cvec_##X* self, size_t size, Value fill_val); \ + CX##_resize(CX* self, size_t size, Value fill_val); \ STC_INLINE void \ - cvec_##X##_swap(cvec_##X* a, cvec_##X* b) {c_swap(cvec_##X, *a, *b);} \ + CX##_swap(CX* a, CX* b) {c_swap(CX, *a, *b);} \ \ - STC_INLINE cvec_##X \ - cvec_##X##_with_size(size_t size, Value null_val) { \ - cvec_##X x = cvec_##X##_init(); \ - cvec_##X##_resize(&x, size, null_val); \ + STC_INLINE CX \ + CX##_with_size(size_t size, Value null_val) { \ + CX x = CX##_init(); \ + CX##_resize(&x, size, null_val); \ return x; \ } \ - STC_INLINE cvec_##X \ - cvec_##X##_with_capacity(size_t size) { \ - cvec_##X x = cvec_##X##_init(); \ - cvec_##X##_reserve(&x, size); \ + STC_INLINE CX \ + CX##_with_capacity(size_t size) { \ + CX x = CX##_init(); \ + CX##_reserve(&x, size); \ return x; \ } \ - STC_API cvec_##X \ - cvec_##X##_clone(cvec_##X vec); \ + STC_API CX \ + CX##_clone(CX vec); \ \ STC_INLINE void \ - cvec_##X##_shrink_to_fit(cvec_##X *self) { \ - cvec_##X x = cvec_##X##_clone(*self); \ - cvec_##X##_del(self); *self = x; \ + CX##_shrink_to_fit(CX *self) { \ + CX x = CX##_clone(*self); \ + CX##_del(self); *self = x; \ } \ STC_API void \ - cvec_##X##_emplace_n(cvec_##X *self, const cvec_##X##_rawvalue_t arr[], size_t size); \ + CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t size); \ STC_API void \ - cvec_##X##_push_back(cvec_##X* self, Value value); \ + CX##_push_back(CX* self, Value value); \ STC_INLINE void \ - cvec_##X##_emplace_back(cvec_##X* self, RawValue raw) { \ - cvec_##X##_push_back(self, valueFromRaw(raw)); \ + CX##_emplace_back(CX* self, RawValue raw) { \ + CX##_push_back(self, valueFromRaw(raw)); \ } \ STC_INLINE void \ - cvec_##X##_pop_back(cvec_##X* self) { \ + CX##_pop_back(CX* self) { \ valueDel(&self->data[--_cvec_rep(self)->size]); \ } \ \ - STC_API cvec_##X##_iter_t \ - cvec_##X##_insert_range_p(cvec_##X* self, cvec_##X##_value_t* pos, const cvec_##X##_value_t* pfirst, const cvec_##X##_value_t* pfinish); \ + STC_API CX##_iter_t \ + CX##_insert_range_p(CX* self, CX##_value_t* pos, const CX##_value_t* pfirst, const CX##_value_t* pfinish); \ \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_insert_range(cvec_##X* self, cvec_##X##_iter_t pos, cvec_##X##_iter_t first, cvec_##X##_iter_t finish) { \ - return cvec_##X##_insert_range_p(self, pos.ref, first.ref, finish.ref); \ + STC_INLINE CX##_iter_t \ + CX##_insert_range(CX* self, CX##_iter_t pos, CX##_iter_t first, CX##_iter_t finish) { \ + return CX##_insert_range_p(self, pos.ref, first.ref, finish.ref); \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_insert_at(cvec_##X* self, cvec_##X##_iter_t pos, Value value) { \ - return cvec_##X##_insert_range_p(self, pos.ref, &value, &value + 1); \ + STC_INLINE CX##_iter_t \ + CX##_insert_at(CX* self, CX##_iter_t pos, Value value) { \ + return CX##_insert_range_p(self, pos.ref, &value, &value + 1); \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_insert(cvec_##X* self, size_t idx, Value value) { \ - return cvec_##X##_insert_range_p(self, self->data + idx, &value, &value + 1); \ + STC_INLINE CX##_iter_t \ + CX##_insert(CX* self, size_t idx, Value value) { \ + return CX##_insert_range_p(self, self->data + idx, &value, &value + 1); \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_emplace_at(cvec_##X* self, cvec_##X##_iter_t pos, RawValue raw) { \ - return cvec_##X##_insert_at(self, pos, valueFromRaw(raw)); \ + STC_INLINE CX##_iter_t \ + CX##_emplace_at(CX* self, CX##_iter_t pos, RawValue raw) { \ + return CX##_insert_at(self, pos, valueFromRaw(raw)); \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_emplace(cvec_##X* self, size_t idx, RawValue raw) { \ - return cvec_##X##_insert(self, idx, valueFromRaw(raw)); \ + STC_INLINE CX##_iter_t \ + CX##_emplace(CX* self, size_t idx, RawValue raw) { \ + return CX##_insert(self, idx, valueFromRaw(raw)); \ } \ \ - STC_API cvec_##X##_iter_t \ - cvec_##X##_erase_range_p(cvec_##X* self, cvec_##X##_value_t* first, cvec_##X##_value_t* finish); \ + STC_API CX##_iter_t \ + CX##_erase_range_p(CX* self, CX##_value_t* first, CX##_value_t* finish); \ \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_erase_range(cvec_##X* self, cvec_##X##_iter_t first, cvec_##X##_iter_t finish) { \ - return cvec_##X##_erase_range_p(self, first.ref, finish.ref); \ + STC_INLINE CX##_iter_t \ + CX##_erase_range(CX* self, CX##_iter_t first, CX##_iter_t finish) { \ + return CX##_erase_range_p(self, first.ref, finish.ref); \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_erase_at(cvec_##X* self, cvec_##X##_iter_t pos) { \ - return cvec_##X##_erase_range_p(self, pos.ref, pos.ref + 1); \ + STC_INLINE CX##_iter_t \ + CX##_erase_at(CX* self, CX##_iter_t pos) { \ + return CX##_erase_range_p(self, pos.ref, pos.ref + 1); \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_erase(cvec_##X* self, size_t idx, size_t n) { \ - return cvec_##X##_erase_range_p(self, self->data + idx, self->data + idx + n); \ + STC_INLINE CX##_iter_t \ + CX##_erase(CX* self, size_t idx, size_t n) { \ + return CX##_erase_range_p(self, self->data + idx, self->data + idx + n); \ } \ \ - STC_INLINE cvec_##X##_value_t* \ - cvec_##X##_front(const cvec_##X* self) {return self->data;} \ - STC_INLINE cvec_##X##_value_t* \ - cvec_##X##_back(const cvec_##X* self) {return self->data + _cvec_rep(self)->size - 1;} \ - STC_INLINE cvec_##X##_value_t* \ - cvec_##X##_at(const cvec_##X* self, size_t i) { \ + STC_INLINE CX##_value_t* \ + CX##_front(const CX* self) {return self->data;} \ + STC_INLINE CX##_value_t* \ + CX##_back(const CX* self) {return self->data + _cvec_rep(self)->size - 1;} \ + STC_INLINE CX##_value_t* \ + CX##_at(const CX* self, size_t i) { \ assert(i < _cvec_rep(self)->size); \ return self->data + i; \ } \ \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_begin(const cvec_##X* self) { \ - cvec_##X##_iter_t it = {self->data}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_begin(const CX* self) { \ + CX##_iter_t it = {self->data}; return it; \ } \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_end(const cvec_##X* self) { \ - cvec_##X##_iter_t it = {self->data + _cvec_rep(self)->size}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_end(const CX* self) { \ + CX##_iter_t it = {self->data + _cvec_rep(self)->size}; return it; \ } \ STC_INLINE void \ - cvec_##X##_next(cvec_##X##_iter_t* it) {++it->ref;} \ - STC_INLINE cvec_##X##_value_t* \ - cvec_##X##_itval(cvec_##X##_iter_t it) {return it.ref;} \ + CX##_next(CX##_iter_t* it) {++it->ref;} \ STC_INLINE size_t \ - cvec_##X##_index(cvec_##X vec, cvec_##X##_iter_t it) {return it.ref - vec.data;} \ + CX##_index(CX vec, CX##_iter_t it) {return it.ref - vec.data;} \ \ - STC_API cvec_##X##_iter_t \ - cvec_##X##_find_in_range(cvec_##X##_iter_t first, cvec_##X##_iter_t finish, RawValue raw); \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_find(const cvec_##X* self, RawValue raw) { \ - return cvec_##X##_find_in_range(cvec_##X##_begin(self), cvec_##X##_end(self), raw); \ + STC_API CX##_iter_t \ + CX##_find_in_range(CX##_iter_t first, CX##_iter_t finish, RawValue raw); \ + STC_INLINE CX##_iter_t \ + CX##_find(const CX* self, RawValue raw) { \ + return CX##_find_in_range(CX##_begin(self), CX##_end(self), raw); \ } \ STC_API int \ - cvec_##X##_value_compare(const cvec_##X##_value_t* x, const cvec_##X##_value_t* y); \ - STC_API cvec_##X##_iter_t \ - cvec_##X##_bsearch_in_range(cvec_##X##_iter_t i1, cvec_##X##_iter_t i2, RawValue raw); \ - STC_INLINE cvec_##X##_iter_t \ - cvec_##X##_bsearch(const cvec_##X* self, RawValue raw) { \ - return cvec_##X##_bsearch_in_range(cvec_##X##_begin(self), cvec_##X##_end(self), raw); \ + CX##_value_compare(const CX##_value_t* x, const CX##_value_t* y); \ + STC_API CX##_iter_t \ + CX##_bsearch_in_range(CX##_iter_t i1, CX##_iter_t i2, RawValue raw); \ + STC_INLINE CX##_iter_t \ + CX##_bsearch(const CX* self, RawValue raw) { \ + return CX##_bsearch_in_range(CX##_begin(self), CX##_end(self), raw); \ } \ STC_INLINE void \ - cvec_##X##_sort_range(cvec_##X##_iter_t i1, cvec_##X##_iter_t i2, \ - int(*cmp)(const cvec_##X##_value_t*, const cvec_##X##_value_t*)) { \ - qsort(i1.ref, i2.ref - i1.ref, sizeof(cvec_##X##_value_t), (c_cmp_fn) cmp); \ + CX##_sort_range(CX##_iter_t i1, CX##_iter_t i2, \ + int(*cmp)(const CX##_value_t*, const CX##_value_t*)) { \ + qsort(i1.ref, i2.ref - i1.ref, sizeof(CX##_value_t), (c_cmp_fn) cmp); \ } \ STC_INLINE void \ - cvec_##X##_sort(cvec_##X* self) { \ - cvec_##X##_sort_range(cvec_##X##_begin(self), cvec_##X##_end(self), cvec_##X##_value_compare); \ + CX##_sort(CX* self) { \ + CX##_sort_range(CX##_begin(self), CX##_end(self), CX##_value_compare); \ } \ \ - _c_implement_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ - typedef cvec_##X cvec_##X##_t + _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + typedef CX CX##_t /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) static struct cvec_rep _cvec_inits = {0, 0}; -#define _c_implement_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ +#define _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ \ - STC_DEF cvec_##X \ - cvec_##X##_init(void) { \ - cvec_##X vec = {(cvec_##X##_value_t *) _cvec_inits.data}; return vec; \ + STC_DEF CX \ + CX##_init(void) { \ + CX vec = {(CX##_value_t *) _cvec_inits.data}; return vec; \ } \ \ STC_DEF void \ - cvec_##X##_emplace_n(cvec_##X *self, const cvec_##X##_rawvalue_t arr[], size_t n) { \ + CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t n) { \ if (!n) return; \ - cvec_##X##_reserve(self, _cvec_rep(self)->size + n); \ - cvec_##X##_value_t* p = self->data + _cvec_rep(self)->size; \ + CX##_reserve(self, _cvec_rep(self)->size + n); \ + CX##_value_t* p = self->data + _cvec_rep(self)->size; \ for (size_t i=0; i < n; ++i) *p++ = valueFromRaw(arr[i]); \ _cvec_rep(self)->size += n; \ } \ \ STC_DEF void \ - cvec_##X##_clear(cvec_##X* self) { \ + CX##_clear(CX* self) { \ struct cvec_rep* rep = _cvec_rep(self); if (rep->cap) { \ - for (cvec_##X##_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \ + for (CX##_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \ valueDel(p); \ rep->size = 0; \ } \ } \ STC_DEF void \ - cvec_##X##_del(cvec_##X* self) { \ - cvec_##X##_clear(self); \ + CX##_del(CX* self) { \ + CX##_clear(self); \ if (_cvec_rep(self)->cap) \ c_free(_cvec_rep(self)); \ } \ \ STC_DEF void \ - cvec_##X##_reserve(cvec_##X* self, size_t cap) { \ + CX##_reserve(CX* self, size_t cap) { \ struct cvec_rep* rep = _cvec_rep(self); \ size_t len = rep->size, oldcap = rep->cap; \ if (cap > oldcap) { \ rep = (struct cvec_rep*) c_realloc(oldcap ? rep : NULL, \ sizeof(struct cvec_rep) + cap*sizeof(Value)); \ - self->data = (cvec_##X##_value_t*) rep->data; \ + self->data = (CX##_value_t*) rep->data; \ rep->size = len; \ rep->cap = cap; \ } \ } \ STC_DEF void \ - cvec_##X##_resize(cvec_##X* self, size_t len, Value null_val) { \ - cvec_##X##_reserve(self, len); \ + CX##_resize(CX* self, size_t len, Value null_val) { \ + CX##_reserve(self, len); \ struct cvec_rep* rep = _cvec_rep(self); \ size_t i, n = rep->size; \ for (i = len; i < n; ++i) valueDel(self->data + i); \ @@ -261,28 +261,28 @@ static struct cvec_rep _cvec_inits = {0, 0}; } \ \ STC_DEF void \ - cvec_##X##_push_back(cvec_##X* self, Value value) { \ + CX##_push_back(CX* self, Value value) { \ size_t len = _cvec_rep(self)->size; \ - if (len == cvec_##X##_capacity(*self)) \ - cvec_##X##_reserve(self, 4 + len*1.5); \ + if (len == CX##_capacity(*self)) \ + CX##_reserve(self, 4 + len*1.5); \ self->data[_cvec_rep(self)->size++] = value; \ } \ \ - STC_DEF cvec_##X \ - cvec_##X##_clone(cvec_##X vec) { \ + STC_DEF CX \ + CX##_clone(CX vec) { \ size_t len = _cvec_rep(&vec)->size; \ - cvec_##X out = cvec_##X##_with_capacity(len); \ - cvec_##X##_insert_range_p(&out, out.data, vec.data, vec.data + len); \ + CX out = CX##_with_capacity(len); \ + CX##_insert_range_p(&out, out.data, vec.data, vec.data + len); \ return out; \ } \ \ - STC_DEF cvec_##X##_iter_t \ - cvec_##X##_insert_range_p(cvec_##X* self, cvec_##X##_value_t* pos, const cvec_##X##_value_t* first, const cvec_##X##_value_t* finish) { \ + STC_DEF CX##_iter_t \ + CX##_insert_range_p(CX* self, CX##_value_t* pos, const CX##_value_t* first, const CX##_value_t* finish) { \ size_t len = finish - first, idx = pos - self->data, size = _cvec_rep(self)->size; \ - cvec_##X##_iter_t it = {pos}; \ + CX##_iter_t it = {pos}; \ if (len == 0) return it; \ - if (size + len > cvec_##X##_capacity(*self)) \ - cvec_##X##_reserve(self, 4 + (size + len)*1.5), \ + if (size + len > CX##_capacity(*self)) \ + CX##_reserve(self, 4 + (size + len)*1.5), \ it.ref = pos = self->data + idx; \ _cvec_rep(self)->size += len; \ memmove(pos + len, pos, (size - idx) * sizeof(Value)); \ @@ -291,29 +291,29 @@ static struct cvec_rep _cvec_inits = {0, 0}; return it; \ } \ \ - STC_DEF cvec_##X##_iter_t \ - cvec_##X##_erase_range_p(cvec_##X* self, cvec_##X##_value_t* first, cvec_##X##_value_t* finish) { \ + STC_DEF CX##_iter_t \ + CX##_erase_range_p(CX* self, CX##_value_t* first, CX##_value_t* finish) { \ intptr_t len = finish - first; \ if (len > 0) { \ - cvec_##X##_value_t* p = first, *end = self->data + _cvec_rep(self)->size; \ + CX##_value_t* p = first, *end = self->data + _cvec_rep(self)->size; \ while (p != finish) valueDel(p++); \ memmove(first, finish, (end - finish) * sizeof(Value)); \ _cvec_rep(self)->size -= len; \ } \ - cvec_##X##_iter_t it = {first}; return it; \ + CX##_iter_t it = {first}; return it; \ } \ \ - STC_DEF cvec_##X##_iter_t \ - cvec_##X##_find_in_range(cvec_##X##_iter_t i1, cvec_##X##_iter_t i2, RawValue raw) { \ + STC_DEF CX##_iter_t \ + CX##_find_in_range(CX##_iter_t i1, CX##_iter_t i2, RawValue raw) { \ for (; i1.ref != i2.ref; ++i1.ref) { \ RawValue r = valueToRaw(i1.ref); \ if (valueCompareRaw(&raw, &r) == 0) return i1; \ } \ return i2; \ } \ - STC_DEF cvec_##X##_iter_t \ - cvec_##X##_bsearch_in_range(cvec_##X##_iter_t i1, cvec_##X##_iter_t i2, RawValue raw) { \ - cvec_##X##_iter_t mid, last = i2; \ + STC_DEF CX##_iter_t \ + CX##_bsearch_in_range(CX##_iter_t i1, CX##_iter_t i2, RawValue raw) { \ + CX##_iter_t mid, last = i2; \ while (i1.ref != i2.ref) { \ mid.ref = i1.ref + ((i2.ref - i1.ref)>>1); \ int c; RawValue m = valueToRaw(mid.ref); \ @@ -325,14 +325,14 @@ static struct cvec_rep _cvec_inits = {0, 0}; } \ \ STC_DEF int \ - cvec_##X##_value_compare(const cvec_##X##_value_t* x, const cvec_##X##_value_t* y) { \ + CX##_value_compare(const CX##_value_t* x, const CX##_value_t* y) { \ RawValue rx = valueToRaw(x); \ RawValue ry = valueToRaw(y); \ return valueCompareRaw(&rx, &ry); \ } #else -#define _c_implement_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) +#define _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #endif #endif -- cgit v1.2.3