summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--benchmarks/others/clist_v1.h2
-rw-r--r--benchmarks/others/csmap_v1.h162
-rw-r--r--docs/carray_api.md52
-rw-r--r--docs/ccommon_api.md2
-rw-r--r--docs/cmap_api.md167
-rw-r--r--docs/cset_api.md21
-rw-r--r--docs/csmap_api.md11
-rw-r--r--docs/csset_api.md25
-rw-r--r--examples/advanced.c2
-rw-r--r--examples/bits.c2
-rw-r--r--examples/complex.c2
-rw-r--r--examples/demos.c22
-rw-r--r--examples/ex_gauss1.c8
-rw-r--r--stc/carray.h62
-rw-r--r--stc/cbits.h98
-rw-r--r--stc/cdeq.h2
-rw-r--r--stc/clist.h2
-rw-r--r--stc/cmap.h85
-rw-r--r--stc/cset.h2
-rw-r--r--stc/csmap.h100
-rw-r--r--stc/csset.h2
-rw-r--r--stc/cstr.h160
-rw-r--r--stc/cvec.h2
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
diff --git a/stc/cdeq.h b/stc/cdeq.h
index b122248a..f4ed7159 100644
--- a/stc/cdeq.h
+++ b/stc/cdeq.h
@@ -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) \
diff --git a/stc/cmap.h b/stc/cmap.h
index 1e1863eb..daefb9e9 100644
--- a/stc/cmap.h
+++ b/stc/cmap.h
@@ -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; \
diff --git a/stc/cset.h b/stc/cset.h
index cae23b80..f8ccc511 100644
--- a/stc/cset.h
+++ b/stc/cset.h
@@ -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_(...)
diff --git a/stc/cstr.h b/stc/cstr.h
index 44d79c72..2bdcf3a0 100644
--- a/stc/cstr.h
+++ b/stc/cstr.h
@@ -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;
diff --git a/stc/cvec.h b/stc/cvec.h
index 5102d6e8..c6ca392a 100644
--- a/stc/cvec.h
+++ b/stc/cvec.h
@@ -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[]; };