diff options
| author | Tyge Løvset <[email protected]> | 2021-09-05 23:12:53 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-09-05 23:12:53 +0200 |
| commit | 44c64073662500684008c87e3a87f33b04e53c13 (patch) | |
| tree | 6a927fe91e6d2eee073cdce5d30ff87f5e709ce6 | |
| parent | b2dc4c367030232068338b9e7b3faee03c2db0a8 (diff) | |
| download | STC-modified-44c64073662500684008c87e3a87f33b04e53c13.tar.gz STC-modified-44c64073662500684008c87e3a87f33b04e53c13.zip | |
New usage style. only cvec is functional. see vec_test_new.c
| -rw-r--r-- | include/stc/carray.h | 155 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 9 | ||||
| -rw-r--r-- | include/stc/cdeq.h | 354 | ||||
| -rw-r--r-- | include/stc/clist.h | 290 | ||||
| -rw-r--r-- | include/stc/cmap.h | 393 | ||||
| -rw-r--r-- | include/stc/cpque.h | 84 | ||||
| -rw-r--r-- | include/stc/cqueue.h | 50 | ||||
| -rw-r--r-- | include/stc/cset.h | 26 | ||||
| -rw-r--r-- | include/stc/csmap.h | 521 | ||||
| -rw-r--r-- | include/stc/csptr.h | 94 | ||||
| -rw-r--r-- | include/stc/csset.h | 26 | ||||
| -rw-r--r-- | include/stc/cstack.h | 50 | ||||
| -rw-r--r-- | include/stc/cvec.h | 611 | ||||
| -rw-r--r-- | include/stc/forward.h | 165 | ||||
| -rw-r--r-- | include/stc/template.h | 149 | ||||
| -rw-r--r-- | include/stc/vec_test_new.c | 53 |
16 files changed, 1499 insertions, 1531 deletions
diff --git a/include/stc/carray.h b/include/stc/carray.h index d67c1410..0d28ff62 100644 --- a/include/stc/carray.h +++ b/include/stc/carray.h @@ -50,169 +50,140 @@ int main() { }
}
*/
-
-#define using_carray2(...) c_MACRO_OVERLOAD(using_carray2, __VA_ARGS__)
-
-#define using_carray2_2(X, Value) \
- _c_using_carray2(carray2##X, Value, c_default_del, c_default_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) \
+ defTypes( _c_carray2_types(Self, i_VAL); )
\
- typedef Value CX##_value_t; \
- typedef struct { CX##_value_t **data; size_t xdim, ydim; } CX; \
- typedef struct { CX##_value_t *ref; } CX##_iter_t; \
+ STC_API Self cx_memb(_with_values)(size_t xdim, size_t ydim, i_VAL value); \
+ STC_API Self cx_memb(_with_storage)(size_t xdim, size_t ydim, cx_value_t* storage); \
+ STC_API Self cx_memb(_clone)(Self src); \
\
- STC_API CX CX##_with_values(size_t xdim, size_t ydim, Value value); \
- STC_API CX CX##_with_storage(size_t xdim, size_t ydim, CX##_value_t* storage); \
- STC_API CX CX##_clone(CX src); \
-\
- STC_INLINE CX CX##_init(size_t xdim, size_t ydim) { \
- return CX##_with_storage(xdim, ydim, c_new_n(CX##_value_t, xdim*ydim)); \
+ STC_INLINE Self cx_memb(_init)(size_t xdim, size_t ydim) { \
+ return cx_memb(_with_storage)(xdim, ydim, c_new_n(cx_value_t, xdim*ydim)); \
} \
- STC_INLINE size_t CX##_size(CX arr) { return arr.xdim*arr.ydim; } \
- STC_INLINE CX##_value_t *CX##_data(CX* self) { return *self->data; } \
- STC_INLINE CX##_value_t *CX##_at(CX* self, size_t x, size_t y) { \
+ STC_INLINE size_t cx_memb(_size)(Self arr) { return arr.xdim*arr.ydim; } \
+ STC_INLINE cx_value_t *cx_memb(_data)(Self* self) { return *self->data; } \
+ STC_INLINE cx_value_t *cx_memb(_at)(Self* self, size_t x, size_t y) { \
return *self->data + self->ydim*x + y; \
} \
- STC_INLINE CX##_value_t *CX##_release(CX* self) { \
- CX##_value_t *t = *self->data; c_free(self->data); self->data = NULL; return t; \
+ STC_INLINE cx_value_t *cx_memb(_release)(Self* self) { \
+ cx_value_t *t = *self->data; c_free(self->data); self->data = NULL; return t; \
} \
\
- STC_INLINE CX##_iter_t CX##_begin(const CX* self) { \
- return c_make(CX##_iter_t){*self->data}; \
+ STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self) { \
+ return c_make(cx_iter_t){*self->data}; \
} \
- STC_INLINE CX##_iter_t CX##_end(const CX* self) { \
- return c_make(CX##_iter_t){*self->data + self->xdim*self->ydim}; \
+ STC_INLINE cx_iter_t cx_memb(_end)(const Self* self) { \
+ return c_make(cx_iter_t){*self->data + self->xdim*self->ydim}; \
} \
- STC_INLINE void CX##_next(CX##_iter_t* it) { ++it->ref; } \
+ STC_INLINE void cx_memb(_next)(cx_iter_t* it) { ++it->ref; } \
\
- _c_implement_carray2(CX, Value, valueDel, valueClone) \
- STC_API void CX##_del(CX* self)
+ _c_implement_carray2(Self, i_VAL, i_VALDEL, i_VALFROM) \
+ STC_API void cx_memb(_del)(Self* self)
// carray3:
-#define using_carray3(...) c_MACRO_OVERLOAD(using_carray3, __VA_ARGS__)
-
-#define using_carray3_2(X, Value) \
- _c_using_carray3(carray3##X, Value, c_default_del, c_default_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 CX##_value_t; \
- typedef struct { CX##_value_t ***data; size_t xdim, ydim, zdim; } CX; \
- typedef struct { CX##_value_t *ref; } CX##_iter_t; \
+ defTypes( _c_carray3_types(Self, i_VAL); )
\
- STC_API CX CX##_with_values(size_t xdim, size_t ydim, size_t zdim, Value value); \
- STC_API CX CX##_with_storage(size_t xdim, size_t ydim, size_t zdim, CX##_value_t* storage); \
- STC_API CX CX##_clone(CX src); \
+ STC_API Self cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i_VAL value); \
+ STC_API Self cx_memb(_with_storage)(size_t xdim, size_t ydim, size_t zdim, cx_value_t* storage); \
+ STC_API Self cx_memb(_clone)(Self src); \
\
- STC_INLINE CX CX##_init(size_t xdim, size_t ydim, size_t zdim) { \
- return CX##_with_storage(xdim, ydim, zdim, c_new_n(CX##_value_t, xdim*ydim*zdim)); \
+ STC_INLINE Self cx_memb(_init)(size_t xdim, size_t ydim, size_t zdim) { \
+ return cx_memb(_with_storage)(xdim, ydim, zdim, c_new_n(cx_value_t, xdim*ydim*zdim)); \
} \
- 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->data; } \
- STC_INLINE CX##_value_t* CX##_at(CX* self, size_t x, size_t y, size_t z) { \
+ STC_INLINE size_t cx_memb(_size)(Self arr) { return arr.xdim*arr.ydim*arr.zdim; } \
+ STC_INLINE cx_value_t* cx_memb(_data)(Self* self) { return **self->data; } \
+ STC_INLINE cx_value_t* cx_memb(_at)(Self* self, size_t x, size_t y, size_t z) { \
return **self->data + self->zdim*(self->ydim*x + y) + z; \
} \
\
- STC_INLINE CX##_value_t* CX##_release(CX* self) { \
- CX##_value_t *values = **self->data; \
+ STC_INLINE cx_value_t* cx_memb(_release)(Self* self) { \
+ cx_value_t *values = **self->data; \
c_free(self->data); self->data = NULL; \
return values; \
} \
\
- STC_INLINE CX##_iter_t CX##_begin(const CX* self) { \
- return c_make(CX##_iter_t){**self->data}; \
+ STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self) { \
+ return c_make(cx_iter_t){**self->data}; \
} \
- STC_INLINE CX##_iter_t CX##_end(const CX* self) { \
- return c_make(CX##_iter_t){**self->data + CX##_size(*self)}; \
+ STC_INLINE cx_iter_t cx_memb(_end)(const Self* self) { \
+ return c_make(cx_iter_t){**self->data + cx_memb(_size)(*self)}; \
} \
- STC_INLINE void CX##_next(CX##_iter_t* it) { ++it->ref; } \
+ STC_INLINE void cx_memb(_next)(cx_iter_t* it) { ++it->ref; } \
\
- _c_implement_carray3(CX, Value, valueDel, valueClone) \
- STC_API void CX##_del(CX* self)
+ _c_implement_carray3(Self, i_VAL, i_VALDEL, i_VALFROM) \
+ STC_API void cx_memb(_del)(Self* self)
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define _c_implement_carray2(CX, Value, valueDel, valueClone) \
+#define _c_implement_carray2(Self, i_VAL, i_VALDEL, i_VALFROM) \
\
- STC_DEF CX CX##_with_storage(size_t xdim, size_t ydim, CX##_value_t* block) { \
- CX _arr = {c_new_n(CX##_value_t*, xdim), xdim, ydim}; \
+ STC_DEF Self cx_memb(_with_storage)(size_t xdim, size_t ydim, cx_value_t* block) { \
+ Self _arr = {c_new_n(cx_value_t*, xdim), xdim, ydim}; \
for (size_t x = 0; x < xdim; ++x, block += ydim) \
_arr.data[x] = block; \
return _arr; \
} \
\
- STC_DEF CX CX##_with_values(size_t xdim, size_t ydim, Value value) { \
- CX _arr = CX##_init(xdim, ydim); \
- for (CX##_value_t* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p) \
+ STC_DEF Self cx_memb(_with_values)(size_t xdim, size_t ydim, i_VAL value) { \
+ Self _arr = cx_memb(_init)(xdim, ydim); \
+ for (cx_value_t* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p) \
*p = value; \
return _arr; \
} \
\
- STC_DEF CX CX##_clone(CX src) { \
- CX _arr = CX##_init(src.xdim, src.ydim); \
- for (CX##_value_t* p = _arr.data[0], *q = src.data[0], *e = p + CX##_size(src); p != e; ++p, ++q) \
- *p = valueClone(*q); \
+ STC_DEF Self cx_memb(_clone)(Self src) { \
+ Self _arr = cx_memb(_init)(src.xdim, src.ydim); \
+ for (cx_value_t* p = _arr.data[0], *q = src.data[0], *e = p + cx_memb(_size)(src); p != e; ++p, ++q) \
+ *p = i_VALFROM(*q); \
return _arr; \
} \
\
- STC_DEF void CX##_del(CX* self) { \
+ STC_DEF void cx_memb(_del)(Self* self) { \
if (!self->data) return; \
- for (CX##_value_t* p = self->data[0], *e = p + CX##_size(*self); p != e; ++p) \
- valueDel(p); \
+ for (cx_value_t* p = self->data[0], *e = p + cx_memb(_size)(*self); p != e; ++p) \
+ i_VALDEL(p); \
c_free(self->data[0]); /* data */ \
c_free(self->data); /* pointers */ \
}
// carray3 impl.
-#define _c_implement_carray3(CX, Value, valueDel, valueClone) \
+#define _c_implement_carray3(Self, i_VAL, i_VALDEL, i_VALFROM) \
\
- STC_DEF CX CX##_with_storage(size_t xdim, size_t ydim, size_t zdim, CX##_value_t* block) { \
- CX _arr = {c_new_n(CX##_value_t**, xdim*(ydim + 1)), xdim, ydim, zdim}; \
- CX##_value_t** p = (CX##_value_t**) &_arr.data[xdim]; \
+ STC_DEF Self cx_memb(_with_storage)(size_t xdim, size_t ydim, size_t zdim, cx_value_t* block) { \
+ Self _arr = {c_new_n(cx_value_t**, xdim*(ydim + 1)), xdim, ydim, zdim}; \
+ cx_value_t** p = (cx_value_t**) &_arr.data[xdim]; \
for (size_t x = 0, y; x < xdim; ++x, p += ydim) \
for (_arr.data[x] = p, y = 0; y < ydim; ++y, block += zdim) \
_arr.data[x][y] = block; \
return _arr; \
} \
\
- STC_DEF CX CX##_with_values(size_t xdim, size_t ydim, size_t zdim, Value value) { \
- CX _arr = CX##_init(xdim, ydim, zdim); \
- for (CX##_value_t* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p) \
+ STC_DEF Self cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i_VAL value) { \
+ Self _arr = cx_memb(_init)(xdim, ydim, zdim); \
+ for (cx_value_t* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p) \
*p = value; \
return _arr; \
} \
\
- STC_DEF CX CX##_clone(CX src) { \
- CX _arr = CX##_init(src.xdim, src.ydim, src.zdim); \
- for (CX##_value_t* p = **_arr.data, *q = **src.data, *e = p + CX##_size(src); p != e; ++p, ++q) \
- *p = valueClone(*q); \
+ STC_DEF Self cx_memb(_clone)(Self src) { \
+ Self _arr = cx_memb(_init)(src.xdim, src.ydim, src.zdim); \
+ for (cx_value_t* p = **_arr.data, *q = **src.data, *e = p + cx_memb(_size)(src); p != e; ++p, ++q) \
+ *p = i_VALFROM(*q); \
return _arr; \
} \
\
- STC_DEF void CX##_del(CX* self) { \
+ STC_DEF void cx_memb(_del)(Self* self) { \
if (!self->data) return; \
- for (CX##_value_t* p = **self->data, *e = p + CX##_size(*self); p != e; ++p) \
- valueDel(p); \
+ for (cx_value_t* p = **self->data, *e = p + cx_memb(_size)(*self); p != e; ++p) \
+ i_VALDEL(p); \
c_free(self->data[0][0]); /* data */ \
c_free(self->data); /* pointers */ \
}
-#else
-#define _c_implement_carray2(CX, Value, valueDel, valueClone)
-#define _c_implement_carray3(CX, Value, valueDel, valueClone)
#endif
#endif
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index b2501416..a8098e43 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -54,8 +54,11 @@ /* Macro overloading feature support based on: https://rextester.com/ONP80107 */
#define c_MACRO_OVERLOAD(name, ...) \
c_SELECT(name, c_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
-#define c_SELECT(name, num) c_CONCAT(name ## _, num)
-#define c_CONCAT(a, b) a ## b
+#define c_SELECT(name, num) c_CONCAT3(name, _, num)
+#define c_CONCAT(a, b) a##b
+#define c_PASTE(a, b) c_CONCAT(a, b)
+#define c_CONCAT3(a, b, c) a##b##c
+#define c_PASTE3(a, b, c) c_CONCAT3(a, b, c)
#define c_EXPAND(...) __VA_ARGS__
#define c_NUM_ARGS(...) _c_APPLY_ARG_N((__VA_ARGS__, _c_RSEQ_N))
@@ -109,6 +112,8 @@ #define c_true(...) __VA_ARGS__
#define c_false(...)
+#define _c_deftypes_ c_false
+#define _c_deftypes_i_FWD c_true
/* Generic algorithms */
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index d052e9eb..a5853301 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -27,178 +27,148 @@ #include <stdlib.h>
#include <string.h>
-#define forward_cdeq(X, Value) _c_cdeq_types(cdeq_##X, Value)
-
-#define using_cdeq(...) c_MACRO_OVERLOAD(using_cdeq, __VA_ARGS__)
-
-#define using_cdeq_2(X, Value) \
- using_cdeq_3(X, Value, c_default_compare)
-#define using_cdeq_3(X, Value, valueCompare) \
- using_cdeq_5(X, Value, valueCompare, c_default_del, c_default_fromraw)
-#define using_cdeq_4(X, Value, valueCompare, valueDel) \
- 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_default_toraw, Value)
-#define using_cdeq_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
- _c_using_cdeq(cdeq_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, c_true)
-#define using_cdeq_8(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes) \
- _c_using_cdeq(cdeq_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes)
-
-#define using_cdeq_str() \
- using_cdeq_7(str, cstr, c_rawstr_compare, cstr_del, cstr_from, cstr_str, const char*)
-
-
-struct cdeq_rep { size_t size, cap; void* base[]; };
-#define _cdeq_rep(self) c_container_of((self)->_base, struct cdeq_rep, base)
-
-#define _c_cdeq_types(CX, Value) \
- typedef Value CX##_value_t; \
- typedef struct {CX##_value_t *ref; } CX##_iter_t; \
- typedef struct {CX##_value_t *_base, *data;} CX
-
-#define _c_using_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes) \
\
- defTypes( _c_cdeq_types(CX, Value); ) \
- typedef RawValue CX##_rawvalue_t; \
+ defTypes( _c_cdeq_types(Self, i_VAL); ) \
+ typedef i_VALRAW cx_rawvalue_t; \
\
- STC_API CX CX##_init(void); \
- STC_API CX CX##_clone(CX cx); \
- STC_API void CX##_clear(CX* self); \
- STC_API void CX##_del(CX* self); \
- STC_API CX##_iter_t CX##_find_in(CX##_iter_t p1, CX##_iter_t p2, RawValue raw); \
- STC_API int CX##_value_compare(const CX##_value_t* x, const CX##_value_t* y); \
- STC_API void CX##_push_back(CX* self, Value value); \
- STC_API void CX##_push_front(CX* self, Value value); \
- STC_API CX##_iter_t CX##_erase_range_p(CX* self, CX##_value_t* p1, CX##_value_t* p2); \
- STC_API CX##_iter_t CX##_insert_range_p(CX* self, CX##_value_t* pos, \
- const CX##_value_t* p1, const CX##_value_t* p2, bool clone); \
- STC_API CX##_iter_t CX##_emplace_range_p(CX* self, CX##_value_t* pos, \
- const CX##_rawvalue_t* p1, const CX##_rawvalue_t* p2); \
- STC_API void CX##_expand_right_(CX* self, size_t idx, size_t n); \
+ STC_API Self cx_memb(_init)(void); \
+ STC_API Self cx_memb(_clone)(Self cx); \
+ STC_API void cx_memb(_clear)(Self* self); \
+ STC_API void cx_memb(_del)(Self* self); \
+ STC_API cx_iter_t cx_memb(_find_in)(cx_iter_t p1, cx_iter_t p2, i_VALRAW raw); \
+ STC_API int cx_memb(_value_compare)(const cx_value_t* x, const cx_value_t* y); \
+ STC_API void cx_memb(_push_back)(Self* self, i_VAL value); \
+ STC_API void cx_memb(_push_front)(Self* self, i_VAL value); \
+ STC_API cx_iter_t cx_memb(_erase_range_p)(Self* self, cx_value_t* p1, cx_value_t* p2); \
+ STC_API cx_iter_t cx_memb(_insert_range_p)(Self* self, cx_value_t* pos, \
+ const cx_value_t* p1, const cx_value_t* p2, bool clone); \
+ STC_API cx_iter_t cx_memb(_emplace_range_p)(Self* self, cx_value_t* pos, \
+ const cx_rawvalue_t* p1, const cx_rawvalue_t* p2); \
+ STC_API void cx_memb(_expand_right_)(Self* self, size_t idx, size_t n); \
\
- STC_INLINE bool CX##_empty(CX cx) {return !_cdeq_rep(&cx)->size;} \
- STC_INLINE size_t CX##_size(CX cx) {return _cdeq_rep(&cx)->size;} \
- STC_INLINE size_t CX##_capacity(CX cx) {return _cdeq_rep(&cx)->cap;} \
- STC_INLINE void CX##_swap(CX* a, CX* b) {c_swap(CX, *a, *b);} \
- STC_INLINE Value CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \
- STC_INLINE RawValue CX##_value_toraw(CX##_value_t* pval) {return valueToRaw(pval);} \
- STC_INLINE Value CX##_value_clone(Value val) \
- {return valueFromRaw(valueToRaw(&val));} \
- STC_INLINE void CX##_emplace_back(CX* self, RawValue raw) \
- {CX##_push_back(self, valueFromRaw(raw));} \
- STC_INLINE void CX##_emplace_front(CX* self, RawValue raw) \
- {CX##_push_front(self, valueFromRaw(raw));} \
- STC_INLINE void CX##_pop_back(CX* self) \
- {valueDel(&self->data[--_cdeq_rep(self)->size]);} \
- STC_INLINE void CX##_pop_front(CX* self) \
- {valueDel(self->data++); --_cdeq_rep(self)->size;} \
- 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 idx) \
- {assert(idx < _cdeq_rep(self)->size); return self->data + idx;} \
- STC_INLINE CX##_iter_t CX##_begin(const CX* self) \
- {return c_make(CX##_iter_t){self->data};} \
- STC_INLINE CX##_iter_t CX##_end(const CX* self) \
- {return c_make(CX##_iter_t){self->data + _cdeq_rep(self)->size};} \
- STC_INLINE void CX##_next(CX##_iter_t* it) {++it->ref;} \
- STC_INLINE CX##_iter_t CX##_adv(CX##_iter_t it, intptr_t offs) {it.ref += offs; return it;} \
- STC_INLINE size_t CX##_idx(CX cx, CX##_iter_t it) {return it.ref - cx.data;} \
+ STC_INLINE bool cx_memb(_empty)(Self cx) { return !_cdeq_rep(&cx)->size; } \
+ STC_INLINE size_t cx_memb(_size)(Self cx) { return _cdeq_rep(&cx)->size; } \
+ STC_INLINE size_t cx_memb(_capacity)(Self cx) { return _cdeq_rep(&cx)->cap; } \
+ STC_INLINE void cx_memb(_swap)(Self* a, Self* b) {c_swap(Self, *a, *b); } \
+ STC_INLINE i_VAL cx_memb(_value_fromraw)(i_VALRAW raw) { return i_VALFROM(raw); } \
+ STC_INLINE i_VALRAW cx_memb(_value_toraw)(cx_value_t* pval) { return i_VALTO(pval); } \
+ STC_INLINE i_VAL cx_memb(_value_clone)(i_VAL val) \
+ { return i_VALFROM(i_VALTO(&val)); } \
+ STC_INLINE void cx_memb(_emplace_back)(Self* self, i_VALRAW raw) \
+ {cx_memb(_push_back)(self, i_VALFROM(raw)); } \
+ STC_INLINE void cx_memb(_emplace_front)(Self* self, i_VALRAW raw) \
+ {cx_memb(_push_front)(self, i_VALFROM(raw)); } \
+ STC_INLINE void cx_memb(_pop_back)(Self* self) \
+ {i_VALDEL(&self->data[--_cdeq_rep(self)->size]); } \
+ STC_INLINE void cx_memb(_pop_front)(Self* self) \
+ {i_VALDEL(self->data++); --_cdeq_rep(self)->size; } \
+ STC_INLINE cx_value_t* cx_memb(_front)(const Self* self) { return self->data; } \
+ STC_INLINE cx_value_t* cx_memb(_back)(const Self* self) \
+ { return self->data + _cdeq_rep(self)->size - 1; } \
+ STC_INLINE cx_value_t* cx_memb(_at)(const Self* self, size_t idx) \
+ {assert(idx < _cdeq_rep(self)->size); return self->data + idx; } \
+ STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self) \
+ { return c_make(cx_iter_t){self->data}; } \
+ STC_INLINE cx_iter_t cx_memb(_end)(const Self* self) \
+ { return c_make(cx_iter_t){self->data + _cdeq_rep(self)->size}; } \
+ STC_INLINE void cx_memb(_next)(cx_iter_t* it) {++it->ref; } \
+ STC_INLINE cx_iter_t cx_memb(_adv)(cx_iter_t it, intptr_t offs) {it.ref += offs; return it; } \
+ STC_INLINE size_t cx_memb(_idx)(Self cx, cx_iter_t it) { return it.ref - cx.data; } \
\
- STC_INLINE CX \
- CX##_with_capacity(size_t n) { \
- CX cx = CX##_init(); \
- CX##_expand_right_(&cx, 0, n); \
+ STC_INLINE Self \
+ cx_memb(_with_capacity)(size_t n) { \
+ Self cx = cx_memb(_init)(); \
+ cx_memb(_expand_right_)(&cx, 0, n); \
return cx; \
} \
\
STC_INLINE void \
- CX##_reserve(CX* self, size_t n) { \
+ cx_memb(_reserve)(Self* self, size_t n) { \
size_t sz = _cdeq_rep(self)->size; \
- if (n > sz) CX##_expand_right_(self, sz, n - sz); \
+ if (n > sz) cx_memb(_expand_right_)(self, sz, n - sz); \
} \
\
STC_INLINE void \
- CX##_shrink_to_fit(CX *self) { \
- CX cx = CX##_clone(*self); \
- CX##_del(self); *self = cx; \
+ cx_memb(_shrink_to_fit)(Self *self) { \
+ Self cx = cx_memb(_clone)(*self); \
+ cx_memb(_del)(self); *self = cx; \
} \
\
- 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, false); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_insert)(Self* self, size_t idx, i_VAL value) { \
+ return cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1, false); \
} \
- STC_INLINE CX##_iter_t \
- CX##_insert_n(CX* self, size_t idx, const CX##_value_t arr[], size_t n) { \
- return CX##_insert_range_p(self, self->data + idx, arr, arr + n, false); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_insert_n)(Self* self, size_t idx, const cx_value_t arr[], size_t n) { \
+ return cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n, false); \
} \
- STC_INLINE CX##_iter_t \
- CX##_insert_at(CX* self, CX##_iter_t it, Value value) { \
- return CX##_insert_range_p(self, it.ref, &value, &value + 1, false); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_insert_at)(Self* self, cx_iter_t it, i_VAL value) { \
+ return cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1, false); \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_emplace(CX* self, size_t idx, RawValue raw) { \
- return CX##_emplace_range_p(self, self->data + idx, &raw, &raw + 1); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_emplace)(Self* self, size_t idx, i_VALRAW raw) { \
+ return cx_memb(_emplace_range_p)(self, self->data + idx, &raw, &raw + 1); \
} \
- STC_INLINE CX##_iter_t \
- CX##_emplace_n(CX* self, size_t idx, const CX##_rawvalue_t arr[], size_t n) { \
- return CX##_emplace_range_p(self, self->data + idx, arr, arr + n); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_emplace_n)(Self* self, size_t idx, const cx_rawvalue_t arr[], size_t n) { \
+ return cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n); \
} \
- STC_INLINE CX##_iter_t \
- CX##_emplace_at(CX* self, CX##_iter_t it, RawValue raw) { \
- return CX##_emplace_range_p(self, it.ref, &raw, &raw + 1); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_emplace_at)(Self* self, cx_iter_t it, i_VALRAW raw) { \
+ return cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1); \
} \
- STC_INLINE CX##_iter_t \
- CX##_emplace_range(CX* self, CX##_iter_t it, CX##_iter_t it1, CX##_iter_t it2) { \
- return CX##_insert_range_p(self, it.ref, it1.ref, it2.ref, true); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_emplace_range)(Self* self, cx_iter_t it, cx_iter_t it1, cx_iter_t it2) { \
+ return cx_memb(_insert_range_p)(self, it.ref, it1.ref, it2.ref, true); \
} \
STC_INLINE void \
- CX##_emplace_items(CX *self, const CX##_rawvalue_t arr[], size_t n) { \
- CX##_emplace_range_p(self, self->data + _cdeq_rep(self)->size, arr, arr + n); \
+ cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n) { \
+ cx_memb(_emplace_range_p)(self, self->data + _cdeq_rep(self)->size, arr, arr + n); \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_erase(CX* self, size_t idx) { \
- return CX##_erase_range_p(self, self->data + idx, self->data + idx + 1); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_erase)(Self* self, size_t idx) { \
+ return cx_memb(_erase_range_p)(self, self->data + idx, self->data + idx + 1); \
} \
- STC_INLINE CX##_iter_t \
- CX##_erase_n(CX* self, size_t idx, size_t n) { \
- return CX##_erase_range_p(self, self->data + idx, self->data + idx + n); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_erase_n)(Self* self, size_t idx, size_t n) { \
+ return cx_memb(_erase_range_p)(self, self->data + idx, self->data + idx + n); \
} \
- STC_INLINE CX##_iter_t \
- CX##_erase_at(CX* self, CX##_iter_t it) { \
- return CX##_erase_range_p(self, it.ref, it.ref + 1); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_erase_at)(Self* self, cx_iter_t it) { \
+ return cx_memb(_erase_range_p)(self, it.ref, it.ref + 1); \
} \
- STC_INLINE CX##_iter_t \
- CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
- return CX##_erase_range_p(self, it1.ref, it2.ref); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_erase_range)(Self* self, cx_iter_t it1, cx_iter_t it2) { \
+ return cx_memb(_erase_range_p)(self, it1.ref, it2.ref); \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawValue raw) { \
- return CX##_find_in(CX##_begin(self), CX##_end(self), raw); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_find)(const Self* self, i_VALRAW raw) { \
+ return cx_memb(_find_in)(cx_memb(_begin)(self), cx_memb(_end)(self), raw); \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_get(const CX* self, RawValue raw) { \
- CX##_iter_t end = CX##_end(self); \
- CX##_value_t* val = CX##_find_in(CX##_begin(self), end, raw).ref; \
+ STC_INLINE cx_value_t* \
+ cx_memb(_get)(const Self* self, i_VALRAW raw) { \
+ cx_iter_t end = cx_memb(_end)(self); \
+ cx_value_t* val = cx_memb(_find_in)(cx_memb(_begin)(self), end, raw).ref; \
return val == end.ref ? NULL : val; \
} \
\
STC_INLINE void \
- CX##_sort_range(CX##_iter_t i1, CX##_iter_t i2, \
- int(*_cmp_)(const CX##_value_t*, const CX##_value_t*)) { \
+ cx_memb(_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 *i1.ref, (int(*)(const void*, const void*)) _cmp_); \
} \
\
STC_INLINE void \
- CX##_sort(CX* self) { \
- CX##_sort_range(CX##_begin(self), CX##_end(self), CX##_value_compare); \
+ cx_memb(_sort)(Self* self) { \
+ cx_memb(_sort_range)(cx_memb(_begin)(self), cx_memb(_end)(self), cx_memb(_value_compare)); \
} \
\
- _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
+ _c_implement_cdeq(Self, i_VAL, i_CMP, i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -208,88 +178,88 @@ struct cdeq_rep { size_t size, cap; void* base[]; }; static struct cdeq_rep _cdeq_sentinel = {0, 0};
#define _cdeq_nfront(self) ((self)->data - (self)->_base)
-#define _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
+#define _c_implement_cdeq(Self, i_VAL, i_CMP, i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW) \
\
- STC_DEF CX \
- CX##_init(void) { \
- CX##_value_t *b = (CX##_value_t *) _cdeq_sentinel.base; \
- return c_make(CX){b, b}; \
+ STC_DEF Self \
+ cx_memb(_init)(void) { \
+ cx_value_t *b = (cx_value_t *) _cdeq_sentinel.base; \
+ return c_make(Self){b, b}; \
} \
\
STC_DEF void \
- CX##_clear(CX* self) { \
+ cx_memb(_clear)(Self* self) { \
struct cdeq_rep* rep = _cdeq_rep(self); if (rep->cap) { \
- for (CX##_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \
- valueDel(p); \
+ for (cx_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \
+ i_VALDEL(p); \
rep->size = 0; \
} \
} \
\
STC_DEF void \
- CX##_del(CX* self) { \
- CX##_clear(self); \
+ cx_memb(_del)(Self* self) { \
+ cx_memb(_clear)(self); \
if (_cdeq_rep(self)->cap) \
c_free(_cdeq_rep(self)); \
} \
\
STC_DEF size_t \
- CX##_realloc_(CX* self, size_t n) { \
+ cx_memb(_realloc_)(Self* self, size_t n) { \
struct cdeq_rep* rep = _cdeq_rep(self); \
size_t sz = rep->size, cap = (size_t) (sz*1.7) + n + 7; \
size_t nfront = _cdeq_nfront(self); \
rep = (struct cdeq_rep*) c_realloc(rep->cap ? rep : NULL, \
- offsetof(struct cdeq_rep, base) + cap*sizeof(Value)); \
+ offsetof(struct cdeq_rep, base) + cap*sizeof(i_VAL)); \
rep->size = sz, rep->cap = cap; \
- self->_base = (CX##_value_t *) rep->base; \
+ self->_base = (cx_value_t *) rep->base; \
self->data = self->_base + nfront; \
return cap; \
} \
\
STC_DEF void \
- CX##_expand_left_(CX* self, size_t idx, size_t n) { \
+ cx_memb(_expand_left_)(Self* self, size_t idx, size_t n) { \
struct cdeq_rep* rep = _cdeq_rep(self); \
size_t sz = rep->size, cap = rep->cap; \
size_t nfront = _cdeq_nfront(self), nback = cap - sz - nfront; \
if (nfront >= n) { \
- self->data = (CX##_value_t *) memmove(self->data - n, self->data, idx*sizeof(Value)); \
+ self->data = (cx_value_t *) memmove(self->data - n, self->data, idx*sizeof(i_VAL)); \
} else { \
- if (sz*1.3 + n > cap) cap = CX##_realloc_(self, n); \
+ if (sz*1.3 + n > cap) cap = cx_memb(_realloc_)(self, n); \
size_t unused = cap - (sz + n); \
size_t pos = (nback*2 < unused) ? unused - nback : unused/2; \
- memmove(self->_base + pos + idx + n, self->data + idx, (sz - idx)*sizeof(Value)); \
- self->data = (CX##_value_t *) memmove(self->_base + pos, self->data, idx*sizeof(Value)); \
+ memmove(self->_base + pos + idx + n, self->data + idx, (sz - idx)*sizeof(i_VAL)); \
+ self->data = (cx_value_t *) memmove(self->_base + pos, self->data, idx*sizeof(i_VAL)); \
} \
} \
\
STC_DEF void \
- CX##_expand_right_(CX* self, size_t idx, size_t n) { \
+ cx_memb(_expand_right_)(Self* self, size_t idx, size_t n) { \
struct cdeq_rep* rep = _cdeq_rep(self); \
size_t sz = rep->size, cap = rep->cap; \
size_t nfront = _cdeq_nfront(self), nback = cap - sz - nfront; \
- if (nback >= n || sz*1.3 + n > cap && CX##_realloc_(self, n)) { \
- memmove(self->data + idx + n, self->data + idx, (sz - idx)*sizeof(Value)); \
+ if (nback >= n || sz*1.3 + n > cap && cx_memb(_realloc_)(self, n)) { \
+ memmove(self->data + idx + n, self->data + idx, (sz - idx)*sizeof(i_VAL)); \
} else { \
size_t unused = cap - (sz + n); \
size_t pos = (nfront*2 < unused) ? nfront : unused/2; \
- memmove(self->_base + pos, self->data, idx*sizeof(Value)); \
- memmove(self->data + pos + idx + n, self->data + idx, (sz - idx)*sizeof(Value)); \
- self->data = ((CX##_value_t *) self->_base) + pos; \
+ memmove(self->_base + pos, self->data, idx*sizeof(i_VAL)); \
+ memmove(self->data + pos + idx + n, self->data + idx, (sz - idx)*sizeof(i_VAL)); \
+ self->data = ((cx_value_t *) self->_base) + pos; \
} \
} \
\
- STC_DEF CX##_value_t* \
- CX##_insert_space_(CX* self, CX##_value_t* pos, size_t n) { \
+ STC_DEF cx_value_t* \
+ cx_memb(_insert_space_)(Self* self, cx_value_t* pos, size_t n) { \
size_t idx = pos - self->data; \
- if (idx*2 < _cdeq_rep(self)->size) CX##_expand_left_(self, idx, n); \
- else CX##_expand_right_(self, idx, n); \
+ if (idx*2 < _cdeq_rep(self)->size) cx_memb(_expand_left_)(self, idx, n); \
+ else cx_memb(_expand_right_)(self, idx, n); \
if (n) _cdeq_rep(self)->size += n; /* do only if size > 0 */ \
return self->data + idx; \
} \
\
STC_DEF void \
- CX##_push_front(CX* self, Value value) { \
+ cx_memb(_push_front)(Self* self, i_VAL value) { \
if (self->data == self->_base) \
- CX##_expand_left_(self, 0, 1); \
+ cx_memb(_expand_left_)(self, 0, 1); \
else \
--self->data; \
*self->data = value; \
@@ -297,70 +267,70 @@ static struct cdeq_rep _cdeq_sentinel = {0, 0}; } \
\
STC_DEF void \
- CX##_push_back(CX* self, Value value) { \
+ cx_memb(_push_back)(Self* self, i_VAL value) { \
struct cdeq_rep* rep = _cdeq_rep(self); \
if (_cdeq_nfront(self) + rep->size == rep->cap) \
- CX##_expand_right_(self, rep->size, 1); \
+ cx_memb(_expand_right_)(self, rep->size, 1); \
self->data[_cdeq_rep(self)->size++] = value; \
} \
\
- STC_DEF CX \
- CX##_clone(CX cx) { \
+ STC_DEF Self \
+ cx_memb(_clone)(Self cx) { \
size_t sz = _cdeq_rep(&cx)->size; \
- CX out = CX##_with_capacity(sz); \
- CX##_insert_range_p(&out, out.data, cx.data, cx.data + sz, true); \
+ Self out = cx_memb(_with_capacity)(sz); \
+ cx_memb(_insert_range_p)(&out, out.data, cx.data, cx.data + sz, true); \
return out; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_insert_range_p(CX* self, CX##_value_t* pos, const CX##_value_t* p1, \
- const CX##_value_t* p2, bool clone) { \
- pos = CX##_insert_space_(self, pos, p2 - p1); \
- CX##_iter_t it = {pos}; \
- if (clone) while (p1 != p2) *pos++ = valueFromRaw(valueToRaw(p1++)); \
+ STC_DEF cx_iter_t \
+ cx_memb(_insert_range_p)(Self* self, cx_value_t* pos, const cx_value_t* p1, \
+ const cx_value_t* p2, bool clone) { \
+ pos = cx_memb(_insert_space_)(self, pos, p2 - p1); \
+ cx_iter_t it = {pos}; \
+ if (clone) while (p1 != p2) *pos++ = i_VALFROM(i_VALTO(p1++)); \
else memcpy(pos, p1, (p2 - p1)*sizeof *p1); \
return it; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_emplace_range_p(CX* self, CX##_value_t* pos, const CX##_rawvalue_t* p1, const CX##_rawvalue_t* p2) { \
- pos = CX##_insert_space_(self, pos, p2 - p1); \
- CX##_iter_t it = {pos}; \
- while (p1 != p2) *pos++ = valueFromRaw(*p1++); \
+ STC_DEF cx_iter_t \
+ cx_memb(_emplace_range_p)(Self* self, cx_value_t* pos, const cx_rawvalue_t* p1, const cx_rawvalue_t* p2) { \
+ pos = cx_memb(_insert_space_)(self, pos, p2 - p1); \
+ cx_iter_t it = {pos}; \
+ while (p1 != p2) *pos++ = i_VALFROM(*p1++); \
return it; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_erase_range_p(CX* self, CX##_value_t* p1, CX##_value_t* p2) { \
+ STC_DEF cx_iter_t \
+ cx_memb(_erase_range_p)(Self* self, cx_value_t* p1, cx_value_t* p2) { \
size_t n = p2 - p1; \
if (n > 0) { \
- CX##_value_t* p = p1, *end = self->data + _cdeq_rep(self)->size; \
- while (p != p2) valueDel(p++); \
+ cx_value_t* p = p1, *end = self->data + _cdeq_rep(self)->size; \
+ while (p != p2) i_VALDEL(p++); \
if (p1 == self->data) self->data += n; \
- else memmove(p1, p2, (end - p2) * sizeof(Value)); \
+ else memmove(p1, p2, (end - p2) * sizeof(i_VAL)); \
_cdeq_rep(self)->size -= n; \
} \
- return c_make(CX##_iter_t){p1}; \
+ return c_make(cx_iter_t){p1}; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_find_in(CX##_iter_t i1, CX##_iter_t i2, RawValue raw) { \
+ STC_DEF cx_iter_t \
+ cx_memb(_find_in)(cx_iter_t i1, cx_iter_t i2, i_VALRAW raw) { \
for (; i1.ref != i2.ref; ++i1.ref) { \
- RawValue r = valueToRaw(i1.ref); \
- if (valueCompareRaw(&raw, &r) == 0) return i1; \
+ i_VALRAW r = i_VALTO(i1.ref); \
+ if (i_CMP(&raw, &r) == 0) return i1; \
} \
return i2; \
} \
\
STC_DEF int \
- 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); \
+ cx_memb(_value_compare)(const cx_value_t* x, const cx_value_t* y) { \
+ i_VALRAW rx = i_VALTO(x); \
+ i_VALRAW ry = i_VALTO(y); \
+ return i_CMP(&rx, &ry); \
}
#else
-#define _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
+#define _c_implement_cdeq(Self, i_VAL, i_CMP, i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW)
#endif
#endif
diff --git a/include/stc/clist.h b/include/stc/clist.h index 75364a4f..9c79864a 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -56,181 +56,147 @@ #include "ccommon.h"
#include <stdlib.h>
-#define forward_clist(X, Value) _c_clist_types(clist_##X, Value)
-#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) \
- using_clist_5(X, Value, valueCompare, c_default_del, c_default_fromraw)
-#define using_clist_4(X, Value, valueCompare, valueDel) \
- 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_default_toraw, Value)
-#define using_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
- _c_using_clist(clist_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, c_true)
-#define using_clist_8(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes) \
- _c_using_clist(clist_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes)
-
-#define using_clist_str() \
- using_clist_7(str, cstr, c_rawstr_compare, cstr_del, cstr_from, cstr_str, const char*)
-
-
-#define _c_clist_types(CX, Value) \
- typedef Value CX##_value_t; \
- typedef struct CX##_node_t CX##_node_t; \
-\
- typedef struct { \
- CX##_node_t *const *_last, *prev; \
- CX##_value_t *ref; \
- } CX##_iter_t; \
-\
- typedef struct { \
- CX##_node_t *last; \
- } CX
-
-#define _c_clist_complete_types(CX) \
- struct CX##_node_t { \
- struct CX##_node_t *next; \
- CX##_value_t value; \
+#define _c_clist_complete_types(Self) \
+ struct cx_node_t { \
+ struct cx_node_t *next; \
+ cx_value_t value; \
}
_c_clist_types(clist_VOID, int);
_c_clist_complete_types(clist_VOID);
STC_API size_t _clist_count(const clist_VOID* self);
-#define _clist_node(CX, vp) c_container_of(vp, CX##_node_t, value)
+#define _clist_node(Self, vp) c_container_of(vp, cx_node_t, value)
-#define _c_using_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes) \
-\
- defTypes( _c_clist_types(CX, Value); ) \
- _c_clist_complete_types(CX); \
- typedef RawValue CX##_rawvalue_t; \
+ defTypes( _c_clist_types(Self, i_VAL); ) \
+ _c_clist_complete_types(Self); \
+ typedef i_VALRAW cx_rawvalue_t; \
\
- STC_API CX CX##_clone(CX cx); \
- STC_API void CX##_del(CX* self); \
- STC_API void CX##_push_back(CX* self, Value value); \
- STC_API void CX##_push_front(CX* self, Value value); \
- STC_API CX##_iter_t CX##_insert(CX* self, CX##_iter_t it, Value value); \
- STC_API void CX##_emplace_items(CX *self, const CX##_rawvalue_t arr[], size_t n); \
- STC_API CX##_iter_t CX##_erase_at(CX* self, CX##_iter_t it); \
- STC_API CX##_iter_t CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2); \
- STC_API size_t CX##_remove(CX* self, RawValue val); \
- STC_API CX##_iter_t CX##_splice(CX* self, CX##_iter_t it, CX* other); \
- STC_API CX CX##_split_off(CX* self, CX##_iter_t it1, CX##_iter_t it2); \
- STC_API void CX##_sort(CX* self); \
- STC_API CX##_iter_t CX##_find_in(CX##_iter_t it1, CX##_iter_t it2, RawValue val); \
- STC_API CX##_node_t* CX##_erase_after_(CX* self, CX##_node_t* node); \
+ STC_API Self cx_memb(_clone)(Self cx); \
+ STC_API void cx_memb(_del)(Self* self); \
+ STC_API void cx_memb(_push_back)(Self* self, i_VAL value); \
+ STC_API void cx_memb(_push_front)(Self* self, i_VAL value); \
+ STC_API cx_iter_t cx_memb(_insert)(Self* self, cx_iter_t it, i_VAL value); \
+ STC_API void cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n); \
+ STC_API cx_iter_t cx_memb(_erase_at)(Self* self, cx_iter_t it); \
+ STC_API cx_iter_t cx_memb(_erase_range)(Self* self, cx_iter_t it1, cx_iter_t it2); \
+ STC_API size_t cx_memb(_remove)(Self* self, i_VALRAW val); \
+ STC_API cx_iter_t cx_memb(_splice)(Self* self, cx_iter_t it, Self* other); \
+ STC_API Self cx_memb(_split_off)(Self* self, cx_iter_t it1, cx_iter_t it2); \
+ STC_API void cx_memb(_sort)(Self* self); \
+ STC_API cx_iter_t cx_memb(_find_in)(cx_iter_t it1, cx_iter_t it2, i_VALRAW val); \
+ STC_API cx_node_t* cx_memb(_erase_after_)(Self* self, cx_node_t* node); \
\
- STC_INLINE CX CX##_init(void) {return c_make(CX){NULL};} \
- STC_INLINE bool CX##_empty(CX cx) {return cx.last == NULL;} \
- STC_INLINE size_t CX##_count(CX cx) \
- {return _clist_count((const clist_VOID*) &cx);} \
- STC_INLINE void CX##_clear(CX* self) {CX##_del(self);} \
- STC_INLINE Value CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \
- STC_INLINE RawValue CX##_value_toraw(CX##_value_t* pval) {return valueToRaw(pval);} \
- STC_INLINE Value CX##_value_clone(Value val) \
- {return valueFromRaw(valueToRaw(&val));} \
- STC_INLINE void CX##_pop_front(CX* self) \
- {CX##_erase_after_(self, self->last);} \
- STC_INLINE CX##_iter_t CX##_erase(CX* self, CX##_iter_t it) \
- {return CX##_erase_at(self, it);} \
- STC_INLINE void CX##_emplace_back(CX* self, RawValue raw) \
- {CX##_push_back(self, valueFromRaw(raw));} \
- STC_INLINE void CX##_emplace_front(CX* self, RawValue raw) \
- {CX##_push_front(self, valueFromRaw(raw));} \
- STC_INLINE CX##_iter_t CX##_emplace(CX* self, CX##_iter_t it, RawValue raw) \
- {return CX##_insert(self, it, valueFromRaw(raw));} \
- STC_INLINE CX##_value_t* CX##_front(const CX* self) {return &self->last->next->value;} \
- STC_INLINE CX##_value_t* CX##_back(const CX* self) {return &self->last->value;} \
+ STC_INLINE Self cx_memb(_init)(void) { return c_make(Self){NULL}; } \
+ STC_INLINE bool cx_memb(_empty)(Self cx) { return cx.last == NULL; } \
+ STC_INLINE size_t cx_memb(_count)(Self cx) \
+ { return _clist_count((const clist_VOID*) &cx); } \
+ STC_INLINE void cx_memb(_clear)(Self* self) {cx_memb(_del)(self); } \
+ STC_INLINE i_VAL cx_memb(_value_fromraw)(i_VALRAW raw) { return i_VALFROM(raw); } \
+ STC_INLINE i_VALRAW cx_memb(_value_toraw)(cx_value_t* pval) { return i_VALTO(pval); } \
+ STC_INLINE i_VAL cx_memb(_value_clone)(i_VAL val) \
+ { return i_VALFROM(i_VALTO(&val)); } \
+ STC_INLINE void cx_memb(_pop_front)(Self* self) \
+ {cx_memb(_erase_after_)(self, self->last); } \
+ STC_INLINE cx_iter_t cx_memb(_erase)(Self* self, cx_iter_t it) \
+ { return cx_memb(_erase_at)(self, it); } \
+ STC_INLINE void cx_memb(_emplace_back)(Self* self, i_VALRAW raw) \
+ {cx_memb(_push_back)(self, i_VALFROM(raw)); } \
+ STC_INLINE void cx_memb(_emplace_front)(Self* self, i_VALRAW raw) \
+ {cx_memb(_push_front)(self, i_VALFROM(raw)); } \
+ STC_INLINE cx_iter_t cx_memb(_emplace)(Self* self, cx_iter_t it, i_VALRAW raw) \
+ { return cx_memb(_insert)(self, it, i_VALFROM(raw)); } \
+ STC_INLINE cx_value_t* cx_memb(_front)(const Self* self) { return &self->last->next->value; } \
+ STC_INLINE cx_value_t* cx_memb(_back)(const Self* self) { return &self->last->value; } \
\
- STC_INLINE CX##_iter_t \
- CX##_iter(const CX* self, CX##_node_t* prev) { \
- return c_make(CX##_iter_t){&self->last, prev, &prev->next->value}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_iter)(const Self* self, cx_node_t* prev) { \
+ return c_make(cx_iter_t){&self->last, prev, &prev->next->value}; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_begin(const CX* self) { \
- CX##_value_t* head = self->last ? &self->last->next->value : NULL; \
- return c_make(CX##_iter_t){&self->last, self->last, head}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_begin)(const Self* self) { \
+ cx_value_t* head = self->last ? &self->last->next->value : NULL; \
+ return c_make(cx_iter_t){&self->last, self->last, head}; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_end(const CX* self) { \
- return c_make(CX##_iter_t){NULL}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_end)(const Self* self) { \
+ return c_make(cx_iter_t){NULL}; \
} \
\
STC_INLINE void \
- CX##_next(CX##_iter_t* it) { \
- CX##_node_t* node = it->prev = _clist_node(CX, it->ref); \
+ cx_memb(_next)(cx_iter_t* it) { \
+ cx_node_t* node = it->prev = _clist_node(Self, it->ref); \
it->ref = (node == *it->_last ? NULL : &node->next->value); \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_fwd(CX##_iter_t it, size_t n) { \
- while (n-- && it.ref) CX##_next(&it); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_fwd)(cx_iter_t it, size_t n) { \
+ while (n-- && it.ref) cx_memb(_next)(&it); \
return it; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_splice_range(CX* self, CX##_iter_t it, \
- CX* other, CX##_iter_t it1, CX##_iter_t it2) { \
- CX tmp = CX##_split_off(other, it1, it2); \
- return CX##_splice(self, it, &tmp); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_splice_range)(Self* self, cx_iter_t it, \
+ Self* other, cx_iter_t it1, cx_iter_t it2) { \
+ Self tmp = cx_memb(_split_off)(other, it1, it2); \
+ return cx_memb(_splice)(self, it, &tmp); \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawValue val) { \
- return CX##_find_in(CX##_begin(self), CX##_end(self), val); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_find)(const Self* self, i_VALRAW val) { \
+ return cx_memb(_find_in)(cx_memb(_begin)(self), cx_memb(_end)(self), val); \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_get(const CX* self, RawValue val) { \
- return CX##_find_in(CX##_begin(self), CX##_end(self), val).ref; \
+ STC_INLINE cx_value_t* \
+ cx_memb(_get)(const Self* self, i_VALRAW val) { \
+ return cx_memb(_find_in)(cx_memb(_begin)(self), cx_memb(_end)(self), val).ref; \
} \
\
- _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
+ _c_implement_clist(Self, i_VAL, i_CMP, i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
+#define _c_implement_clist(Self, i_VAL, i_CMP, i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW) \
\
- STC_DEF CX \
- CX##_clone(CX cx) { \
- CX out = CX##_init(); \
- c_foreach_3 (it, CX, cx) CX##_emplace_back(&out, valueToRaw(it.ref)); \
+ STC_DEF Self \
+ cx_memb(_clone)(Self cx) { \
+ Self out = cx_memb(_init)(); \
+ c_foreach_3 (it, Self, cx) cx_memb(_emplace_back)(&out, i_VALTO(it.ref)); \
return out; \
} \
\
STC_DEF void \
- CX##_del(CX* self) { \
- while (self->last) CX##_erase_after_(self, self->last); \
+ cx_memb(_del)(Self* self) { \
+ while (self->last) cx_memb(_erase_after_)(self, self->last); \
} \
\
STC_DEF void \
- CX##_push_back(CX* self, Value value) { \
- _c_clist_insert_after(self, CX, self->last, value); \
+ cx_memb(_push_back)(Self* self, i_VAL value) { \
+ _c_clist_insert_after(self, Self, self->last, value); \
self->last = entry; \
} \
\
STC_DEF void \
- CX##_push_front(CX* self, Value value) { \
- _c_clist_insert_after(self, CX, self->last, value); \
+ cx_memb(_push_front)(Self* self, i_VAL value) { \
+ _c_clist_insert_after(self, Self, self->last, value); \
if (!self->last) self->last = entry; \
} \
\
STC_DEF void \
- CX##_emplace_items(CX *self, const CX##_rawvalue_t arr[], size_t n) { \
- for (size_t i=0; i<n; ++i) CX##_push_back(self, valueFromRaw(arr[i])); \
+ cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n) { \
+ for (size_t i=0; i<n; ++i) cx_memb(_push_back)(self, i_VALFROM(arr[i])); \
} \
\
- STC_DEF CX##_iter_t \
- CX##_insert(CX* self, CX##_iter_t it, Value value) { \
- CX##_node_t* node = it.ref ? it.prev : self->last; \
- _c_clist_insert_after(self, CX, node, value); \
+ STC_DEF cx_iter_t \
+ cx_memb(_insert)(Self* self, cx_iter_t it, i_VAL value) { \
+ cx_node_t* node = it.ref ? it.prev : self->last; \
+ _c_clist_insert_after(self, Self, node, value); \
if (!self->last || !it.ref) { \
it.prev = self->last ? self->last : entry; \
self->last = entry; \
@@ -239,63 +205,63 @@ STC_API size_t _clist_count(const clist_VOID* self); return it; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_erase_at(CX* self, CX##_iter_t it) { \
- CX##_node_t *node = _clist_node(CX, it.ref); \
+ STC_DEF cx_iter_t \
+ cx_memb(_erase_at)(Self* self, cx_iter_t it) { \
+ cx_node_t *node = _clist_node(Self, it.ref); \
it.ref = (node == self->last) ? NULL : &node->next->value; \
- CX##_erase_after_(self, it.prev); \
+ cx_memb(_erase_after_)(self, it.prev); \
return it; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
- CX##_node_t *node = it1.ref ? it1.prev : NULL, \
- *done = it2.ref ? _clist_node(CX, it2.ref) : NULL; \
+ STC_DEF cx_iter_t \
+ cx_memb(_erase_range)(Self* self, cx_iter_t it1, cx_iter_t it2) { \
+ cx_node_t *node = it1.ref ? it1.prev : NULL, \
+ *done = it2.ref ? _clist_node(Self, it2.ref) : NULL; \
while (node && node->next != done) \
- node = CX##_erase_after_(self, node); \
+ node = cx_memb(_erase_after_)(self, node); \
return it2; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_find_in(CX##_iter_t it1, CX##_iter_t it2, RawValue val) { \
- c_foreach_4 (it, CX, it1, it2) { \
- RawValue r = valueToRaw(it.ref); \
- if (valueCompareRaw(&r, &val) == 0) return it; \
+ STC_DEF cx_iter_t \
+ cx_memb(_find_in)(cx_iter_t it1, cx_iter_t it2, i_VALRAW val) { \
+ c_foreach_4 (it, Self, it1, it2) { \
+ i_VALRAW r = i_VALTO(it.ref); \
+ if (i_CMP(&r, &val) == 0) return it; \
} \
it2.ref = NULL; return it2; \
} \
\
- STC_DEF CX##_node_t* \
- CX##_erase_after_(CX* self, CX##_node_t* node) { \
- CX##_node_t* del = node->next, *next = del->next; \
+ STC_DEF cx_node_t* \
+ cx_memb(_erase_after_)(Self* 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; \
- valueDel(&del->value); c_free(del); \
+ i_VALDEL(&del->value); c_free(del); \
return node; \
} \
\
STC_DEF size_t \
- CX##_remove(CX* self, RawValue val) { \
+ cx_memb(_remove)(Self* self, i_VALRAW val) { \
size_t n = 0; \
- CX##_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 = CX##_erase_after_(self, prev), ++n; \
+ i_VALRAW r = i_VALTO(&node->value); \
+ if (i_CMP(&r, &val) == 0) \
+ prev = cx_memb(_erase_after_)(self, prev), ++n; \
else \
prev = (node == self->last ? NULL : node); \
} \
return n; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_splice(CX* self, CX##_iter_t it, CX* other) { \
+ STC_DEF cx_iter_t \
+ cx_memb(_splice)(Self* self, cx_iter_t it, Self* other) { \
if (!self->last) \
self->last = other->last; \
else if (other->last) { \
- CX##_node_t *p = it.ref ? it.prev : self->last, *next = p->next; \
+ cx_node_t *p = it.ref ? it.prev : self->last, *next = p->next; \
it.prev = other->last; \
p->next = it.prev->next; \
it.prev->next = next; \
@@ -304,33 +270,33 @@ STC_API size_t _clist_count(const clist_VOID* self); other->last = NULL; return it; \
} \
\
- STC_DEF CX \
- CX##_split_off(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
- CX cx = {NULL}; \
+ STC_DEF Self \
+ cx_memb(_split_off)(Self* self, cx_iter_t it1, cx_iter_t it2) { \
+ Self cx = {NULL}; \
if (it1.ref == it2.ref) return cx; \
- CX##_node_t *p1 = it1.prev, \
+ cx_node_t *p1 = it1.prev, \
*p2 = it2.ref ? it2.prev : self->last; \
- p1->next = p2->next, p2->next = _clist_node(CX, it1.ref); \
+ p1->next = p2->next, p2->next = _clist_node(Self, it1.ref); \
if (self->last == p2) self->last = (p1 == p2) ? NULL : p1; \
cx.last = p2; \
return cx; \
} \
\
STC_DEF int \
- CX##_sort_cmp_(const clist_VOID_node_t* x, const clist_VOID_node_t* y) { \
- RawValue a = valueToRaw(&((const CX##_node_t *) x)->value); \
- RawValue b = valueToRaw(&((const CX##_node_t *) y)->value); \
- return valueCompareRaw(&a, &b); \
+ cx_memb(_sort_cmp_)(const clist_VOID_node_t* x, const clist_VOID_node_t* y) { \
+ i_VALRAW a = i_VALTO(&((const cx_node_t *) x)->value); \
+ i_VALRAW b = i_VALTO(&((const cx_node_t *) y)->value); \
+ return i_CMP(&a, &b); \
} \
STC_DEF void \
- CX##_sort(CX* self) { \
+ cx_memb(_sort)(Self* self) { \
if (self->last) \
- self->last = (CX##_node_t *) _clist_mergesort((clist_VOID_node_t *) self->last->next, CX##_sort_cmp_); \
+ self->last = (cx_node_t *) _clist_mergesort((clist_VOID_node_t *) self->last->next, cx_memb(_sort_cmp_)); \
}
-#define _c_clist_insert_after(self, CX, node, val) \
- CX##_node_t *entry = c_new (CX##_node_t); \
+#define _c_clist_insert_after(self, Self, node, val) \
+ cx_node_t *entry = c_new (cx_node_t); \
if (node) entry->next = node->next, node->next = entry; \
else entry->next = entry; \
entry->value = val
@@ -396,8 +362,6 @@ _clist_mergesort(clist_VOID_node_t *list, int (*cmp)(const clist_VOID_node_t*, c }
}
-#else
-#define _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
-#endif
#endif
+#endif
diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 68a5fd4b..39d9fce8 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -51,276 +51,170 @@ int main(void) { #include <stdlib.h>
#include <string.h>
-#define using_cmap(...) c_MACRO_OVERLOAD(using_cmap, __VA_ARGS__)
-#define using_cmap_3(X, Key, Mapped) \
- using_cmap_5(X, Key, Mapped, c_default_equals, c_default_hash)
-#define using_cmap_5(X, Key, Mapped, keyEquals, keyHash) \
- using_cmap_7(X, Key, Mapped, keyEquals, keyHash, \
- c_default_del, c_default_fromraw)
-#define using_cmap_6(X, Key, Mapped, keyEquals, keyHash, mappedDel) \
- using_cmap_7(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, c_no_clone)
-#define using_cmap_7(X, Key, Mapped, keyEquals, keyHash, mappedDel, mappedClone) \
- using_cmap_10(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, mappedClone, c_default_toraw, Mapped, c_true)
-#define using_cmap_10(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- using_cmap_14(X, Key, Mapped, keyEquals, keyHash, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- c_default_del, c_default_fromraw, c_default_toraw, Key, defTypes)
-#define using_cmap_14(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-
-#define using_cmap_keydef(...) c_MACRO_OVERLOAD(using_cmap_keydef, __VA_ARGS__)
-
-#define using_cmap_keydef_7(X, Key, Mapped, keyEquals, keyHash, keyDel, keyClone) \
- using_cmap_keydef_10(X, Key, Mapped, keyEquals, keyHash, \
- keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_cmap_keydef_10(X, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cmap_##X, cmap_, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- c_default_del, c_default_fromraw, c_default_toraw, Mapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define using_cmap_str() \
- _c_using_chash(cmap_str, cmap_, cstr, cstr, c_rawstr_equals, c_rawstr_hash, \
- cstr_del, cstr_from, cstr_str, const char*, \
- cstr_del, cstr_from, cstr_str, const char*, c_true)
-
-
-#define using_cmap_strkey(...) c_MACRO_OVERLOAD(using_cmap_strkey, __VA_ARGS__)
-
-#define using_cmap_strkey_2(X, Mapped) \
- using_cmap_strkey_4(X, Mapped, c_default_del, c_default_fromraw)
-#define using_cmap_strkey_3(X, Mapped, mappedDel) \
- using_cmap_strkey_4(X, Mapped, mappedDel, c_no_clone)
-#define using_cmap_strkey_4(X, Mapped, mappedDel, mappedClone) \
- using_cmap_strkey_7(X, Mapped, mappedDel, mappedClone, c_default_toraw, Mapped, c_true)
-#define using_cmap_strkey_7(X, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- _c_using_chash_strkey(X, cmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes)
-#define _c_using_chash_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- _c_using_chash(C##X, C, cstr, Mapped, c_rawstr_equals, c_rawstr_hash, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- cstr_del, cstr_from, cstr_str, const char*, defTypes)
-
-
-#define using_cmap_strval(...) c_MACRO_OVERLOAD(using_cmap_strval, __VA_ARGS__)
-
-#define using_cmap_strval_2(X, Key) \
- using_cmap_strval_4(X, Key, c_default_equals, c_default_hash)
-#define using_cmap_strval_4(X, Key, keyEquals, keyHash) \
- using_cmap_strval_6(X, Key, keyEquals, keyHash, c_default_del, c_default_fromraw)
-#define using_cmap_strval_5(X, Key, keyEquals, keyHash, keyDel) \
- using_cmap_strval_6(X, Key, keyEquals, keyHash, keyDel, c_no_clone)
-#define using_cmap_strval_6(X, Key, keyEquals, keyHash, keyDel, keyClone) \
- using_cmap_strval_9(X, Key, keyEquals, keyHash, keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_cmap_strval_9(X, Key, keyEqualsRaw, keyHashRaw, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cmap_##X, cmap_, Key, cstr, keyEqualsRaw, keyHashRaw, \
- cstr_del, cstr_from, cstr_str, const char*, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define SET_ONLY_cmap_(...)
-#define MAP_ONLY_cmap_(...) __VA_ARGS__
#define KEY_REF_cmap_(vp) (&(vp)->first)
-#ifndef CMAP_SIZE_T
-#define CMAP_SIZE_T uint32_t
-#endif
#define _cmap_inits {NULL, NULL, 0, 0, 0.85f}
-typedef struct {size_t idx; uint_fast8_t hx;} chash_bucket_t; \
+typedef struct {size_t idx; uint_fast8_t hx; } chash_bucket_t; \
STC_API uint64_t c_default_hash(const void *data, size_t len);
STC_INLINE uint64_t c_string_hash(const char *s)
- {return c_default_hash(s, strlen(s));}
+ { return c_default_hash(s, strlen(s)); }
STC_INLINE uint64_t c_default_hash32(const void* data, size_t ignored)
- {return *(const uint32_t *)data * 0xc6a4a7935bd1e99d;}
+ { return *(const uint32_t *)data * 0xc6a4a7935bd1e99d; }
STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored)
- {return *(const uint64_t *)data * 0xc6a4a7935bd1e99d;}
+ { return *(const uint64_t *)data * 0xc6a4a7935bd1e99d; }
-#define _c_chash_types(CX, C, Key, Mapped) \
- typedef Key CX##_key_t; \
- typedef Mapped CX##_mapped_t; \
- typedef CMAP_SIZE_T CX##_size_t; \
-\
- typedef SET_ONLY_##C( CX##_key_t ) \
- MAP_ONLY_##C( struct CX##_value_t ) \
- CX##_value_t; \
-\
- typedef struct { \
- CX##_value_t *ref; \
- bool inserted; \
- } CX##_result_t; \
-\
- typedef struct { \
- CX##_value_t *ref; \
- uint8_t* _hx; \
- } CX##_iter_t; \
-\
- typedef struct { \
- CX##_value_t* table; \
- uint8_t* _hashx; \
- CX##_size_t size, bucket_count; \
- float max_load_factor; \
- } CX
-#define _c_using_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- defTypes( _c_chash_types(CX, C, Key, Mapped); ) \
+ defTypes( _c_chash_types(Self, C, i_KEY, i_VAL); ) \
\
- MAP_ONLY_##C( struct CX##_value_t { \
- CX##_key_t first; \
- CX##_mapped_t second; \
+ MAP_ONLY_##C( struct cx_value_t { \
+ cx_key_t first; \
+ cx_mapped_t second; \
}; ) \
\
- typedef RawKey CX##_rawkey_t; \
- typedef RawMapped CX##_rawmapped_t; \
- typedef SET_ONLY_##C( RawKey ) \
- MAP_ONLY_##C( struct { RawKey first; \
- RawMapped second; } ) \
- CX##_rawvalue_t; \
+ typedef i_KEYRAW cx_rawkey_t; \
+ typedef i_VALRAW cx_memb(_rawmapped_t); \
+ typedef SET_ONLY_##C( i_KEYRAW ) \
+ MAP_ONLY_##C( struct { i_KEYRAW first; \
+ i_VALRAW second; } ) \
+ cx_rawvalue_t; \
\
- STC_API CX CX##_with_capacity(size_t cap); \
- STC_API CX CX##_clone(CX map); \
- STC_API void CX##_del(CX* self); \
- STC_API void CX##_clear(CX* self); \
- STC_API void CX##_reserve(CX* self, size_t capacity); \
- STC_API chash_bucket_t CX##_bucket_(const CX* self, const CX##_rawkey_t* rkeyptr); \
- STC_API CX##_result_t CX##_insert_entry_(CX* self, RawKey rkey); \
- STC_API void CX##_erase_entry(CX* self, CX##_value_t* val); \
+ STC_API Self cx_memb(_with_capacity)(size_t cap); \
+ STC_API Self cx_memb(_clone)(Self map); \
+ STC_API void cx_memb(_del)(Self* self); \
+ STC_API void cx_memb(_clear)(Self* self); \
+ STC_API void cx_memb(_reserve)(Self* self, size_t capacity); \
+ STC_API chash_bucket_t cx_memb(_bucket_)(const Self* self, const cx_rawkey_t* rkeyptr); \
+ STC_API cx_result_t cx_memb(_insert_entry_)(Self* self, i_KEYRAW rkey); \
+ STC_API void cx_memb(_erase_entry)(Self* self, cx_value_t* val); \
\
- STC_INLINE CX CX##_init(void) {return c_make(CX)_cmap_inits;} \
- STC_INLINE void CX##_shrink_to_fit(CX* self) {CX##_reserve(self, self->size);} \
- STC_INLINE void CX##_max_load_factor(CX* self, float ml) {self->max_load_factor = ml;} \
- STC_INLINE bool CX##_empty(CX m) {return m.size == 0;} \
- STC_INLINE size_t CX##_size(CX m) {return m.size;} \
- STC_INLINE size_t CX##_bucket_count(CX map) {return map.bucket_count;} \
- STC_INLINE size_t CX##_capacity(CX map) \
- {return (size_t) (map.bucket_count * map.max_load_factor);} \
- STC_INLINE void CX##_swap(CX *map1, CX *map2) {c_swap(CX, *map1, *map2);} \
- STC_INLINE bool CX##_contains(const CX* self, RawKey rkey) \
- {return self->size && self->_hashx[CX##_bucket_(self, &rkey).idx];} \
+ STC_INLINE Self cx_memb(_init)(void) { return c_make(Self)_cmap_inits; } \
+ STC_INLINE void cx_memb(_shrink_to_fit)(Self* self) {cx_memb(_reserve)(self, self->size); } \
+ STC_INLINE void cx_memb(_max_load_factor)(Self* self, float ml) {self->max_load_factor = ml; } \
+ STC_INLINE bool cx_memb(_empty)(Self m) { return m.size == 0; } \
+ STC_INLINE size_t cx_memb(_size)(Self m) { return m.size; } \
+ STC_INLINE size_t cx_memb(_bucket_count)(Self map) { return map.bucket_count; } \
+ STC_INLINE size_t cx_memb(_capacity)(Self map) \
+ { return (size_t) (map.bucket_count * map.max_load_factor); } \
+ STC_INLINE void cx_memb(_swap)(Self *map1, Self *map2) {c_swap(Self, *map1, *map2); } \
+ STC_INLINE bool cx_memb(_contains)(const Self* self, i_KEYRAW rkey) \
+ { return self->size && self->_hashx[cx_memb(_bucket_)(self, &rkey).idx]; } \
\
STC_INLINE void \
- CX##_value_clone(CX##_value_t* _dst, CX##_value_t* _val) { \
- *KEY_REF_##C(_dst) = keyFromRaw(keyToRaw(KEY_REF_##C(_val))); \
- MAP_ONLY_##C( _dst->second = mappedFromRaw(mappedToRaw(&_val->second)); ) \
+ cx_memb(_value_clone)(cx_value_t* _dst, cx_value_t* _val) { \
+ *KEY_REF_##C(_dst) = i_KEYFROM(i_KEYTO(KEY_REF_##C(_val))); \
+ MAP_ONLY_##C( _dst->second = i_VALFROM(i_VALTO(&_val->second)); ) \
} \
\
- STC_INLINE CX##_rawvalue_t \
- CX##_value_toraw(CX##_value_t* val) { \
- return SET_ONLY_##C( keyToRaw(val) ) \
- MAP_ONLY_##C( c_make(CX##_rawvalue_t){keyToRaw(&val->first), mappedToRaw(&val->second)} ); \
+ STC_INLINE cx_rawvalue_t \
+ cx_memb(_value_toraw)(cx_value_t* val) { \
+ return SET_ONLY_##C( i_KEYTO(val) ) \
+ MAP_ONLY_##C( c_make(cx_rawvalue_t){i_KEYTO(&val->first), i_VALTO(&val->second)} ); \
} \
\
STC_INLINE void \
- CX##_value_del(CX##_value_t* _val) { \
- keyDel(KEY_REF_##C(_val)); \
- MAP_ONLY_##C( mappedDel(&_val->second); ) \
+ cx_memb(_value_del)(cx_value_t* _val) { \
+ i_KEYDEL(KEY_REF_##C(_val)); \
+ MAP_ONLY_##C( i_VALDEL(&_val->second); ) \
} \
\
- STC_INLINE CX##_result_t \
- CX##_emplace(CX* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \
- CX##_result_t _res = CX##_insert_entry_(self, rkey); \
+ STC_INLINE cx_result_t \
+ cx_memb(_emplace)(Self* self, i_KEYRAW rkey MAP_ONLY_##C(, i_VALRAW rmapped)) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, rkey); \
if (_res.inserted) { \
- *KEY_REF_##C(_res.ref) = keyFromRaw(rkey); \
- MAP_ONLY_##C(_res.ref->second = mappedFromRaw(rmapped);) \
+ *KEY_REF_##C(_res.ref) = i_KEYFROM(rkey); \
+ MAP_ONLY_##C(_res.ref->second = i_VALFROM(rmapped);) \
} \
return _res; \
} \
\
STC_INLINE void \
- CX##_emplace_items(CX* self, const CX##_rawvalue_t arr[], size_t n) { \
- for (size_t i=0; i<n; ++i) SET_ONLY_##C( CX##_emplace(self, arr[i]); ) \
- MAP_ONLY_##C( CX##_emplace(self, arr[i].first, arr[i].second); ) \
+ cx_memb(_emplace_items)(Self* self, const cx_rawvalue_t arr[], size_t n) { \
+ for (size_t i=0; i<n; ++i) SET_ONLY_##C( cx_memb(_emplace)(self, arr[i]); ) \
+ MAP_ONLY_##C( cx_memb(_emplace)(self, arr[i].first, arr[i].second); ) \
} \
\
- STC_INLINE CX##_result_t \
- CX##_insert(CX* self, Key _key MAP_ONLY_##C(, Mapped _mapped)) { \
- CX##_result_t _res = CX##_insert_entry_(self, keyToRaw(&_key)); \
+ STC_INLINE cx_result_t \
+ cx_memb(_insert)(Self* self, i_KEY _key MAP_ONLY_##C(, i_VAL _mapped)) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, i_KEYTO(&_key)); \
if (_res.inserted) {*KEY_REF_##C(_res.ref) = _key; MAP_ONLY_##C( _res.ref->second = _mapped; )} \
- else {keyDel(&_key); MAP_ONLY_##C( mappedDel(&_mapped); )} \
+ else {i_KEYDEL(&_key); MAP_ONLY_##C( i_VALDEL(&_mapped); )} \
return _res; \
} \
\
MAP_ONLY_##C( \
- STC_INLINE CX##_result_t \
- CX##_insert_or_assign(CX* self, Key _key, Mapped _mapped) { \
- CX##_result_t _res = CX##_insert_entry_(self, keyToRaw(&_key)); \
+ STC_INLINE cx_result_t \
+ cx_memb(_insert_or_assign)(Self* self, i_KEY _key, i_VAL _mapped) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, i_KEYTO(&_key)); \
if (_res.inserted) _res.ref->first = _key; \
- else {keyDel(&_key); mappedDel(&_res.ref->second);} \
+ else {i_KEYDEL(&_key); i_VALDEL(&_res.ref->second); } \
_res.ref->second = _mapped; return _res; \
} \
\
- STC_INLINE CX##_result_t \
- CX##_put(CX* self, Key k, Mapped m) { /* shorter, like operator[] */ \
- return CX##_insert_or_assign(self, k, m); \
+ STC_INLINE cx_result_t \
+ cx_memb(_put)(Self* self, i_KEY k, i_VAL m) { /* shorter, like operator[] */ \
+ return cx_memb(_insert_or_assign)(self, k, m); \
} \
\
- STC_INLINE CX##_result_t \
- CX##_emplace_or_assign(CX* self, RawKey rkey, RawMapped rmapped) { \
- CX##_result_t _res = CX##_insert_entry_(self, rkey); \
- if (_res.inserted) _res.ref->first = keyFromRaw(rkey); \
- else mappedDel(&_res.ref->second); \
- _res.ref->second = mappedFromRaw(rmapped); return _res; \
+ STC_INLINE cx_result_t \
+ cx_memb(_emplace_or_assign)(Self* self, i_KEYRAW rkey, i_VALRAW rmapped) { \
+ cx_result_t _res = cx_memb(_insert_entry_)(self, rkey); \
+ if (_res.inserted) _res.ref->first = i_KEYFROM(rkey); \
+ else i_VALDEL(&_res.ref->second); \
+ _res.ref->second = i_VALFROM(rmapped); return _res; \
} \
\
- STC_INLINE CX##_mapped_t* \
- CX##_at(const CX* self, RawKey rkey) { \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
+ STC_INLINE cx_mapped_t* \
+ cx_memb(_at)(const Self* self, i_KEYRAW rkey) { \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
return &self->table[b.idx].second; \
}) \
\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawKey rkey) { \
- CX##_iter_t it = {NULL}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_find)(const Self* self, i_KEYRAW rkey) { \
+ cx_iter_t it = {NULL}; \
if (self->size == 0) return it; \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
if (*(it._hx = self->_hashx+b.idx)) it.ref = self->table+b.idx; \
return it; \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_get(const CX* self, RawKey rkey) \
- {return CX##_find(self, rkey).ref;} \
+ STC_INLINE cx_value_t* \
+ cx_memb(_get)(const Self* self, i_KEYRAW rkey) \
+ { return cx_memb(_find)(self, rkey).ref; } \
\
- STC_INLINE CX##_iter_t \
- CX##_begin(const CX* self) { \
- CX##_iter_t it = {self->table, self->_hashx}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_begin)(const Self* self) { \
+ cx_iter_t it = {self->table, self->_hashx}; \
if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; \
return it; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_end(const CX* self) \
- {return c_make(CX##_iter_t){self->table + self->bucket_count};} \
+ STC_INLINE cx_iter_t \
+ cx_memb(_end)(const Self* self) \
+ { return c_make(cx_iter_t){self->table + self->bucket_count}; } \
\
STC_INLINE void \
- CX##_next(CX##_iter_t* it) \
- {while ((++it->ref, *++it->_hx == 0)) ;} \
+ cx_memb(_next)(cx_iter_t* it) \
+ {while ((++it->ref, *++it->_hx == 0)) ; } \
\
STC_INLINE size_t \
- CX##_erase(CX* self, RawKey rkey) { \
+ cx_memb(_erase)(Self* self, i_KEYRAW rkey) { \
if (self->size == 0) return 0; \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
- return self->_hashx[b.idx] ? CX##_erase_entry(self, self->table + b.idx), 1 : 0; \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
+ return self->_hashx[b.idx] ? cx_memb(_erase_entry)(self, self->table + b.idx), 1 : 0; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_erase_at(CX* self, CX##_iter_t it) { \
- CX##_erase_entry(self, it.ref); \
- if (*it._hx == 0) CX##_next(&it); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_erase_at)(Self* self, cx_iter_t it) { \
+ cx_memb(_erase_entry)(self, it.ref); \
+ if (*it._hx == 0) cx_memb(_next)(&it); \
return it; \
} \
\
- _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey) \
+ _c_implement_chash(Self, C, i_KEY, i_VAL, i_EQU, i_HASH, \
+ i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW, \
+ i_KEYDEL, i_KEYFROM, i_KEYTO, i_KEYRAW) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -329,63 +223,63 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) #ifdef c_umul128
STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \
- {uint64_t l, h; c_umul128(x, n, &l, &h); return h;}
+ {uint64_t l, h; c_umul128(x, n, &l, &h); return h; }
#endif
#define fastrange_uint32_t(x, n) ((size_t) (((uint32_t)(x)*(uint64_t)(n)) >> 32))
#define chash_index_(h, entryPtr) ((entryPtr) - (h).table)
-#define _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey) \
- STC_DEF CX \
- CX##_with_capacity(size_t cap) { \
- CX h = _cmap_inits; \
- CX##_reserve(&h, cap); \
+#define _c_implement_chash(Self, C, i_KEY, i_VAL, i_EQU, i_HASH, \
+ i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW, \
+ i_KEYDEL, i_KEYFROM, i_KEYTO, i_KEYRAW) \
+ STC_DEF Self \
+ cx_memb(_with_capacity)(size_t cap) { \
+ Self h = _cmap_inits; \
+ cx_memb(_reserve)(&h, cap); \
return h; \
} \
\
- STC_INLINE void CX##_wipe_(CX* self) { \
+ STC_INLINE void cx_memb(_wipe_)(Self* self) { \
if (self->size == 0) return; \
- CX##_value_t* e = self->table, *end = e + self->bucket_count; \
+ cx_value_t* e = self->table, *end = e + self->bucket_count; \
uint8_t *hx = self->_hashx; \
- for (; e != end; ++e) if (*hx++) CX##_value_del(e); \
+ for (; e != end; ++e) if (*hx++) cx_memb(_value_del)(e); \
} \
\
- STC_DEF void CX##_del(CX* self) { \
- CX##_wipe_(self); \
+ STC_DEF void cx_memb(_del)(Self* self) { \
+ cx_memb(_wipe_)(self); \
c_free(self->_hashx); \
c_free((void *) self->table); \
} \
\
- STC_DEF void CX##_clear(CX* self) { \
- CX##_wipe_(self); \
+ STC_DEF void cx_memb(_clear)(Self* self) { \
+ cx_memb(_wipe_)(self); \
self->size = 0; \
memset(self->_hashx, 0, self->bucket_count); \
} \
\
STC_DEF chash_bucket_t \
- CX##_bucket_(const CX* self, const CX##_rawkey_t* rkeyptr) { \
- const uint64_t _hash = keyHashRaw(rkeyptr, sizeof *rkeyptr); \
+ cx_memb(_bucket_)(const Self* self, const cx_rawkey_t* rkeyptr) { \
+ const uint64_t _hash = i_HASH(rkeyptr, sizeof *rkeyptr); \
uint_fast8_t _hx; size_t _cap = self->bucket_count; \
chash_bucket_t b = {c_SELECT(fastrange,CMAP_SIZE_T)(_hash, _cap), (uint_fast8_t)(_hash | 0x80)}; \
const uint8_t* _hashx = self->_hashx; \
while ((_hx = _hashx[b.idx])) { \
if (_hx == b.hx) { \
- CX##_rawkey_t _raw = keyToRaw(KEY_REF_##C(self->table + b.idx)); \
- if (keyEqualsRaw(&_raw, rkeyptr)) break; \
+ cx_rawkey_t _raw = i_KEYTO(KEY_REF_##C(self->table + b.idx)); \
+ if (i_EQU(&_raw, rkeyptr)) break; \
} \
if (++b.idx == _cap) b.idx = 0; \
} \
return b; \
} \
\
- STC_DEF CX##_result_t \
- CX##_insert_entry_(CX* self, RawKey rkey) { \
- if (self->size + 1 >= (CX##_size_t) (self->bucket_count * self->max_load_factor)) \
- CX##_reserve(self, 8 + (self->size*13ull >> 3)); \
- chash_bucket_t b = CX##_bucket_(self, &rkey); \
- CX##_result_t res = {&self->table[b.idx], !self->_hashx[b.idx]}; \
+ STC_DEF cx_result_t \
+ cx_memb(_insert_entry_)(Self* self, i_KEYRAW rkey) { \
+ if (self->size + 1 >= (cx_memb(_size_t)) (self->bucket_count * self->max_load_factor)) \
+ cx_memb(_reserve)(self, 8 + (self->size*13ull >> 3)); \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &rkey); \
+ cx_result_t res = {&self->table[b.idx], !self->_hashx[b.idx]}; \
if (res.inserted) { \
self->_hashx[b.idx] = b.hx; \
++self->size; \
@@ -393,39 +287,39 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ return res; \
} \
\
- STC_DEF CX \
- CX##_clone(CX m) { \
- CX clone = { \
- c_new_n(CX##_value_t, m.bucket_count), \
+ STC_DEF Self \
+ cx_memb(_clone)(Self m) { \
+ Self clone = { \
+ c_new_n(cx_value_t, m.bucket_count), \
(uint8_t *) memcpy(c_malloc(m.bucket_count + 1), m._hashx, m.bucket_count + 1), \
m.size, m.bucket_count, \
m.max_load_factor \
}; \
- CX##_value_t *e = m.table, *end = e + m.bucket_count, *dst = clone.table; \
+ cx_value_t *e = m.table, *end = e + m.bucket_count, *dst = clone.table; \
for (uint8_t *hx = m._hashx; e != end; ++hx, ++e, ++dst) \
- if (*hx) CX##_value_clone(dst, e); \
+ if (*hx) cx_memb(_value_clone)(dst, e); \
return clone; \
} \
\
STC_DEF void \
- CX##_reserve(CX* self, size_t _newcap) { \
+ cx_memb(_reserve)(Self* self, size_t _newcap) { \
if (_newcap < self->size) return; \
size_t _oldcap = self->bucket_count; \
_newcap = (size_t) (2 + _newcap / self->max_load_factor) | 1; \
- CX _tmp = { \
- c_new_n(CX##_value_t, _newcap), \
+ Self _tmp = { \
+ c_new_n(cx_value_t, _newcap), \
(uint8_t *) c_calloc(_newcap + 1, sizeof(uint8_t)), \
- self->size, (CX##_size_t) _newcap, \
+ self->size, (cx_memb(_size_t)) _newcap, \
self->max_load_factor \
}; \
/* Rehash: */ \
- _tmp._hashx[_newcap] = 0xff; c_swap(CX, *self, _tmp); \
- CX##_value_t* e = _tmp.table, *_slot = self->table; \
+ _tmp._hashx[_newcap] = 0xff; c_swap(Self, *self, _tmp); \
+ cx_value_t* e = _tmp.table, *_slot = self->table; \
uint8_t* _hashx = self->_hashx; \
for (size_t i = 0; i < _oldcap; ++i, ++e) \
if (_tmp._hashx[i]) { \
- CX##_rawkey_t _raw = keyToRaw(KEY_REF_##C(e)); \
- chash_bucket_t b = CX##_bucket_(self, &_raw); \
+ cx_rawkey_t _raw = i_KEYTO(KEY_REF_##C(e)); \
+ chash_bucket_t b = cx_memb(_bucket_)(self, &_raw); \
memcpy((void *) &_slot[b.idx], e, sizeof *e); \
_hashx[b.idx] = (uint8_t) b.hx; \
} \
@@ -434,17 +328,17 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ } \
\
STC_DEF void \
- CX##_erase_entry(CX* self, CX##_value_t* _val) { \
+ cx_memb(_erase_entry)(Self* self, cx_value_t* _val) { \
size_t i = chash_index_(*self, _val), j = i, k, _cap = self->bucket_count; \
- CX##_value_t* _slot = self->table; \
+ cx_value_t* _slot = self->table; \
uint8_t* _hashx = self->_hashx; \
- CX##_value_del(&_slot[i]); \
+ cx_memb(_value_del)(&_slot[i]); \
for (;;) { /* delete without leaving tombstone */ \
if (++j == _cap) j = 0; \
if (! _hashx[j]) \
break; \
- CX##_rawkey_t _raw = keyToRaw(KEY_REF_##C(_slot+j)); \
- k = c_SELECT(fastrange,CMAP_SIZE_T)(keyHashRaw(&_raw, sizeof _raw), _cap); \
+ cx_rawkey_t _raw = i_KEYTO(KEY_REF_##C(_slot+j)); \
+ k = c_SELECT(fastrange,CMAP_SIZE_T)(i_HASH(&_raw, sizeof _raw), _cap); \
if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ \
memcpy((void *) &_slot[i], &_slot[j], sizeof *_slot), _hashx[i] = _hashx[j], i = j; \
} \
@@ -457,7 +351,7 @@ STC_DEF uint64_t c_default_hash(const void *key, size_t len) { const uint64_t m = 0xb5ad4eceda1ce2a9;
uint64_t k, h = m + len;
const uint8_t *p = (const uint8_t *)key, *end = p + (len & ~7ull);
- for (; p != end; p += 8) {memcpy(&k, p, 8); h ^= m*k;}
+ for (; p != end; p += 8) {memcpy(&k, p, 8); h ^= m*k; }
switch (len & 7) {
case 7: h ^= (uint64_t) p[6] << 48;
case 6: h ^= (uint64_t) p[5] << 40;
@@ -470,10 +364,5 @@ STC_DEF uint64_t c_default_hash(const void *key, size_t len) { return h ^ (h >> 15);
}
-#else
-#define _c_implement_chash(CX, C, Key, Mapped, keyEqualsRaw, keyHashRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey)
#endif
-
#endif
diff --git a/include/stc/cpque.h b/include/stc/cpque.h index c6e0ed61..1958628c 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -55,36 +55,36 @@ #define using_cpque_2(X, ctype) \
_c_using_cpque(cpque_##X, ctype, ctype##_value_compare)
-#define using_cpque_3(X, ctype, valueCompare) \
- _c_using_cpque(cpque_##X, ctype, valueCompare)
+#define using_cpque_3(X, ctype, i_CMP) \
+ _c_using_cpque(cpque_##X, ctype, i_CMP)
-#define _c_using_cpque(CX, ctype, valueCompare) \
- typedef ctype CX; \
- typedef ctype##_value_t CX##_value_t; \
- typedef ctype##_rawvalue_t CX##_rawvalue_t; \
+#define _c_using_cpque(Self, ctype, i_CMP) \
+ typedef ctype Self; \
+ typedef ctype##_value_t cx_value_t; \
+ typedef ctype##_rawvalue_t cx_rawvalue_t; \
\
- 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 Self cx_memb(_init)(void) { return ctype##_init(); } \
+ STC_INLINE Self cx_memb(_clone)(Self pq) { return ctype##_clone(pq); } \
+ STC_INLINE cx_value_t cx_memb(_value_clone)(cx_value_t val) \
+ { return ctype##_value_clone(val); } \
+ STC_INLINE void cx_memb(_clear)(Self* self) {ctype##_clear(self); } \
+ STC_INLINE void cx_memb(_del)(Self* self) {ctype##_del(self); } \
\
- STC_INLINE size_t CX##_size(CX pq) {return ctype##_size(pq);} \
- STC_INLINE bool CX##_empty(CX pq) {return ctype##_empty(pq);} \
+ STC_INLINE size_t cx_memb(_size)(Self pq) { return ctype##_size(pq); } \
+ STC_INLINE bool cx_memb(_empty)(Self pq) { return ctype##_empty(pq); } \
\
- STC_API void CX##_make_heap(CX* self); \
- STC_API void CX##_erase_at(CX* self, size_t idx); \
+ STC_API void cx_memb(_make_heap)(Self* self); \
+ STC_API void cx_memb(_erase_at)(Self* self, size_t idx); \
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);} \
+ const cx_value_t* cx_memb(_top)(const Self* self) { return &self->data[0]; } \
+ STC_INLINE void cx_memb(_pop)(Self* self) {cx_memb(_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_items(CX *self, const CX##_rawvalue_t arr[], size_t n); \
+ STC_API void cx_memb(_push)(Self* self, cx_value_t value); \
+ STC_INLINE void cx_memb(_emplace)(Self* self, cx_rawvalue_t raw) \
+ {cx_memb(_push)(self, ctype##_value_fromraw(raw)); } \
+ STC_API void cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n); \
\
- _c_implement_cpque(CX, ctype, valueCompare) \
+ _c_implement_cpque(Self, ctype, i_CMP) \
struct stc_trailing_semicolon
@@ -92,15 +92,15 @@ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define _c_implement_cpque(CX, ctype, valueCompare) \
+#define _c_implement_cpque(Self, ctype, i_CMP) \
\
STC_INLINE void \
- CX##_sift_down_(CX##_value_t* arr, size_t i, size_t n) { \
+ cx_memb(_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) { \
- CX##_value_t tmp = arr[r]; arr[r] = arr[c]; arr[r = c] = tmp; \
+ c += (c < n && i_CMP(&arr[c], &arr[c + 1]) < 0); \
+ if (i_CMP(&arr[r], &arr[c]) < 0) { \
+ cx_value_t tmp = arr[r]; arr[r] = arr[c]; arr[r = c] = tmp; \
} else \
return; \
c <<= 1; \
@@ -108,39 +108,39 @@ } \
\
STC_API void \
- CX##_make_heap(CX* self) { \
- size_t n = CX##_size(*self); \
- CX##_value_t *arr = self->data - 1; \
+ cx_memb(_make_heap)(Self* self) { \
+ size_t n = cx_memb(_size)(*self); \
+ cx_value_t *arr = self->data - 1; \
for (size_t k = n >> 1; k != 0; --k) \
- CX##_sift_down_(arr, k, n); \
+ cx_memb(_sift_down_)(arr, k, n); \
} \
\
STC_API void \
- CX##_erase_at(CX* self, size_t idx) { \
- size_t n = CX##_size(*self) - 1; \
+ cx_memb(_erase_at)(Self* self, size_t idx) { \
+ size_t n = cx_memb(_size)(*self) - 1; \
self->data[idx] = self->data[n]; \
ctype##_pop_back(self); \
- CX##_sift_down_(self->data - 1, idx + 1, n); \
+ cx_memb(_sift_down_)(self->data - 1, idx + 1, n); \
} \
\
STC_API void \
- CX##_push(CX* self, CX##_value_t value) { \
+ cx_memb(_push)(Self* self, cx_value_t value) { \
ctype##_push_back(self, value); /* sift-up the value */ \
- 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) \
+ size_t n = cx_memb(_size)(*self), c = n; \
+ cx_value_t *arr = self->data - 1; \
+ for (; c > 1 && i_CMP(&arr[c >> 1], &value) < 0; c >>= 1) \
arr[c] = arr[c >> 1]; \
if (c != n) arr[c] = value; \
} \
\
STC_API void \
- CX##_emplace_items(CX *self, const CX##_rawvalue_t arr[], size_t n) { \
+ cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n) { \
for (size_t i = 0; i < n; ++i) \
- CX##_push(self, ctype##_value_fromraw(arr[i])); \
+ cx_memb(_push)(self, ctype##_value_fromraw(arr[i])); \
} \
#else
-#define _c_implement_cpque(CX, ctype, valueCompare)
+#define _c_implement_cpque(Self, ctype, i_CMP)
#endif
#endif
diff --git a/include/stc/cqueue.h b/include/stc/cqueue.h index b89291c8..596f50a9 100644 --- a/include/stc/cqueue.h +++ b/include/stc/cqueue.h @@ -59,35 +59,35 @@ #define using_cqueue(X, ctype) \
_c_using_cqueue(cqueue_##X, ctype)
-#define _c_using_cqueue(CX, ctype) \
- typedef struct { ctype rep; size_t size; } CX; \
- typedef ctype##_value_t CX##_value_t; \
- typedef ctype##_rawvalue_t CX##_rawvalue_t; \
- typedef ctype##_iter_t CX##_iter_t; \
+#define _c_using_cqueue(Self, ctype) \
+ typedef struct { ctype rep; size_t size; } Self; \
+ 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 c_make(CX){ctype##_init(), 0};} \
- STC_INLINE CX CX##_clone(CX q) {return c_make(CX){ctype##_clone(q.rep), q.size};} \
- 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->rep); self->size = 0;} \
- STC_INLINE void CX##_del(CX* self) {ctype##_del(&self->rep);} \
+ STC_INLINE Self cx_memb(_init)(void) { return c_make(Self){ctype##_init(), 0}; } \
+ STC_INLINE Self cx_memb(_clone)(Self q) { return c_make(Self){ctype##_clone(q.rep), q.size}; } \
+ STC_INLINE cx_value_t cx_memb(_value_clone)(cx_value_t val) \
+ { return ctype##_value_clone(val); } \
+ STC_INLINE void cx_memb(_clear)(Self* self) {ctype##_clear(&self->rep); self->size = 0; } \
+ STC_INLINE void cx_memb(_del)(Self* self) {ctype##_del(&self->rep); } \
\
- STC_INLINE size_t CX##_size(CX q) {return q.size;} \
- STC_INLINE bool CX##_empty(CX q) {return q.size == 0;} \
- STC_INLINE CX##_value_t* CX##_front(const CX* self) {return ctype##_front(&self->rep);} \
- STC_INLINE CX##_value_t* CX##_back(const CX* self) {return ctype##_back(&self->rep);} \
+ STC_INLINE size_t cx_memb(_size)(Self q) { return q.size; } \
+ STC_INLINE bool cx_memb(_empty)(Self q) { return q.size == 0; } \
+ STC_INLINE cx_value_t* cx_memb(_front)(const Self* self) { return ctype##_front(&self->rep); } \
+ STC_INLINE cx_value_t* cx_memb(_back)(const Self* self) { return ctype##_back(&self->rep); } \
\
- STC_INLINE void CX##_pop(CX* self) {ctype##_pop_front(&self->rep); --self->size;} \
- STC_INLINE void CX##_push(CX* self, ctype##_value_t value) \
- {ctype##_push_back(&self->rep, value); ++self->size;} \
- STC_INLINE void CX##_emplace(CX* self, CX##_rawvalue_t raw) \
- {ctype##_emplace_back(&self->rep, raw); ++self->size;} \
- STC_INLINE void CX##_emplace_items(CX *self, const CX##_rawvalue_t arr[], size_t n) \
- {ctype##_emplace_items(&self->rep, arr, n); self->size += n;} \
+ STC_INLINE void cx_memb(_pop)(Self* self) {ctype##_pop_front(&self->rep); --self->size; } \
+ STC_INLINE void cx_memb(_push)(Self* self, ctype##_value_t value) \
+ {ctype##_push_back(&self->rep, value); ++self->size; } \
+ STC_INLINE void cx_memb(_emplace)(Self* self, cx_rawvalue_t raw) \
+ {ctype##_emplace_back(&self->rep, raw); ++self->size; } \
+ STC_INLINE void cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n) \
+ {ctype##_emplace_items(&self->rep, arr, n); self->size += n; } \
\
- STC_INLINE CX##_iter_t CX##_begin(const CX* self) {return ctype##_begin(&self->rep);} \
- STC_INLINE CX##_iter_t CX##_end(const CX* self) {return ctype##_end(&self->rep);} \
- STC_INLINE void CX##_next(CX##_iter_t* it) {ctype##_next(it);} \
+ STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self) { return ctype##_begin(&self->rep); } \
+ STC_INLINE cx_iter_t cx_memb(_end)(const Self* self) { return ctype##_end(&self->rep); } \
+ STC_INLINE void cx_memb(_next)(cx_iter_t* it) {ctype##_next(it); } \
struct stc_trailing_semicolon
#endif
diff --git a/include/stc/cset.h b/include/stc/cset.h index 6979311a..e1ea8497 100644 --- a/include/stc/cset.h +++ b/include/stc/cset.h @@ -41,30 +41,8 @@ int main(void) { }
*/
+#define i_CNT cmap
+#define KEY_REF_cset(vp) (vp)
#include "cmap.h"
-#define forward_cset(X, Key) _c_chash_types(cset_##X, cset_, Key, Key)
-
-#define using_cset(...) c_MACRO_OVERLOAD(using_cset, __VA_ARGS__)
-
-#define using_cset_2(X, Key) \
- using_cset_4(X, Key, c_default_equals, c_default_hash)
-#define using_cset_4(X, Key, keyEquals, keyHash) \
- using_cset_6(X, Key, keyEquals, keyHash, c_default_del, c_default_fromraw)
-#define using_cset_5(X, Key, keyEquals, keyHash, keyDel) \
- using_cset_6(X, Key, keyEquals, keyHash, keyDel, c_no_clone)
-#define using_cset_6(X, Key, keyEquals, keyHash, keyDel, keyClone) \
- using_cset_9(X, Key, keyEquals, keyHash, keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_cset_9(X, Key, keyEqualsRaw, keyHashRaw, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_chash(cset_##X, cset_, Key, Key, keyEqualsRaw, keyHashRaw, \
- @@, @@, @@, void, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define using_cset_str() \
- using_cset_9(str, cstr, c_rawstr_equals, c_rawstr_hash, cstr_del, \
- cstr_from, cstr_str, const char*, c_true)
-
-#define SET_ONLY_cset_(...) __VA_ARGS__
-#define MAP_ONLY_cset_(...)
-#define KEY_REF_cset_(vp) (vp)
-
#endif
diff --git a/include/stc/csmap.h b/include/stc/csmap.h index bf7fd6ab..4437757d 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -47,269 +47,165 @@ int main(void) { }
*/
#include "ccommon.h"
+#include "template.h"
#include <stdlib.h>
#include <string.h>
-#define forward_csmap(X, Key, Mapped) _c_aatree_types(csmap_##X, csmap_, Key, Mapped)
-
-
-#define using_csmap(...) c_MACRO_OVERLOAD(using_csmap, __VA_ARGS__)
-
-#define using_csmap_3(X, Key, Mapped) \
- using_csmap_4(X, Key, Mapped, c_default_compare)
-#define using_csmap_4(X, Key, Mapped, keyCompare) \
- using_csmap_6(X, Key, Mapped, keyCompare, c_default_del, c_default_fromraw)
-#define using_csmap_5(X, Key, Mapped, keyCompare, mappedDel) \
- using_csmap_6(X, Key, Mapped, keyCompare, mappedDel, c_no_clone)
-#define using_csmap_6(X, Key, Mapped, keyCompare, mappedDel, mappedClone) \
- using_csmap_9(X, Key, Mapped, keyCompare, mappedDel, mappedClone, c_default_toraw, Mapped, c_true)
-#define using_csmap_9(X, Key, Mapped, keyCompare, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- using_csmap_13(X, Key, Mapped, keyCompare, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- c_default_del, c_default_fromraw, c_default_toraw, Key, defTypes)
-#define using_csmap_13(X, Key, Mapped, keyCompareRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_aatree(csmap_##X, csmap_, Key, Mapped, keyCompareRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-
-#define using_csmap_keydef(...) c_MACRO_OVERLOAD(using_csmap_keydef, __VA_ARGS__)
-
-#define using_csmap_keydef_6(X, Key, Mapped, keyCompare, keyDel, keyClone) \
- using_csmap_keydef_9(X, Key, Mapped, keyCompare, \
- keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_csmap_keydef_9(X, Key, Mapped, keyCompareRaw, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_aatree(csmap_##X, csmap_, Key, Mapped, keyCompareRaw, \
- c_default_del, c_default_fromraw, c_default_toraw, Mapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define using_csmap_str() \
- _c_using_aatree(csmap_str, csmap_, cstr, cstr, c_rawstr_compare, \
- cstr_del, cstr_from, cstr_str, const char*, \
- cstr_del, cstr_from, cstr_str, const char*, c_true)
-
-
-#define using_csmap_strkey(...) c_MACRO_OVERLOAD(using_csmap_strkey, __VA_ARGS__)
-
-#define using_csmap_strkey_2(X, Mapped) \
- using_csmap_strkey_4(X, Mapped, c_default_del, c_default_fromraw)
-#define using_csmap_strkey_3(X, Mapped, mappedDel) \
- using_csmap_strkey_4(X, Mapped, mappedDel, c_no_clone)
-#define using_csmap_strkey_4(X, Mapped, mappedDel, mappedClone) \
- using_csmap_strkey_7(X, Mapped, mappedDel, mappedClone, c_default_toraw, Mapped, c_true)
-#define using_csmap_strkey_7(X, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- _c_using_aatree_strkey(X, csmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes)
-#define _c_using_aatree_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped, defTypes) \
- _c_using_aatree(C##X, C, cstr, Mapped, c_rawstr_compare, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- cstr_del, cstr_from, cstr_str, const char*, defTypes)
-
-
-#define using_csmap_strval(...) c_MACRO_OVERLOAD(using_csmap_strval, __VA_ARGS__)
-
-#define using_csmap_strval_2(X, Key) \
- using_csmap_strval_3(X, Key, c_default_compare)
-#define using_csmap_strval_3(X, Key, keyCompare) \
- using_csmap_strval_5(X, Key, keyCompare, c_default_del, c_default_fromraw)
-#define using_csmap_strval_4(X, Key, keyCompare, keyDel) \
- using_csmap_strval_5(X, Key, keyCompare, keyDel, c_no_clone)
-#define using_csmap_strval_5(X, Key, keyCompare, keyDel, keyClone) \
- using_csmap_strval_8(X, Key, keyCompare, keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_csmap_strval_8(X, Key, keyCompareRaw, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_aatree(csmap_##X, csmap_, Key, cstr, keyCompareRaw, \
- cstr_del, cstr_from, cstr_str, const char*, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define SET_ONLY_csmap_(...)
-#define MAP_ONLY_csmap_(...) __VA_ARGS__
#define KEY_REF_csmap_(vp) (&(vp)->first)
-#ifndef CSMAP_SIZE_T
-#define CSMAP_SIZE_T uint32_t
-#endif
struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; };
#define _csmap_rep(self) c_container_of((self)->nodes, struct csmap_rep, nodes)
-#define _c_aatree_types(CX, C, Key, Mapped) \
- typedef Key CX##_key_t; \
- typedef Mapped CX##_mapped_t; \
- typedef CSMAP_SIZE_T CX##_size_t; \
-\
- typedef SET_ONLY_##C( CX##_key_t ) \
- MAP_ONLY_##C( struct CX##_value_t ) \
- CX##_value_t; \
-\
- typedef struct { \
- CX##_value_t *ref; \
- bool inserted; \
- } CX##_result_t; \
-\
- typedef struct CX##_node_t CX##_node_t; \
-\
- typedef struct { \
- CX##_value_t *ref; \
- CX##_node_t *_d; \
- int _top; \
- CX##_size_t _tn, _st[36]; \
- } CX##_iter_t; \
-\
- typedef struct { \
- CX##_node_t *nodes; \
- } CX
+#if !defined cx_forwarded
+ _c_aatree_types(Self, C, i_KEY, i_VAL);
+#endif
-#define _c_using_aatree(CX, C, Key, Mapped, keyCompareRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- defTypes( _c_aatree_types(CX, C, Key, Mapped); ) \
-\
- MAP_ONLY_##C( struct CX##_value_t { \
- CX##_key_t first; \
- CX##_mapped_t second; \
+\
+ MAP_ONLY_##C( struct cx_value_t { \
+ cx_key_t first; \
+ cx_mapped_t second; \
}; ) \
\
- struct CX##_node_t { \
- CX##_size_t link[2]; \
+ struct cx_node_t { \
+ cx_memb(_size_t) link[2]; \
int8_t level; \
- CX##_value_t value; \
+ cx_value_t value; \
}; \
\
- typedef RawKey CX##_rawkey_t; \
- typedef RawMapped CX##_rawmapped_t; \
- typedef SET_ONLY_##C( RawKey ) \
- MAP_ONLY_##C( struct { RawKey first; \
- RawMapped second; } ) \
- CX##_rawvalue_t; \
-\
- STC_API CX CX##_init(void); \
- STC_API CX CX##_clone(CX tree); \
- STC_API void CX##_del(CX* self); \
- STC_API void CX##_reserve(CX* self, size_t cap); \
- STC_API CX##_value_t* CX##_find_it(const CX* self, RawKey rkey, CX##_iter_t* out); \
- STC_API CX##_iter_t CX##_lower_bound(const CX* self, RawKey rkey); \
- STC_API CX##_value_t* CX##_front(const CX* self); \
- STC_API CX##_value_t* CX##_back(const CX* self); \
- STC_API int CX##_erase(CX* self, RawKey rkey); \
- STC_API CX##_iter_t CX##_erase_at(CX* self, CX##_iter_t it); \
- STC_API CX##_iter_t CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2); \
- STC_API CX##_result_t CX##_insert_entry_(CX* self, RawKey rkey); \
- STC_API void CX##_next(CX##_iter_t* it); \
-\
- STC_INLINE bool CX##_empty(CX tree) {return _csmap_rep(&tree)->size == 0;} \
- STC_INLINE size_t CX##_size(CX tree) {return _csmap_rep(&tree)->size;} \
- STC_INLINE size_t CX##_capacity(CX tree) {return _csmap_rep(&tree)->cap;} \
- STC_INLINE void CX##_clear(CX* self) {CX##_del(self); *self = CX##_init();} \
- STC_INLINE void CX##_swap(CX* a, CX* b) {c_swap(CX, *a, *b);} \
- STC_INLINE bool CX##_contains(const CX* self, RawKey rkey) \
- {CX##_iter_t it; return CX##_find_it(self, rkey, &it) != NULL;} \
- STC_INLINE CX##_value_t* CX##_get(const CX* self, RawKey rkey) \
- {CX##_iter_t it; return CX##_find_it(self, rkey, &it);} \
-\
- STC_INLINE CX \
- CX##_with_capacity(size_t size) { \
- CX tree = CX##_init(); \
- CX##_reserve(&tree, size); \
+ typedef i_KEYRAW cx_rawkey_t; \
+ typedef i_VALRAW cx_memb(_rawmapped_t); \
+ typedef SET_ONLY_##C( i_KEYRAW ) \
+ MAP_ONLY_##C( struct { i_KEYRAW first; \
+ i_VALRAW second; } ) \
+ cx_rawvalue_t; \
+\
+ STC_API Self cx_memb(_init)(void); \
+ STC_API Self cx_memb(_clone)(Self tree); \
+ STC_API void cx_memb(_del)(Self* self); \
+ STC_API void cx_memb(_reserve)(Self* self, size_t cap); \
+ STC_API cx_value_t* cx_memb(_find_it)(const Self* self, i_KEYRAW rkey, cx_iter_t* out); \
+ STC_API cx_iter_t cx_memb(_lower_bound)(const Self* self, i_KEYRAW rkey); \
+ STC_API cx_value_t* cx_memb(_front)(const Self* self); \
+ STC_API cx_value_t* cx_memb(_back)(const Self* self); \
+ STC_API int cx_memb(_erase)(Self* self, i_KEYRAW rkey); \
+ STC_API cx_iter_t cx_memb(_erase_at)(Self* self, cx_iter_t it); \
+ STC_API cx_iter_t cx_memb(_erase_range)(Self* self, cx_iter_t it1, cx_iter_t it2); \
+ STC_API cx_result_t cx_memb(_insert_entry_)(Self* self, i_KEYRAW rkey); \
+ STC_API void cx_memb(_next)(cx_iter_t* it); \
+\
+ STC_INLINE bool cx_memb(_empty)(Self tree) { return _csmap_rep(&tree)->size == 0; } \
+ STC_INLINE size_t cx_memb(_size)(Self tree) { return _csmap_rep(&tree)->size; } \
+ STC_INLINE size_t cx_memb(_capacity)(Self tree) { return _csmap_rep(&tree)->cap; } \
+ STC_INLINE void cx_memb(_clear)(Self* self) {cx_memb(_del)(self); *self = cx_memb(_init)(); } \
+ STC_INLINE void cx_memb(_swap)(Self* a, Self* b) {c_swap(Self, *a, *b); } \
+ STC_INLINE bool cx_memb(_contains)(const Self* self, i_KEYRAW rkey) \
+ {cx_iter_t it; return cx_memb(_find_it)(self, rkey, &it) != NULL; } \
+ STC_INLINE cx_value_t* cx_memb(_get)(const Self* self, i_KEYRAW rkey) \
+ {cx_iter_t it; return cx_memb(_find_it)(self, rkey, &it); } \
+\
+ STC_INLINE Self \
+ cx_memb(_with_capacity)(size_t size) { \
+ Self tree = cx_memb(_init)(); \
+ cx_memb(_reserve)(&tree, size); \
return tree; \
} \
\
- STC_INLINE CX##_rawvalue_t \
- CX##_value_toraw(CX##_value_t* val) { \
- return SET_ONLY_##C( keyToRaw(val) ) \
- MAP_ONLY_##C( c_make(CX##_rawvalue_t){keyToRaw(&val->first), mappedToRaw(&val->second)} ); \
+ STC_INLINE cx_rawvalue_t \
+ cx_memb(_value_toraw)(cx_value_t* val) { \
+ return SET_ONLY_##C( i_KEYTO(val) ) \
+ MAP_ONLY_##C( c_make(cx_rawvalue_t){i_KEYTO(&val->first), i_VALTO(&val->second)} ); \
} \
STC_INLINE void \
- CX##_value_del(CX##_value_t* val) { \
- keyDel(KEY_REF_##C(val)); \
- MAP_ONLY_##C( mappedDel(&val->second); ) \
+ cx_memb(_value_del)(cx_value_t* val) { \
+ i_KEYDEL(KEY_REF_##C(val)); \
+ MAP_ONLY_##C( i_VALDEL(&val->second); ) \
} \
STC_INLINE void \
- CX##_value_clone(CX##_value_t* dst, CX##_value_t* val) { \
- *KEY_REF_##C(dst) = keyFromRaw(keyToRaw(KEY_REF_##C(val))); \
- MAP_ONLY_##C( dst->second = mappedFromRaw(mappedToRaw(&val->second)); ) \
+ cx_memb(_value_clone)(cx_value_t* dst, cx_value_t* val) { \
+ *KEY_REF_##C(dst) = i_KEYFROM(i_KEYTO(KEY_REF_##C(val))); \
+ MAP_ONLY_##C( dst->second = i_VALFROM(i_VALTO(&val->second)); ) \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawKey rkey) { \
- CX##_iter_t it; \
- CX##_find_it(self, rkey, &it); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_find)(const Self* self, i_KEYRAW rkey) { \
+ cx_iter_t it; \
+ cx_memb(_find_it)(self, rkey, &it); \
return it; \
} \
\
- STC_INLINE CX##_result_t \
- CX##_emplace(CX* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \
- CX##_result_t res = CX##_insert_entry_(self, rkey); \
+ STC_INLINE cx_result_t \
+ cx_memb(_emplace)(Self* self, i_KEYRAW rkey MAP_ONLY_##C(, i_VALRAW rmapped)) { \
+ cx_result_t res = cx_memb(_insert_entry_)(self, rkey); \
if (res.inserted) { \
- *KEY_REF_##C(res.ref) = keyFromRaw(rkey); \
- MAP_ONLY_##C(res.ref->second = mappedFromRaw(rmapped);) \
+ *KEY_REF_##C(res.ref) = i_KEYFROM(rkey); \
+ MAP_ONLY_##C(res.ref->second = i_VALFROM(rmapped);) \
} \
return res; \
} \
\
STC_INLINE void \
- CX##_emplace_items(CX* self, const CX##_rawvalue_t arr[], size_t n) { \
- for (size_t i=0; i<n; ++i) SET_ONLY_##C( CX##_emplace(self, arr[i]); ) \
- MAP_ONLY_##C( CX##_emplace(self, arr[i].first, arr[i].second); ) \
+ cx_memb(_emplace_items)(Self* self, const cx_rawvalue_t arr[], size_t n) { \
+ for (size_t i=0; i<n; ++i) SET_ONLY_##C( cx_memb(_emplace)(self, arr[i]); ) \
+ MAP_ONLY_##C( cx_memb(_emplace)(self, arr[i].first, arr[i].second); ) \
} \
\
- STC_INLINE CX##_result_t \
- CX##_insert(CX* self, Key key MAP_ONLY_##C(, Mapped mapped)) { \
- CX##_result_t res = CX##_insert_entry_(self, keyToRaw(&key)); \
+ STC_INLINE cx_result_t \
+ cx_memb(_insert)(Self* self, i_KEY key MAP_ONLY_##C(, i_VAL mapped)) { \
+ cx_result_t res = cx_memb(_insert_entry_)(self, i_KEYTO(&key)); \
if (res.inserted) {*KEY_REF_##C(res.ref) = key; MAP_ONLY_##C( res.ref->second = mapped; )} \
- else {keyDel(&key); MAP_ONLY_##C( mappedDel(&mapped); )} \
+ else {i_KEYDEL(&key); MAP_ONLY_##C( i_VALDEL(&mapped); )} \
return res; \
} \
\
MAP_ONLY_##C( \
- STC_INLINE CX##_result_t \
- CX##_insert_or_assign(CX* self, Key key, Mapped mapped) { \
- CX##_result_t res = CX##_insert_entry_(self, keyToRaw(&key)); \
+ STC_INLINE cx_result_t \
+ cx_memb(_insert_or_assign)(Self* self, i_KEY key, i_VAL mapped) { \
+ cx_result_t res = cx_memb(_insert_entry_)(self, i_KEYTO(&key)); \
if (res.inserted) res.ref->first = key; \
- else {keyDel(&key); mappedDel(&res.ref->second);} \
+ else {i_KEYDEL(&key); i_VALDEL(&res.ref->second); } \
res.ref->second = mapped; return res; \
} \
\
- STC_INLINE CX##_result_t \
- CX##_put(CX* self, Key key, Mapped mapped) { \
- return CX##_insert_or_assign(self, key, mapped); \
+ STC_INLINE cx_result_t \
+ cx_memb(_put)(Self* self, i_KEY key, i_VAL mapped) { \
+ return cx_memb(_insert_or_assign)(self, key, mapped); \
} \
\
- STC_INLINE CX##_result_t \
- CX##_emplace_or_assign(CX* self, RawKey rkey, RawMapped rmapped) { \
- CX##_result_t res = CX##_insert_entry_(self, rkey); \
- if (res.inserted) res.ref->first = keyFromRaw(rkey); \
- else mappedDel(&res.ref->second); \
- res.ref->second = mappedFromRaw(rmapped); return res; \
+ STC_INLINE cx_result_t \
+ cx_memb(_emplace_or_assign)(Self* self, i_KEYRAW rkey, i_VALRAW rmapped) { \
+ cx_result_t res = cx_memb(_insert_entry_)(self, rkey); \
+ if (res.inserted) res.ref->first = i_KEYFROM(rkey); \
+ else i_VALDEL(&res.ref->second); \
+ res.ref->second = i_VALFROM(rmapped); return res; \
} \
\
- STC_INLINE CX##_mapped_t* \
- CX##_at(const CX* self, RawKey rkey) { \
- CX##_iter_t it; \
- return &CX##_find_it(self, rkey, &it)->second; \
+ STC_INLINE cx_mapped_t* \
+ cx_memb(_at)(const Self* self, i_KEYRAW rkey) { \
+ cx_iter_t it; \
+ return &cx_memb(_find_it)(self, rkey, &it)->second; \
}) \
\
- STC_INLINE CX##_iter_t \
- CX##_begin(const CX* self) { \
- CX##_iter_t it; it._d = self->nodes, it._top = 0; \
- it._tn = (CX##_size_t) _csmap_rep(self)->root; \
- if (it._tn) CX##_next(&it); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_begin)(const Self* self) { \
+ cx_iter_t it; it._d = self->nodes, it._top = 0; \
+ it._tn = (cx_memb(_size_t)) _csmap_rep(self)->root; \
+ if (it._tn) cx_memb(_next)(&it); \
return it; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_end(const CX* self) {\
- return c_make(CX##_iter_t){.ref = NULL}; \
+ STC_INLINE cx_iter_t \
+ cx_memb(_end)(const Self* self) {\
+ return c_make(cx_iter_t){.ref = NULL}; \
} \
\
- STC_INLINE CX##_iter_t \
- CX##_fwd(CX##_iter_t it, size_t n) { \
- while (n-- && it.ref) CX##_next(&it); \
+ STC_INLINE cx_iter_t \
+ cx_memb(_fwd)(cx_iter_t it, size_t n) { \
+ while (n-- && it.ref) cx_memb(_next)(&it); \
return it; \
} \
\
- _c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey) \
+ _c_implement_aatree(Self, C, i_KEY, i_VAL, i_CMP, \
+ i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW, \
+ i_KEYDEL, i_KEYFROM, i_KEYTO, i_KEYRAW) \
struct stc_trailing_semicolon
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -317,68 +213,68 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0};
-#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 *) _csmap_sentinel.nodes}; \
+#define _c_implement_aatree(Self, C, i_KEY, i_VAL, i_CMP, \
+ i_VALDEL, i_VALFROM, i_VALTO, i_VALRAW, \
+ i_KEYDEL, i_KEYFROM, i_KEYTO, i_KEYRAW) \
+ STC_DEF Self \
+ cx_memb(_init)(void) { \
+ Self tree = {(cx_node_t *) _csmap_sentinel.nodes}; \
return tree; \
} \
\
- 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; \
+ STC_DEF cx_value_t* \
+ cx_memb(_front)(const Self* self) { \
+ cx_node_t *d = self->nodes; \
+ cx_memb(_size_t) tn = (cx_memb(_size_t)) _csmap_rep(self)->root; \
while (d[tn].link[0]) tn = d[tn].link[0]; \
return &d[tn].value; \
} \
\
- 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; \
+ STC_DEF cx_value_t* \
+ cx_memb(_back)(const Self* self) { \
+ cx_node_t *d = self->nodes; \
+ cx_memb(_size_t) tn = (cx_memb(_size_t)) _csmap_rep(self)->root; \
while (d[tn].link[1]) tn = d[tn].link[1]; \
return &d[tn].value; \
} \
\
STC_DEF void \
- CX##_reserve(CX* self, size_t cap) { \
+ cx_memb(_reserve)(Self* self, size_t cap) { \
struct csmap_rep* rep = _csmap_rep(self); \
- CX##_size_t oldcap = rep->cap; \
+ cx_memb(_size_t) oldcap = rep->cap; \
if (cap > oldcap) { \
rep = (struct csmap_rep*) c_realloc(oldcap ? rep : NULL, \
- sizeof(struct csmap_rep) + (cap + 1)*sizeof(CX##_node_t)); \
+ sizeof(struct csmap_rep) + (cap + 1)*sizeof(cx_node_t)); \
if (oldcap == 0) \
- memset(rep, 0, sizeof(struct csmap_rep) + sizeof(CX##_node_t)); \
+ memset(rep, 0, sizeof(struct csmap_rep) + sizeof(cx_node_t)); \
rep->cap = cap; \
- self->nodes = (CX##_node_t *) rep->nodes; \
+ self->nodes = (cx_node_t *) rep->nodes; \
} \
} \
\
- STC_DEF CX##_size_t \
- CX##_node_new_(CX* self, int level) { \
+ STC_DEF cx_memb(_size_t) \
+ cx_memb(_node_new_)(Self* 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) CX##_reserve(self, 4 + (tn*13 >> 3)); \
+ if ((tn = rep->head + 1) > rep->cap) cx_memb(_reserve)(self, 4 + (tn*13 >> 3)); \
++_csmap_rep(self)->head; /* do after reserve */ \
} \
- CX##_node_t* dn = &self->nodes[tn]; \
+ cx_node_t* dn = &self->nodes[tn]; \
dn->link[0] = dn->link[1] = 0; dn->level = level; \
- return (CX##_size_t) tn; \
+ return (cx_memb(_size_t)) tn; \
} \
\
- 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; \
+ STC_DEF cx_value_t* \
+ cx_memb(_find_it)(const Self* self, i_KEYRAW rkey, cx_iter_t* out) { \
+ cx_memb(_size_t) tn = _csmap_rep(self)->root; \
+ cx_node_t *d = out->_d = self->nodes; \
out->_top = 0; \
while (tn) { \
- int c; CX##_rawkey_t raw = keyToRaw(KEY_REF_##C(&d[tn].value)); \
- if ((c = keyCompareRaw(&raw, &rkey)) < 0) \
+ int c; cx_rawkey_t raw = i_KEYTO(KEY_REF_##C(&d[tn].value)); \
+ if ((c = i_CMP(&raw, &rkey)) < 0) \
tn = d[tn].link[1]; \
else if (c > 0) \
{ out->_st[out->_top++] = tn; tn = d[tn].link[0]; } \
@@ -388,12 +284,12 @@ static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0}; return (out->ref = NULL); \
} \
\
- STC_DEF CX##_iter_t \
- CX##_lower_bound(const CX* self, RawKey rkey) { \
- CX##_iter_t it; \
- CX##_find_it(self, rkey, &it); \
+ STC_DEF cx_iter_t \
+ cx_memb(_lower_bound)(const Self* self, i_KEYRAW rkey) { \
+ cx_iter_t it; \
+ cx_memb(_find_it)(self, rkey, &it); \
if (!it.ref && it._top) { \
- CX##_size_t tn = it._st[--it._top]; \
+ cx_memb(_size_t) tn = it._st[--it._top]; \
it._tn = it._d[tn].link[1]; \
it.ref = &it._d[tn].value; \
} \
@@ -401,8 +297,8 @@ static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0}; } \
\
STC_DEF void \
- CX##_next(CX##_iter_t *it) { \
- CX##_size_t tn = it->_tn; \
+ cx_memb(_next)(cx_iter_t *it) { \
+ cx_memb(_size_t) tn = it->_tn; \
if (it->_top || tn) { \
while (tn) { \
it->_st[it->_top++] = tn; \
@@ -415,20 +311,20 @@ static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0}; it->ref = NULL; \
} \
\
- static CX##_size_t \
- CX##_skew_(CX##_node_t *d, CX##_size_t tn) { \
+ static cx_memb(_size_t) \
+ cx_memb(_skew_)(cx_node_t *d, cx_memb(_size_t) tn) { \
if (tn && d[d[tn].link[0]].level == d[tn].level) { \
- CX##_size_t tmp = d[tn].link[0]; \
+ cx_memb(_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 CX##_size_t \
- CX##_split_(CX##_node_t *d, CX##_size_t tn) { \
+ static cx_memb(_size_t) \
+ cx_memb(_split_)(cx_node_t *d, cx_memb(_size_t) tn) { \
if (d[d[d[tn].link[1]].link[1]].level == d[tn].level) { \
- CX##_size_t tmp = d[tn].link[1]; \
+ cx_memb(_size_t) tmp = d[tn].link[1]; \
d[tn].link[1] = d[tmp].link[0]; \
d[tmp].link[0] = tn; \
tn = tmp; \
@@ -437,62 +333,62 @@ static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0}; return tn; \
} \
\
- STC_DEF 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], tx = tn; \
- CX##_node_t* d = self->nodes; \
+ STC_DEF cx_memb(_size_t) \
+ cx_memb(_insert_entry_i_)(Self* self, cx_memb(_size_t) tn, const cx_rawkey_t* rkey, cx_result_t* res) { \
+ cx_memb(_size_t) up[64], tx = tn; \
+ cx_node_t* d = self->nodes; \
int c, top = 0, dir = 0; \
while (tx) { \
up[top++] = tx; \
- RawKey raw = keyToRaw(KEY_REF_##C(&d[tx].value)); \
- if ((c = keyCompareRaw(&raw, rkey)) == 0) {res->ref = &d[tx].value; return tn;} \
+ i_KEYRAW raw = i_KEYTO(KEY_REF_##C(&d[tx].value)); \
+ if ((c = i_CMP(&raw, rkey)) == 0) {res->ref = &d[tx].value; return tn; } \
dir = (c < 0); \
tx = d[tx].link[dir]; \
} \
- tx = CX##_node_new_(self, 1); d = self->nodes; \
+ tx = cx_memb(_node_new_)(self, 1); d = self->nodes; \
res->ref = &d[tx].value, res->inserted = true; \
if (top == 0) return tx; \
d[up[top - 1]].link[dir] = tx; \
while (top--) { \
if (top) dir = (d[up[top - 1]].link[1] == up[top]); \
- up[top] = CX##_skew_(d, up[top]); \
- up[top] = CX##_split_(d, up[top]); \
+ up[top] = cx_memb(_skew_)(d, up[top]); \
+ up[top] = cx_memb(_split_)(d, up[top]); \
if (top) d[up[top - 1]].link[dir] = up[top]; \
} \
return up[0]; \
} \
\
- 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); \
+ STC_DEF cx_result_t \
+ cx_memb(_insert_entry_)(Self* self, i_KEYRAW rkey) { \
+ cx_result_t res = {NULL, false}; \
+ cx_memb(_size_t) tn = cx_memb(_insert_entry_i_)(self, (cx_memb(_size_t)) _csmap_rep(self)->root, &rkey, &res); \
_csmap_rep(self)->root = tn; \
_csmap_rep(self)->size += res.inserted; \
return res; \
} \
\
- STC_DEF CX##_size_t \
- CX##_erase_r_(CX##_node_t *d, CX##_size_t tn, const CX##_rawkey_t* rkey, int *erased) { \
+ STC_DEF cx_memb(_size_t) \
+ cx_memb(_erase_r_)(cx_node_t *d, cx_memb(_size_t) tn, const cx_rawkey_t* rkey, int *erased) { \
if (tn == 0) return 0; \
- RawKey raw = keyToRaw(KEY_REF_##C(&d[tn].value)); \
- CX##_size_t tx; int c = keyCompareRaw(&raw, rkey); \
+ i_KEYRAW raw = i_KEYTO(KEY_REF_##C(&d[tn].value)); \
+ cx_memb(_size_t) tx; int c = i_CMP(&raw, rkey); \
if (c != 0) \
- d[tn].link[c < 0] = CX##_erase_r_(d, d[tn].link[c < 0], rkey, erased); \
+ d[tn].link[c < 0] = cx_memb(_erase_r_)(d, d[tn].link[c < 0], rkey, erased); \
else { \
- if (!(*erased)++) CX##_value_del(&d[tn].value); \
+ if (!(*erased)++) cx_memb(_value_del)(&d[tn].value); \
if (d[tn].link[0] && d[tn].link[1]) { \
tx = d[tn].link[0]; \
while (d[tx].link[1]) \
tx = d[tx].link[1]; \
memcpy((void *) &d[tn].value, &d[tx].value, sizeof d[0].value); /* move */ \
- raw = keyToRaw(KEY_REF_##C(&d[tn].value)); \
- d[tn].link[0] = CX##_erase_r_(d, d[tn].link[0], &raw, erased); \
+ raw = i_KEYTO(KEY_REF_##C(&d[tn].value)); \
+ d[tn].link[0] = cx_memb(_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] = (CX##_size_t) rep->disp; \
+ d[tx].link[1] = (cx_memb(_size_t)) rep->disp; \
rep->disp = tx; \
} \
} \
@@ -500,84 +396,79 @@ static struct csmap_rep _csmap_sentinel = {0, 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 = 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]); \
+ tn = cx_memb(_skew_)(d, tn); \
+ tx = d[tn].link[1] = cx_memb(_skew_)(d, d[tn].link[1]); \
+ d[tx].link[1] = cx_memb(_skew_)(d, d[tx].link[1]); \
+ tn = cx_memb(_split_)(d, tn); \
+ d[tn].link[1] = cx_memb(_split_)(d, d[tn].link[1]); \
} \
return tn; \
} \
\
STC_DEF int \
- CX##_erase(CX* self, RawKey rkey) { \
+ cx_memb(_erase)(Self* self, i_KEYRAW rkey) { \
int erased = 0; \
- CX##_size_t root = CX##_erase_r_(self->nodes, (CX##_size_t) _csmap_rep(self)->root, &rkey, &erased); \
+ cx_memb(_size_t) root = cx_memb(_erase_r_)(self->nodes, (cx_memb(_size_t)) _csmap_rep(self)->root, &rkey, &erased); \
return erased ? (_csmap_rep(self)->root = root, --_csmap_rep(self)->size, 1) : 0; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_erase_at(CX* self, CX##_iter_t it) { \
- CX##_rawkey_t raw = keyToRaw(KEY_REF_##C(it.ref)), nxt; \
- CX##_next(&it); \
- if (it.ref) nxt = keyToRaw(KEY_REF_##C(it.ref)); \
- CX##_erase(self, raw); \
- if (it.ref) CX##_find_it(self, nxt, &it); \
+ STC_DEF cx_iter_t \
+ cx_memb(_erase_at)(Self* self, cx_iter_t it) { \
+ cx_rawkey_t raw = i_KEYTO(KEY_REF_##C(it.ref)), nxt; \
+ cx_memb(_next)(&it); \
+ if (it.ref) nxt = i_KEYTO(KEY_REF_##C(it.ref)); \
+ cx_memb(_erase)(self, raw); \
+ if (it.ref) cx_memb(_find_it)(self, nxt, &it); \
return it; \
} \
\
- STC_DEF CX##_iter_t \
- CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
- if (!it2.ref) { while (it1.ref) it1 = CX##_erase_at(self, it1); \
+ STC_DEF cx_iter_t \
+ cx_memb(_erase_range)(Self* self, cx_iter_t it1, cx_iter_t it2) { \
+ if (!it2.ref) { while (it1.ref) it1 = cx_memb(_erase_at)(self, it1); \
return it1; } \
- CX##_key_t k1 = *KEY_REF_##C(it1.ref), k2 = *KEY_REF_##C(it2.ref); \
- CX##_rawkey_t r1 = keyToRaw(&k1); \
+ cx_key_t k1 = *KEY_REF_##C(it1.ref), k2 = *KEY_REF_##C(it2.ref); \
+ cx_rawkey_t r1 = i_KEYTO(&k1); \
for (;;) { \
if (memcmp(&k1, &k2, sizeof k1) == 0) return it1; \
- CX##_next(&it1); k1 = *KEY_REF_##C(it1.ref); \
- CX##_erase(self, r1); \
- CX##_find_it(self, (r1 = keyToRaw(&k1)), &it1); \
+ cx_memb(_next)(&it1); k1 = *KEY_REF_##C(it1.ref); \
+ cx_memb(_erase)(self, r1); \
+ cx_memb(_find_it)(self, (r1 = i_KEYTO(&k1)), &it1); \
} \
} \
\
- static CX##_size_t \
- CX##_clone_r_(CX* self, CX##_node_t* src, CX##_size_t sn) { \
+ static cx_memb(_size_t) \
+ cx_memb(_clone_r_)(Self* self, cx_node_t* src, cx_memb(_size_t) sn) { \
if (sn == 0) return 0; \
- CX##_size_t tx, tn = CX##_node_new_(self, src[sn].level); \
- CX##_value_clone(&self->nodes[tn].value, &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; \
+ cx_memb(_size_t) tx, tn = cx_memb(_node_new_)(self, src[sn].level); \
+ cx_memb(_value_clone)(&self->nodes[tn].value, &src[sn].value); \
+ tx = cx_memb(_clone_r_)(self, src, src[sn].link[0]); self->nodes[tn].link[0] = tx; \
+ tx = cx_memb(_clone_r_)(self, src, src[sn].link[1]); self->nodes[tn].link[1] = tx; \
return tn; \
} \
- 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); \
+ STC_DEF Self \
+ cx_memb(_clone)(Self tree) { \
+ Self clone = cx_memb(_with_capacity)(_csmap_rep(&tree)->size); \
+ cx_memb(_size_t) root = cx_memb(_clone_r_)(&clone, tree.nodes, (cx_memb(_size_t)) _csmap_rep(&tree)->root); \
_csmap_rep(&clone)->root = root; \
_csmap_rep(&clone)->size = _csmap_rep(&tree)->size; \
return clone; \
} \
\
STC_DEF void \
- CX##_del_r_(CX##_node_t* d, CX##_size_t tn) { \
+ cx_memb(_del_r_)(cx_node_t* d, cx_memb(_size_t) tn) { \
if (tn) { \
- CX##_del_r_(d, d[tn].link[0]); \
- CX##_del_r_(d, d[tn].link[1]); \
- CX##_value_del(&d[tn].value); \
+ cx_memb(_del_r_)(d, d[tn].link[0]); \
+ cx_memb(_del_r_)(d, d[tn].link[1]); \
+ cx_memb(_value_del)(&d[tn].value); \
} \
} \
STC_DEF void \
- CX##_del(CX* self) { \
+ cx_memb(_del)(Self* self) { \
if (_csmap_rep(self)->root) { \
- CX##_del_r_(self->nodes, (CX##_size_t) _csmap_rep(self)->root); \
+ cx_memb(_del_r_)(self->nodes, (cx_memb(_size_t)) _csmap_rep(self)->root); \
c_free(_csmap_rep(self)); \
} \
}
-#else
-#define _c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, \
- mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
- keyDel, keyFromRaw, keyToRaw, RawKey)
#endif
-
#endif
diff --git a/include/stc/csptr.h b/include/stc/csptr.h index 4f183498..1729235e 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -68,112 +68,92 @@ typedef long atomic_count_t; }
#endif
-#define forward_csptr(X, Value) _csptr_types(csptr_##X, Value)
+#define forward_csptr(X, i_VAL) _csptr_types(csptr_##X, i_VAL)
#define csptr_null {NULL, NULL}
-#define using_csptr(...) c_MACRO_OVERLOAD(using_csptr, __VA_ARGS__)
-
-#define using_csptr_2(X, Value) \
- using_csptr_3(X, Value, c_default_compare)
-#define using_csptr_3(X, Value, valueCompare) \
- using_csptr_4(X, Value, valueCompare, c_default_del)
-#define using_csptr_4(X, Value, valueCompare, valueDel) \
- _c_using_csptr(csptr_##X, Value, valueCompare, valueDel, c_true)
-#define using_csptr_5(X, Value, valueCompare, valueDel, defTypes) \
- _c_using_csptr(csptr_##X, Value, valueCompare, valueDel, defTypes)
-
-#define _csptr_types(CX, Value) \
- typedef Value CX##_value_t; \
-\
- typedef struct { \
- CX##_value_t* get; \
- atomic_count_t* use_count; \
- } CX
-
-#define _c_using_csptr(CX, Value, valueCompare, valueDel, defTypes) \
- defTypes( _csptr_types(CX, Value); ) \
- struct CX##_rep_ {atomic_count_t cnt; CX##_value_t val;}; \
+ defTypes( _csptr_types(Self, i_VAL); ) \
+ struct cx_memb(_rep_) {atomic_count_t cnt; cx_value_t val; }; \
\
- STC_INLINE CX \
- CX##_init() { return c_make(CX){NULL, NULL}; } \
+ STC_INLINE Self \
+ cx_memb(_init)() { return c_make(Self){NULL, NULL}; } \
\
STC_INLINE atomic_count_t \
- CX##_use_count(CX ptr) { return ptr.use_count ? *ptr.use_count : 0; } \
+ cx_memb(_use_count)(Self ptr) { return ptr.use_count ? *ptr.use_count : 0; } \
\
- STC_INLINE CX \
- CX##_from(CX##_value_t* p) { \
- CX ptr = {p}; \
+ STC_INLINE Self \
+ cx_memb(_from)(cx_value_t* p) { \
+ Self ptr = {p}; \
if (p) *(ptr.use_count = c_new(atomic_count_t)) = 1; \
return ptr; \
} \
\
- STC_INLINE CX \
- CX##_make(CX##_value_t val) { \
- CX ptr; struct CX##_rep_ *rep = c_new(struct CX##_rep_); \
+ STC_INLINE Self \
+ cx_memb(_make)(cx_value_t val) { \
+ Self ptr; struct cx_memb(_rep_) *rep = c_new(struct cx_memb(_rep_)); \
*(ptr.use_count = &rep->cnt) = 1; \
*(ptr.get = &rep->val) = val; \
return ptr; \
} \
\
- STC_INLINE CX \
- CX##_clone(CX ptr) { \
+ STC_INLINE Self \
+ cx_memb(_clone)(Self ptr) { \
if (ptr.use_count) c_atomic_increment(ptr.use_count); \
return ptr; \
} \
\
- STC_INLINE CX \
- CX##_move(CX* self) { \
- CX ptr = *self; \
+ STC_INLINE Self \
+ cx_memb(_move)(Self* self) { \
+ Self ptr = *self; \
self->get = NULL, self->use_count = NULL; \
return ptr; \
} \
\
STC_INLINE void \
- CX##_del(CX* self) { \
+ cx_memb(_del)(Self* self) { \
if (self->use_count && c_atomic_decrement(self->use_count) == 0) { \
- valueDel(self->get); \
- if (self->get != &((struct CX##_rep_*)self->use_count)->val) c_free(self->get); \
+ i_VALDEL(self->get); \
+ if (self->get != &((struct cx_memb(_rep_)*)self->use_count)->val) c_free(self->get); \
c_free(self->use_count); \
} \
} \
\
STC_INLINE void \
- CX##_reset(CX* self) { \
- CX##_del(self); \
+ cx_memb(_reset)(Self* self) { \
+ cx_memb(_del)(self); \
self->use_count = NULL, self->get = NULL; \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_reset_with(CX* self, CX##_value_t* p) { \
- CX##_del(self); \
- *self = CX##_from(p); \
+ STC_INLINE cx_value_t* \
+ cx_memb(_reset_with)(Self* self, cx_value_t* p) { \
+ cx_memb(_del)(self); \
+ *self = cx_memb(_from)(p); \
return self->get; \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_reset_make(CX* self, CX##_value_t val) { \
- CX##_del(self); \
- *self = CX##_make(val); \
+ STC_INLINE cx_value_t* \
+ cx_memb(_reset_make)(Self* self, cx_value_t val) { \
+ cx_memb(_del)(self); \
+ *self = cx_memb(_make)(val); \
return self->get; \
} \
\
- STC_INLINE CX##_value_t* \
- CX##_copy(CX* self, CX ptr) { \
- CX##_del(self); \
+ STC_INLINE cx_value_t* \
+ cx_memb(_copy)(Self* self, Self ptr) { \
+ cx_memb(_del)(self); \
*self = ptr; \
if (self->use_count) c_atomic_increment(self->use_count); \
return self->get; \
} \
\
STC_INLINE int \
- CX##_compare(const CX* x, const CX* y) { \
- return valueCompare(x->get, y->get); \
+ cx_memb(_compare)(const Self* x, const Self* y) { \
+ return i_CMP(x->get, y->get); \
} \
\
STC_INLINE bool \
- CX##_equals(const CX* x, const CX* y) { \
- return valueCompare(x->get, y->get) == 0; \
+ cx_memb(_equals)(const Self* x, const Self* y) { \
+ return i_CMP(x->get, y->get) == 0; \
} \
struct stc_trailing_semicolon
diff --git a/include/stc/csset.h b/include/stc/csset.h index 747307e4..a5e1499c 100644 --- a/include/stc/csset.h +++ b/include/stc/csset.h @@ -43,30 +43,8 @@ int main(void) { }
*/
+#define i_CNT csset
+#define KEY_REF_csset(vp) (vp)
#include "csmap.h"
-#define forward_csset(X, Key) _c_aatree_types(csset_##X, csset_, Key, Key)
-
-#define using_csset(...) c_MACRO_OVERLOAD(using_csset, __VA_ARGS__)
-
-#define using_csset_2(X, Key) \
- using_csset_3(X, Key, c_default_compare)
-#define using_csset_3(X, Key, keyCompare) \
- using_csset_5(X, Key, keyCompare, c_default_del, c_default_fromraw)
-#define using_csset_4(X, Key, keyCompare, keyDel) \
- using_csset_5(X, Key, keyCompare, keyDel, c_no_clone)
-#define using_csset_5(X, Key, keyCompare, keyDel, keyClone) \
- using_csset_8(X, Key, keyCompare, keyDel, keyClone, c_default_toraw, Key, c_true)
-#define using_csset_8(X, Key, keyCompareRaw, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes) \
- _c_using_aatree(csset_##X, csset_, Key, Key, keyCompareRaw, \
- @@, @@, @@, void, keyDel, keyFromRaw, keyToRaw, RawKey, defTypes)
-
-#define using_csset_str() \
- using_csset_8(str, cstr, c_rawstr_compare, cstr_del, \
- cstr_from, cstr_str, const char*, c_true)
-
-#define SET_ONLY_csset_(...) __VA_ARGS__
-#define MAP_ONLY_csset_(...)
-#define KEY_REF_csset_(vp) (vp)
-
#endif
diff --git a/include/stc/cstack.h b/include/stc/cstack.h index d6b1b3ad..30fc4f71 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -47,36 +47,36 @@ #include "cvec.h"
#define using_cstack(X, ctype) \
- _c_using_cstack(cstack_##X, ctype)
+ _c_using_cstack(cstack_##X, ctype)
-#define _c_using_cstack(CX, ctype) \
- typedef ctype CX; \
- typedef ctype##_value_t CX##_value_t; \
- typedef ctype##_rawvalue_t CX##_rawvalue_t; \
- typedef ctype##_iter_t CX##_iter_t; \
+#define _c_using_cstack(Self, ctype) \
+ typedef ctype Self; \
+ 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 Self cx_memb(_init)(void) { return ctype##_init(); } \
+ STC_INLINE Self cx_memb(_clone)(Self st) { return ctype##_clone(st); } \
+ STC_INLINE cx_value_t cx_memb(_value_clone)(cx_value_t val) \
+ { return ctype##_value_clone(val); } \
+ STC_INLINE void cx_memb(_clear)(Self* self) {ctype##_clear(self); } \
+ STC_INLINE void cx_memb(_del)(Self* 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 size_t cx_memb(_size)(Self st) { return ctype##_size(st); } \
+ STC_INLINE bool cx_memb(_empty)(Self st) { return ctype##_empty(st); } \
+ STC_INLINE cx_value_t* cx_memb(_top)(const Self* self) { return ctype##_back(self); } \
\
- 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_items(CX *self, const CX##_rawvalue_t arr[], size_t n) \
- {ctype##_emplace_items(self, arr, n);} \
+ STC_INLINE void cx_memb(_pop)(Self* self) {ctype##_pop_back(self); } \
+ STC_INLINE void cx_memb(_push)(Self* self, ctype##_value_t value) \
+ {ctype##_push_back(self, value); } \
+ STC_INLINE void cx_memb(_emplace)(Self* self, cx_rawvalue_t raw) \
+ {ctype##_emplace_back(self, raw); } \
+ STC_INLINE void cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n) \
+ {ctype##_emplace_items(self, arr, n); } \
\
- 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);} \
+ STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self) { return ctype##_begin(self); } \
+ STC_INLINE cx_iter_t cx_memb(_end)(const Self* self) { return ctype##_end(self); } \
+ STC_INLINE void cx_memb(_next)(cx_iter_t* it) {ctype##_next(it); } \
struct stc_trailing_semicolon
#endif
diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 567c22ae..daa95170 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -20,332 +20,307 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef CVEC_H_INCLUDED
-#define CVEC_H_INCLUDED
+#ifndef CVEC_H_INCLUDED
#include "ccommon.h"
+#include "forward.h"
#include <stdlib.h>
#include <string.h>
-#define forward_cvec(X, Value) _c_cvec_types(cvec_##X, Value)
-
-#define using_cvec(...) c_MACRO_OVERLOAD(using_cvec, __VA_ARGS__)
-
-#define using_cvec_2(X, Value) \
- using_cvec_3(X, Value, c_default_compare)
-#define using_cvec_3(X, Value, valueCompare) \
- using_cvec_5(X, Value, valueCompare, c_default_del, c_default_fromraw)
-#define using_cvec_4(X, Value, valueCompare, valueDel) \
- 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_default_toraw, Value)
-#define using_cvec_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
- _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, c_true)
-#define using_cvec_8(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes) \
- _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes)
-
-#define using_cvec_str() \
- using_cvec_7(str, cstr, c_rawstr_compare, cstr_del, cstr_from, cstr_str, const char*)
-
-struct cvec_rep { size_t size, cap; void* data[]; };
-#define _cvec_rep(self) c_container_of((self)->data, struct cvec_rep, data)
-
-#define _c_cvec_types(CX, Value) \
- typedef Value CX##_value_t; \
- typedef struct { CX##_value_t *ref; } CX##_iter_t; \
- typedef struct { CX##_value_t *data; } CX
-
-#define _c_using_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue, defTypes) \
-\
- defTypes( _c_cvec_types(CX, Value); ) \
- typedef RawValue CX##_rawvalue_t; \
-\
- STC_API CX CX##_init(void); \
- STC_API CX CX##_clone(CX cx); \
- STC_API void CX##_del(CX* self); \
- STC_API void CX##_clear(CX* self); \
- STC_API void CX##_reserve(CX* self, size_t cap); \
- STC_API void CX##_resize(CX* self, size_t size, Value fill_val); \
- STC_API int CX##_value_compare(const CX##_value_t* x, const CX##_value_t* y); \
- STC_API CX##_iter_t CX##_find_in(CX##_iter_t it1, CX##_iter_t it2, RawValue raw); \
- STC_API CX##_iter_t CX##_bsearch_in(CX##_iter_t it1, CX##_iter_t it2, RawValue raw); \
- STC_API void CX##_push_back(CX* self, Value value); \
- STC_API CX##_iter_t CX##_erase_range_p(CX* self, CX##_value_t* p1, CX##_value_t* p2); \
- STC_API CX##_iter_t CX##_insert_range_p(CX* self, CX##_value_t* pos, \
- const CX##_value_t* p1, const CX##_value_t* p2, bool clone); \
- STC_API CX##_iter_t CX##_emplace_range_p(CX* self, CX##_value_t* pos, \
- const CX##_rawvalue_t* p1, const CX##_rawvalue_t* p2); \
-\
- STC_INLINE size_t CX##_size(CX cx) { return _cvec_rep(&cx)->size; } \
- STC_INLINE size_t CX##_capacity(CX cx) { return _cvec_rep(&cx)->cap; } \
- STC_INLINE bool CX##_empty(CX cx) {return !_cvec_rep(&cx)->size;} \
- STC_INLINE Value CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \
- STC_INLINE RawValue CX##_value_toraw(CX##_value_t* val) {return valueToRaw(val);} \
- STC_INLINE Value CX##_value_clone(CX##_value_t val) \
- {return valueFromRaw(valueToRaw(&val));} \
- STC_INLINE void CX##_swap(CX* a, CX* b) {c_swap(CX, *a, *b);} \
- 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 void CX##_emplace_back(CX* self, RawValue raw) \
- {CX##_push_back(self, valueFromRaw(raw));} \
- STC_INLINE void CX##_pop_back(CX* self) \
- {valueDel(&self->data[--_cvec_rep(self)->size]);} \
- STC_INLINE CX##_iter_t CX##_begin(const CX* self) \
- {return c_make(CX##_iter_t){self->data};} \
- STC_INLINE CX##_iter_t CX##_end(const CX* self) \
- {return c_make(CX##_iter_t){self->data + _cvec_rep(self)->size};} \
- STC_INLINE void CX##_next(CX##_iter_t* it) {++it->ref;} \
- STC_INLINE CX##_iter_t CX##_adv(CX##_iter_t it, intptr_t offs) {it.ref += offs; return it;} \
- STC_INLINE size_t CX##_idx(CX cx, CX##_iter_t it) {return it.ref - cx.data;} \
-\
- STC_INLINE CX \
- CX##_with_size(size_t size, Value null_val) { \
- CX cx = CX##_init(); \
- CX##_resize(&cx, size, null_val); \
- return cx; \
- } \
-\
- STC_INLINE CX \
- CX##_with_capacity(size_t size) { \
- CX cx = CX##_init(); \
- CX##_reserve(&cx, size); \
- return cx; \
- } \
-\
- STC_INLINE void \
- CX##_shrink_to_fit(CX *self) { \
- CX cx = CX##_clone(*self); \
- CX##_del(self); *self = cx; \
- } \
-\
- 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, false); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_insert_n(CX* self, size_t idx, const CX##_value_t arr[], size_t n) { \
- return CX##_insert_range_p(self, self->data + idx, arr, arr + n, false); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_insert_at(CX* self, CX##_iter_t it, Value value) { \
- return CX##_insert_range_p(self, it.ref, &value, &value + 1, false); \
- } \
-\
- STC_INLINE CX##_iter_t \
- CX##_emplace(CX* self, size_t idx, RawValue raw) { \
- return CX##_emplace_range_p(self, self->data + idx, &raw, &raw + 1); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_emplace_n(CX* self, size_t idx, const CX##_rawvalue_t arr[], size_t n) { \
- return CX##_emplace_range_p(self, self->data + idx, arr, arr + n); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_emplace_at(CX* self, CX##_iter_t it, RawValue raw) { \
- return CX##_emplace_range_p(self, it.ref, &raw, &raw + 1); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_emplace_range(CX* self, CX##_iter_t it, CX##_iter_t it1, CX##_iter_t it2) { \
- return CX##_insert_range_p(self, it.ref, it1.ref, it2.ref, true); \
- } \
- STC_INLINE void \
- CX##_emplace_items(CX *self, const CX##_rawvalue_t arr[], size_t n) { \
- CX##_emplace_range_p(self, self->data + _cvec_rep(self)->size, arr, arr + n); \
- } \
-\
- STC_INLINE CX##_iter_t \
- CX##_erase(CX* self, size_t idx) { \
- return CX##_erase_range_p(self, self->data + idx, self->data + idx + 1); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_erase_n(CX* self, size_t idx, size_t n) { \
- return CX##_erase_range_p(self, self->data + idx, self->data + idx + n); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_erase_at(CX* self, CX##_iter_t it) { \
- return CX##_erase_range_p(self, it.ref, it.ref + 1); \
- } \
- STC_INLINE CX##_iter_t \
- CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
- return CX##_erase_range_p(self, it1.ref, it2.ref); \
- } \
-\
- STC_INLINE CX##_value_t* \
- CX##_at(const CX* self, size_t idx) { \
- assert(idx < _cvec_rep(self)->size); \
- return self->data + idx; \
- } \
-\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawValue raw) { \
- return CX##_find_in(CX##_begin(self), CX##_end(self), raw); \
- } \
-\
- STC_INLINE CX##_value_t* \
- CX##_get(const CX* self, RawValue raw) { \
- CX##_iter_t end = CX##_end(self); \
- CX##_value_t* val = CX##_find_in(CX##_begin(self), end, raw).ref; \
- return val == end.ref ? NULL : val; \
- } \
-\
- STC_INLINE CX##_iter_t \
- CX##_bsearch(const CX* self, RawValue raw) { \
- return CX##_bsearch_in(CX##_begin(self), CX##_end(self), raw); \
- } \
- STC_INLINE void \
- 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), (int(*)(const void*, const void*)) _cmp_); \
- } \
- STC_INLINE void \
- CX##_sort(CX* self) { \
- CX##_sort_range(CX##_begin(self), CX##_end(self), CX##_value_compare); \
- } \
-\
- _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
- struct stc_trailing_semicolon
+struct cvec_Rep_ { size_t size, cap; void* data[]; };
+#define cvec_rep_(self) c_container_of((self)->data, struct cvec_Rep_, data)
+#endif // CVEC_H_INCLUDED
+
+#define i_CNT cvec
+#include "template.h"
+
+#if !defined i_FWD
+ cx_deftypes(_c_cvec_types, Self, i_VAL);
+#endif
+typedef i_VALRAW cx_rawvalue_t;
+
+STC_API Self cx_memb(_init)(void);
+STC_API Self cx_memb(_clone)(Self cx);
+STC_API void cx_memb(_del)(Self* self);
+STC_API void cx_memb(_clear)(Self* self);
+STC_API void cx_memb(_reserve)(Self* self, size_t cap);
+STC_API void cx_memb(_resize)(Self* self, size_t size, i_VAL fill_val);
+STC_API int cx_memb(_value_compare)(const cx_value_t* x, const cx_value_t* y);
+STC_API cx_iter_t cx_memb(_find_in)(cx_iter_t it1, cx_iter_t it2, i_VALRAW raw);
+STC_API cx_iter_t cx_memb(_bsearch_in)(cx_iter_t it1, cx_iter_t it2, i_VALRAW raw);
+STC_API void cx_memb(_push_back)(Self* self, i_VAL value);
+STC_API cx_iter_t cx_memb(_erase_range_p)(Self* self, cx_value_t* p1, cx_value_t* p2);
+STC_API cx_iter_t cx_memb(_insert_range_p)(Self* self, cx_value_t* pos,
+ const cx_value_t* p1, const cx_value_t* p2, bool clone);
+STC_API cx_iter_t cx_memb(_emplace_range_p)(Self* self, cx_value_t* pos,
+ const cx_rawvalue_t* p1, const cx_rawvalue_t* p2);
+
+STC_INLINE size_t cx_memb(_size)(Self cx) { return cvec_rep_(&cx)->size; }
+STC_INLINE size_t cx_memb(_capacity)(Self cx) { return cvec_rep_(&cx)->cap; }
+STC_INLINE bool cx_memb(_empty)(Self cx) { return !cvec_rep_(&cx)->size; }
+STC_INLINE i_VAL cx_memb(_value_fromraw)(i_VALRAW raw) { return i_VALFROM(raw); }
+STC_INLINE i_VALRAW cx_memb(_value_toraw)(cx_value_t* val) { return i_VALTO(val); }
+STC_INLINE i_VAL cx_memb(_value_clone)(cx_value_t val)
+ { return i_VALFROM(i_VALTO(&val)); }
+STC_INLINE void cx_memb(_swap)(Self* a, Self* b) {c_swap(Self, *a, *b); }
+STC_INLINE cx_value_t* cx_memb(_front)(const Self* self) { return self->data; }
+STC_INLINE cx_value_t* cx_memb(_back)(const Self* self)
+ { return self->data + cvec_rep_(self)->size - 1; }
+STC_INLINE void cx_memb(_emplace_back)(Self* self, i_VALRAW raw)
+ { cx_memb(_push_back)(self, i_VALFROM(raw)); }
+STC_INLINE void cx_memb(_pop_back)(Self* self)
+ { i_VALDEL(&self->data[--cvec_rep_(self)->size]); }
+STC_INLINE cx_iter_t cx_memb(_begin)(const Self* self)
+ { return c_make(cx_iter_t){self->data}; }
+STC_INLINE cx_iter_t cx_memb(_end)(const Self* self)
+ { return c_make(cx_iter_t){self->data + cvec_rep_(self)->size}; }
+STC_INLINE void cx_memb(_next)(cx_iter_t* it) {++it->ref; }
+STC_INLINE cx_iter_t cx_memb(_adv)(cx_iter_t it, intptr_t offs) {it.ref += offs; return it; }
+STC_INLINE size_t cx_memb(_idx)(Self cx, cx_iter_t it) { return it.ref - cx.data; }
+
+STC_INLINE Self
+cx_memb(_with_size)(size_t size, i_VAL null_val) {
+ Self cx = cx_memb(_init)();
+ cx_memb(_resize)(&cx, size, null_val);
+ return cx;
+}
+
+STC_INLINE Self
+cx_memb(_with_capacity)(size_t size) {
+ Self cx = cx_memb(_init)();
+ cx_memb(_reserve)(&cx, size);
+ return cx;
+}
+
+STC_INLINE void
+cx_memb(_shrink_to_fit)(Self *self) {
+ Self cx = cx_memb(_clone)(*self);
+ cx_memb(_del)(self); *self = cx;
+}
+
+STC_INLINE cx_iter_t
+cx_memb(_insert)(Self* self, size_t idx, i_VAL value) {
+ return cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1, false);
+}
+STC_INLINE cx_iter_t
+cx_memb(_insert_n)(Self* self, size_t idx, const cx_value_t arr[], size_t n) {
+ return cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n, false);
+}
+STC_INLINE cx_iter_t
+cx_memb(_insert_at)(Self* self, cx_iter_t it, i_VAL value) {
+ return cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1, false);
+}
+
+STC_INLINE cx_iter_t
+cx_memb(_emplace)(Self* self, size_t idx, i_VALRAW raw) {
+ return cx_memb(_emplace_range_p)(self, self->data + idx, &raw, &raw + 1);
+}
+STC_INLINE cx_iter_t
+cx_memb(_emplace_n)(Self* self, size_t idx, const cx_rawvalue_t arr[], size_t n) {
+ return cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
+}
+STC_INLINE cx_iter_t
+cx_memb(_emplace_at)(Self* self, cx_iter_t it, i_VALRAW raw) {
+ return cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
+}
+STC_INLINE cx_iter_t
+cx_memb(_emplace_range)(Self* self, cx_iter_t it, cx_iter_t it1, cx_iter_t it2) {
+ return cx_memb(_insert_range_p)(self, it.ref, it1.ref, it2.ref, true);
+}
+STC_INLINE void
+cx_memb(_emplace_items)(Self *self, const cx_rawvalue_t arr[], size_t n) {
+ cx_memb(_emplace_range_p)(self, self->data + cvec_rep_(self)->size, arr, arr + n);
+}
+
+STC_INLINE cx_iter_t
+cx_memb(_erase)(Self* self, size_t idx) {
+ return cx_memb(_erase_range_p)(self, self->data + idx, self->data + idx + 1);
+}
+STC_INLINE cx_iter_t
+cx_memb(_erase_n)(Self* self, size_t idx, size_t n) {
+ return cx_memb(_erase_range_p)(self, self->data + idx, self->data + idx + n);
+}
+STC_INLINE cx_iter_t
+cx_memb(_erase_at)(Self* self, cx_iter_t it) {
+ return cx_memb(_erase_range_p)(self, it.ref, it.ref + 1);
+}
+STC_INLINE cx_iter_t
+cx_memb(_erase_range)(Self* self, cx_iter_t it1, cx_iter_t it2) {
+ return cx_memb(_erase_range_p)(self, it1.ref, it2.ref);
+}
+
+STC_INLINE cx_value_t*
+cx_memb(_at)(const Self* self, size_t idx) {
+ assert(idx < cvec_rep_(self)->size);
+ return self->data + idx;
+}
+
+STC_INLINE cx_iter_t
+cx_memb(_find)(const Self* self, i_VALRAW raw) {
+ return cx_memb(_find_in)(cx_memb(_begin)(self), cx_memb(_end)(self), raw);
+}
+
+STC_INLINE cx_value_t*
+cx_memb(_get)(const Self* self, i_VALRAW raw) {
+ cx_iter_t end = cx_memb(_end)(self);
+ cx_value_t* val = cx_memb(_find_in)(cx_memb(_begin)(self), end, raw).ref;
+ return val == end.ref ? NULL : val;
+}
+
+STC_INLINE cx_iter_t
+cx_memb(_bsearch)(const Self* self, i_VALRAW raw) {
+ return cx_memb(_bsearch_in)(cx_memb(_begin)(self), cx_memb(_end)(self), raw);
+}
+STC_INLINE void
+cx_memb(_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), (int(*)(const void*, const void*)) _cmp_);
+}
+STC_INLINE void
+cx_memb(_sort)(Self* self) {
+ cx_memb(_sort_range)(cx_memb(_begin)(self), cx_memb(_end)(self), cx_memb(_value_compare));
+}
/* -------------------------- IMPLEMENTATION ------------------------- */
-#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-static struct cvec_rep _cvec_sentinel = {0, 0};
-
-#define _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
-\
- STC_DEF CX \
- CX##_init(void) { \
- CX cx = {(CX##_value_t *) _cvec_sentinel.data}; \
- return cx; \
- } \
-\
- STC_DEF void \
- CX##_clear(CX* self) { \
- struct cvec_rep* rep = _cvec_rep(self); if (rep->cap) { \
- for (CX##_value_t *p = self->data, *q = p + rep->size; p != q; ++p) \
- valueDel(p); \
- rep->size = 0; \
- } \
- } \
-\
- STC_DEF void \
- CX##_del(CX* self) { \
- CX##_clear(self); \
- if (_cvec_rep(self)->cap) \
- c_free(_cvec_rep(self)); \
- } \
-\
- STC_DEF void \
- 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, \
- offsetof(struct cvec_rep, data) + cap*sizeof(Value)); \
- self->data = (CX##_value_t*) rep->data; \
- rep->size = len; \
- rep->cap = cap; \
- } \
- } \
-\
- STC_DEF void \
- 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); \
- for (i = n; i < len; ++i) self->data[i] = null_val; \
- if (rep->cap) rep->size = len; \
- } \
-\
- STC_DEF void \
- CX##_push_back(CX* self, Value value) { \
- size_t len = _cvec_rep(self)->size; \
- if (len == CX##_capacity(*self)) \
- CX##_reserve(self, (len*13 >> 3) + 4); \
- self->data[_cvec_rep(self)->size++] = value; \
- } \
-\
- STC_DEF CX \
- CX##_clone(CX cx) { \
- size_t len = _cvec_rep(&cx)->size; \
- CX out = CX##_with_capacity(len); \
- CX##_insert_range_p(&out, out.data, cx.data, cx.data + len, true); \
- return out; \
- } \
-\
- STC_DEF CX##_value_t* \
- CX##_insert_space_(CX* self, CX##_value_t* pos, size_t len) { \
- size_t idx = pos - self->data, size = _cvec_rep(self)->size; \
- if (len == 0) return pos; \
- if (size + len > CX##_capacity(*self)) \
- CX##_reserve(self, (size*13 >> 3) + len), \
- pos = self->data + idx; \
- _cvec_rep(self)->size += len; \
- memmove(pos + len, pos, (size - idx) * sizeof(Value)); \
- return pos; \
- } \
-\
- STC_DEF CX##_iter_t \
- CX##_insert_range_p(CX* self, CX##_value_t* pos, const CX##_value_t* p1, \
- const CX##_value_t* p2, bool clone) { \
- pos = CX##_insert_space_(self, pos, p2 - p1); \
- CX##_iter_t it = {pos}; \
- if (clone) while (p1 != p2) *pos++ = valueFromRaw(valueToRaw(p1++)); \
- else memcpy(pos, p1, (p2 - p1)*sizeof *p1); \
- return it; \
- } \
-\
- STC_DEF CX##_iter_t \
- CX##_emplace_range_p(CX* self, CX##_value_t* pos, const CX##_rawvalue_t* p1, const CX##_rawvalue_t* p2) { \
- pos = CX##_insert_space_(self, pos, p2 - p1); \
- CX##_iter_t it = {pos}; \
- while (p1 != p2) *pos++ = valueFromRaw(*p1++); \
- return it; \
- } \
-\
- STC_DEF CX##_iter_t \
- CX##_erase_range_p(CX* self, CX##_value_t* p1, CX##_value_t* p2) { \
- intptr_t len = p2 - p1; \
- if (len > 0) { \
- CX##_value_t* p = p1, *end = self->data + _cvec_rep(self)->size; \
- while (p != p2) valueDel(p++); \
- memmove(p1, p2, (end - p2) * sizeof(Value)); \
- _cvec_rep(self)->size -= len; \
- } \
- return c_make(CX##_iter_t){.ref = p1}; \
- } \
-\
- STC_DEF CX##_iter_t \
- CX##_find_in(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 CX##_iter_t \
- CX##_bsearch_in(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); \
- if ((c = valueCompareRaw(&raw, &m)) == 0) return mid; \
- else if (c < 0) i2.ref = mid.ref; \
- else i1.ref = mid.ref + 1; \
- } \
- return last; \
- } \
-\
- STC_DEF int \
- 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); \
+#if defined i_IMP
+#ifndef CVEC_H_INCLUDED
+static struct cvec_Rep_ _cvec_sentinel = {0, 0};
+#endif
+
+STC_DEF Self
+cx_memb(_init)(void) {
+ Self cx = {(cx_value_t *) _cvec_sentinel.data};
+ return cx;
+}
+
+STC_DEF void
+cx_memb(_clear)(Self* self) {
+ struct cvec_Rep_* rep = cvec_rep_(self); if (rep->cap) {
+ for (cx_value_t *p = self->data, *q = p + rep->size; p != q; ++p)
+ i_VALDEL(p);
+ rep->size = 0;
}
+}
-#else
-#define _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
-#endif
+STC_DEF void
+cx_memb(_del)(Self* self) {
+ cx_memb(_clear)(self);
+ if (cvec_rep_(self)->cap)
+ c_free(cvec_rep_(self));
+}
+
+STC_DEF void
+cx_memb(_reserve)(Self* 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,
+ offsetof(struct cvec_Rep_, data) + cap*sizeof(i_VAL));
+ self->data = (cx_value_t*) rep->data;
+ rep->size = len;
+ rep->cap = cap;
+ }
+}
+
+STC_DEF void
+cx_memb(_resize)(Self* self, size_t len, i_VAL null_val) {
+ cx_memb(_reserve)(self, len);
+ struct cvec_Rep_* rep = cvec_rep_(self);
+ size_t i, n = rep->size;
+ for (i = len; i < n; ++i) i_VALDEL(self->data + i);
+ for (i = n; i < len; ++i) self->data[i] = null_val;
+ if (rep->cap) rep->size = len;
+}
+
+STC_DEF void
+cx_memb(_push_back)(Self* self, i_VAL value) {
+ size_t len = cvec_rep_(self)->size;
+ if (len == cx_memb(_capacity)(*self))
+ cx_memb(_reserve)(self, (len*13 >> 3) + 4);
+ self->data[cvec_rep_(self)->size++] = value;
+}
+
+STC_DEF Self
+cx_memb(_clone)(Self cx) {
+ size_t len = cvec_rep_(&cx)->size;
+ Self out = cx_memb(_with_capacity)(len);
+ cx_memb(_insert_range_p)(&out, out.data, cx.data, cx.data + len, true);
+ return out;
+}
+
+STC_DEF cx_value_t*
+cx_memb(_insert_space_)(Self* self, cx_value_t* pos, size_t len) {
+ size_t idx = pos - self->data, size = cvec_rep_(self)->size;
+ if (len == 0) return pos;
+ if (size + len > cx_memb(_capacity)(*self))
+ cx_memb(_reserve)(self, (size*13 >> 3) + len),
+ pos = self->data + idx;
+ cvec_rep_(self)->size += len;
+ memmove(pos + len, pos, (size - idx) * sizeof(i_VAL));
+ return pos;
+}
+
+STC_DEF cx_iter_t
+cx_memb(_insert_range_p)(Self* self, cx_value_t* pos, const cx_value_t* p1,
+ const cx_value_t* p2, bool clone) {
+ pos = cx_memb(_insert_space_)(self, pos, p2 - p1);
+ cx_iter_t it = {pos};
+ if (clone) while (p1 != p2) *pos++ = i_VALFROM(i_VALTO(p1++));
+ else memcpy(pos, p1, (p2 - p1)*sizeof *p1);
+ return it;
+}
-#endif
\ No newline at end of file +STC_DEF cx_iter_t
+cx_memb(_emplace_range_p)(Self* self, cx_value_t* pos, const cx_rawvalue_t* p1,
+ const cx_rawvalue_t* p2) {
+ pos = cx_memb(_insert_space_)(self, pos, p2 - p1);
+ cx_iter_t it = {pos};
+ while (p1 != p2) *pos++ = i_VALFROM(*p1++);
+ return it;
+}
+
+STC_DEF cx_iter_t
+cx_memb(_erase_range_p)(Self* self, cx_value_t* p1, cx_value_t* p2) {
+ intptr_t len = p2 - p1;
+ if (len > 0) {
+ cx_value_t* p = p1, *end = self->data + cvec_rep_(self)->size;
+ while (p != p2) i_VALDEL(p++);
+ memmove(p1, p2, (end - p2) * sizeof(i_VAL));
+ cvec_rep_(self)->size -= len;
+ }
+ return c_make(cx_iter_t){.ref = p1};
+}
+
+STC_DEF cx_iter_t
+cx_memb(_find_in)(cx_iter_t i1, cx_iter_t i2, i_VALRAW raw) {
+ for (; i1.ref != i2.ref; ++i1.ref) {
+ i_VALRAW r = i_VALTO(i1.ref);
+ if (i_CMP(&raw, &r) == 0) return i1;
+ }
+ return i2;
+}
+
+STC_DEF cx_iter_t
+cx_memb(_bsearch_in)(cx_iter_t i1, cx_iter_t i2, i_VALRAW raw) {
+ cx_iter_t mid, last = i2;
+ while (i1.ref != i2.ref) {
+ mid.ref = i1.ref + ((i2.ref - i1.ref)>>1);
+ int c; i_VALRAW m = i_VALTO(mid.ref);
+ if ((c = i_CMP(&raw, &m)) == 0) return mid;
+ else if (c < 0) i2.ref = mid.ref;
+ else i1.ref = mid.ref + 1;
+ }
+ return last;
+}
+
+STC_DEF int
+cx_memb(_value_compare)(const cx_value_t* x, const cx_value_t* y) {
+ i_VALRAW rx = i_VALTO(x);
+ i_VALRAW ry = i_VALTO(y);
+ return i_CMP(&rx, &ry);
+}
+
+#endif
+#define CVEC_H_INCLUDED
+#include "template.h"
diff --git a/include/stc/forward.h b/include/stc/forward.h new file mode 100644 index 00000000..2c904aa7 --- /dev/null +++ b/include/stc/forward.h @@ -0,0 +1,165 @@ +/* MIT License
+ *
+ * Copyright (c) 2021 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef STC_FORWARD_H_INCLUDED
+#define STC_FORWARD_H_INCLUDED
+
+#define forward_carray2(TAG, VAL) _c_carray2_types(carray2##TAG, VAL)
+#define forward_carray3(TAG, VAL) _c_carray3_types(carray2##TAG, VAL)
+#define forward_cdeq(TAG, VAL) _c_cdeq_types(cdeq_##TAG, VAL)
+#define forward_clist(TAG, VAL) _c_clist_types(clist_##TAG, VAL)
+#define forward_cmap(TAG, KEY, VAL) _c_chash_types(csmap_##TAG, cmap, KEY, VAL)
+#define forward_csmap(TAG, KEY, VAL) _c_aatree_types(csmap_##TAG, csmap, KEY, VAL)
+#define forward_cset(TAG, KEY) _c_chash_types(cset_##TAG, cset, KEY, KEY)
+#define forward_csset(TAG, KEY) _c_aatree_types(csset_##TAG, csset, KEY, KEY)
+#define forward_csptr(TAG, VAL) _csptr_types(csptr_##TAG, VAL)
+#define forward_cpque(TAG, ctype) _c_cpque_types(cpque_##TAG, ctype)
+#define forward_cqueue(TAG, ctype) _c_cqueue_types(cqueue_##TAG, ctype)
+#define forward_cstack(TAG, ctype) _c_cstack_types(cstack_##TAG, ctype)
+#define forward_cvec(TAG, VAL) _c_cvec_types(cvec_##TAG, VAL)
+
+#define SET_ONLY_cmap_(...)
+#define MAP_ONLY_cmap_(...) __VA_ARGS__
+#define SET_ONLY_cset_(...) __VA_ARGS__
+#define MAP_ONLY_cset_(...)
+
+#define SET_ONLY_csmap_(...)
+#define MAP_ONLY_csmap_(...) __VA_ARGS__
+#define SET_ONLY_csset_(...) __VA_ARGS__
+#define MAP_ONLY_csset_(...)
+
+#ifndef MAP_SIZE_T
+#define MAP_SIZE_T uint32_t
+#endif
+
+#define _c_carray2_types(SELF, VAL) \
+ typedef VAL SELF##_value_t; \
+ typedef struct { SELF##_value_t *ref; } SELF##_iter_t; \
+ typedef struct { SELF##_value_t **data; size_t xdim, ydim; } SELF
+
+#define _c_carray3_types(SELF, VAL) \
+ typedef VAL SELF##_value_t; \
+ typedef struct { SELF##_value_t *ref; } SELF##_iter_t; \
+ typedef struct { SELF##_value_t ***data; size_t xdim, ydim, zdim; } SELF
+
+#define _c_cdeq_types(SELF, VAL) \
+ typedef VAL SELF##_value_t; \
+ typedef struct {SELF##_value_t *ref; } SELF##_iter_t; \
+ typedef struct {SELF##_value_t *_base, *data;} SELF
+
+#define _c_clist_types(SELF, VAL) \
+ typedef VAL SELF##_value_t; \
+ typedef struct SELF##_node_t SELF##_node_t; \
+\
+ typedef struct { \
+ SELF##_node_t *const *_last, *prev; \
+ SELF##_value_t *ref; \
+ } SELF##_iter_t; \
+\
+ typedef struct { \
+ SELF##_node_t *last; \
+ } SELF
+
+#define _c_chash_types(SELF, C, KEY, VAL) \
+ typedef KEY SELF##_key_t; \
+ typedef VAL SELF##_mapped_t; \
+ typedef MAP_SIZE_T SELF##_size_t; \
+\
+ typedef SET_ONLY_##C( SELF##_key_t ) \
+ MAP_ONLY_##C( struct SELF##_value_t ) \
+ SELF##_value_t; \
+\
+ typedef struct { \
+ SELF##_value_t *ref; \
+ bool inserted; \
+ } SELF##_result_t; \
+\
+ typedef struct { \
+ SELF##_value_t *ref; \
+ uint8_t* _hx; \
+ } SELF##_iter_t; \
+\
+ typedef struct { \
+ SELF##_value_t* table; \
+ uint8_t* _hashx; \
+ SELF##_size_t size, bucket_count; \
+ float max_load_factor; \
+ } SELF
+
+#define _c_aatree_types(SELF, C, KEY, VAL) \
+ typedef KEY SELF##_key_t; \
+ typedef VAL SELF##_mapped_t; \
+ typedef MAP_SIZE_T SELF##_size_t; \
+\
+ typedef SET_ONLY_##C( SELF##_key_t ) \
+ MAP_ONLY_##C( struct SELF##_value_t ) \
+ SELF##_value_t; \
+\
+ typedef struct { \
+ SELF##_value_t *ref; \
+ bool inserted; \
+ } SELF##_result_t; \
+\
+ typedef struct SELF##_node_t SELF##_node_t; \
+\
+ typedef struct { \
+ SELF##_value_t *ref; \
+ SELF##_node_t *_d; \
+ int _top; \
+ SELF##_size_t _tn, _st[36]; \
+ } SELF##_iter_t; \
+\
+ typedef struct { \
+ SELF##_node_t *nodes; \
+ } SELF
+
+#define _csptr_types(SELF, VAL) \
+ typedef VAL SELF##_value_t; \
+\
+ typedef struct { \
+ SELF##_value_t* get; \
+ long* use_count; \
+ } SELF
+
+#define _c_cpque_types(SELF, ctype) \
+ typedef ctype##_value_t SELF##_value_t; \
+ typedef ctype##_rawvalue_t SELF##_rawvalue_t; \
+ typedef ctype SELF
+
+#define _c_cqueue_types(SELF, ctype) \
+ typedef ctype##_value_t SELF##_value_t; \
+ typedef ctype##_rawvalue_t SELF##_rawvalue_t; \
+ typedef ctype##_iter_t SELF##_iter_t; \
+ typedef struct { ctype rep; size_t size; } SELF
+
+#define _c_cstack_types(SELF, ctype) \
+ typedef ctype##_value_t SELF##_value_t; \
+ typedef ctype##_rawvalue_t SELF##_rawvalue_t; \
+ typedef ctype##_iter_t SELF##_iter_t; \
+ typedef ctype SELF
+
+#define _c_cvec_types(SELF, VAL) \
+ typedef VAL SELF##_value_t; \
+ typedef struct { SELF##_value_t *ref; } SELF##_iter_t; \
+ typedef struct { SELF##_value_t *data; } SELF
+
+#endif // STC_FORWARD_H_INCLUDED
\ No newline at end of file diff --git a/include/stc/template.h b/include/stc/template.h new file mode 100644 index 00000000..46059bf9 --- /dev/null +++ b/include/stc/template.h @@ -0,0 +1,149 @@ +#ifndef STC_TEMPLATE_INCLUDED
+#define STC_TEMPLATE_INCLUDED
+
+#if defined I_TAG
+ #define i_TAG I_TAG
+ #define i_IMP
+#endif
+#if defined f_TAG
+ #define i_TAG f_TAG
+ #define i_FWD
+#endif
+#if defined F_TAG
+ #define i_TAG F_TAG
+ #define i_FWD
+ #define i_IMP
+#endif
+
+#if defined i_KEY_str
+ #define i_KEY cstr
+ #define i_CMP c_rawstr_compare
+ #define i_EQU c_rawstr_equals
+ #define i_HASH c_rawstr_hash
+ #define i_KEYDEL cstr_del
+ #define i_KEYFROM cstr_from
+ #define i_KEYTO cstr_str
+ #define i_KEYRAW const char*
+#endif
+#if defined i_VAL_str
+ #define i_VAL cstr
+ #ifndef i_KEY
+ #define i_CMP c_rawstr_compare
+ #endif
+ #define i_VALDEL cstr_del
+ #define i_VALFROM cstr_from
+ #define i_VALTO cstr_str
+ #define i_VALRAW const char*
+#endif
+
+#if !defined i_TAG && (defined i_KEY_str || defined i_VAL_str)
+ #define i_TAG str
+#endif
+#if !defined i_TAG && defined i_KEY
+ #define i_TAG i_KEY
+#elif !defined i_TAG && defined i_VAL
+ #define i_TAG i_VAL
+#endif
+
+#define Self c_PASTE3(i_CNT, _, i_TAG)
+#define cx_memb(name) c_PASTE(Self, name)
+
+#define cx_value_t cx_memb(_value_t)
+#define cx_rawvalue_t cx_memb(_rawvalue_t)
+#define cx_iter_t cx_memb(_iter_t)
+
+#if defined i_VALTO ^ defined i_VALRAW
+ #error i_VALTO and i_VALRAW must both be defined
+#endif
+#if defined i_KEYTO ^ defined i_KEYRAW
+ #error i_KEYTO and i_KEYRAW must both be defined
+#endif
+
+#if defined i_KEY
+ #define cx_key_t cx_memb(_key_t)
+ #define cx_rawkey_t cx_memb(_rawkey_t)
+ #define cx_mapped_t cx_memb(_mapped_t)
+ #define cx_rawmapped_t cx_memb(_rawmapped_t)
+ #define cx_result_t cx_memb(_result_t)
+
+ #if !defined i_KEYFROM && defined i_KEYDEL
+ #define i_KEYFROM c_no_clone
+ #elif !defined i_KEYFROM
+ #define i_KEYFROM c_default_fromraw
+ #endif
+ #ifndef i_KEYRAW
+ #define i_KEYRAW i_KEY
+ #define i_KEYTO c_default_toraw
+ #endif
+#endif
+
+#if !defined i_VALFROM && defined i_VALDEL
+ #define i_VALFROM c_no_clone
+#elif !defined i_VALFROM
+ #define i_VALFROM c_default_fromraw
+#endif
+#ifndef i_VALRAW
+ #define i_VALRAW i_VAL
+ #define i_VALTO c_default_toraw
+#endif
+
+#ifndef i_KEYDEL
+ #define i_KEYDEL c_default_del
+#endif
+#ifndef i_VALDEL
+ #define i_VALDEL c_default_del
+#endif
+#ifndef i_EQU
+ #define i_EQU c_default_equals
+#endif
+#ifndef i_HASH
+ #define i_HASH c_default_hash
+#endif
+#ifndef i_CMP
+ #define i_CMP c_default_compare
+#endif
+
+// typedef container types defined in forward.h
+#define cx_deftypes(macro, Self, ...) macro(Self, __VA_ARGS__)
+// criteria for implementation
+#if !defined i_IMP && (defined STC_IMPLEMENTATION || !defined STC_HEADER)
+#define i_IMP
+#endif
+
+#else // -------------------------------------------------------
+
+#undef i_CNT
+#undef i_TAG
+#undef f_TAG
+#undef i_IMP
+#undef i_FWD
+#undef i_CMP
+#undef i_EQU
+#undef i_HASH
+#undef i_VAL
+#undef i_VAL_str
+#undef i_VALDEL
+#undef i_VALFROM
+#undef i_VALTO
+#undef i_VALRAW
+#undef i_KEY
+#undef i_KEY_str
+#undef i_KEYDEL
+#undef i_KEYFROM
+#undef i_KEYTO
+#undef i_KEYRAW
+
+#undef Self
+#undef cx_memb
+#undef cx_deftypes
+#undef cx_value_t
+#undef cx_rawvalue_t
+#undef cx_iter_t
+#undef cx_key_t
+#undef cx_rawkey_t
+#undef cx_mapped_t
+#undef cx_rawmapped_t
+#undef cx_result_t
+
+#undef STC_TEMPLATE_INCLUDED
+#endif
diff --git a/include/stc/vec_test_new.c b/include/stc/vec_test_new.c new file mode 100644 index 00000000..65bb0ff9 --- /dev/null +++ b/include/stc/vec_test_new.c @@ -0,0 +1,53 @@ +#include "cstr.h"
+#include "forward.h"
+
+forward_cvec(i32, int);
+forward_cvec(pnt, struct Point);
+
+struct MyStruct {
+ cvec_i32 intvec;
+ cvec_pnt pntvec;
+} typedef MyStruct;
+
+
+#define f_TAG i32
+#define i_VAL int
+#include "cvec.h"
+
+#define i_TAG f32
+#define i_VAL float
+#include "cvec.h"
+
+struct Point { int x, y; } typedef Point;
+int point_compare(const Point* a, const Point* b) {
+ int c = c_default_compare(&a->x, &b->x);
+ return c ? c : c_default_compare(&a->y, &b->y);
+}
+#define f_TAG pnt
+#define i_VAL Point
+#define i_CMP point_compare
+#include "cvec.h"
+
+#define i_VAL_str
+#include "cvec.h"
+
+
+int main()
+{
+ cvec_i32 vec = cvec_i32_init();
+ cvec_i32_push_back(&vec, 123);
+
+ cvec_f32 fvec = cvec_f32_init();
+ cvec_f32_push_back(&fvec, 123.3);
+
+ cvec_pnt pvec = cvec_pnt_init();
+ cvec_pnt_push_back(&pvec, (Point){42, 14});
+ cvec_pnt_push_back(&pvec, (Point){32, 94});
+ cvec_pnt_push_back(&pvec, (Point){62, 81});
+ cvec_pnt_sort(&pvec);
+ c_foreach (i, cvec_pnt, pvec)
+ printf(" (%d %d)", i.ref->x, i.ref->y);
+ puts("");
+ cvec_str svec = cvec_str_init();
+ cvec_str_emplace_back(&svec, "Hello, friend");
+}
\ No newline at end of file |
