diff options
| -rw-r--r-- | benchmarks/others/clist_v1.h | 2 | ||||
| -rw-r--r-- | benchmarks/others/csmap_v1.h | 162 | ||||
| -rw-r--r-- | docs/carray_api.md | 52 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 2 | ||||
| -rw-r--r-- | docs/cmap_api.md | 167 | ||||
| -rw-r--r-- | docs/cset_api.md | 21 | ||||
| -rw-r--r-- | docs/csmap_api.md | 11 | ||||
| -rw-r--r-- | docs/csset_api.md | 25 | ||||
| -rw-r--r-- | examples/advanced.c | 2 | ||||
| -rw-r--r-- | examples/bits.c | 2 | ||||
| -rw-r--r-- | examples/complex.c | 2 | ||||
| -rw-r--r-- | examples/demos.c | 22 | ||||
| -rw-r--r-- | examples/ex_gauss1.c | 8 | ||||
| -rw-r--r-- | stc/carray.h | 62 | ||||
| -rw-r--r-- | stc/cbits.h | 98 | ||||
| -rw-r--r-- | stc/cdeq.h | 2 | ||||
| -rw-r--r-- | stc/clist.h | 2 | ||||
| -rw-r--r-- | stc/cmap.h | 85 | ||||
| -rw-r--r-- | stc/cset.h | 2 | ||||
| -rw-r--r-- | stc/csmap.h | 100 | ||||
| -rw-r--r-- | stc/csset.h | 2 | ||||
| -rw-r--r-- | stc/cstr.h | 160 | ||||
| -rw-r--r-- | stc/cvec.h | 2 |
23 files changed, 526 insertions, 467 deletions
diff --git a/benchmarks/others/clist_v1.h b/benchmarks/others/clist_v1.h index c2fd7164..0887d5b3 100644 --- a/benchmarks/others/clist_v1.h +++ b/benchmarks/others/clist_v1.h @@ -69,7 +69,7 @@ _c_using_clist(clist_##X, Value, valueCompare, valueDel, valueFromRaw, valueToRaw, RawValue)
#define using_clist_str() \
- _c_using_clist(clist_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
+ _c_using_clist(clist_str, cstr, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
#define _c_using_clist_types(CX, Value) \
diff --git a/benchmarks/others/csmap_v1.h b/benchmarks/others/csmap_v1.h index 654fb9c3..1d65b516 100644 --- a/benchmarks/others/csmap_v1.h +++ b/benchmarks/others/csmap_v1.h @@ -47,13 +47,10 @@ int main(void) { #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_trivial_del, c_trivial_fromraw)
-
#define using_csmap_6(X, Key, Mapped, keyCompare, mappedDel, mappedClone) \
using_csmap_8(X, Key, Mapped, keyCompare, mappedDel, mappedClone, c_trivial_del, c_trivial_fromraw)
-
#define using_csmap_8(X, Key, Mapped, keyCompare, mappedDel, mappedClone, keyDel, keyClone) \
using_csmap_10(X, Key, Mapped, keyCompare, mappedDel, mappedClone, \
keyDel, keyClone, c_trivial_toraw, Key)
@@ -68,22 +65,19 @@ int main(void) { #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_trivial_del, c_trivial_fromraw)
-
#define using_csset_5(X, Key, keyCompare, keyDel, keyClone) \
using_csset_7(X, Key, keyCompare, keyDel, keyClone, c_trivial_toraw, Key)
-
#define using_csset_7(X, Key, keyCompareRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \
_c_using_aatree(csset_##X, csset_, Key, Key, keyCompareRaw, @@, keyDel, \
keyFromRaw, keyToRaw, RawKey, @@, @@, void)
/* csset_str, csmap_str, csmap_strkey, csmap_strval: */
#define using_csset_str() \
- _c_using_aatree_strkey(str, csset_, cstr_t, @@, @@)
+ _c_using_aatree_strkey(str, csset_, cstr, @@, @@)
#define using_csmap_str() \
- _c_using_aatree(csmap_str, csmap_, cstr_t, cstr_t, cstr_compare_raw, cstr_del, cstr_del, \
+ _c_using_aatree(csmap_str, csmap_, cstr, cstr, cstr_compare_raw, cstr_del, cstr_del, \
cstr_from, cstr_c_str, const char*, cstr_from, cstr_c_str, const char*)
@@ -91,12 +85,10 @@ int main(void) { #define using_csmap_strkey_2(X, Mapped) \
_c_using_aatree_strkey(X, csmap_, Mapped, c_trivial_del, c_trivial_fromraw)
-
#define using_csmap_strkey_4(X, Mapped, mappedDel, mappedClone) \
_c_using_aatree_strkey(X, csmap_, Mapped, mappedDel, mappedClone)
-
#define _c_using_aatree_strkey(X, C, Mapped, mappedDel, mappedClone) \
- _c_using_aatree(C##X, C, cstr_t, Mapped, cstr_compare_raw, mappedDel, cstr_del, \
+ _c_using_aatree(C##X, C, cstr, Mapped, cstr_compare_raw, mappedDel, cstr_del, \
cstr_from, cstr_c_str, const char*, mappedClone, c_trivial_toraw, Mapped)
@@ -104,15 +96,12 @@ int main(void) { #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_trivial_del, c_trivial_fromraw)
-
#define using_csmap_strval_5(X, Key, keyCompare, keyDel, keyClone) \
using_csmap_strval_7(X, Key, keyCompare, keyDel, keyClone, c_trivial_toraw, Key)
-
#define using_csmap_strval_7(X, Key, keyCompare, keyDel, keyFromRaw, keyToRaw, RawKey) \
- _c_using_aatree(csmap_##X, csmap_, Key, cstr_t, keyCompare, cstr_del, keyDel, \
+ _c_using_aatree(csmap_##X, csmap_, Key, cstr, keyCompare, cstr_del, keyDel, \
keyFromRaw, keyToRaw, RawKey, cstr_from, cstr_c_str, const char*)
#define SET_ONLY_csset_(...) __VA_ARGS__
@@ -140,7 +129,7 @@ int main(void) { typedef struct { \
CX##_value_t *ref; \
int _top; \
- CX##_node_t *_tn, *_st[48]; \
+ CX##_node_t *_tn, *_st[36]; \
} CX##_iter_t
@@ -165,60 +154,42 @@ int main(void) { bool inserted; \
} CX##_result_t; \
\
- STC_API CX \
- CX##_init(void); \
- STC_INLINE bool \
- CX##_empty(CX m) {return m.size == 0;} \
- STC_INLINE size_t \
- CX##_size(CX m) {return m.size;} \
-\
- STC_API void \
- CX##_del_r_(CX##_node_t* tn); \
-\
- STC_INLINE void \
- CX##_del(CX* self) {CX##_del_r_(self->root);} \
- 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_API CX CX##_init(void); \
+ 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##_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##_node_t* CX##_erase_r_(CX##_node_t *tn, const CX##_rawkey_t* rkey, int *erased); \
+ STC_API void CX##_del_r_(CX##_node_t* tn); \
+ STC_API CX##_node_t* CX##_clone_r_(CX##_node_t *tn); \
+ 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 m) {return m.size == 0;} \
+ STC_INLINE size_t CX##_size(CX m) {return m.size;} \
+ STC_INLINE void CX##_del(CX* self) {CX##_del_r_(self->root);} \
+ 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 CX CX##_clone(CX m) {CX c = {CX##_clone_r_(m.root), m.size}; return c;} \
+ STC_INLINE CX##_iter_t CX##_find(const CX* self, RawKey rkey) \
+ {CX##_iter_t it; CX##_find_it(self, rkey, &it); return it;} \
+ STC_INLINE bool 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 void \
CX##_value_del(CX##_value_t* val) { \
keyDel(KEY_REF_##C(val)); \
MAP_ONLY_##C( mappedDel(&val->second); ) \
} \
- STC_INLINE CX##_value_t \
- CX##_value_clone(CX##_value_t val) { \
- *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \
- MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \
- return val; \
- } \
\
- STC_API CX##_node_t* CX##_clone_r_(CX##_node_t *tn); \
- STC_INLINE CX \
- CX##_clone(CX bst) { \
- CX clone = {CX##_clone_r_(bst.root), bst.size}; \
- return clone; \
- } \
-\
- STC_API CX##_value_t* \
- CX##_find_it(const CX* self, RawKey rkey, CX##_iter_t* out); \
-\
- STC_INLINE CX##_iter_t \
- CX##_find(const CX* self, RawKey rkey) { \
- CX##_iter_t it; \
- CX##_find_it(self, rkey, &it); \
- return it; \
- } \
- STC_INLINE bool \
- CX##_contains(const CX* self, RawKey rkey) { \
- CX##_iter_t it; \
- return CX##_find_it(self, rkey, &it) != NULL; \
+ 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)); ) \
} \
\
- STC_API CX##_result_t \
- CX##_insert_entry_(CX* self, RawKey rkey); \
-\
STC_INLINE CX##_result_t \
CX##_emplace(CX* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \
CX##_result_t res = CX##_insert_entry_(self, rkey); \
@@ -228,6 +199,7 @@ int main(void) { } \
return res; \
} \
+\
STC_INLINE void \
CX##_emplace_n(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]); ) \
@@ -250,10 +222,12 @@ int main(void) { else {keyDel(&key); mappedDel(&res.ref->second);} \
res.ref->second = mapped; return res; \
} \
+ \
STC_INLINE CX##_result_t \
CX##_put(CX* self, Key k, Mapped m) { \
return CX##_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); \
@@ -261,6 +235,7 @@ int main(void) { else mappedDel(&res.ref->second); \
res.ref->second = mappedFromRaw(rmapped); return res; \
} \
+ \
STC_INLINE CX##_mapped_t* \
CX##_at(const CX* self, RawKey rkey) { \
CX##_iter_t it; \
@@ -273,6 +248,7 @@ int main(void) { while (tn->link[0]->level) tn = tn->link[0]; \
return &tn->value; \
} \
+\
STC_INLINE CX##_value_t* \
CX##_back(const CX* self) { \
CX##_node_t *tn = self->root; \
@@ -280,24 +256,16 @@ int main(void) { return &tn->value; \
} \
\
- STC_API void \
- CX##_next(CX##_iter_t* it); \
-\
STC_INLINE CX##_iter_t \
CX##_begin(const CX* self) { \
CX##_iter_t it = {NULL, 0, self->root}; \
CX##_next(&it); return it; \
} \
+\
STC_INLINE CX##_iter_t \
CX##_end(const CX* self) {\
CX##_iter_t it = {NULL}; return it; \
} \
- STC_INLINE CX##_mapped_t* \
- CX##_itval(CX##_iter_t it) {return SET_ONLY_##C( it.ref ) \
- MAP_ONLY_##C( &it.ref->second );} \
-\
- STC_API CX##_node_t* \
- CX##_erase_r_(CX##_node_t *tn, const CX##_rawkey_t* rkey, int *erased); \
\
STC_INLINE size_t \
CX##_erase(CX* self, RawKey rkey) { \
@@ -305,10 +273,6 @@ int main(void) { self->root = CX##_erase_r_(self->root, &rkey, &erased); \
self->size -= erased; return erased; \
} \
- STC_INLINE size_t \
- CX##_erase_at(CX* self, CX##_iter_t pos) { \
- return CX##_erase(self, keyToRaw(KEY_REF_##C(pos.ref))); \
- } \
\
_c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, mappedDel, keyDel, \
keyFromRaw, keyToRaw, RawKey, mappedFromRaw, mappedToRaw, RawMapped) \
@@ -338,6 +302,18 @@ int main(void) { 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); \
+ if (!it.ref && it._top) { \
+ CX##_node_t *tn = it._st[--it._top]; \
+ it._tn = tn->link[1]; \
+ it.ref = &tn->value; \
+ } \
+ return it; \
+ } \
+\
STC_DEF void \
CX##_next(CX##_iter_t *it) { \
CX##_node_t *tn = it->_tn; \
@@ -378,13 +354,13 @@ int main(void) { \
static inline CX##_node_t* \
CX##_insert_entry_i_(CX##_node_t* tn, const CX##_rawkey_t* rkey, CX##_result_t* res) { \
- CX##_node_t *up[64], *it = tn; \
+ CX##_node_t *up[64], *tx = tn; \
int c, top = 0, dir = 0; \
- while (it->level) { \
- up[top++] = it; \
- CX##_rawkey_t r = keyToRaw(KEY_REF_##C(&it->value)); \
- if ((c = keyCompareRaw(&r, rkey)) == 0) {res->ref = &it->value; return tn;} \
- it = it->link[(dir = (c < 0))]; \
+ while (tx->level) { \
+ up[top++] = tx; \
+ CX##_rawkey_t r = keyToRaw(KEY_REF_##C(&tx->value)); \
+ if ((c = keyCompareRaw(&r, rkey)) == 0) {res->ref = &tx->value; return tn;} \
+ tx = tx->link[(dir = (c < 0))]; \
} \
tn = c_new(CX##_node_t); \
res->ref = &tn->value, res->inserted = true; \
@@ -408,6 +384,30 @@ int main(void) { return res; \
} \
\
+ 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); \
+ 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); \
+ return it1; } \
+ CX##_key_t k1 = *KEY_REF_##C(it1.ref), k2 = *KEY_REF_##C(it2.ref); \
+ CX##_rawkey_t r1 = keyToRaw(&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); \
+ } \
+ } \
+\
STC_DEF CX##_node_t* \
CX##_erase_r_(CX##_node_t *tn, const CX##_rawkey_t* rkey, int *erased) { \
if (tn->level == 0) \
@@ -450,7 +450,7 @@ int main(void) { cn->link[0] = CX##_clone_r_(tn->link[0]); \
cn->link[1] = CX##_clone_r_(tn->link[1]); \
cn->level = tn->level; \
- cn->value = CX##_value_clone(tn->value); \
+ CX##_value_clone(&cn->value, &tn->value); \
return cn; \
} \
\
diff --git a/docs/carray_api.md b/docs/carray_api.md index 3fbd8c37..51688fd3 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -28,14 +28,15 @@ be replaced by `i` in all of the following documentation. ## Methods ```c -carray2X carray2X_init(size_t xdim, size_t ydim, Value val); -carray2X carray2X_from(Value* array, size_t xdim, size_t ydim); +carray2X carray2X_init(size_t xdim, size_t ydim); +carray2X carray2X_with_value(size_t xdim, size_t ydim, Value val); +carray2X carray2X_with_storage(size_t xdim, size_t ydim, Value* array); carray2X carray2X_clone(carray2X arr); -Value* carray2X_release(carray2X* self); // give away data +Value* carray2X_release(carray2X* self); // release storage (not freed) void carray2X_del(carray2X* self); size_t carray2X_size(carray2X arr); -Value* carray2X_data(carray2X* self); // contiguous memory +Value* carray2X_data(carray2X* self); // access storage data Value* carray2X_at(carray2X* self, size_t x, size_t y); carray2X_iter_t carray2X_begin(const carray2X* self); @@ -43,14 +44,15 @@ carray2X_iter_t carray2X_end(const carray2X* self); void carray2X_next(carray2X_iter_t* it); ``` ```c -carray3X carray3X_init(size_t xdim, size_t ydim, size_t zdim, Value val); -carray3X carray3X_from(Value* array, size_t xdim, size_t ydim, size_t zdim); +carray3X carray3X_init(size_t xdim, size_t ydim, size_t zdim); +carray3X carray3X_with_value(size_t xdim, size_t ydim, size_t zdim, Value val); +carray3X carray3X_with_storage(size_t xdim, size_t ydim, size_t zdim, Value* array); carray3X carray3X_clone(carray3X arr); -Value* carray3X_release(carray3X* self); // give away data +Value* carray3X_release(carray3X* self); // release storage (not freed) void carray3X_del(carray3X* self); size_t carray3X_size(carray3X arr); -Value* carray3X_data(carray3X* self); // contiguous memory +Value* carray3X_data(carray3X* self); // access storage data Value* carray3X_at(carray3X* self, size_t x, size_t y, size_t z); carray3X_iter_t carray3X_begin(const carray3X* self); @@ -59,14 +61,14 @@ void carray3X_next(carray3X_iter_t* it); ``` ## Types -| Type name | Type definition | Used to represent... | -|:---------------------|:---------------------------------------------------|:--------------------------| -| `carray2X` | `struct { Value **data; size_t xdim,ydim; }` | The carray2 type | -| `carray2X_value_t` | `Value` | The value type | -| `carray2X_iter_t` | `struct { Value *ref; }` | Iterator type | -| `carray3X` | `struct { Value ***data; size_t xdim,ydim,zdim; }` | The carray3 type | -| `carray3X_value_t` | `Value` | The value type | -| `carray3X_iter_t` | `struct { Value *ref; }` | Iterator type | +| Type name | Type definition | Used to represent... | +|:---------------------|:-----------------------------------------------------|:--------------------------| +| `carray2X` | `struct { Value **data; size_t xdim, ydim; }` | The carray2 type | +| `carray2X_value_t` | `Value` | The value type | +| `carray2X_iter_t` | `struct { Value *ref; }` | Iterator type | +| `carray3X` | `struct { Value ***data; size_t xdim, ydim, zdim; }` | The carray3 type | +| `carray3X_value_t` | `Value` | The value type | +| `carray3X_iter_t` | `struct { Value *ref; }` | Iterator type | The **carray** elements can be accessed like `carray3i arr = ...; int val = arr.data[x][y][z];`, or with `carray3i_at(&arr, x, y, z)`. @@ -82,20 +84,20 @@ int main() { // Ex1 int xd = 30, yd = 20, zd = 10; - carray3f a3 = carray3f_init(xd, yd, zd, 0.0f); // define a3[30][20][10], init with 0.0f. - a3.data[5][4][3] = 3.14f; + carray3f arr3 = carray3f_init(xd, yd, zd, 0.0f); // define arr3[30][20][10], init with 0.0f. + arr3.data[5][4][3] = 3.14f; - float *a1 = a3.data[5][4]; - float **a2 = a3.data[5]; + float *arr1 = arr3.data[5][4]; + float **arr2 = arr3.data[5]; - printf("%f\n", a1[3]); // 3.14 - printf("%f\n", a2[4][3]); // 3.14 - printf("%f\n", a3.data[5][4][3]); // 3.14 - carray3f_del(&a3); // free array + printf("%f\n", arr1[3]); // 3.14 + printf("%f\n", arr2[4][3]); // 3.14 + printf("%f\n", arr3.data[5][4][3]); // 3.14 + carray3f_del(&arr3); // free array // Ex2 int w = 256, h = 128; - carray2i image = carray2i_from(c_new_n(uint32_t, w*h), w, h); // no value init + carray2i image = carray2i_init(w, h); int n = 0; c_foreach (i, carray2i, image) { uint32_t t = n++ % 256; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index cabd2711..ec546dd6 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -71,7 +71,7 @@ cvec_str readFile(const char* name) { // Next line declares, opens, and closes the FILE* c_withfile (fp, fopen(name, "r")) { - cstr_t line = cstr_init(); + cstr line = cstr_init(); while (cstr_getline(&line, fp)) cvec_str_emplace_back(&vec, line.str); cstr_del(&line); diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 78aecfa9..99cee282 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -62,9 +62,10 @@ size_t cmap_X_size(cmap_X map); size_t cmap_X_capacity(cmap_X map); // buckets * max_load_factor size_t cmap_X_bucket_count(cmap_X map); // num. of allocated buckets -cmap_X_iter_t cmap_X_find(const cmap_X* self, RawKey rkey); bool cmap_X_contains(const cmap_X* self, RawKey rkey); cmap_X_mapped_t* cmap_X_at(const cmap_X* self, RawKey rkey); // rkey must be in map. +cmap_X_value_t* cmap_X_get(const cmap_X* self, RawKey rkey); // return NULL if not found +cmap_X_iter_t cmap_X_find(const cmap_X* self, RawKey rkey); cmap_X_result_t cmap_X_insert(cmap_X* self, Key key, Mapped mapped); // no change if key in map cmap_X_result_t cmap_X_insert_or_assign(cmap_X* self, Key key, Mapped mapped); // always update mapped @@ -106,7 +107,7 @@ void c_trivial_del(Type* val); // doe | `cmap_X_rawvalue_t` | `struct { RawKey first; RawMapped second; }` | RawKey + RawMapped type | | `cmap_X_key_t` | `Key` | The key type | | `cmap_X_mapped_t` | `Mapped` | The mapped type | -| `cmap_X_value_t` | `struct { Key first; Mapped second; }` | The value type | +| `cmap_X_value_t` | `struct { const Key first; Mapped second; }` | The value: key is immutable | | `cmap_X_result_t` | `struct { cmap_X_value_t *ref; bool inserted; }`| Result of insert/put/emplace | | `cmap_X_iter_t` | `struct { cmap_X_value_t *ref; ... }` | Iterator type | @@ -165,15 +166,17 @@ using_cmap_strval(id, int); int main() { uint32_t col = 0xcc7744ff; - c_init (cmap_id, idnames, { - {100, "Red"}, - {110, "Blue"}, - }); - /* put replaces existing mapped value: */ + + cmap_id idnames = cmap_id_init(); + c_emplace(cmap_id, idnames, { {100, "Red"}, {110, "Blue"} }); + + /* replace existing mapped value: */ cmap_id_emplace_or_assign(&idnames, 110, "White"); - /* put a constructed mapped value into map: */ + + /* insert a new constructed mapped string into map: */ cmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); - /* emplace inserts only when key does not exist: */ + + /* emplace/insert does nothing if key already exist: */ cmap_id_emplace(&idnames, 100, "Green"); c_foreach (i, cmap_id, idnames) @@ -197,22 +200,22 @@ Demonstrate cmap with plain-old-data key type Vec3i and int as mapped type: cmap typedef struct { int x, y, z; } Vec3i; -using_cmap(v3, Vec3i, int, c_trivial_equals, // bitwise equals +using_cmap(vi, Vec3i, int, c_trivial_equals, // bitwise equals c_default_hash); // bytewise hash int main() { - cmap_v3 vecs = cmap_v3_init(); + cmap_vi vecs = cmap_vi_init(); - cmap_v3_emplace(&vecs, (Vec3i){100, 0, 0}, 1); - cmap_v3_emplace(&vecs, (Vec3i){ 0, 100, 0}, 2); - cmap_v3_emplace(&vecs, (Vec3i){ 0, 0, 100}, 3); - cmap_v3_emplace(&vecs, (Vec3i){100, 100, 100}, 4); + cmap_vi_emplace(&vecs, (Vec3i){100, 0, 0}, 1); + cmap_vi_emplace(&vecs, (Vec3i){ 0, 100, 0}, 2); + cmap_vi_emplace(&vecs, (Vec3i){ 0, 0, 100}, 3); + cmap_vi_emplace(&vecs, (Vec3i){100, 100, 100}, 4); - c_foreach (i, cmap_v3, vecs) + c_foreach (i, cmap_vi, vecs) printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second); - cmap_v3_del(&vecs); + cmap_vi_del(&vecs); } ``` Output: @@ -255,64 +258,47 @@ Output: ``` ### Example 5 -Advanced, rare usage: Complex key type. +Advanced 1: Key type is struct. ```c #include <stc/cmap.h> #include <stc/cstr.h> -typedef struct Viking { +typedef struct { cstr name; cstr country; } Viking; -void viking_del(Viking* vk) { - cstr_del(&vk->name); - cstr_del(&vk->country); +static int Viking_equals(const Viking* a, const Viking* b) { + return cstr_equals_s(a->name, b->name) && cstr_equals_s(a->country, b->country); } -// Define Viking raw struct with hash, equals, and convertion functions between Viking and VikingRaw structs: - -typedef struct VikingRaw { - const char* name; - const char* country; -} VikingRaw; - -uint32_t vikingraw_hash(const VikingRaw* raw, size_t ignore) { - uint32_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) << 3); - return hash; -} -static inline int vikingraw_equals(const VikingRaw* rx, const VikingRaw* ry) { - return strcmp(rx->name, ry->name) == 0 && strcmp(rx->country, ry->country) == 0; +static uint32_t Viking_hash(const Viking* a, int ignored) { + return c_strhash(a->name.str) ^ (c_strhash(a->country.str) >> 15); } -static inline Viking viking_fromRaw(VikingRaw raw) { // note: parameter is by value - Viking vk = {cstr_from(raw.name), cstr_from(raw.country)}; return vk; -} -static inline VikingRaw viking_toRaw(Viking* vk) { - VikingRaw raw = {vk->name.str, vk->country.str}; return raw; +static void Viking_del(Viking* v) { + c_del(cstr, &v->name, &v->country); } -// With this in place, we use the using_cmap_keydef() macro to define {Viking -> int} hash map type: -using_cmap_keydef(vk, Viking, int, vikingraw_equals, vikingraw_hash, - viking_del, viking_fromRaw, viking_toRaw, VikingRaw); +using_cmap_keydef(vk, Viking, int, Viking_equals, Viking_hash, Viking_del, c_no_clone); int main() { - c_init (cmap_vk, vikings, { - { {"Einar", "Norway"}, 20 }, - { {"Olaf", "Denmark"}, 24 }, - { {"Harald", "Iceland"}, 12 }, - }); - cmap_vk_emplace_or_assign(&vikings, (VikingRaw){"Bjorn", "Sweden"}, 10); - - VikingRaw lookup = {"Einar", "Norway"}; - - cmap_vk_value_t *e = cmap_vk_find(&vikings, lookup).ref; - e->second += 3; // add 3 hp points to Einar - cmap_vk_emplace(&vikings, lookup, 0).ref->second += 5; // add 5 more to Einar - - c_foreach (k, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", k.ref->first.name.str, k.ref->first.country.str, k.ref->second); + // Use a HashMap to store the vikings' health points. + cmap_vk vikings = cmap_vk_init(); + + cmap_vk_insert(&vikings, (Viking){cstr_from("Einar"), cstr_from("Norway")}, 25); + cmap_vk_insert(&vikings, (Viking){cstr_from("Olaf"), cstr_from("Denmark")}, 24); + cmap_vk_insert(&vikings, (Viking){cstr_from("Harald"), cstr_from("Iceland")}, 12); + cmap_vk_insert(&vikings, (Viking){cstr_from("Einar"), cstr_from("Denmark")}, 21); + + Viking lookup = (Viking){cstr_from("Einar"), cstr_from("Norway")}; + printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, lookup)); + Viking_del(&lookup); + + // Print the status of the vikings. + c_foreach (i, cmap_vk, vikings) { + printf("%s of %s has %d hp\n", i.ref->first.name.str, i.ref->first.country.str, i.ref->second); } cmap_vk_del(&vikings); } @@ -320,7 +306,68 @@ int main() Output: ``` Olaf of Denmark has 24 hp -Bjorn of Sweden has 10 hp -Einar of Norway has 28 hp +Einar of Denmark has 21 hp +Einar of Norway has 25 hp Harald of Iceland has 12 hp ``` + +### Example 6 +Advanced 2: In example 5 we needed to construct a lookup key which allocated strings, and then had to free it after. In this example we use +rawtype feature to make it even simpler to use. Note that we must use the emplace() methods to add "raw" type entries (otherwise compile error): +```c +#include <stc/cmap.h> +#include <stc/cstr.h> + +typedef struct { + cstr name; + cstr country; +} Viking; + +static void Viking_del(Viking* v) { + c_del(cstr, &v->name, &v->country); +} + +// Define a "raw" type with equals, hash, fromraw, toraw functions: + +typedef struct { + const char* name; + const char* country; +} RViking; + +static int RViking_equals(const RViking* r1, const RViking* r2) { + return !strcmp(r1->name, r2->name) && !strcmp(r1->country, r2->country); +} + +static uint32_t RViking_hash(const RViking* r, int ignored) { + return c_strhash(r->name) ^ (c_strhash(r->country) >> 15); +} + +static Viking Viking_fromR(RViking r) {return (Viking){cstr_from(r.name), cstr_from(r.country)};} +static RViking Viking_toR(const Viking* v) {return (RViking){v->name.str, v->country.str};} + +using_cmap_keydef(vk, Viking, int, RViking_equals, RViking_hash, Viking_del, + Viking_fromR, Viking_toR, RViking); + +int main() +{ + // Use a HashMap to store the vikings' health points. + cmap_vk vikings = cmap_vk_init(); + + // insert works as before, takes a constructed Viking object + cmap_vk_insert(&vikings, (Viking){cstr_from("Einar"), cstr_from("Norway")}, 25); + cmap_vk_insert(&vikings, (Viking){cstr_from("Olaf"), cstr_from("Denmark")}, 24); + + // emplace is simple to use now. + cmap_vk_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); + cmap_vk_emplace(&vikings, (RViking){"Einar", "Denmark"}, 21); + + // And lookup uses "raw" key type, so no need construct/destruct key: + printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, (RViking){"Einar", "Norway"})); + + // Print the status of the vikings. + c_foreach (i, cmap_vk, vikings) { + printf("%s of %s has %d hp\n", i.ref->first.name.str, i.ref->first.country.str, i.ref->second); + } + cmap_vk_del(&vikings); +} +``` diff --git a/docs/cset_api.md b/docs/cset_api.md index a1265ee8..be083b75 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -39,8 +39,9 @@ size_t cset_X_size(cset_X set); size_t cset_X_capacity(cset_X set); // buckets * max_load_factor
size_t cset_X_bucket_count(cset_X set);
-cset_X_iter_t cset_X_find(const cset_X* self, RawKey rkey);
bool cset_X_contains(const cset_X* self, RawKey rkey);
+cset_X_value_t* cset_X_get(const cset_X* self, RawKey rkey); // return NULL if not found
+cset_X_iter_t cset_X_find(const cset_X* self, RawKey rkey);
cset_X_result_t cset_X_insert(cset_X* self, Key key);
cset_X_result_t cset_X_emplace(cset_X* self, RawKey rkey);
@@ -59,15 +60,15 @@ cset_X_value_t cset_X_value_clone(cset_X_value_t val); ## Types
-| Type name | Type definition | Used to represent... |
-|:---------------------|:-------------------------------------------------|:-------------------------|
-| `cset_X` | `struct { ... }` | The cset type |
-| `cset_X_rawkey_t` | `RawKey` | The raw key type |
-| `cset_X_rawvalue_t` | `cset_X_rawkey_t` | The raw key type |
-| `cset_X_key_t` | `Key` | The key type |
-| `cset_X_value_t` | `cset_X_key_t` | The value type |
-| `cset_X_result_t` | `struct { cset_X_value_t* ref; bool inserted; }` | Result of insert/emplace |
-| `cset_X_iter_t` | `struct { cset_X_value_t *ref; ... }` | Iterator type |
+| Type name | Type definition | Used to represent... |
+|:---------------------|:-------------------------------------------------|:----------------------------|
+| `cset_X` | `struct { ... }` | The cset type |
+| `cset_X_rawkey_t` | `RawKey` | The raw key type |
+| `cset_X_rawvalue_t` | `RawKey` | The raw value type |
+| `cset_X_key_t` | `Key` | The key type |
+| `cset_X_value_t` | `const Key` | The value: key is immutable |
+| `cset_X_result_t` | `struct { cset_X_value_t* ref; bool inserted; }` | Result of insert/emplace |
+| `cset_X_iter_t` | `struct { cset_X_value_t *ref; ... }` | Iterator type |
## Example
```c
diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 5717c287..ba9a2978 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -54,11 +54,12 @@ void csmap_X_del(csmap_X* self); bool csmap_X_empty(csmap_X map); size_t csmap_X_size(csmap_X map); -csmap_X_iter_t csmap_X_find(const csmap_X* self, RawKey rkey); -csmap_X_iter_t csmap_X_lower_bound(const csmap_X* self, RawKey rkey); // find closest entry >= rkey bool csmap_X_contains(const csmap_X* self, RawKey rkey); -csmap_X_value_t* csmap_X_find_it(const csmap_X* self, RawKey rkey, csmap_X_iter_t* out); // return NULL if not found csmap_X_mapped_t* csmap_X_at(const csmap_X* self, RawKey rkey); // rkey must be in map. +csmap_X_value_t* csmap_X_get(const csmap_X* self, RawKey rkey); // return NULL if not found +csmap_X_iter_t csmap_X_lower_bound(const csmap_X* self, RawKey rkey); // find closest entry >= rkey +csmap_X_iter_t csmap_X_find(const csmap_X* self, RawKey rkey); +csmap_X_value_t* csmap_X_find_it(const csmap_X* self, RawKey rkey, csmap_X_iter_t* out); // return NULL if not found csmap_X_result_t csmap_X_insert(csmap_X* self, Key key, Mapped mapped); // no change if key in map csmap_X_result_t csmap_X_insert_or_assign(csmap_X* self, Key key, Mapped mapped); // always update mapped @@ -85,10 +86,10 @@ csmap_X_value_t csmap_X_value_clone(csmap_X_value_t val); | `csmap_X` | `struct { ... }` | The csmap type | | `csmap_X_rawkey_t` | `RawKey` | The raw key type | | `csmap_X_rawmapped_t` | `RawMapped` | The raw mapped type | -| `csmap_X_rawvalue_t` | `struct { RawKey first; RawMapped second; }` | RawKey + RawVal type | +| `csmap_X_rawvalue_t` | `struct { RawKey first; RawMapped second; }` | RawKey+RawMapped type | | `csmap_X_key_t` | `Key` | The key type | | `csmap_X_mapped_t` | `Mapped` | The mapped type | -| `csmap_X_value_t` | `struct { Key first; Mapped second; }` | The value type | +| `csmap_X_value_t` | `struct { const Key first; Mapped second; }` | The value: key is immutable | | `csmap_X_result_t` | `struct { csmap_X_value_t *ref; bool inserted; }` | Result of insert/put/emplace | | `csmap_X_iter_t` | `struct { csmap_X_value_t *ref; ... }` | Iterator type | diff --git a/docs/csset_api.md b/docs/csset_api.md index 500e38e4..3e8f1aff 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -34,10 +34,11 @@ void csset_X_del(csset_X* self); bool csset_X_empty(csset_X set);
size_t csset_X_size(csset_X set);
-csset_X_iter_t csset_X_find(const csset_X* self, RawKey rkey);
-csset_X_iter_t csset_X_lower_bound(const csset_X* self, RawKey rkey); // find closest entry >= rkey
-csset_X_value_t* csset_X_find_it(const csset_X* self, RawKey rkey, csset_X_iter_t* out);
bool csset_X_contains(const csset_X* self, RawKey rkey);
+csset_X_value_t* csset_X_get(const csset_X* self, RawKey rkey); // return NULL if not found
+csset_X_iter_t csset_X_lower_bound(const csset_X* self, RawKey rkey); // find closest entry >= rkey
+csset_X_iter_t csset_X_find(const csset_X* self, RawKey rkey);
+csset_X_value_t* csset_X_find_it(const csset_X* self, RawKey rkey, csset_X_iter_t* out); // return NULL if not found
csset_X_result_t csset_X_insert(csset_X* self, Key key);
csset_X_result_t csset_X_emplace(csset_X* self, RawKey rkey);
@@ -56,15 +57,15 @@ csset_X_value_t csset_X_value_clone(csset_X_value_t val); ## Types
-| Type name | Type definition | Used to represent... |
-|:---------------------|:--------------------------------------------------|:-------------------------|
-| `csset_X` | `struct { ... }` | The csset type |
-| `csset_X_rawkey_t` | `RawKey` | The raw key type |
-| `csset_X_rawvalue_t` | `csset_X_rawkey_t` | The raw key type |
-| `csset_X_key_t` | `Key` | The key type |
-| `csset_X_value_t` | `csset_X_key_t` | The value type |
-| `csset_X_result_t` | `struct { csset_X_value_t* ref; bool inserted; }` | Result of insert/emplace |
-| `csset_X_iter_t` | `struct { csset_X_value_t *ref; ... }` | Iterator type |
+| Type name | Type definition | Used to represent... |
+|:---------------------|:--------------------------------------------------|:----------------------------|
+| `csset_X` | `struct { ... }` | The csset type |
+| `csset_X_rawkey_t` | `RawKey` | The raw key type |
+| `csset_X_rawvalue_t` | `csset_X_rawkey_t` | The raw key type |
+| `csset_X_key_t` | `Key` | The key type |
+| `csset_X_value_t` | `const Key` | The value: key is immutable |
+| `csset_X_result_t` | `struct { csset_X_value_t* ref; bool inserted; }` | Result of insert/emplace |
+| `csset_X_iter_t` | `struct { csset_X_value_t *ref; ... }` | Iterator type |
## Example
```c
diff --git a/examples/advanced.c b/examples/advanced.c index 795f3f63..84e148ac 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -30,7 +30,7 @@ static inline int vikingraw_equals(const VikingRaw* rx, const VikingRaw* ry) { static inline Viking viking_fromRaw(VikingRaw raw) { // note: parameter is by value Viking vk = {cstr_from(raw.name), cstr_from(raw.country)}; return vk; } -static inline VikingRaw viking_toRaw(Viking* vk) { +static inline VikingRaw viking_toRaw(const Viking* vk) { VikingRaw raw = {vk->name.str, vk->country.str}; return raw; } diff --git a/examples/bits.c b/examples/bits.c index c8b037a2..e7b843fb 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -34,7 +34,7 @@ int main() { printf("%d", cbits_test(set, i));
puts("");
- cbits_t s2 = cbits_clone(set);
+ cbits s2 = cbits_clone(set);
cbits_flip_all(&s2);
cbits_set(&s2, 16);
cbits_set(&s2, 17);
diff --git a/examples/complex.c b/examples/complex.c index 32bbd057..eea92dbd 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -22,7 +22,7 @@ int main() { cmap_map myMap = cmap_map_init();
cmap_lst listMap = cmap_lst_init();
clist_arr tableList = clist_arr_init();
- carray2f arr2 = carray2f_init(xdim, ydim, 1.f);
+ carray2f arr2 = carray2f_with_value(xdim, ydim, 1.f);
printf("arr2 size: %zu x %zu\n", arr2.xdim, arr2.ydim);
diff --git a/examples/demos.c b/examples/demos.c index 286c2e79..3502f5f1 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -184,23 +184,23 @@ using_carray3(f, float); void arraydemo1()
{
printf("\nARRAYDEMO1\n");
- carray3f a3 = carray3f_init(30, 20, 10, 0.0f);
- a3.data[5][4][3] = 10.2f;
- float **a2 = a3.data[5];
- float *a1 = a3.data[5][4];
+ carray3f arr3 = carray3f_with_value(30, 20, 10, 0.0f);
+ arr3.data[5][4][3] = 10.2f;
+ float **arr2 = arr3.data[5];
+ float *arr1 = arr3.data[5][4];
- printf("a3: %zu: (%zu, %zu, %zu) = %zu\n", sizeof(a3), a3.xdim, a3.ydim, a3.zdim, carray3f_size(a3));
+ printf("arr3: %zu: (%zu, %zu, %zu) = %zu\n", sizeof(arr3), arr3.xdim, arr3.ydim, arr3.zdim, carray3f_size(arr3));
- printf("%g\n", a1[3]); // = 10.2
- printf("%g\n", a2[4][3]); // = 10.2
- printf("%g\n", a3.data[5][4][3]); // = 10.2
+ printf("%g\n", arr1[3]); // = 10.2
+ printf("%g\n", arr2[4][3]); // = 10.2
+ printf("%g\n", arr3.data[5][4][3]); // = 10.2
float x = 0.0;
- c_foreach (i, carray3f, a3)
+ c_foreach (i, carray3f, arr3)
*i.ref = ++x;
- printf("%g\n", a3.data[29][19][9]); // = 6000
+ printf("%g\n", arr3.data[29][19][9]); // = 6000
- carray3f_del(&a3);
+ carray3f_del(&arr3);
}
diff --git a/examples/ex_gauss1.c b/examples/ex_gauss1.c index 99d17b23..75b96482 100644 --- a/examples/ex_gauss1.c +++ b/examples/ex_gauss1.c @@ -10,10 +10,12 @@ using_cmap(i, int, size_t);
// Declare int vector with map entries that can be sorted by map keys.
-static int compare(cmap_i_value_t *a, cmap_i_value_t *b) {
+struct mapval {int first; size_t second;};
+static int compare(struct mapval *a, struct mapval *b) {
return c_default_compare(&a->first, &b->first);
}
-using_cvec(e, cmap_i_value_t, compare);
+
+using_cvec(e, struct mapval, compare);
int main()
{
@@ -37,7 +39,7 @@ int main() // Transfer map to vec and sort it by map keys.
cvec_e vhist = cvec_e_init();
c_foreach (i, cmap_i, mhist)
- cvec_e_push_back(&vhist, *i.ref);
+ cvec_e_push_back(&vhist, (struct mapval){i.ref->first, i.ref->second});
cvec_e_sort(&vhist);
// Print the gaussian bar chart
diff --git a/stc/carray.h b/stc/carray.h index ebb20321..3fad0df7 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -67,10 +67,13 @@ int main() { typedef struct { CX##_value_t **data; size_t xdim, ydim; } CX; \
typedef struct { CX##_value_t *ref; } CX##_iter_t; \
\
- STC_API CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim); \
- STC_API CX CX##_init(size_t xdim, size_t ydim, Value value); \
+ STC_API CX CX##_with_value(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 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) { \
@@ -84,7 +87,7 @@ int main() { CX##_iter_t it = {*self->data}; return it; \
} \
STC_INLINE CX##_iter_t CX##_end(const CX* self) { \
- CX##_iter_t it = {*self->data + CX##_size(*self)}; return it; \
+ CX##_iter_t it = {*self->data + self->xdim*self->ydim}; return it; \
} \
STC_INLINE void CX##_next(CX##_iter_t* it) { ++it->ref; } \
\
@@ -108,17 +111,23 @@ int main() { typedef struct { CX##_value_t ***data; size_t xdim, ydim, zdim; } CX; \
typedef struct { CX##_value_t *ref; } CX##_iter_t; \
\
- STC_API CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim, size_t zdim); \
- STC_API CX CX##_init(size_t xdim, size_t ydim, size_t zdim, Value value); \
+ STC_API CX CX##_with_value(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_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 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 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) { \
return **self->data + self->zdim*(self->ydim*x + y) + z; \
} \
- 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##_release(CX* 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) { \
@@ -138,43 +147,40 @@ int main() { #define _c_implement_carray2(CX, Value, valueDel, valueClone) \
\
- STC_DEF CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim) { \
- size_t n = xdim * ydim; \
+ 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}; \
for (size_t x = 0; x < xdim; ++x, block += ydim) \
_arr.data[x] = block; \
return _arr; \
} \
\
- STC_DEF CX CX##_init(size_t xdim, size_t ydim, Value value) { \
- size_t n = xdim*ydim; \
- CX _arr = CX##_from(c_new_n(CX##_value_t, n), xdim, ydim); \
- for (CX##_value_t* p = _arr.data[0], *e = p + n; p != e; ++p) \
+ STC_DEF CX CX##_with_value(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) \
*p = value; \
return _arr; \
} \
\
STC_DEF CX CX##_clone(CX src) { \
- size_t n = src.xdim*src.ydim; \
- CX _arr = CX##_from(c_new_n(CX##_value_t, n), src.xdim, src.ydim); \
- for (CX##_value_t* p = _arr.data[0], *q = src.data[0], *e = p + n; p != e; ++p, ++q) \
+ 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); \
return _arr; \
} \
\
STC_DEF void CX##_del(CX* self) { \
if (!self->data) return; \
- for (CX##_value_t* p = self->data[0], *e = p + self->xdim*self->ydim; p != e; ++p) \
+ for (CX##_value_t* p = self->data[0], *e = p + CX##_size(*self); p != e; ++p) \
valueDel(p); \
c_free(self->data[0]); /* data */ \
- c_free(self->data); \
+ c_free(self->data); /* pointers */ \
}
// carray3 impl.
#define _c_implement_carray3(CX, Value, valueDel, valueClone) \
\
- STC_DEF CX CX##_from(CX##_value_t* block, size_t xdim, size_t ydim, size_t zdim) { \
+ 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]; \
for (size_t x = 0, y; x < xdim; ++x, p += ydim) \
@@ -183,18 +189,16 @@ int main() { return _arr; \
} \
\
- STC_DEF CX CX##_init(size_t xdim, size_t ydim, size_t zdim, Value value) { \
- size_t n = xdim*ydim*zdim; \
- CX _arr = CX##_from(c_new_n(CX##_value_t, n), xdim, ydim, zdim); \
- for (CX##_value_t* p = **_arr.data, *e = p + n; p != e; ++p) \
+ STC_DEF CX CX##_with_value(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) \
*p = value; \
return _arr; \
} \
\
STC_DEF CX CX##_clone(CX src) { \
- size_t n = CX##_size(src); \
- CX _arr = CX##_from(c_new_n(CX##_value_t, n), src.xdim, src.ydim, src.zdim); \
- for (CX##_value_t* p = **_arr.data, *q = **src.data, *e = p + n; p != e; ++p, ++q) \
+ 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); \
return _arr; \
} \
@@ -204,7 +208,7 @@ int main() { for (CX##_value_t* p = **self->data, *e = p + CX##_size(*self); p != e; ++p) \
valueDel(p); \
c_free(self->data[0][0]); /* data */ \
- c_free(self->data); /* pointers */ \
+ c_free(self->data); /* pointers */ \
}
#else
diff --git a/stc/cbits.h b/stc/cbits.h index 0da46f11..4c708a7d 100644 --- a/stc/cbits.h +++ b/stc/cbits.h @@ -30,7 +30,7 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h"
int main() {
- cbits_t bset = cbits_with_size(23, true);
+ cbits bset = cbits_with_size(23, true);
cbits_reset(&bset, 9);
cbits_resize(&bset, 43, false);
@@ -55,89 +55,89 @@ int main() { #include <string.h>
#include "ccommon.h"
-typedef struct cbits {
+typedef struct {
uint64_t *at64;
size_t size;
-} cbits, cbits_t;
-
-STC_API cbits_t cbits_with_size(size_t size, bool value);
-STC_API cbits_t cbits_with_values(size_t size, uint64_t pattern);
-STC_API cbits_t cbits_from_str(const char* str);
-STC_API char* cbits_to_str(cbits_t set, char* str, size_t start, intptr_t stop);
-STC_API cbits_t cbits_clone(cbits_t other);
-STC_API void cbits_resize(cbits_t* self, size_t size, bool value);
-STC_API cbits_t* cbits_assign(cbits_t* self, cbits_t other);
-STC_API size_t cbits_count(cbits_t set);
-STC_API bool cbits_subset_of(cbits_t set, cbits_t other);
-STC_API bool cbits_disjoint(cbits_t set, cbits_t other);
-
-STC_INLINE cbits_t cbits_init() { cbits_t set = {NULL, 0}; return set; }
-STC_INLINE void cbits_clear(cbits_t* self) { self->size = 0; }
-STC_INLINE void cbits_del(cbits_t* self) { c_free(self->at64); }
-STC_INLINE size_t cbits_size(cbits_t set) { return set.size; }
-
-STC_INLINE cbits_t* cbits_take(cbits_t* self, cbits_t other) {
+} cbits;
+
+STC_API cbits cbits_with_size(size_t size, bool value);
+STC_API cbits cbits_with_values(size_t size, uint64_t pattern);
+STC_API cbits cbits_from_str(const char* str);
+STC_API char* cbits_to_str(cbits set, char* str, size_t start, intptr_t stop);
+STC_API cbits cbits_clone(cbits other);
+STC_API void cbits_resize(cbits* self, size_t size, bool value);
+STC_API cbits* cbits_assign(cbits* self, cbits other);
+STC_API size_t cbits_count(cbits set);
+STC_API bool cbits_subset_of(cbits set, cbits other);
+STC_API bool cbits_disjoint(cbits set, cbits other);
+
+STC_INLINE cbits cbits_init() { cbits set = {NULL, 0}; return set; }
+STC_INLINE void cbits_clear(cbits* self) { self->size = 0; }
+STC_INLINE void cbits_del(cbits* self) { c_free(self->at64); }
+STC_INLINE size_t cbits_size(cbits set) { return set.size; }
+
+STC_INLINE cbits* cbits_take(cbits* self, cbits other) {
if (self->at64 != other.at64) {cbits_del(self); *self = other;}
return self;
}
-STC_INLINE cbits_t cbits_move(cbits_t* self) {
- cbits_t tmp = *self; self->at64 = NULL, self->size = 0;
+STC_INLINE cbits cbits_move(cbits* self) {
+ cbits tmp = *self; self->at64 = NULL, self->size = 0;
return tmp;
}
-STC_INLINE bool cbits_test(cbits_t set, size_t i) {
+STC_INLINE bool cbits_test(cbits set, size_t i) {
return (set.at64[i >> 6] & (1ull << (i & 63))) != 0;
}
-STC_INLINE bool cbits_at(cbits_t set, size_t i) {
+STC_INLINE bool cbits_at(cbits set, size_t i) {
return (set.at64[i >> 6] & (1ull << (i & 63))) != 0;
}
-STC_INLINE void cbits_set(cbits_t *self, size_t i) {
+STC_INLINE void cbits_set(cbits *self, size_t i) {
self->at64[i >> 6] |= 1ull << (i & 63);
}
-STC_INLINE void cbits_reset(cbits_t *self, size_t i) {
+STC_INLINE void cbits_reset(cbits *self, size_t i) {
self->at64[i >> 6] &= ~(1ull << (i & 63));
}
-STC_INLINE void cbits_set_value(cbits_t *self, size_t i, bool value) {
+STC_INLINE void cbits_set_value(cbits *self, size_t i, bool value) {
self->at64[i >> 6] ^= (-(uint64_t)value ^ self->at64[i >> 6]) & 1ull << (i & 63);
}
-STC_INLINE void cbits_flip(cbits_t *self, size_t i) {
+STC_INLINE void cbits_flip(cbits *self, size_t i) {
self->at64[i >> 6] ^= 1ull << (i & 63);
}
-STC_INLINE void cbits_set_all(cbits_t *self, bool value) {
+STC_INLINE void cbits_set_all(cbits *self, bool value) {
memset(self->at64, -(int)value, ((self->size + 63) >> 6) * 8);
}
-STC_INLINE void cbits_set_values(cbits_t *self, uint64_t pattern) {
+STC_INLINE void cbits_set_values(cbits *self, uint64_t pattern) {
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->at64[i] = pattern;
}
-STC_INLINE void cbits_flip_all(cbits_t *self) {
+STC_INLINE void cbits_flip_all(cbits *self) {
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->at64[i] ^= ~0ull;
}
/* Intersection */
-STC_INLINE void cbits_intersect(cbits_t *self, cbits_t other) {
+STC_INLINE void cbits_intersect(cbits *self, cbits other) {
assert(self->size == other.size);
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->at64[i] &= other.at64[i];
}
/* Union */
-STC_INLINE void cbits_union(cbits_t *self, cbits_t other) {
+STC_INLINE void cbits_union(cbits *self, cbits other) {
assert(self->size == other.size);
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->at64[i] |= other.at64[i];
}
/* Exclusive disjunction */
-STC_INLINE void cbits_xor(cbits_t *self, cbits_t other) {
+STC_INLINE void cbits_xor(cbits *self, cbits other) {
assert(self->size == other.size);
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->at64[i] ^= other.at64[i];
@@ -159,14 +159,14 @@ STC_INLINE void cbits_xor(cbits_t *self, cbits_t other) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-STC_DEF cbits_t* cbits_assign(cbits_t* self, cbits_t other) {
+STC_DEF cbits* cbits_assign(cbits* self, cbits other) {
if (self->at64 == other.at64) return self;
if (self->size != other.size) return cbits_take(self, cbits_clone(other));
memcpy(self->at64, other.at64, ((other.size + 63) >> 6)*8);
return self;
}
-STC_DEF void cbits_resize(cbits_t* self, size_t size, bool value) {
+STC_DEF void cbits_resize(cbits* self, size_t size, bool value) {
size_t new_n = (size + 63) >> 6, osize = self->size, old_n = (osize + 63) >> 6;
self->at64 = (uint64_t *) c_realloc(self->at64, new_n * 8);
self->size = size;
@@ -179,33 +179,33 @@ STC_DEF void cbits_resize(cbits_t* self, size_t size, bool value) { }
}
-STC_DEF cbits_t cbits_with_size(size_t size, bool value) {
- cbits_t set = {(uint64_t *) c_malloc(((size + 63) >> 6) * 8), size};
+STC_DEF cbits cbits_with_size(size_t size, bool value) {
+ cbits set = {(uint64_t *) c_malloc(((size + 63) >> 6) * 8), size};
cbits_set_all(&set, value);
return set;
}
-STC_DEF cbits_t cbits_with_values(size_t size, uint64_t pattern) {
- cbits_t set = {(uint64_t *) c_malloc(((size + 63) >> 6) * 8), size};
+STC_DEF cbits cbits_with_values(size_t size, uint64_t pattern) {
+ cbits set = {(uint64_t *) c_malloc(((size + 63) >> 6) * 8), size};
cbits_set_values(&set, pattern);
return set;
}
-STC_DEF cbits_t cbits_from_str(const char* str) {
+STC_DEF cbits cbits_from_str(const char* str) {
const char* p = str; while (*p) ++p;
- cbits_t set = cbits_with_size(p - str, false);
+ cbits set = cbits_with_size(p - str, false);
for (size_t i=0; i<set.size; ++i) if (str[i] == '1') cbits_set(&set, i);
return set;
}
-STC_DEF char* cbits_to_str(cbits_t set, char* out, size_t start, intptr_t stop) {
+STC_DEF char* cbits_to_str(cbits set, char* out, size_t start, intptr_t stop) {
size_t end = stop < 0 ? set.size : stop;
for (size_t i=start; i<end; ++i) out[i] = cbits_test(set, i) ? '1' : '0';
out[end] = '\0'; return out;
}
-STC_DEF cbits_t cbits_clone(cbits_t other) {
+STC_DEF cbits cbits_clone(cbits other) {
size_t bytes = ((other.size + 63) >> 6) * 8;
- cbits_t set = {(uint64_t *) memcpy(c_malloc(bytes), other.at64, bytes), other.size};
+ cbits set = {(uint64_t *) memcpy(c_malloc(bytes), other.at64, bytes), other.size};
return set;
}
-STC_DEF size_t cbits_count(cbits_t s) {
+STC_DEF size_t cbits_count(cbits s) {
size_t count = 0, n = s.size >> 6;
for (size_t i = 0; i < n; ++i) count += cpopcount64(s.at64[i]);
if (s.size & 63) count += cpopcount64(s.at64[n] & ((1ull << (s.size & 63)) - 1));
@@ -222,8 +222,8 @@ STC_DEF size_t cbits_count(cbits_t s) { uint64_t i = n, m = (1ull << (s.size & 63)) - 1; \
return ((s.at64[i] OPR other.at64[i]) & m) == (x & m)
-STC_DEF bool cbits_subset_of(cbits_t s, cbits_t other) { _cbits_SETOP(|, s.at64[i]); }
-STC_DEF bool cbits_disjoint(cbits_t s, cbits_t other) { _cbits_SETOP(&, 0); }
+STC_DEF bool cbits_subset_of(cbits s, cbits other) { _cbits_SETOP(|, s.at64[i]); }
+STC_DEF bool cbits_disjoint(cbits s, cbits other) { _cbits_SETOP(&, 0); }
#endif
#endif
@@ -41,7 +41,7 @@ _c_using_cdeq(cdeq_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
#define using_cdeq_str() \
- _c_using_cdeq(cdeq_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
+ _c_using_cdeq(cdeq_str, cstr, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
struct cdeq_rep { size_t size, cap; void* base[]; };
diff --git a/stc/clist.h b/stc/clist.h index dbdac503..d44636a8 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -69,7 +69,7 @@ _c_using_clist(clist_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
#define using_clist_str() \
- _c_using_clist(clist_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
+ _c_using_clist(clist_str, cstr, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
#define _c_using_clist_types(CX, Value) \
@@ -90,7 +90,7 @@ int main(void) { keyDel, keyFromRaw, keyToRaw, RawKey)
#define using_cmap_str() \
- _c_using_chash(cmap_str, cmap_, cstr_t, cstr_t, cstr_equals_raw, cstr_hash_raw, \
+ _c_using_chash(cmap_str, cmap_, cstr, cstr, cstr_equals_raw, cstr_hash_raw, \
cstr_del, cstr_from, cstr_c_str, const char*, \
cstr_del, cstr_from, cstr_c_str, const char*)
@@ -107,7 +107,7 @@ int main(void) { _c_using_chash_strkey(X, cmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped)
#define _c_using_chash_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \
- _c_using_chash(C##X, C, cstr_t, Mapped, cstr_equals_raw, cstr_hash_raw, \
+ _c_using_chash(C##X, C, cstr, Mapped, cstr_equals_raw, cstr_hash_raw, \
mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
cstr_del, cstr_from, cstr_c_str, const char*)
@@ -124,7 +124,7 @@ int main(void) { using_cmap_strval_8(X, Key, keyEquals, keyHash, keyDel, keyClone, c_trivial_toraw, Key)
#define using_cmap_strval_8(X, Key, keyEqualsRaw, keyHashRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \
- _c_using_chash(cmap_##X, cmap_, Key, cstr_t, keyEqualsRaw, keyHashRaw, \
+ _c_using_chash(cmap_##X, cmap_, Key, cstr, keyEqualsRaw, keyHashRaw, \
cstr_del, cstr_from, cstr_c_str, const char*, \
keyDel, keyFromRaw, keyToRaw, RawKey)
@@ -153,8 +153,8 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) typedef RawMapped CX##_rawmapped_t; \
typedef CMAP_SIZE_T CX##_size_t; \
\
- typedef SET_ONLY_##C( Key ) \
- MAP_ONLY_##C( struct {Key first; \
+ typedef SET_ONLY_##C( const CX##_key_t ) \
+ MAP_ONLY_##C( struct {const CX##_key_t first; \
Mapped second;} ) \
CX##_value_t; \
\
@@ -180,38 +180,39 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) uint8_t* _hx; \
} CX##_iter_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 CX##_iter_t CX##_find(const CX* self, RawKey rkey); \
- STC_API void CX##_erase_entry(CX* self, CX##_value_t* val); \
+ 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 CX##_iter_t CX##_find(const CX* self, RawKey rkey); \
+ STC_API void CX##_erase_entry(CX* self, CX##_value_t* val); \
\
- STC_INLINE CX CX##_init(void) {CX m = _cmap_inits; return m;} \
- 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) \
+ STC_INLINE CX CX##_init(void) {CX m = _cmap_inits; return m;} \
+ 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) \
+ 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 CX##_value_t* CX##_get(const CX* self, RawKey rkey) \
+ {return CX##_find(self, rkey).ref;} \
\
- STC_INLINE CX##_value_t \
- CX##_value_clone(CX##_value_t val) { \
- *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \
- MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \
- return val; \
+ STC_INLINE void \
+ CX##_value_clone(CX##_value_t* dst, CX##_value_t* val) { \
+ *(CX##_key_t*) KEY_REF_##C(dst) = keyFromRaw(keyToRaw(KEY_REF_##C(val))); \
+ MAP_ONLY_##C( dst->second = mappedFromRaw(mappedToRaw(&val->second)); ) \
} \
\
STC_INLINE void \
CX##_value_del(CX##_value_t* val) { \
- keyDel(KEY_REF_##C(val)); \
+ keyDel((CX##_key_t*) KEY_REF_##C(val)); \
MAP_ONLY_##C( mappedDel(&val->second); ) \
} \
\
@@ -219,7 +220,7 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) CX##_emplace(CX* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \
CX##_result_t res = CX##_insert_entry_(self, rkey); \
if (res.inserted) { \
- *KEY_REF_##C(res.ref) = keyFromRaw(rkey); \
+ *(CX##_key_t*) KEY_REF_##C(res.ref) = keyFromRaw(rkey); \
MAP_ONLY_##C(res.ref->second = mappedFromRaw(rmapped);) \
} \
return res; \
@@ -234,7 +235,7 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) 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)); \
- if (res.inserted) {*KEY_REF_##C(res.ref) = key; MAP_ONLY_##C( res.ref->second = mapped; )} \
+ if (res.inserted) {*(CX##_key_t*) KEY_REF_##C(res.ref) = key; MAP_ONLY_##C( res.ref->second = mapped; )} \
else {keyDel(&key); MAP_ONLY_##C( mappedDel(&mapped); )} \
return res; \
} \
@@ -243,25 +244,27 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) STC_INLINE CX##_result_t \
CX##_insert_or_assign(CX* self, Key key, Mapped mapped) { \
CX##_result_t res = CX##_insert_entry_(self, keyToRaw(&key)); \
- if (res.inserted) res.ref->first = key; \
+ if (res.inserted) *(CX##_key_t*) &res.ref->first = key; \
else {keyDel(&key); mappedDel(&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##_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); \
+ if (res.inserted) *(CX##_key_t*) &res.ref->first = keyFromRaw(rkey); \
else mappedDel(&res.ref->second); \
res.ref->second = mappedFromRaw(rmapped); return res; \
} \
+ \
STC_INLINE CX##_mapped_t* \
CX##_at(const CX* self, RawKey rkey) { \
chash_bucket_t b = CX##_bucket_(self, &rkey); \
- assert(self->_hashx[b.idx]); \
return &self->table[b.idx].second; \
}) \
\
@@ -271,10 +274,12 @@ STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; \
return it; \
} \
+\
STC_INLINE CX##_iter_t \
CX##_end(const CX* self) {\
CX##_iter_t it = {self->table + self->bucket_count}; return it; \
} \
+\
STC_INLINE void \
CX##_next(CX##_iter_t* it) { \
while ((++it->ref, *++it->_hx == 0)) ; \
@@ -331,7 +336,7 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ STC_DEF void CX##_del(CX* self) { \
CX##_wipe_(self); \
c_free(self->_hashx); \
- c_free(self->table); \
+ c_free((void *) self->table); \
} \
\
STC_DEF void CX##_clear(CX* self) { \
@@ -388,7 +393,7 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ }; \
CX##_value_t *e = m.table, *end = e + m.bucket_count, *dst = clone.table; \
for (uint8_t *hx = m._hashx; e != end; ++hx, ++e, ++dst) \
- if (*hx) *dst = CX##_value_clone(*e); \
+ if (*hx) CX##_value_clone(dst, e); \
return clone; \
} \
\
@@ -411,11 +416,11 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ if (tmp._hashx[i]) { \
CX##_rawkey_t raw = keyToRaw(KEY_REF_##C(e)); \
chash_bucket_t b = CX##_bucket_(self, &raw); \
- slot[b.idx] = *e, \
+ memcpy((void *) &slot[b.idx], e, sizeof *e); \
hashx[b.idx] = (uint8_t) b.hx; \
} \
c_free(tmp._hashx); \
- c_free(tmp.table); \
+ c_free((void *) tmp.table); \
} \
\
STC_DEF void \
@@ -428,10 +433,10 @@ STC_INLINE size_t fastrange_uint64_t(uint64_t x, uint64_t n) \ if (++j == cap) j = 0; \
if (! hashx[j]) \
break; \
- CX##_rawkey_t raw = keyToRaw(KEY_REF_##C(slot + j)); \
+ CX##_rawkey_t raw = keyToRaw(KEY_REF_##C(slot+j)); \
k = _c_SELECT(fastrange,CMAP_SIZE_T)(keyHashRaw(&raw, sizeof raw), cap); \
if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ \
- slot[i] = slot[j], hashx[i] = hashx[j], i = j; \
+ memcpy((void *) &slot[i], &slot[j], sizeof *slot), hashx[i] = hashx[j], i = j; \
} \
hashx[i] = 0; \
--self->size; \
@@ -62,7 +62,7 @@ int main(void) { /* cset_str: */
#define using_cset_str() \
- _c_using_chash_strkey(str, cset_, cstr_t, @@, @@, @@, void)
+ _c_using_chash_strkey(str, cset_, cstr, @@, @@, @@, void)
#define SET_ONLY_cset_(...) __VA_ARGS__
#define MAP_ONLY_cset_(...)
diff --git a/stc/csmap.h b/stc/csmap.h index 04f7fcaa..6fe35118 100644 --- a/stc/csmap.h +++ b/stc/csmap.h @@ -85,7 +85,7 @@ int main(void) { keyDel, keyFromRaw, keyToRaw, RawKey)
#define using_csmap_str() \
- _c_using_aatree(csmap_str, csmap_, cstr_t, cstr_t, cstr_compare_raw, \
+ _c_using_aatree(csmap_str, csmap_, cstr, cstr, cstr_compare_raw, \
cstr_del, cstr_from, cstr_c_str, const char*, \
cstr_del, cstr_from, cstr_c_str, const char*)
@@ -102,7 +102,7 @@ int main(void) { _c_using_aatree_strkey(X, csmap_, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped)
#define _c_using_aatree_strkey(X, C, Mapped, mappedDel, mappedFromRaw, mappedToRaw, RawMapped) \
- _c_using_aatree(C##X, C, cstr_t, Mapped, cstr_compare_raw, \
+ _c_using_aatree(C##X, C, cstr, Mapped, cstr_compare_raw, \
mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
cstr_del, cstr_from, cstr_c_str, const char*)
@@ -119,7 +119,7 @@ int main(void) { using_csmap_strval_7(X, Key, keyCompare, keyDel, keyClone, c_trivial_toraw, Key)
#define using_csmap_strval_7(X, Key, keyCompareRaw, keyDel, keyFromRaw, keyToRaw, RawKey) \
- _c_using_aatree(csmap_##X, csmap_, Key, cstr_t, keyCompareRaw, \
+ _c_using_aatree(csmap_##X, csmap_, Key, cstr, keyCompareRaw, \
cstr_del, cstr_from, cstr_c_str, const char*, \
keyDel, keyFromRaw, keyToRaw, RawKey)
@@ -142,8 +142,8 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; typedef RawMapped CX##_rawmapped_t; \
typedef CSMAP_SIZE_T CX##_size_t; \
\
- typedef SET_ONLY_##C( CX##_key_t ) \
- MAP_ONLY_##C( struct {CX##_key_t first; \
+ typedef SET_ONLY_##C( const CX##_key_t ) \
+ MAP_ONLY_##C( struct {const CX##_key_t first; \
CX##_mapped_t second;} ) \
CX##_value_t; \
\
@@ -174,43 +174,46 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; CX##_size_t _tn, _st[36]; \
} CX##_iter_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_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 x = CX##_init(); \
- CX##_reserve(&x, size); \
- return x; \
+ CX tree = CX##_init(); \
+ CX##_reserve(&tree, size); \
+ return tree; \
} \
\
STC_INLINE void \
CX##_value_del(CX##_value_t* val) { \
- keyDel(KEY_REF_##C(val)); \
+ keyDel((CX##_key_t*) KEY_REF_##C(val)); \
MAP_ONLY_##C( mappedDel(&val->second); ) \
} \
- STC_INLINE CX##_value_t \
- CX##_value_clone(CX##_value_t val) { \
- *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \
- MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \
- return val; \
+ STC_INLINE void \
+ CX##_value_clone(CX##_value_t* dst, CX##_value_t* val) { \
+ *(CX##_key_t*) KEY_REF_##C(dst) = keyFromRaw(keyToRaw(KEY_REF_##C(val))); \
+ MAP_ONLY_##C( dst->second = mappedFromRaw(mappedToRaw(&val->second)); ) \
} \
\
STC_INLINE CX##_iter_t \
@@ -220,17 +223,11 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; return it; \
} \
\
- 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##_result_t \
CX##_emplace(CX* self, RawKey rkey MAP_ONLY_##C(, RawMapped rmapped)) { \
CX##_result_t res = CX##_insert_entry_(self, rkey); \
if (res.inserted) { \
- *KEY_REF_##C(res.ref) = keyFromRaw(rkey); \
+ *(CX##_key_t*) KEY_REF_##C(res.ref) = keyFromRaw(rkey); \
MAP_ONLY_##C(res.ref->second = mappedFromRaw(rmapped);) \
} \
return res; \
@@ -245,7 +242,7 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; 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)); \
- if (res.inserted) {*KEY_REF_##C(res.ref) = key; MAP_ONLY_##C( res.ref->second = mapped; )} \
+ if (res.inserted) {*(CX##_key_t*) KEY_REF_##C(res.ref) = key; MAP_ONLY_##C( res.ref->second = mapped; )} \
else {keyDel(&key); MAP_ONLY_##C( mappedDel(&mapped); )} \
return res; \
} \
@@ -254,24 +251,24 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; STC_INLINE CX##_result_t \
CX##_insert_or_assign(CX* self, Key key, Mapped mapped) { \
CX##_result_t res = CX##_insert_entry_(self, keyToRaw(&key)); \
- if (res.inserted) res.ref->first = key; \
+ if (res.inserted) *(CX##_key_t*) &res.ref->first = key; \
else {keyDel(&key); mappedDel(&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##_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); \
+ if (res.inserted) *(CX##_key_t*) &res.ref->first = keyFromRaw(rkey); \
else mappedDel(&res.ref->second); \
res.ref->second = mappedFromRaw(rmapped); return res; \
} \
-\
+ \
STC_INLINE CX##_mapped_t* \
CX##_at(const CX* self, RawKey rkey) { \
CX##_iter_t it; \
@@ -463,12 +460,12 @@ static struct csmap_rep _csmap_inits = {0, 0, 0, 0}; if (c != 0) \
d[tn].link[c < 0] = CX##_erase_r_(d, d[tn].link[c < 0], rkey, erased); \
else { \
- if (!*erased) {CX##_value_del(&d[tn].value); *erased = 1;} \
+ if (!(*erased)++) CX##_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]; \
- d[tn].value = d[tx].value; /* move */ \
+ 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); \
} else { /* unlink node */ \
@@ -497,8 +494,7 @@ static struct csmap_rep _csmap_inits = {0, 0, 0, 0}; CX##_erase(CX* self, RawKey rkey) { \
int erased = 0; \
CX##_size_t root = CX##_erase_r_(self->nodes, (CX##_size_t) _csmap_rep(self)->root, &rkey, &erased); \
- if (erased) {_csmap_rep(self)->root = root; --_csmap_rep(self)->size;} \
- return erased; \
+ return erased ? (_csmap_rep(self)->root = root, --_csmap_rep(self)->size, 1) : 0; \
} \
\
STC_DEF CX##_iter_t \
@@ -526,10 +522,10 @@ static struct csmap_rep _csmap_inits = {0, 0, 0, 0}; } \
\
static CX##_size_t \
- CX##_clone_r_(CX* self, const CX##_node_t* src, CX##_size_t sn) { \
+ CX##_clone_r_(CX* self, CX##_node_t* src, CX##_size_t sn) { \
if (sn == 0) return 0; \
CX##_size_t tx, tn = CX##_node_new_(self, src[sn].level); \
- self->nodes[tn].value = CX##_value_clone(src[sn].value); \
+ 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; \
return tn; \
diff --git a/stc/csset.h b/stc/csset.h index 7d02b055..48ad6656 100644 --- a/stc/csset.h +++ b/stc/csset.h @@ -62,7 +62,7 @@ int main(void) { @@, @@, @@, void, keyDel, keyFromRaw, keyToRaw, RawKey)
#define using_csset_str() \
- _c_using_aatree_strkey(str, csset_, cstr_t, @@, @@, @@, void)
+ _c_using_aatree_strkey(str, csset_, cstr, @@, @@, @@, void)
#define SET_ONLY_csset_(...) __VA_ARGS__
#define MAP_ONLY_csset_(...)
@@ -30,138 +30,138 @@ #include <stdio.h> /* vsnprintf */
#include <ctype.h>
-typedef struct { char* str; } cstr, cstr_t;
+typedef struct { char* str; } cstr;
typedef struct { char *ref; } cstr_iter_t;
typedef char cstr_value_t;
#define cstr_npos ((size_t) (-1))
struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; };
#define _cstr_rep(self) c_container_of((self)->str, struct cstr_rep, str)
-STC_LIBRARY_ONLY( extern const cstr_t cstr_inits; )
+STC_LIBRARY_ONLY( extern const cstr cstr_inits; )
STC_STATIC_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}};
- static const cstr_t cstr_inits = {_cstr_nullrep.str}; )
+ static const cstr cstr_inits = {_cstr_nullrep.str}; )
/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */
#define _cstr_opt_mem(cap) ((((offsetof(struct cstr_rep, str) + (cap) + 8)>>4)<<4) + 8)
/* optimal string capacity: 7, 23, 39, ... */
#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(struct cstr_rep, str) - 1)
-STC_API cstr_t cstr_from_n(const char* str, size_t n);
-STC_API cstr_t cstr_from_fmt(const char* fmt, ...);
-STC_API void cstr_fmt(cstr_t* self, const char* fmt, ...);
-STC_API size_t cstr_reserve(cstr_t* self, size_t cap);
-STC_API void cstr_resize(cstr_t* self, size_t len, char fill);
-STC_API cstr_t* cstr_assign_n(cstr_t* self, const char* str, size_t n);
-STC_API cstr_t* cstr_append_n(cstr_t* self, const char* str, size_t n);
-STC_API void cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n);
-STC_API void cstr_erase_n(cstr_t* self, size_t pos, size_t n);
-STC_API size_t cstr_find(cstr_t s, const char* needle);
-STC_API size_t cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t n);
-STC_API size_t cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t n);
-STC_API bool cstr_getdelim(cstr_t *self, int delim, FILE *stream);
+STC_API cstr cstr_from_n(const char* str, size_t n);
+STC_API cstr cstr_from_fmt(const char* fmt, ...);
+STC_API void cstr_fmt(cstr* self, const char* fmt, ...);
+STC_API size_t cstr_reserve(cstr* self, size_t cap);
+STC_API void cstr_resize(cstr* self, size_t len, char fill);
+STC_API cstr* cstr_assign_n(cstr* self, const char* str, size_t n);
+STC_API cstr* cstr_append_n(cstr* self, const char* str, size_t n);
+STC_API void cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n);
+STC_API void cstr_erase_n(cstr* self, size_t pos, size_t n);
+STC_API size_t cstr_find(cstr s, const char* needle);
+STC_API size_t cstr_find_n(cstr s, const char* needle, size_t pos, size_t n);
+STC_API size_t cstr_ifind_n(cstr s, const char* needle, size_t pos, size_t n);
+STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream);
STC_API int c_strncasecmp(const char* s1, const char* s2, size_t n);
STC_API char* c_strnstr(const char* s, const char* needle, size_t nmax);
STC_API char* c_strncasestr(const char* s, const char* needle, size_t nmax);
-STC_INLINE cstr_t cstr_init() { return cstr_inits; }
-STC_INLINE size_t cstr_size(cstr_t s) { return _cstr_rep(&s)->size; }
-STC_INLINE size_t cstr_capacity(cstr_t s) { return _cstr_rep(&s)->cap; }
-STC_INLINE size_t cstr_empty(cstr_t s) { return _cstr_rep(&s)->size == 0; }
-STC_INLINE size_t cstr_length(cstr_t s) { return _cstr_rep(&s)->size; }
-STC_INLINE void cstr_del(cstr_t* self)
+STC_INLINE cstr cstr_init() { return cstr_inits; }
+STC_INLINE size_t cstr_size(cstr s) { return _cstr_rep(&s)->size; }
+STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_rep(&s)->cap; }
+STC_INLINE size_t cstr_empty(cstr s) { return _cstr_rep(&s)->size == 0; }
+STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; }
+STC_INLINE void cstr_del(cstr* self)
{ if (_cstr_rep(self)->cap) c_free(_cstr_rep(self)); }
-STC_INLINE cstr_t cstr_from(const char* str)
+STC_INLINE cstr cstr_from(const char* str)
{ return cstr_from_n(str, strlen(str)); }
-STC_INLINE cstr_t cstr_clone(cstr_t s)
+STC_INLINE cstr cstr_clone(cstr s)
{ return cstr_from_n(s.str, _cstr_rep(&s)->size); }
-STC_INLINE void cstr_clear(cstr_t* self)
+STC_INLINE void cstr_clear(cstr* self)
{ self->str[_cstr_rep(self)->size = 0] = '\0'; }
-STC_INLINE cstr_t* cstr_assign(cstr_t* self, const char* str)
+STC_INLINE cstr* cstr_assign(cstr* self, const char* str)
{ return cstr_assign_n(self, str, strlen(str)); }
-STC_INLINE cstr_t* cstr_assign_s(cstr_t* self, cstr s)
+STC_INLINE cstr* cstr_assign_s(cstr* self, cstr s)
{ return cstr_assign_n(self, s.str, _cstr_rep(&s)->size); }
-STC_INLINE cstr_t* cstr_append(cstr_t* self, const char* str)
+STC_INLINE cstr* cstr_append(cstr* self, const char* str)
{ return cstr_append_n(self, str, strlen(str)); }
-STC_INLINE cstr_t* cstr_append_s(cstr_t* self, cstr s)
+STC_INLINE cstr* cstr_append_s(cstr* self, cstr s)
{ return cstr_append_n(self, s.str, _cstr_rep(&s)->size); }
-STC_INLINE void cstr_push_back(cstr_t* self, char value)
+STC_INLINE void cstr_push_back(cstr* self, char value)
{ cstr_append_n(self, &value, 1); }
-STC_INLINE void cstr_pop_back(cstr_t* self)
+STC_INLINE void cstr_pop_back(cstr* self)
{ self->str[ --_cstr_rep(self)->size ] = '\0'; }
-STC_INLINE void cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n)
+STC_INLINE void cstr_insert_n(cstr* self, size_t pos, const char* str, size_t n)
{ cstr_replace_n(self, pos, 0, str, n); }
-STC_INLINE void cstr_insert(cstr_t* self, size_t pos, const char* str)
+STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str)
{ cstr_replace_n(self, pos, 0, str, strlen(str)); }
-STC_INLINE void cstr_insert_s(cstr_t* self, size_t pos, cstr s)
+STC_INLINE void cstr_insert_s(cstr* self, size_t pos, cstr s)
{ cstr_replace_n(self, pos, 0, s.str, _cstr_rep(&s)->size); }
-STC_INLINE void cstr_replace(cstr_t* self, size_t pos, size_t len, const char* str)
+STC_INLINE void cstr_replace(cstr* self, size_t pos, size_t len, const char* str)
{ cstr_replace_n(self, pos, len, str, strlen(str)); }
-STC_INLINE void cstr_replace_s(cstr_t* self, size_t pos, size_t len, cstr s)
+STC_INLINE void cstr_replace_s(cstr* self, size_t pos, size_t len, cstr s)
{ cstr_replace_n(self, pos, len, s.str, _cstr_rep(&s)->size); }
-STC_INLINE void cstr_erase(cstr_t* self, size_t pos)
+STC_INLINE void cstr_erase(cstr* self, size_t pos)
{ cstr_erase_n(self, pos, 1); }
-STC_INLINE char* cstr_front(cstr_t* self) { return self->str; }
-STC_INLINE char* cstr_back(cstr_t* self)
+STC_INLINE char* cstr_front(cstr* self) { return self->str; }
+STC_INLINE char* cstr_back(cstr* self)
{ return self->str + _cstr_rep(self)->size - 1; }
-STC_INLINE cstr_iter_t cstr_begin(cstr_t* self)
+STC_INLINE cstr_iter_t cstr_begin(cstr* self)
{ cstr_iter_t it = {self->str}; return it; }
-STC_INLINE cstr_iter_t cstr_end(cstr_t* self)
+STC_INLINE cstr_iter_t cstr_end(cstr* self)
{ cstr_iter_t it = {self->str + _cstr_rep(self)->size}; return it; }
STC_INLINE void cstr_next(cstr_iter_t* it) {++it->ref; }
-STC_INLINE bool cstr_equals(cstr_t s1, const char* str)
+STC_INLINE bool cstr_equals(cstr s1, const char* str)
{ return strcmp(s1.str, str) == 0; }
-STC_INLINE bool cstr_equals_s(cstr_t s1, cstr_t s2)
+STC_INLINE bool cstr_equals_s(cstr s1, cstr s2)
{ return strcmp(s1.str, s2.str) == 0; }
-STC_INLINE bool cstr_iequals(cstr_t s1, const char* str)
+STC_INLINE bool cstr_iequals(cstr s1, const char* str)
{ return c_strncasecmp(s1.str, str, cstr_npos) == 0; }
-STC_INLINE bool cstr_contains(cstr_t s, const char* needle)
+STC_INLINE bool cstr_contains(cstr s, const char* needle)
{ return strstr(s.str, needle) != NULL; }
-STC_INLINE bool cstr_icontains(cstr_t s, const char* needle)
+STC_INLINE bool cstr_icontains(cstr s, const char* needle)
{ return c_strncasestr(s.str, needle, cstr_npos) != NULL; }
-STC_INLINE bool cstr_begins_with(cstr_t s, const char* needle)
+STC_INLINE bool cstr_begins_with(cstr s, const char* needle)
{ return strncmp(s.str, needle, strlen(needle)) == 0; }
-STC_INLINE bool cstr_ibegins_with(cstr_t s, const char* needle)
+STC_INLINE bool cstr_ibegins_with(cstr s, const char* needle)
{ return c_strncasecmp(s.str, needle, strlen(needle)) == 0; }
-STC_INLINE bool cstr_getline(cstr_t *self, FILE *stream)
+STC_INLINE bool cstr_getline(cstr *self, FILE *stream)
{ return cstr_getdelim(self, '\n', stream); }
-STC_INLINE cstr_t
+STC_INLINE cstr
cstr_with_capacity(size_t cap) {
- cstr_t s = cstr_inits;
+ cstr s = cstr_inits;
cstr_reserve(&s, cap);
return s;
}
-STC_INLINE cstr_t
+STC_INLINE cstr
cstr_with_size(size_t len, char fill) {
- cstr_t s = cstr_inits;
+ cstr s = cstr_inits;
cstr_resize(&s, len, fill);
return s;
}
-STC_INLINE cstr_t*
-cstr_take(cstr_t* self, cstr_t s) {
+STC_INLINE cstr*
+cstr_take(cstr* self, cstr s) {
if (self->str != s.str && _cstr_rep(self)->cap)
c_free(_cstr_rep(self));
self->str = s.str;
return self;
}
-STC_INLINE cstr_t
-cstr_move(cstr_t* self) {
- cstr_t tmp = *self;
+STC_INLINE cstr
+cstr_move(cstr* self) {
+ cstr tmp = *self;
*self = cstr_inits;
return tmp;
}
STC_INLINE bool
-cstr_ends_with(cstr_t s, const char* needle) {
+cstr_ends_with(cstr s, const char* needle) {
size_t n = strlen(needle), sz = _cstr_rep(&s)->size;
return n <= sz ? memcmp(s.str + sz - n, needle, n) == 0 : false;
}
STC_INLINE bool
-cstr_iends_with(cstr_t s, const char* needle) {
+cstr_iends_with(cstr s, const char* needle) {
size_t n = strlen(needle), sz = _cstr_rep(&s)->size;
return n <= sz ? c_strncasecmp(s.str + sz - n, needle, n) == 0 : false;
}
@@ -183,10 +183,10 @@ cstr_iends_with(cstr_t s, const char* needle) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
STC_LIBRARY_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}};
- const cstr_t cstr_inits = {_cstr_nullrep.str}; )
+ const cstr cstr_inits = {_cstr_nullrep.str}; )
STC_DEF size_t
-cstr_reserve(cstr_t* self, size_t cap) {
+cstr_reserve(cstr* self, size_t cap) {
struct cstr_rep* rep = _cstr_rep(self);
size_t oldcap = rep->cap;
if (cap > oldcap) {
@@ -199,18 +199,18 @@ cstr_reserve(cstr_t* self, size_t cap) { }
STC_DEF void
-cstr_resize(cstr_t* self, size_t len, char fill) {
+cstr_resize(cstr* self, size_t len, char fill) {
size_t n = _cstr_rep(self)->size;
cstr_reserve(self, len);
if (len > n) memset(self->str + n, fill, len - n);
if (len | n) self->str[_cstr_rep(self)->size = len] = '\0';
}
-STC_DEF cstr_t
+STC_DEF cstr
cstr_from_n(const char* str, size_t n) {
if (n == 0) return cstr_inits;
struct cstr_rep* rep = (struct cstr_rep*) c_malloc(_cstr_opt_mem(n));
- cstr_t s = {(char *) memcpy(rep->str, str, n)};
+ cstr s = {(char *) memcpy(rep->str, str, n)};
s.str[rep->size = n] = '\0';
rep->cap = _cstr_opt_cap(n);
return s;
@@ -225,7 +225,7 @@ cstr_from_n(const char* str, size_t n) { #endif
///
STC_DEF void
-cstr_vfmt(cstr_t* self, const char* fmt, va_list args) {
+cstr_vfmt(cstr* self, const char* fmt, va_list args) {
va_list args2;
va_copy(args2, args);
int len = vsnprintf(NULL, (size_t)0, fmt, args);
@@ -242,23 +242,23 @@ cstr_vfmt(cstr_t* self, const char* fmt, va_list args) { #endif
STC_DEF void
-cstr_fmt(cstr_t* self, const char* fmt, ...) {
+cstr_fmt(cstr* self, const char* fmt, ...) {
va_list args; va_start(args, fmt);
cstr_vfmt(self, fmt, args);
va_end(args);
}
-STC_DEF cstr_t
+STC_DEF cstr
cstr_from_fmt(const char* fmt, ...) {
- cstr_t ret = cstr_inits;
+ cstr ret = cstr_inits;
va_list args; va_start(args, fmt);
cstr_vfmt(&ret, fmt, args);
va_end(args);
return ret;
}
-STC_DEF cstr_t*
-cstr_assign_n(cstr_t* self, const char* str, size_t n) {
+STC_DEF cstr*
+cstr_assign_n(cstr* self, const char* str, size_t n) {
if (n || _cstr_rep(self)->cap) {
cstr_reserve(self, n);
memmove(self->str, str, n);
@@ -267,8 +267,8 @@ cstr_assign_n(cstr_t* self, const char* str, size_t n) { return self;
}
-STC_DEF cstr_t*
-cstr_append_n(cstr_t* self, const char* str, size_t n) {
+STC_DEF cstr*
+cstr_append_n(cstr* self, const char* str, size_t n) {
if (n) {
size_t oldlen = _cstr_rep(self)->size, newlen = oldlen + n;
if (newlen > _cstr_rep(self)->cap) {
@@ -282,7 +282,7 @@ cstr_append_n(cstr_t* self, const char* str, size_t n) { return self;
}
-STC_INLINE void _cstr_internal_move(cstr_t* self, size_t pos1, size_t pos2) {
+STC_INLINE void _cstr_internal_move(cstr* self, size_t pos1, size_t pos2) {
if (pos1 == pos2)
return;
size_t len = _cstr_rep(self)->size, newlen = len + pos2 - pos1;
@@ -293,7 +293,7 @@ STC_INLINE void _cstr_internal_move(cstr_t* self, size_t pos1, size_t pos2) { }
STC_DEF void
-cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n) {
+cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n) {
c_withbuffer (xstr, char, n) {
memcpy(xstr, str, n);
_cstr_internal_move(self, pos + len, pos + n);
@@ -302,7 +302,7 @@ cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n) }
STC_DEF void
-cstr_erase_n(cstr_t* self, size_t pos, size_t n) {
+cstr_erase_n(cstr* self, size_t pos, size_t n) {
size_t len = _cstr_rep(self)->size;
if (len) {
memmove(&self->str[pos], &self->str[pos + n], len - (pos + n));
@@ -311,7 +311,7 @@ cstr_erase_n(cstr_t* self, size_t pos, size_t n) { }
STC_DEF bool
-cstr_getdelim(cstr_t *self, int delim, FILE *fp) {
+cstr_getdelim(cstr *self, int delim, FILE *fp) {
size_t pos = 0, cap = _cstr_rep(self)->cap;
int c = fgetc(fp);
if (c == EOF)
@@ -329,20 +329,20 @@ cstr_getdelim(cstr_t *self, int delim, FILE *fp) { }
STC_DEF size_t
-cstr_find(cstr_t s, const char* needle) {
+cstr_find(cstr s, const char* needle) {
char* res = strstr(s.str, needle);
return res ? res - s.str : cstr_npos;
}
STC_DEF size_t
-cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t n) {
+cstr_find_n(cstr s, const char* needle, size_t pos, size_t n) {
if (pos > _cstr_rep(&s)->size) return cstr_npos;
char* res = c_strnstr(s.str + pos, needle, n);
return res ? res - s.str : cstr_npos;
}
STC_DEF size_t
-cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t n) {
+cstr_ifind_n(cstr s, const char* needle, size_t pos, size_t n) {
if (pos > _cstr_rep(&s)->size) return cstr_npos;
char* res = c_strncasestr(s.str + pos, needle, n);
return res ? res - s.str : cstr_npos;
@@ -41,7 +41,7 @@ _c_using_cvec(cvec_##X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue)
#define using_cvec_str() \
- _c_using_cvec(cvec_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
+ _c_using_cvec(cvec_str, cstr, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*)
struct cvec_rep { size_t size, cap; void* data[]; };
|
