From 90624d6d398ff1d0f79df3dd656c4ad0c9c498a9 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 9 Aug 2022 17:34:13 +0200 Subject: Experiment with other type of iterator. Does not compile. --- docs/csview_api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/csview_api.md b/docs/csview_api.md index 09f377d1..1e2ed408 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -150,7 +150,7 @@ int main() printf("%s\n", cstr_str(&s1)); c_foreach (i, cstr, s1) - printf("%.*s,", c_ARGsv(i.chr)); + printf("%.*s,", c_ARGsv(i.u8.chr)); } } ``` -- cgit v1.2.3 From 8b63c557e383736b617594d6c0f38956f770dc3b Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 08:19:09 +0200 Subject: API Change cvec/cdeq: Return iter from all range operations instead of pointers. --- docs/cdeq_api.md | 16 +++++++------- docs/cvec_api.md | 18 ++++++++-------- include/stc/cdeq.h | 57 ++++++++++++++++++++++++------------------------ include/stc/cvec.h | 63 +++++++++++++++++++++++++++--------------------------- 4 files changed, 77 insertions(+), 77 deletions(-) (limited to 'docs') diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 6826946c..e7336a26 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -57,17 +57,17 @@ cdeq_X_value* cdeq_X_emplace_back(cdeq_X* self, i_valraw raw); cdeq_X_value* cdeq_X_emplace(cdeq_X* self, i_valraw raw); // alias for emplace_back() void cdeq_X_pop_back(cdeq_X* self); -cdeq_X_value* cdeq_X_insert(cdeq_X* self, size_t idx, i_val value); // move value -cdeq_X_value* cdeq_X_insert_n(cdeq_X* self, size_t idx, const i_val[] arr, size_t n); // move arr values -cdeq_X_value* cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); // move value -cdeq_X_value* cdeq_X_insert_range_p(cdeq_X* self, i_val* pos, +cdeq_X_iter cdeq_X_insert(cdeq_X* self, size_t idx, i_val value); // move value +cdeq_X_iter cdeq_X_insert_n(cdeq_X* self, size_t idx, const i_val[] arr, size_t n); // move arr values +cdeq_X_iter cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); // move value +cdeq_X_iter cdeq_X_insert_range_p(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2); -cdeq_X_value* cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); -cdeq_X_value* cdeq_X_emplace_at(cdeq_X* self, cdeq_X_iter it, i_valraw raw); -cdeq_X_value* cdeq_X_emplace_range(cdeq_X* self, cdeq_X_iter it, // will clone +cdeq_X_iter cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); +cdeq_X_iter cdeq_X_emplace_at(cdeq_X* self, cdeq_X_iter it, i_valraw raw); +cdeq_X_iter cdeq_X_emplace_range(cdeq_X* self, cdeq_X_iter it, // will clone cdeq_X_iter it1, cdeq_X_iter it2); -cdeq_X_value* cdeq_X_emplace_range_p(cdeq_X* self, i_val* pos, +cdeq_X_iter cdeq_X_emplace_range_p(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2); cdeq_X_iter cdeq_X_erase_n(cdeq_X* self, size_t idx, size_t n); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index a907c827..b33cdc75 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -36,7 +36,7 @@ void cvec_X_clear(cvec_X* self); void cvec_X_copy(cvec_X* self, const cvec_X* other); bool cvec_X_reserve(cvec_X* self, size_t cap); bool cvec_X_resize(cvec_X* self, size_t size, i_val null); -cvec_X_value* cvec_X_append_uninit(cvec_X* self, size_t n); // return start of uninit +cvec_X_iter cvec_X_insert_uninit_p(cvec_X* self, i_val* pos, size_t n); // return pos iter void cvec_X_shrink_to_fit(cvec_X* self); void cvec_X_swap(cvec_X* a, cvec_X* b); void cvec_X_drop(cvec_X* self); // destructor @@ -68,17 +68,17 @@ cvec_X_value* cvec_X_emplace_back(cvec_X* self, i_valraw raw); void cvec_X_pop(cvec_X* self); void cvec_X_pop_back(cvec_X* self); // alias for pop -cvec_X_value* cvec_X_insert(cvec_X* self, size_t idx, i_val value); // move value -cvec_X_value* cvec_X_insert_n(cvec_X* self, size_t idx, const i_val[] arr, size_t n); // move n values -cvec_X_value* cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); // move value -cvec_X_value* cvec_X_insert_range_p(cvec_X* self, i_val* pos, +cvec_X_iter cvec_X_insert(cvec_X* self, size_t idx, i_val value); // move value +cvec_X_iter cvec_X_insert_n(cvec_X* self, size_t idx, const i_val[] arr, size_t n); // move n values +cvec_X_iter cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); // move value +cvec_X_iter cvec_X_insert_range_p(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2); -cvec_X_value* cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); -cvec_X_value* cvec_X_emplace_at(cvec_X* self, cvec_X_iter it, i_valraw raw); -cvec_X_value* cvec_X_emplace_range(cvec_X* self, cvec_X_iter it, // will clone +cvec_X_iter cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); +cvec_X_iter cvec_X_emplace_at(cvec_X* self, cvec_X_iter it, i_valraw raw); +cvec_X_iter cvec_X_emplace_range(cvec_X* self, cvec_X_iter it, // will clone cvec_X_iter it1, cvec_X_iter it2); -cvec_X_value* cvec_X_emplace_range_p(cvec_X* self, i_val* pos, +cvec_X_iter cvec_X_emplace_range_p(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2); cvec_X_iter cvec_X_erase_n(cvec_X* self, size_t idx, size_t n); diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 644af838..179959fd 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -50,11 +50,11 @@ STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value); STC_API void _cx_memb(_shrink_to_fit)(_cx_self *self); #if !defined _i_queue #if !defined _i_no_emplace -STC_API _cx_value* _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2); #endif // _i_no_emplace #if !defined _i_no_clone -STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2); #endif // !_i_no_clone @@ -64,7 +64,7 @@ STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value #endif STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_key value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2); -STC_API _cx_value* _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2); #endif // !_i_queue @@ -110,15 +110,15 @@ STC_INLINE _cx_value* _cx_memb(_at_mut)(_cx_self* self, const size_t idx) { STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value) { return _cx_memb(_push)(self, value); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) { return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], const size_t n) { return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { return _cx_memb(_insert_range_p)(self, (it.ref ? it.ref : it._end), &value, &value + 1); } @@ -161,11 +161,11 @@ STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw) { return _cx_memb(_push)(self, i_keyfrom(raw)); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], const size_t n) { return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it._end), &raw, &raw + 1); } @@ -345,16 +345,17 @@ _cx_memb(_expand_left_half_)(_cx_self* self, const size_t idx, const size_t n) { } } -static _cx_value* +static _cx_iter _cx_memb(_insert_uninit_p)(_cx_self* self, const _cx_value* pos, const size_t n) { const size_t idx = pos - self->data; if (idx*2 < cdeq_rep_(self)->size) _cx_memb(_expand_left_half_)(self, idx, n); else _cx_memb(_expand_right_half_)(self, idx, n); + struct cdeq_rep* rep = cdeq_rep_(self); if (n) - cdeq_rep_(self)->size += n; /* do only if size > 0 */ - return self->data + idx; + rep->size += n; /* do only if size > 0 */ + return c_make(_cx_iter){self->data + idx, self->data + rep->size}; } STC_DEF _cx_value* @@ -368,45 +369,45 @@ _cx_memb(_push_front)(_cx_self* self, i_key value) { return self->data; } -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { - pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); - if (pos) - memcpy(pos, p1, (p2 - p1)*sizeof *p1); - return pos; + _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + if (it.ref) + memcpy(it.ref, p1, (p2 - p1)*sizeof *p1); + return it; } STC_DEF _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { intptr_t len = p2 - p1; - _cx_value* p = p1, *end = self->data + cdeq_rep_(self)->size; + struct cdeq_rep* r = cdeq_rep_(self); + _cx_value* p = p1, *end = self->data + r->size; for (; p != p2; ++p) { i_keydrop(p); } memmove(p1, p2, (end - p2) * sizeof *p1); - cdeq_rep_(self)->size -= len; + r->size -= len; return c_make(_cx_iter){p2 == end ? NULL : p1, end - len}; } #if !defined _i_no_emplace -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { - pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); - _cx_value* it = pos; - if (pos) for (; p1 != p2; ++p1) - *pos++ = i_keyfrom((*p1)); + _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + if (it.ref) + for (_cx_iter j = it; p1 != p2; ++p1) + *j.ref++ = i_keyfrom((*p1)); return it; } #endif // !_i_no_emplace #if !defined _i_no_clone -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { - pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); - _cx_value* it = pos; - if (pos) for (; p1 != p2; ++p1) - *pos++ = i_keyclone((*p1)); + _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + if (it.ref) for (_cx_iter j; p1 != p2; ++p1) + *j.ref++ = i_keyclone((*p1)); return it; } #endif // !_i_no_clone diff --git a/include/stc/cvec.h b/include/stc/cvec.h index a457c3dc..a5e1fac6 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -84,9 +84,9 @@ STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap); STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_key null); STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2); -STC_API _cx_value* _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2); -STC_API _cx_value* _cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n); +STC_API _cx_iter _cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n); #if !c_option(c_no_cmp) STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y); STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, _cx_raw raw); @@ -94,17 +94,17 @@ STC_API _cx_iter _cx_memb(_binary_search_in)(_cx_iter it1, _cx_iter it2, #endif #if !defined _i_no_emplace -STC_API _cx_value* _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2); STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw) { return _cx_memb(_push)(self, i_keyfrom(raw)); } STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw) { return _cx_memb(_push)(self, i_keyfrom(raw)); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], const size_t n) { return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it._end), &raw, &raw + 1); } @@ -112,7 +112,7 @@ _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { #if !defined _i_no_clone STC_API _cx_self _cx_memb(_clone)(_cx_self cx); -STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2); STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val) { return i_keyclone(val); } @@ -156,20 +156,20 @@ _cx_memb(_shrink_to_fit)(_cx_self* self) { _cx_memb(_reserve)(self, _cx_memb(_size)(self)); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_append_uninit)(_cx_self* self, const size_t n) { return _cx_memb(_insert_uninit_p)(self, self->data + _cx_memb(_size)(self), n); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) { return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], const size_t n) { return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n); } -STC_INLINE _cx_value* +STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { return _cx_memb(_insert_range_p)(self, (it.ref ? it.ref : it._end), &value, &value + 1); } @@ -330,40 +330,39 @@ _cx_memb(_push)(_cx_self* self, i_key value) { *v = value; return v; } -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n) { const size_t idx = pos - self->data; struct cvec_rep* r = cvec_rep_(self); - if (!n) - return pos; if (r->size + n > r->cap) { if (!_cx_memb(_reserve)(self, r->size*3/2 + n)) - return NULL; + return _cx_memb(_end)(self); r = cvec_rep_(self); pos = self->data + idx; } memmove(pos + n, pos, (r->size - idx)*sizeof *pos); r->size += n; - return pos; + return c_make(_cx_iter){pos, self->data + r->size}; } -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { - pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); - if (pos) - memcpy(pos, p1, (p2 - p1)*sizeof *p1); - return pos; + _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + if (it.ref) + memcpy(it.ref, p1, (p2 - p1)*sizeof *p1); + return it; } STC_DEF _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { intptr_t len = p2 - p1; - _cx_value* p = p1, *end = self->data + cvec_rep_(self)->size; + struct cvec_rep* r = cvec_rep_(self); + _cx_value* p = p1, *end = self->data + r->size; for (; p != p2; ++p) { i_keydrop(p); } memmove(p1, p2, (end - p2) * sizeof *p1); - cvec_rep_(self)->size -= len; + r->size -= len; return c_make(_cx_iter){p2 == end ? NULL : p1, end - len}; } @@ -377,24 +376,24 @@ _cx_memb(_clone)(_cx_self cx) { return out; } -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { - pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); - _cx_value* it = pos; - if (pos) for (; p1 != p2; ++p1) - *pos++ = i_keyclone((*p1)); + _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + if (it.ref) + for (_cx_iter j = it; p1 != p2; ++p1) + *j.ref++ = i_keyclone((*p1)); return it; } #if !defined _i_no_emplace -STC_DEF _cx_value* +STC_DEF _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { - pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); - _cx_value* it = pos; - if (pos) for (; p1 != p2; ++p1) - *pos++ = i_keyfrom((*p1)); + _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + if (it.ref) + for (_cx_iter j = it; p1 != p2; ++p1) + *j.ref++ = i_keyfrom((*p1)); return it; } #endif // !_i_no_emplace -- cgit v1.2.3 From 5cf6b762012168be51b32a1a85ab2bc33504f020 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 11 Aug 2022 17:58:15 +0200 Subject: Fixed issue with cbox / carc. Minor update some examples. --- docs/carc_api.md | 12 +++---- docs/cbox_api.md | 8 ++--- examples/music_arc.c | 37 +++++++++++---------- examples/prime.c | 7 ++++ examples/rawptr_elements.c | 82 ++++++++++++++++++++-------------------------- include/stc/carc.h | 17 ++++++---- include/stc/cbox.h | 11 ++++--- include/stc/template.h | 5 +++ 8 files changed, 92 insertions(+), 87 deletions(-) (limited to 'docs') diff --git a/docs/carc_api.md b/docs/carc_api.md index 687e9547..243349a8 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -32,8 +32,8 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ## Methods ```c carc_X carc_X_init(); // empty shared pointer -carc_X carc_X_from(i_valraw raw); // construct a new value in an carc from raw type. -carc_X carc_X_make(i_val val); // make a carc from constructed val object. Faster than from_ptr(). +carc_X carc_X_new(i_valraw raw); // construct a new value in an carc from raw type. +carc_X carc_X_from(i_val val); // create a carc from constructed val object. Faster than from_ptr(). carc_X carc_X_from_ptr(i_val* p); // create a carc from raw pointer. Takes ownership of p. carc_X carc_X_clone(carc_X other); // return other with increased use count @@ -96,18 +96,18 @@ int main() // POPULATE s1 with shared pointers to Map: Map *map; - map = Stack_push(&s1, Arc_make(Map_init()))->get; // push empty map to s1. + map = Stack_push(&s1, Arc_from(Map_init()))->get; // push empty map to s1. c_forarray (Map_raw, v, { {"Joey", 1990}, {"Mary", 1995}, {"Joanna", 1992}}) { Map_emplace(map, v->first, v->second); // populate it. } - map = Stack_push(&s1, Arc_make(Map_init()))->get; + map = Stack_push(&s1, Arc_from(Map_init()))->get; c_forarray (Map_raw, v, { {"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980} }) { Map_emplace(map, v->first, v->second); } // POPULATE s2: - map = Stack_push(&s2, Arc_make(Map_init()))->get; + map = Stack_push(&s2, Arc_from(Map_init()))->get; c_forarray (Map_raw, v, { {"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003} }) { Map_emplace(map, v->first, v->second); } @@ -118,7 +118,7 @@ int main() // Deep-copy (does not share) a Map from s1 to s2. // s2 will contain two shared and two unshared maps. - map = Stack_push(&s2, Arc_make(Map_clone(*s1.data[1].get)))->get; + map = Stack_push(&s2, Arc_from(Map_clone(*s1.data[1].get)))->get; // Add one more element to the cloned map: Map_emplace_or_assign(map, "Cloned", 2022); diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 1119d930..9801ad92 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -68,7 +68,7 @@ void int_drop(int* x) { #define i_type IBox #define i_val int #define i_valdrop int_drop // optional func, just to display elements destroyed -#define i_valclone(x) x // must specify because i_valdrop was defined. +#define i_valclone(x) x // must specified when i_valdrop is defined. #include #define i_type ISet @@ -84,10 +84,8 @@ int main() c_auto (IVec, vec) // declare and init vec, call drop at scope exit c_auto (ISet, set) // similar { - c_forarray (IBox, v, { - IBox_make(2021), IBox_make(2012), - IBox_make(2022), IBox_make(2015), - }) IVec_push(&vec, *v); + c_forarray (int, v, {2021, 2012, 2022, 2015}) + IVec_emplace(&vec, *v); // same as: IVec_push(&vec, IBox_from(*v)); printf("vec:"); c_foreach (i, IVec, vec) diff --git a/examples/music_arc.c b/examples/music_arc.c index ac730bc3..8cbcbb59 100644 --- a/examples/music_arc.c +++ b/examples/music_arc.c @@ -8,7 +8,7 @@ struct Song cstr title; } typedef Song; -Song Song_new(const char* artist, const char* title) +Song Song_from(const char* artist, const char* title) { return (Song){cstr_from(artist), cstr_from(title)}; } void Song_drop(Song* s) { @@ -16,39 +16,40 @@ void Song_drop(Song* s) { c_drop(cstr, &s->artist, &s->title); } -#define i_type SongPtr +#define i_type SongArc #define i_val Song #define i_valdrop Song_drop #define i_opt c_no_cmp #include #define i_type SongVec -#define i_val_arcbox SongPtr +#define i_val_arcbox SongArc #include void example3() { c_auto (SongVec, vec, vec2) { - c_forarray (SongPtr, v, { - SongPtr_make(Song_new("Bob Dylan", "The Times They Are A Changing")), - SongPtr_make(Song_new("Aretha Franklin", "Bridge Over Troubled Water")), - SongPtr_make(Song_new("Thalia", "Entre El Mar y Una Estrella")) + c_forarray (SongArc, v, { + SongArc_make(Song_from("Bob Dylan", "The Times They Are A Changing")), + SongArc_make(Song_from("Aretha Franklin", "Bridge Over Troubled Water")), + SongArc_make(Song_from("Thalia", "Entre El Mar y Una Estrella")) }) SongVec_push_back(&vec, *v); c_foreach (s, SongVec, vec) if (!cstr_equals(s.ref->get->artist, "Bob Dylan")) - SongVec_push_back(&vec2, SongPtr_clone(*s.ref)); - - c_forarray (SongPtr, v, { - SongPtr_make(Song_new("Michael Jackson", "Billie Jean")), - SongPtr_make(Song_new("Rihanna", "Stay")), - }) SongVec_push_back(&vec2, *v); - - c_foreach (s, SongVec, vec2) - printf("%s - %s: refs %lu\n", cstr_str(&s.ref->get->artist), - cstr_str(&s.ref->get->title), - *s.ref->use_count); + SongVec_push_back(&vec2, SongArc_clone(*s.ref)); + + SongVec_push_back(&vec2, SongArc_make(Song_from("Michael Jackson", "Billie Jean"))); + SongVec_push_back(&vec2, SongArc_make(Song_from("Rihanna", "Stay"))); + + c_forarray (SongVec, v, {vec, vec2}) { + puts("VEC:"); + c_foreach (s, SongVec, *v) + printf(" %s - %s, REFS: %lu\n", cstr_str(&s.ref->get->artist), + cstr_str(&s.ref->get->title), + *s.ref->use_count); + } } } diff --git a/examples/prime.c b/examples/prime.c index 01a6800b..85a66ee5 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -37,5 +37,12 @@ int main(void) for (size_t i = 3; i < 1000; i += 2) if (cbits_test(&primes, i>>1)) printf(" %" PRIuMAX "", i); puts(""); + + int k = 20; + c_forrange (intptr_t, i, n-1, 1, -2) { + if (k == 0) break; + else if (cbits_test(&primes, i>>1)) printf("%" PRIdMAX "\n", i), k--; + } + puts(""); } } diff --git a/examples/rawptr_elements.c b/examples/rawptr_elements.c index c3e3188d..bae314fd 100644 --- a/examples/rawptr_elements.c +++ b/examples/rawptr_elements.c @@ -1,67 +1,55 @@ #include #include -struct { double x, y; } typedef Point; - -// Set of Point pointers: define all template parameters "in-line" -// Note it may be simpler to use a cbox for this. -#define i_key Point* -#define i_keydrop(x) c_free(*(x)) -#define i_keyclone(x) c_new(Point, *(x)) -#define i_hash(x) c_default_hash(*(x)) -#define i_cmp(x, y) memcmp(*(x), *(y), sizeof **(x)) // not good! -#define i_tag pnt -#include - #include -// Map of int64 pointers: Define i_valraw as int64_t for easy emplace calls! +// Map of cstr => int64 pointers typedef int64_t inttype; + +// Do it without cbox: +#define i_type SIPtrMap #define i_key_str #define i_val inttype* #define i_valraw inttype -#define i_valfrom(raw) (puts("from"), c_new(inttype, raw)) -#define i_valto(x) (puts("to"), **(x)) -#define i_valclone c_derived_valclone // enables clone via valto+valfrom -#define i_valdrop(x) c_free(*(x)) +#define i_valfrom(raw) c_new(inttype, raw) +#define i_valto(x) **x +#define i_valclone(x) c_new(inttype, *x) +#define i_valdrop(x) c_free(*x) #include -int main() -{ - c_auto (cset_pnt, set, cpy) - { - printf("Set with pointer elements:\n"); - // c++: set.insert(new Point{1.2, 3.4}); - cset_pnt_insert(&set, c_new(Point, {1.2, 3.4})); - Point* q = *cset_pnt_insert(&set, c_new(Point, {6.1, 4.7})).ref; - cset_pnt_insert(&set, c_new(Point, {5.7, 2.3})); - - cpy = cset_pnt_clone(set); - cset_pnt_erase(&cpy, q); +// With cbox: +#define i_type IBox +#define i_val int +#include // - printf("set:"); - c_foreach (i, cset_pnt, set) - printf(" (%g %g)", i.ref[0]->x, i.ref[0]->y); - - printf("\ncpy:"); - c_foreach (i, cset_pnt, cpy) - printf(" (%g %g)", i.ref[0]->x, i.ref[0]->y); - puts(""); - } +#define i_type SIBoxMap +#define i_key_str +#define i_val_arcbox IBox +#include - c_auto (cmap_str, map, m2) +int main() +{ + c_auto (SIPtrMap, map, m1) + c_auto (SIBoxMap, m2) { printf("\nMap with pointer elements:\n"); - cmap_str_insert(&map, cstr_new("testing"), c_new(inttype, 999)); - cmap_str_insert(&map, cstr_new("done"), c_new(inttype, 111)); + SIPtrMap_insert(&map, cstr_from("testing"), c_new(inttype, 1)); + SIPtrMap_insert(&map, cstr_from("done"), c_new(inttype, 2)); - // Emplace: implicit key, val construction using i_keyfrom/i_valfrom: - cmap_str_emplace(&map, "hello", 200); - cmap_str_emplace(&map, "goodbye", 400); + // Emplace: implicit key, val construction: + SIPtrMap_emplace(&map, "hello", 3); + SIPtrMap_emplace(&map, "goodbye", 4); - // default uses i_valfrom+i_valto when no i_valclone defined: - m2 = cmap_str_clone(map); + m1 = SIPtrMap_clone(map); - c_forpair (name, number, cmap_str, m2) + c_forpair (name, number, SIPtrMap, m1) printf("%s: %" PRIdMAX "\n", cstr_str(_.name), **_.number); + + + puts("\nIBox map:"); + SIBoxMap_insert(&m2, cstr_from("Hello"), IBox_from(123)); + SIBoxMap_emplace(&m2, "World", 999); + c_forpair (name, number, SIBoxMap, m2) + printf("%s: %d\n", cstr_str(_.name), *_.number->get); + puts(""); } } diff --git a/include/stc/carc.h b/include/stc/carc.h index 57f00899..62b33bed 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -34,18 +34,18 @@ void Person_drop(Person* p) { c_drop(cstr, &p->name, &p->last); } -#define i_tag person +#define i_type ArcPers #define i_key Person #define i_keydrop Person_drop #define i_opt c_no_cmp #include int main() { - carc_person p = carc_person_make(Person_new("John", "Smiths")); - carc_person q = carc_person_clone(p); // share the pointer + ArcPers p = ArcPers_from(Person_new("John", "Smiths")); + ArcPers q = ArcPers_clone(p); // share the pointer printf("%s %s. uses: %" PRIuMAX "\n", cstr_str(&q.get->name), cstr_str(&q.get->last), *q.use_count); - c_drop(carc_person, &p, &q); + c_drop(ArcPers, &p, &q); } */ #include "ccommon.h" @@ -104,13 +104,16 @@ STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) { } // c++: std::make_shared<_cx_value>(val) -STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) { +STC_INLINE _cx_self _cx_memb(_from)(_cx_value val) { _cx_self ptr; _cx_carc_rep *rep = c_alloc(_cx_carc_rep); *(ptr.use_count = &rep->counter) = 1; *(ptr.get = &rep->value) = val; return ptr; } +// [deprecated] +STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) + { return _cx_memb(_from)(val); } STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self) { return i_keyto(self->get); } @@ -144,8 +147,8 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) { } #if !defined _i_no_clone && !defined _i_no_emplace - STC_INLINE _cx_self _cx_memb(_from)(_cx_raw raw) - { return _cx_memb(_make)(i_keyfrom(raw)); } + STC_INLINE _cx_self _cx_memb(_new)(_cx_raw raw) + { return _cx_memb(_from)(i_keyfrom(raw)); } #endif // !_i_no_clone // does not use i_keyclone, so OK to always define. diff --git a/include/stc/cbox.h b/include/stc/cbox.h index c3a9dd02..467dd645 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -48,7 +48,7 @@ void Person_drop(Person* p) { int main() { c_auto (PBox, p, q) { - p = PBox_make(Person_from("John Smiths", "josmiths@gmail.com")); + p = PBox_from(Person_from("John Smiths", "josmiths@gmail.com")); q = PBox_clone(p); cstr_assign(&q.get->name, "Joe Smiths"); @@ -89,10 +89,13 @@ STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) { return c_make(_cx_self){p}; } // c++: std::make_unique(val) -STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) { +STC_INLINE _cx_self _cx_memb(_from)(_cx_value val) { _cx_self ptr = {c_alloc(_cx_value)}; *ptr.get = val; return ptr; } +// [deprecated] +STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) + { return _cx_memb(_from)(val); } STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self) { return i_keyto(self->get); } @@ -128,8 +131,8 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) { #if !defined _i_no_clone #if !defined _i_no_emplace - STC_INLINE _cx_self _cx_memb(_from)(_cx_raw raw) - { return _cx_memb(_make)(i_keyfrom(raw)); } + STC_INLINE _cx_self _cx_memb(_new)(_cx_raw raw) + { return _cx_memb(_from)(i_keyfrom(raw)); } #endif STC_INLINE _cx_self _cx_memb(_clone)(_cx_self other) { if (!other.get) diff --git a/include/stc/template.h b/include/stc/template.h index ac9d5b5e..eeccc39e 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -109,6 +109,7 @@ #endif #elif defined i_key_arcbox #define i_key_bind i_key_arcbox + #define i_keyfrom c_paste(i_key_arcbox, _from) #define i_keyraw c_paste(i_key_arcbox, _value) #define i_keyto c_paste(i_key_arcbox, _toval) #define i_eq c_paste(i_key_arcbox, _value_eq) @@ -199,6 +200,7 @@ #define i_valto cstr_sv #elif defined i_val_arcbox #define i_val_bind i_val_arcbox + #define i_valfrom c_paste(i_val_arcbox, _from) #define i_valraw c_paste(i_val_arcbox, _value) #define i_valto c_paste(i_val_arcbox, _toval) #endif @@ -216,6 +218,9 @@ #endif #endif +#ifndef i_val + #error "i_val* must be defined for maps" +#endif #if defined i_valraw ^ defined i_valto #error "both i_valto and i_valraw must be defined, if any" #elif defined i_valfrom && !defined i_valraw -- cgit v1.2.3 From 2526ae23267a5381f0564100b2aba73dfc367b58 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 22:34:16 +0200 Subject: Update cbox/carc docs. --- docs/carc_api.md | 14 ++++++++++---- docs/cbox_api.md | 15 +++++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'docs') diff --git a/docs/carc_api.md b/docs/carc_api.md index 243349a8..8061c642 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -47,10 +47,16 @@ long carc_X_use_count(carc_X ptr); void carc_X_reset(carc_X* self); void carc_X_reset_to(carc_X* self, i_val* p); // assign new carc from ptr. Takes ownership of p. -uint64_t carc_X_value_hash(const i_val* x); // hash value -int carc_X_value_cmp(const i_val* x, const i_val* y); // compares pointer addresses if 'i_opt c_no_cmp' - // is defined. Otherwise uses 'i_cmp' or default compare. -bool carc_X_value_eq(const i_val* x, const i_val* y); // carc_X_value_cmp == 0 +uint64_t carc_X_hash(const carc_X* x); // hash value +int carc_X_cmp(const carc_X* x, const carc_X* y); // compares pointer addresses if 'i_opt c_no_cmp' + // is defined. Otherwise uses 'i_cmp' or default cmp. +bool carc_X_eq(const carc_X* x, const carc_X* y); // carc_X_cmp() == 0 + +// functions on pointed to objects. + +uint64_t carc_X_value_hash(const i_val* x); +int carc_X_value_cmp(const i_val* x, const i_val* y); +bool carc_X_value_eq(const i_val* x, const i_val* y); ``` ## Types and constants diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 9801ad92..2587fdf8 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -44,11 +44,18 @@ void cbox_X_drop(cbox_X* self); // destruct the co void cbox_X_reset(cbox_X* self); void cbox_X_reset_to(cbox_X* self, i_val* p); // assign new cbox from ptr. Takes ownership of p. -uint64_t cbox_X_value_hash(const i_val* p); // hash value -int cbox_X_value_cmp(const i_val* p, const i_val* y); // compares pointer addresses if 'i_opt c_no_cmp' - // is defined. Otherwise uses 'i_cmp' or default compare. -bool cbox_X_value_eq(const i_val* p, const i_val* y); // cbox_X_value_cmp == 0 +uint64_t cbox_X_hash(const cbox_X* x); // hash value +int cbox_X_cmp(const cbox_X* x, const cbox_X* y); // compares pointer addresses if 'i_opt c_no_cmp' + // is defined. Otherwise uses 'i_cmp' or default cmp. +bool cbox_X_eq(const cbox_X* x, const cbox_X* y); // cbox_X_cmp() == 0 + +// functions on pointed to objects. + +uint64_t cbox_X_value_hash(const i_val* x); +int cbox_X_value_cmp(const i_val* x, const i_val* y); +bool cbox_X_value_eq(const i_val* x, const i_val* y); ``` + ## Types and constants | Type name | Type definition | Used to represent... | -- cgit v1.2.3 From f534db7ac4a993a05074868b8840a3a674ac76b4 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 23:33:14 +0200 Subject: find_if, find_in changed. --- docs/ccommon_api.md | 9 ++++----- examples/arc_containers.c | 2 +- examples/arcvec_erase.c | 7 +++---- examples/city.c | 9 ++++++--- include/stc/ccommon.h | 17 ++++++++++------- 5 files changed, 24 insertions(+), 20 deletions(-) (limited to 'docs') diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index b4a90036..179e7398 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -209,16 +209,15 @@ c_forrange (int, i, 30, 0, -5) printf(" %d", i); ### c_find_if, c_find_in Search linearily in containers using a predicate ``` -// NOTE: it.ref is NULL if not found, not cvec_i_end(&vec).ref -// This makes it easier to test. -cvec_i_iter it; +cvec_i_iter it, it1, it2; // Search vec for first value > 2: -c_find_if(cvec_i, vec, it, *it.ref > 2); +// NOTE: it.ref is NULL if not found +c_find_if(it, cvec_i, vec, *it.ref > 2); if (it.ref) printf("%d\n", *it.ref); // Search within a range: -c_find_in(csmap_str, it1, it2, it, cstr_contains(*it.ref, "hello")); +c_find_in(it, csmap_str, it1, it2, cstr_contains(*it.ref, "hello")); if (it.ref) cmap_str_erase_at(&map, it); ``` diff --git a/examples/arc_containers.c b/examples/arc_containers.c index e8716129..debc6617 100644 --- a/examples/arc_containers.c +++ b/examples/arc_containers.c @@ -53,7 +53,7 @@ int main() // Clone (deep copy) a Map from the stack to the list // List will contain two shared and two unshared maps. - map = List_push_back(&list, Arc_make(Map_clone(*stack.data[1].get)))->get; + map = List_push_back(&list, Arc_from(Map_clone(*stack.data[1].get)))->get; // Add one more element to the cloned map: Map_emplace_or_assign(map, "CLONED", 2021); diff --git a/examples/arcvec_erase.c b/examples/arcvec_erase.c index eba77f51..b96f4278 100644 --- a/examples/arcvec_erase.c +++ b/examples/arcvec_erase.c @@ -20,13 +20,12 @@ int main() { c_auto (Vec, vec) { - const int v[] = {2012, 1990, 2012, 2019, 2015}; - c_forrange (i, c_arraylen(v)) - Vec_push_back(&vec, Arc_make(v[i])); + c_forarray (int, v, {2012, 1990, 2012, 2019, 2015}) + Vec_emplace(&vec, *v); // clone the second 2012 and push it back. // note: cloning make sure that vec.data[2] has ref count 2. - Vec_push_back(&vec, Arc_clone(vec.data[2])); + Vec_push(&vec, Arc_clone(vec.data[2])); printf("vec before erase :"); c_foreach (i, Vec, vec) diff --git a/examples/city.c b/examples/city.c index c22693f9..0fcee341 100644 --- a/examples/city.c +++ b/examples/city.c @@ -58,8 +58,9 @@ int main(void) {"Berlin", "Germany", 4.3, 23.2, 9000000}, {"London", "UK", 4.3, 23.2, 9000000}, }) { - Cities_push(&cities, CityArc_make((City){cstr_from(c->name), cstr_from(c->country), - c->lat, c->lon, c->pop})); + Cities_emplace(&cities, (City){cstr_from(c->name), + cstr_from(c->country), + c->lat, c->lon, c->pop}); } copy = Cities_clone(cities); // share each element! @@ -73,7 +74,9 @@ int main(void) printf("Vec:\n"); c_foreach (c, Cities, cities) - printf("city:%s, %d, use:%ld\n", cstr_str(&c.ref->get->name), c.ref->get->population, CityArc_use_count(*c.ref)); + printf("city:%s, %d, use:%ld\n", cstr_str(&c.ref->get->name), + c.ref->get->population, + CityArc_use_count(*c.ref)); printf("\nMap:\n"); c_forpair (id, city, CityMap, map) diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 8ea58314..a4ae28aa 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -219,16 +219,19 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, #define c_pair(v) (v)->first, (v)->second #define c_drop(C, ...) do { c_forarray_p(C*, _p, {__VA_ARGS__}) C##_drop(*_p); } while(0) -#define c_find_if(C, cnt, it, pred) \ - c_find_in(C, C##_begin(&cnt), C##_end(&cnt), it, pred) +// it.ref == NULL when not found: +#define c_find_if(it, C, cnt, pred) do { \ + size_t index = 0; \ + for (it = C##_begin(&cnt); it.ref && !(pred); C##_next(&it)) \ + ++index; \ +} while (0) -// NB: it.ref == NULL when not found, not end.ref: -#define c_find_in(C, start, end, it, pred) do { \ +#define c_find_in(it, C, start, end, pred) do { \ size_t index = 0; \ - C##_iter _end = end; \ - for (it = start; it.ref != _end.ref && !(pred); C##_next(&it)) \ + const C##_value* _endref = (end).ref; \ + for (it = start; it.ref != _endref && !(pred); C##_next(&it)) \ ++index; \ - if (it.ref == _end.ref) it.ref = NULL; \ + if (it.ref == _endref) it.ref = NULL; \ } while (0) #endif // CCOMMON_H_INCLUDED -- cgit v1.2.3 From a417e5affc99233abb6dbb685154bfdea1b726e3 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Fri, 12 Aug 2022 11:38:10 +0200 Subject: More misc changes carc/cbox, cdeq/cvec. --- docs/carc_api.md | 10 +++++----- docs/cbox_api.md | 6 +++--- docs/cdeq_api.md | 8 ++++---- docs/cvec_api.md | 10 +++++----- examples/city.c | 25 +++++++++++-------------- include/stc/carc.h | 22 +++++++++++----------- include/stc/cbox.h | 16 +++------------- include/stc/cdeq.h | 29 +++++++++++++++++------------ include/stc/cvec.h | 17 +++++++++-------- include/stc/forward.h | 2 +- include/stc/template.h | 8 ++++---- 11 files changed, 73 insertions(+), 80 deletions(-) (limited to 'docs') diff --git a/docs/carc_api.md b/docs/carc_api.md index 8061c642..d09b1839 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -32,17 +32,17 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ## Methods ```c carc_X carc_X_init(); // empty shared pointer -carc_X carc_X_new(i_valraw raw); // construct a new value in an carc from raw type. -carc_X carc_X_from(i_val val); // create a carc from constructed val object. Faster than from_ptr(). -carc_X carc_X_from_ptr(i_val* p); // create a carc from raw pointer. Takes ownership of p. +carc_X carc_X_new(i_valraw raw); // create an carc from raw type (available if i_valraw defined by user). +carc_X carc_X_from(i_val val); // create an carc from constructed val object. Faster than from_ptr(). +carc_X carc_X_from_ptr(i_val* p); // create an carc from raw pointer. Takes ownership of p. carc_X carc_X_clone(carc_X other); // return other with increased use count carc_X carc_X_move(carc_X* self); // transfer ownership to another carc. void carc_X_take(carc_X* self, carc_X other); // take ownership of other. -void carc_X_assign(carc_X* self, carc_X other); // copy shared (increase use count) +void carc_X_copy(carc_X* self, carc_X other); // shared assign (increase use count) void carc_X_drop(carc_X* self); // destruct (decrease use count, free at 0) -long carc_X_use_count(carc_X ptr); +long carc_X_use_count(const carc_X* self); void carc_X_reset(carc_X* self); void carc_X_reset_to(carc_X* self, i_val* p); // assign new carc from ptr. Takes ownership of p. diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 2587fdf8..dc90fa8e 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -31,14 +31,14 @@ compare the pointer addresses when used. Additionally, `c_no_clone` or `i_is_fwd ## Methods ```c cbox_X cbox_X_init(); // return an empty cbox -cbox_X cbox_X_from(i_valraw raw); // construct a new boxed object from raw type, if defined. -cbox_X cbox_X_make(i_val val); // make a cbox from constructed val object. +cbox_X cbox_X_new(i_valraw raw); // create a cbox from raw type. Avail if i_valraw user defined. +cbox_X cbox_X_from(i_val val); // create a cbox from constructed val object. cbox_X cbox_X_from_ptr(i_val* p); // create a cbox from a pointer. Takes ownership of p. cbox_X cbox_X_clone(cbox_X other); // return deep copied clone cbox_X cbox_X_move(cbox_X* self); // transfer ownership to another cbox. void cbox_X_take(cbox_X* self, cbox_X other); // take ownership of other. -void cbox_X_assign(cbox_X* self, cbox_X other); // deep copy to self +void cbox_X_copy(cbox_X* self, cbox_X other); // deep copy to self void cbox_X_drop(cbox_X* self); // destruct the contained object and free's it. void cbox_X_reset(cbox_X* self); diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index e7336a26..a8d2baeb 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -29,6 +29,7 @@ cdeq_X cdeq_X_clone(cdeq_X deq); void cdeq_X_clear(cdeq_X* self); void cdeq_X_copy(cdeq_X* self, const cdeq_X* other); +cdeq_X_iter cdeq_X_copy_range_p(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2); bool cdeq_X_reserve(cdeq_X* self, size_t cap); void cdeq_X_shrink_to_fit(cdeq_X* self); void cdeq_X_swap(cdeq_X* a, cdeq_X* b); @@ -63,16 +64,15 @@ cdeq_X_iter cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); cdeq_X_iter cdeq_X_insert_range_p(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2); -cdeq_X_iter cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); +cdeq_X_iter cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); // clone values cdeq_X_iter cdeq_X_emplace_at(cdeq_X* self, cdeq_X_iter it, i_valraw raw); -cdeq_X_iter cdeq_X_emplace_range(cdeq_X* self, cdeq_X_iter it, // will clone - cdeq_X_iter it1, cdeq_X_iter it2); cdeq_X_iter cdeq_X_emplace_range_p(cdeq_X* self, i_val* pos, - const i_val* p1, const i_val* p2); + const i_valraw* p1, const i_valraw* p2); cdeq_X_iter cdeq_X_erase_n(cdeq_X* self, size_t idx, size_t n); cdeq_X_iter cdeq_X_erase_at(cdeq_X* self, cdeq_X_iter it); cdeq_X_iter cdeq_X_erase_range(cdeq_X* self, cdeq_X_iter it1, cdeq_X_iter it2); +cdeq_X_iter cdeq_X_erase_range_p(cdeq_X* self, i_val* p1, i_val* p2); void cdeq_X_sort(cdeq_X* self); void cdeq_X_sort_range(cdeq_X_iter i1, cdeq_X_iter i2, diff --git a/docs/cvec_api.md b/docs/cvec_api.md index b33cdc75..ea26c345 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -34,6 +34,7 @@ cvec_X cvec_X_clone(cvec_X vec); void cvec_X_clear(cvec_X* self); void cvec_X_copy(cvec_X* self, const cvec_X* other); +cvec_X_iter cvec_X_copy_range_p(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2); bool cvec_X_reserve(cvec_X* self, size_t cap); bool cvec_X_resize(cvec_X* self, size_t size, i_val null); cvec_X_iter cvec_X_insert_uninit_p(cvec_X* self, i_val* pos, size_t n); // return pos iter @@ -74,16 +75,15 @@ cvec_X_iter cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); cvec_X_iter cvec_X_insert_range_p(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2); -cvec_X_iter cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); +cvec_X_iter cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); // clone values cvec_X_iter cvec_X_emplace_at(cvec_X* self, cvec_X_iter it, i_valraw raw); -cvec_X_iter cvec_X_emplace_range(cvec_X* self, cvec_X_iter it, // will clone - cvec_X_iter it1, cvec_X_iter it2); -cvec_X_iter cvec_X_emplace_range_p(cvec_X* self, i_val* pos, - const i_val* p1, const i_val* p2); +cvec_X_iter cvec_X_emplace_range_p(cvec_X* self, i_val* pos, + const i_valraw* p1, const i_valraw* p2); cvec_X_iter cvec_X_erase_n(cvec_X* self, size_t idx, size_t n); cvec_X_iter cvec_X_erase_at(cvec_X* self, cvec_X_iter it); cvec_X_iter cvec_X_erase_range(cvec_X* self, cvec_X_iter it1, cvec_X_iter it2); +cvec_X_iter cvec_X_erase_range_p(cvec_X* self, i_val* p1, i_val* p2); void cvec_X_sort(cvec_X* self); void cvec_X_sort_range(cvec_X_iter i1, cvec_X_iter i2, diff --git a/examples/city.c b/examples/city.c index 0fcee341..c6a9417f 100644 --- a/examples/city.c +++ b/examples/city.c @@ -32,8 +32,9 @@ static inline void City_drop(City* c) { #define i_type CityArc #define i_key_bind City -#include -//#include // try instead of cbox.h +#define i_opt c_no_atomic +//#include +#include // try instead of cbox.h #define i_type Cities #define i_key_arcbox CityArc @@ -50,17 +51,13 @@ int main(void) c_auto (Cities, cities, copy) c_auto (CityMap, map) { - struct City_s { const char *name, *country; float lat, lon; int pop; }; - - c_forarray (struct City_s, c, { - {"New York", "US", 4.3, 23.2, 9000000}, - {"Paris", "France", 4.3, 23.2, 9000000}, - {"Berlin", "Germany", 4.3, 23.2, 9000000}, - {"London", "UK", 4.3, 23.2, 9000000}, + c_forarray (City, c, { + {cstr_new("New York"), cstr_new("US"), 4.3, 23.2, 9000000}, + {cstr_new("Paris"), cstr_new("France"), 4.3, 23.2, 9000000}, + {cstr_new("Berlin"), cstr_new("Germany"), 4.3, 23.2, 9000000}, + {cstr_new("London"), cstr_new("UK"), 4.3, 23.2, 9000000}, }) { - Cities_emplace(&cities, (City){cstr_from(c->name), - cstr_from(c->country), - c->lat, c->lon, c->pop}); + Cities_emplace(&cities, *c); } copy = Cities_clone(cities); // share each element! @@ -76,12 +73,12 @@ int main(void) c_foreach (c, Cities, cities) printf("city:%s, %d, use:%ld\n", cstr_str(&c.ref->get->name), c.ref->get->population, - CityArc_use_count(*c.ref)); + CityArc_use_count(c.ref)); printf("\nMap:\n"); c_forpair (id, city, CityMap, map) printf("id:%d, city:%s, %d, use:%ld\n", *_.id, cstr_str(&_.city->get->name), - _.city->get->population, CityArc_use_count(*_.city)); + _.city->get->population, CityArc_use_count(_.city)); puts(""); } } diff --git a/include/stc/carc.h b/include/stc/carc.h index 20ba26b0..6e8f7d38 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -56,14 +56,17 @@ int main() { #include #if defined(__GNUC__) || defined(__clang__) + typedef long catomic_long; #define c_atomic_inc(v) (void)__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST) #define c_atomic_dec_and_test(v) !__atomic_sub_fetch(v, 1, __ATOMIC_SEQ_CST) #elif defined(_MSC_VER) #include + typedef long catomic_long; #define c_atomic_inc(v) (void)_InterlockedIncrement(v) #define c_atomic_dec_and_test(v) !_InterlockedDecrement(v) #else #include + typedef _Atomic long catomic_long; #define c_atomic_inc(v) (void)atomic_fetch_add(v, 1) #define c_atomic_dec_and_test(v) (atomic_fetch_sub(v, 1) == 1) #endif @@ -88,18 +91,18 @@ typedef i_keyraw _cx_raw; #if !c_option(c_is_fwd) _cx_deftypes(_c_carc_types, _cx_self, i_key); #endif -_cx_carc_rep { long counter; i_key value; }; +_cx_carc_rep { catomic_long counter; i_key value; }; STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL, NULL}; } -STC_INLINE long _cx_memb(_use_count)(_cx_self ptr) - { return ptr.use_count ? *ptr.use_count : 0; } +STC_INLINE long _cx_memb(_use_count)(const _cx_self* self) + { return self->use_count ? *self->use_count : 0; } STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) { _cx_self ptr = {p}; if (p) - *(ptr.use_count = c_alloc(long)) = 1; + *(ptr.use_count = c_alloc(catomic_long)) = 1; return ptr; } @@ -111,16 +114,13 @@ STC_INLINE _cx_self _cx_memb(_from)(_cx_value val) { *(ptr.get = &rep->value) = val; return ptr; } -// [deprecated] -STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) + +STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) // [deprecated] { return _cx_memb(_from)(val); } STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self) { return i_keyto(self->get); } -STC_INLINE _cx_value _cx_memb(_toval)(const _cx_self* self) - { return *self->get; } - STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) { _cx_self ptr = *self; self->get = NULL, self->use_count = NULL; @@ -132,7 +132,7 @@ STC_INLINE void _cx_memb(_drop)(_cx_self* self) { i_keydrop(self->get); if ((char *)self->get != (char *)self->use_count + offsetof(_cx_carc_rep, value)) c_free(self->get); - c_free(self->use_count); + c_free((long*)self->use_count); } } @@ -158,7 +158,7 @@ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self ptr) { return ptr; } -STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self ptr) { +STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self ptr) { if (ptr.use_count) _i_atomic_inc(ptr.use_count); _cx_memb(_drop)(self); diff --git a/include/stc/cbox.h b/include/stc/cbox.h index d26a63c8..02a73fdc 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -82,8 +82,8 @@ _cx_deftypes(_c_cbox_types, _cx_self, i_key); STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL}; } -STC_INLINE long _cx_memb(_use_count)(_cx_self box) - { return (long)(box.get != NULL); } +STC_INLINE long _cx_memb(_use_count)(const _cx_self* self) + { return (long)(self->get != NULL); } STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) { return c_make(_cx_self){p}; } @@ -100,9 +100,6 @@ STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self) { return i_keyto(self->get); } -STC_INLINE _cx_value _cx_memb(_toval)(const _cx_self* self) - { return *self->get; } - // destructor STC_INLINE void _cx_memb(_drop)(_cx_self* self) { if (self->get) { @@ -129,11 +126,11 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) { self->get = p; } -#if !defined _i_no_clone #if !defined _i_no_emplace STC_INLINE _cx_self _cx_memb(_new)(_cx_raw raw) { return _cx_memb(_from)(i_keyfrom(raw)); } #endif +#if !defined _i_no_clone STC_INLINE _cx_self _cx_memb(_clone)(_cx_self other) { if (!other.get) return other; @@ -141,13 +138,6 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) { *out.get = i_keyclone(*other.get); return out; } - - STC_INLINE void _cx_memb(_assign)(_cx_self* self, const _cx_self ptr) { - if (self->get == ptr.get) - return; - _cx_memb(_drop)(self); - *self = _cx_memb(_clone)(ptr); - } #endif // !_i_no_clone STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self other) { diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index afe26f4b..ef6c9f26 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -48,15 +48,12 @@ STC_API void _cx_memb(_clear)(_cx_self* self); STC_API void _cx_memb(_drop)(_cx_self* self); STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value); STC_API void _cx_memb(_shrink_to_fit)(_cx_self *self); + #if !defined _i_queue #if !defined _i_no_emplace STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2); #endif // _i_no_emplace -#if !defined _i_no_clone -STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2); -#endif // !_i_no_clone #if !c_option(c_no_cmp) STC_API _cx_iter _cx_memb(_find_in)(_cx_iter p1, _cx_iter p2, _cx_raw raw); @@ -68,19 +65,26 @@ STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos const _cx_value* p1, const _cx_value* p2); #endif // !_i_queue -#if !defined _i_no_clone -STC_API _cx_self _cx_memb(_clone)(_cx_self cx); #if !defined _i_no_emplace STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw) { return _cx_memb(_push)(self, i_keyfrom(raw)); } #endif -STC_INLINE i_key _cx_memb(_value_clone)(i_key val) - { return i_keyclone(val); } + +#if !defined _i_no_clone +#if !defined _i_queue +STC_API _cx_iter _cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2); + STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) { if (self->data == other->data) return; - _cx_memb(_drop)(self); - *self = _cx_memb(_clone)(*other); + _cx_memb(_clear)(self); + _cx_memb(_copy_range_p)(self, self->data, other->data, + other->data + cdeq_rep_(other)->size); } +#endif // !_i_queue +STC_API _cx_self _cx_memb(_clone)(_cx_self cx); +STC_INLINE i_key _cx_memb(_value_clone)(i_key val) + { return i_keyclone(val); } #endif // !_i_no_clone STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return cdeq_rep_(cx)->size; } STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* cx) { return cdeq_rep_(cx)->cap; } @@ -222,6 +226,7 @@ _cx_memb(_clear)(_cx_self* self) { --q; i_keydrop(q); } rep->size = 0; + self->data = self->_base; } } @@ -409,8 +414,8 @@ _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, co #if !defined _i_no_clone STC_DEF _cx_iter -_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2) { +_cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2) { _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); if (it.ref) for (_cx_iter j; p1 != p2; ++p1) *j.ref++ = i_keyclone((*p1)); diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 371d6a29..a7828708 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -112,14 +112,15 @@ _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { #if !defined _i_no_clone STC_API _cx_self _cx_memb(_clone)(_cx_self cx); -STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2); +STC_API _cx_iter _cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2); STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val) { return i_keyclone(val); } STC_INLINE void _cx_memb(_copy)(_cx_self* self, const _cx_self* other) { if (self->data == other->data) return; - _cx_memb(_drop)(self); - *self = _cx_memb(_clone)(*other); + _cx_memb(_clear)(self); + _cx_memb(_copy_range_p)(self, self->data, other->data, + other->data + cvec_rep_(other)->size); } #endif // !_i_no_clone @@ -372,19 +373,20 @@ _cx_memb(_clone)(_cx_self cx) { const size_t len = cvec_rep_(&cx)->size; _cx_self out = _cx_memb(_with_capacity)(len); if (cvec_rep_(&out)->cap) - _cx_memb(_clone_range_p)(&out, out.data, cx.data, cx.data + len); + _cx_memb(_copy_range_p)(&out, out.data, cx.data, cx.data + len); return out; } STC_DEF _cx_iter -_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2) { +_cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2) { _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); if (it.ref) for (_cx_iter j = it; p1 != p2; ++p1) *j.ref++ = i_keyclone((*p1)); return it; } +#endif // !_i_no_clone #if !defined _i_no_emplace STC_DEF _cx_iter @@ -397,7 +399,6 @@ _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, return it; } #endif // !_i_no_emplace -#endif // !_i_no_clone #if !c_option(c_no_cmp) STC_DEF _cx_iter diff --git a/include/stc/forward.h b/include/stc/forward.h index 8a0278a5..264d6939 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -68,7 +68,7 @@ typedef union { \ typedef struct { \ SELF##_value* get; \ - long* use_count; \ + catomic_long* use_count; \ } SELF #define _c_carr2_types(SELF, VAL) \ diff --git a/include/stc/template.h b/include/stc/template.h index eeccc39e..4597e02c 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -109,9 +109,9 @@ #endif #elif defined i_key_arcbox #define i_key_bind i_key_arcbox - #define i_keyfrom c_paste(i_key_arcbox, _from) #define i_keyraw c_paste(i_key_arcbox, _value) - #define i_keyto c_paste(i_key_arcbox, _toval) + #define i_keyfrom c_paste(i_key_arcbox, _from) + #define i_keyto(x) *(x)->get #define i_eq c_paste(i_key_arcbox, _value_eq) #endif @@ -200,9 +200,9 @@ #define i_valto cstr_sv #elif defined i_val_arcbox #define i_val_bind i_val_arcbox - #define i_valfrom c_paste(i_val_arcbox, _from) #define i_valraw c_paste(i_val_arcbox, _value) - #define i_valto c_paste(i_val_arcbox, _toval) + #define i_valfrom c_paste(i_val_arcbox, _from) + #define i_valto(x) *(x)->get #endif #ifdef i_val_bind -- cgit v1.2.3 From 5f8a7951996728f6e91ef9ae2e904ce51ac0c883 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 12 Aug 2022 16:45:30 +0200 Subject: Renamed cdeq/cvec *_range() functions again (revert). Call alloc macros in cregex. --- docs/cdeq_api.md | 10 +++++----- docs/cvec_api.md | 12 ++++++------ include/stc/cdeq.h | 36 +++++++++++++++++------------------ include/stc/cvec.h | 56 ++++++++++++++++++++++++++++-------------------------- src/cregex.c | 14 +++++++------- 5 files changed, 65 insertions(+), 63 deletions(-) (limited to 'docs') diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index a8d2baeb..79e6bf39 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -29,7 +29,7 @@ cdeq_X cdeq_X_clone(cdeq_X deq); void cdeq_X_clear(cdeq_X* self); void cdeq_X_copy(cdeq_X* self, const cdeq_X* other); -cdeq_X_iter cdeq_X_copy_range_p(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2); +cdeq_X_iter cdeq_X_copy_range(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2); bool cdeq_X_reserve(cdeq_X* self, size_t cap); void cdeq_X_shrink_to_fit(cdeq_X* self); void cdeq_X_swap(cdeq_X* a, cdeq_X* b); @@ -61,13 +61,13 @@ void cdeq_X_pop_back(cdeq_X* self); cdeq_X_iter cdeq_X_insert(cdeq_X* self, size_t idx, i_val value); // move value cdeq_X_iter cdeq_X_insert_n(cdeq_X* self, size_t idx, const i_val[] arr, size_t n); // move arr values cdeq_X_iter cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); // move value -cdeq_X_iter cdeq_X_insert_range_p(cdeq_X* self, i_val* pos, - const i_val* p1, const i_val* p2); +cdeq_X_iter cdeq_X_insert_range(cdeq_X* self, i_val* pos, + const i_val* p1, const i_val* p2); cdeq_X_iter cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); // clone values cdeq_X_iter cdeq_X_emplace_at(cdeq_X* self, cdeq_X_iter it, i_valraw raw); -cdeq_X_iter cdeq_X_emplace_range_p(cdeq_X* self, i_val* pos, - const i_valraw* p1, const i_valraw* p2); +cdeq_X_iter cdeq_X_emplace_range(cdeq_X* self, i_val* pos, + const i_valraw* p1, const i_valraw* p2); cdeq_X_iter cdeq_X_erase_n(cdeq_X* self, size_t idx, size_t n); cdeq_X_iter cdeq_X_erase_at(cdeq_X* self, cdeq_X_iter it); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index ea26c345..a1d27a23 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -34,10 +34,10 @@ cvec_X cvec_X_clone(cvec_X vec); void cvec_X_clear(cvec_X* self); void cvec_X_copy(cvec_X* self, const cvec_X* other); -cvec_X_iter cvec_X_copy_range_p(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2); +cvec_X_iter cvec_X_copy_range(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2); bool cvec_X_reserve(cvec_X* self, size_t cap); bool cvec_X_resize(cvec_X* self, size_t size, i_val null); -cvec_X_iter cvec_X_insert_uninit_p(cvec_X* self, i_val* pos, size_t n); // return pos iter +cvec_X_iter cvec_X_insert_uninit(cvec_X* self, i_val* pos, size_t n); // return pos iter void cvec_X_shrink_to_fit(cvec_X* self); void cvec_X_swap(cvec_X* a, cvec_X* b); void cvec_X_drop(cvec_X* self); // destructor @@ -72,13 +72,13 @@ void cvec_X_pop_back(cvec_X* self); cvec_X_iter cvec_X_insert(cvec_X* self, size_t idx, i_val value); // move value cvec_X_iter cvec_X_insert_n(cvec_X* self, size_t idx, const i_val[] arr, size_t n); // move n values cvec_X_iter cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); // move value -cvec_X_iter cvec_X_insert_range_p(cvec_X* self, i_val* pos, - const i_val* p1, const i_val* p2); +cvec_X_iter cvec_X_insert_range(cvec_X* self, i_val* pos, + const i_val* p1, const i_val* p2); cvec_X_iter cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); // clone values cvec_X_iter cvec_X_emplace_at(cvec_X* self, cvec_X_iter it, i_valraw raw); -cvec_X_iter cvec_X_emplace_range_p(cvec_X* self, i_val* pos, - const i_valraw* p1, const i_valraw* p2); +cvec_X_iter cvec_X_emplace_range(cvec_X* self, i_val* pos, + const i_valraw* p1, const i_valraw* p2); cvec_X_iter cvec_X_erase_n(cvec_X* self, size_t idx, size_t n); cvec_X_iter cvec_X_erase_at(cvec_X* self, cvec_X_iter it); diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index ef6c9f26..4bef2f38 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -51,8 +51,8 @@ STC_API void _cx_memb(_shrink_to_fit)(_cx_self *self); #if !defined _i_queue #if !defined _i_no_emplace -STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, - const _cx_raw* p1, const _cx_raw* p2); +STC_API _cx_iter _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, + const _cx_raw* p1, const _cx_raw* p2); #endif // _i_no_emplace #if !c_option(c_no_cmp) @@ -61,8 +61,8 @@ STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value #endif STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_key value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2); -STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2); +STC_API _cx_iter _cx_memb(_insert_range)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2); #endif // !_i_queue #if !defined _i_no_emplace @@ -72,13 +72,13 @@ STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw) #if !defined _i_no_clone #if !defined _i_queue -STC_API _cx_iter _cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, +STC_API _cx_iter _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2); STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) { if (self->data == other->data) return; _cx_memb(_clear)(self); - _cx_memb(_copy_range_p)(self, self->data, other->data, + _cx_memb(_copy_range)(self, self->data, other->data, other->data + cdeq_rep_(other)->size); } #endif // !_i_queue @@ -116,15 +116,15 @@ STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value) { } STC_INLINE _cx_iter _cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) { - return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1); + return _cx_memb(_insert_range)(self, self->data + idx, &value, &value + 1); } STC_INLINE _cx_iter _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], const size_t n) { - return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n); + return _cx_memb(_insert_range)(self, self->data + idx, arr, arr + n); } STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { - return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1); + return _cx_memb(_insert_range)(self, it.ref, &value, &value + 1); } STC_INLINE _cx_iter @@ -167,11 +167,11 @@ STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw) { STC_INLINE _cx_iter _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], const size_t n) { - return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n); + return _cx_memb(_emplace_range)(self, self->data + idx, arr, arr + n); } STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); + return _cx_memb(_emplace_range)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -352,7 +352,7 @@ _cx_memb(_expand_left_half_)(_cx_self* self, const size_t idx, const size_t n) { } static _cx_iter -_cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n) { +_cx_memb(_insert_uninit)(_cx_self* self, _cx_value* pos, const size_t n) { struct cdeq_rep* r = cdeq_rep_(self); if (n) { if (!pos) pos = self->data + r->size; @@ -380,9 +380,9 @@ _cx_memb(_push_front)(_cx_self* self, i_key value) { } STC_DEF _cx_iter -_cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, +_cx_memb(_insert_range)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { - _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) memcpy(it.ref, p1, (p2 - p1)*sizeof *p1); return it; @@ -403,8 +403,8 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { #if !defined _i_no_emplace STC_DEF _cx_iter -_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { - _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); +_cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { + _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) for (_cx_iter j = it; p1 != p2; ++p1) *j.ref++ = i_keyfrom((*p1)); @@ -414,9 +414,9 @@ _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, co #if !defined _i_no_clone STC_DEF _cx_iter -_cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, +_cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { - _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); + _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) for (_cx_iter j; p1 != p2; ++p1) *j.ref++ = i_keyclone((*p1)); return it; diff --git a/include/stc/cvec.h b/include/stc/cvec.h index a7828708..c734abb6 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -84,9 +84,9 @@ STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap); STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_key null); STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value); STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2); -STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2); -STC_API _cx_iter _cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n); +STC_API _cx_iter _cx_memb(_insert_range)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2); +STC_API _cx_iter _cx_memb(_insert_uninit)(_cx_self* self, _cx_value* pos, const size_t n); #if !c_option(c_no_cmp) STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y); STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, _cx_raw raw); @@ -94,33 +94,33 @@ STC_API _cx_iter _cx_memb(_binary_search_in)(_cx_iter it1, _cx_iter it2, #endif #if !defined _i_no_emplace -STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, - const _cx_raw* p1, const _cx_raw* p2); +STC_API _cx_iter _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, + const _cx_raw* p1, const _cx_raw* p2); STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw) { return _cx_memb(_push)(self, i_keyfrom(raw)); } STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw) { return _cx_memb(_push)(self, i_keyfrom(raw)); } STC_INLINE _cx_iter _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], const size_t n) { - return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n); + return _cx_memb(_emplace_range)(self, self->data + idx, arr, arr + n); } STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); + return _cx_memb(_emplace_range)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); } #endif // !_i_no_emplace #if !defined _i_no_clone STC_API _cx_self _cx_memb(_clone)(_cx_self cx); -STC_API _cx_iter _cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2); +STC_API _cx_iter _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2); STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val) { return i_keyclone(val); } STC_INLINE void _cx_memb(_copy)(_cx_self* self, const _cx_self* other) { if (self->data == other->data) return; _cx_memb(_clear)(self); - _cx_memb(_copy_range_p)(self, self->data, other->data, - other->data + cvec_rep_(other)->size); + _cx_memb(_copy_range)(self, self->data, other->data, + other->data + cvec_rep_(other)->size); } #endif // !_i_no_clone @@ -160,15 +160,15 @@ _cx_memb(_shrink_to_fit)(_cx_self* self) { STC_INLINE _cx_iter _cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) { - return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1); + return _cx_memb(_insert_range)(self, self->data + idx, &value, &value + 1); } STC_INLINE _cx_iter _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], const size_t n) { - return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n); + return _cx_memb(_insert_range)(self, self->data + idx, arr, arr + n); } STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { - return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1); + return _cx_memb(_insert_range)(self, it.ref, &value, &value + 1); } STC_INLINE _cx_iter @@ -291,7 +291,8 @@ _cx_memb(_reserve)(_cx_self* self, const size_t cap) { const size_t len = rep->size; if (cap > rep->cap || (cap && cap == len)) { rep = (struct cvec_rep*) c_realloc(rep->cap ? rep : NULL, - offsetof(struct cvec_rep, data) + cap*sizeof(i_key)); + offsetof(struct cvec_rep, data) + + cap*sizeof(i_key)); if (!rep) return false; self->data = (_cx_value*) rep->data; @@ -328,7 +329,7 @@ _cx_memb(_push)(_cx_self* self, i_key value) { } STC_DEF _cx_iter -_cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n) { +_cx_memb(_insert_uninit)(_cx_self* self, _cx_value* pos, const size_t n) { struct cvec_rep* r = cvec_rep_(self); if (n) { if (!pos) pos = self->data + r->size; @@ -346,9 +347,9 @@ _cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n) { } STC_DEF _cx_iter -_cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2) { - _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); +_cx_memb(_insert_range)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2) { + _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) memcpy(it.ref, p1, (p2 - p1)*sizeof *p1); return it; @@ -373,14 +374,14 @@ _cx_memb(_clone)(_cx_self cx) { const size_t len = cvec_rep_(&cx)->size; _cx_self out = _cx_memb(_with_capacity)(len); if (cvec_rep_(&out)->cap) - _cx_memb(_copy_range_p)(&out, out.data, cx.data, cx.data + len); + _cx_memb(_copy_range)(&out, out.data, cx.data, cx.data + len); return out; } STC_DEF _cx_iter -_cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2) { - _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); +_cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, + const _cx_value* p1, const _cx_value* p2) { + _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) for (_cx_iter j = it; p1 != p2; ++p1) *j.ref++ = i_keyclone((*p1)); @@ -390,9 +391,9 @@ _cx_memb(_copy_range_p)(_cx_self* self, _cx_value* pos, #if !defined _i_no_emplace STC_DEF _cx_iter -_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, - const _cx_raw* p1, const _cx_raw* p2) { - _cx_iter it = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1); +_cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, + const _cx_raw* p1, const _cx_raw* p2) { + _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) for (_cx_iter j = it; p1 != p2; ++p1) *j.ref++ = i_keyfrom((*p1)); @@ -413,7 +414,8 @@ _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) { } STC_DEF _cx_iter -_cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, _cx_iter* lower_bound) { +_cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, + _cx_iter* lower_bound) { const _cx_value* p2 = i2.ref ? i2.ref : i2.end; _cx_iter mid = i1; while (i1.ref != p2) { diff --git a/src/cregex.c b/src/cregex.c index 690c9ad5..46d4d323 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -532,7 +532,7 @@ optimize(Parser *par, Reprog *pp) */ uintptr_t ipp = (uintptr_t)pp; size_t size = sizeof(Reprog) + (par->freep - pp->firstinst)*sizeof(Reinst); - Reprog *npp = (Reprog *)realloc(pp, size); + Reprog *npp = (Reprog *)c_realloc(pp, size); ptrdiff_t diff = (uintptr_t)npp - ipp; if ((npp == NULL) | (diff == 0)) @@ -798,10 +798,10 @@ regcomp1(Reprog *progp, Parser *par, const char *s, int cflags) /* get memory for the program. estimated max usage */ const int instcap = 5 + 6*strlen(s); - Reprog* pp = (Reprog *)realloc(progp, sizeof(Reprog) + instcap*sizeof(Reinst)); + Reprog* pp = (Reprog *)c_realloc(progp, sizeof(Reprog) + instcap*sizeof(Reinst)); if (pp == NULL) { par->error = cre_outofmemory; - free(progp); + c_free(progp); return NULL; } pp->flags.caseless = (cflags & cre_c_caseless) != 0; @@ -861,7 +861,7 @@ regcomp1(Reprog *progp, Parser *par, const char *s, int cflags) #endif out: if (par->error) { - free(pp); + c_free(pp); pp = NULL; } return pp; @@ -1090,7 +1090,7 @@ regexec2(const Reprog *progp, /* program to run */ Relist *relists; /* mark space */ - relists = (Relist *)malloc(2 * BIGLISTSIZE*sizeof(Relist)); + relists = (Relist *)c_malloc(2 * BIGLISTSIZE*sizeof(Relist)); if (relists == NULL) return -1; @@ -1100,7 +1100,7 @@ regexec2(const Reprog *progp, /* program to run */ j->reliste[1] = relists + 2*BIGLISTSIZE - 2; rv = regexec1(progp, bol, mp, ms, j, mflags); - free(relists); + c_free(relists); return rv; } @@ -1265,5 +1265,5 @@ cregex_replace_pe(const char* input, const char* pattern, const char* replace, u void cregex_drop(cregex* self) { - free(self->prog); + c_free(self->prog); } -- cgit v1.2.3 From ccb63f1abbae18657708dd8ea38e0892aa0fc48a Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 12 Aug 2022 21:54:53 +0200 Subject: cstr V4: Changed cstr functions to take pointers to self, not values. This is consistent with the rest of the containers. csview will still use values, as it is designed to be passed by value. --- benchmarks/misc/string_bench_STC.cpp | 4 +- docs/ccommon_api.md | 2 +- docs/cstr_api.md | 54 +++++++++--------- docs/csview_api.md | 12 ++-- examples/astar.c | 4 +- examples/cstr_match.c | 14 ++--- examples/demos.c | 2 +- examples/music_arc.c | 2 +- examples/regex1.c | 2 +- examples/sso_map.c | 2 +- examples/sso_substr.c | 2 +- include/stc/alt/cstr.h | 47 ++++++++-------- include/stc/cstr.h | 106 +++++++++++++++++------------------ 13 files changed, 128 insertions(+), 125 deletions(-) (limited to 'docs') diff --git a/benchmarks/misc/string_bench_STC.cpp b/benchmarks/misc/string_bench_STC.cpp index 648cb1f3..065b6dd7 100644 --- a/benchmarks/misc/string_bench_STC.cpp +++ b/benchmarks/misc/string_bench_STC.cpp @@ -101,7 +101,7 @@ void initShortStringVec(cvec_str* vs, cvec_sv* vsv) c_foreach (i, cvec_str, *vs) { cvec_sv_push_back(vsv, cstr_sv(i.ref)); - num += cstr_size(*i.ref); + num += cstr_size(i.ref); } std::cout << "num strings: " << cvec_sv_size(vsv) << std::endl; std::cout << "avg str len: " << num / (float)cvec_sv_size(vsv) << std::endl; @@ -147,7 +147,7 @@ void initLongStringVec(cvec_str* vs, cvec_sv* vsv) c_foreach (i, cvec_str, *vs) { cvec_sv_push_back(vsv, cstr_sv(i.ref)); - num += cstr_size(*i.ref); + num += cstr_size(i.ref); } std::cout << "num strings: " << cvec_sv_size(vsv) << std::endl; std::cout << "avg str len: " << num / (float)cvec_sv_size(vsv) << std::endl; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 179e7398..6745317d 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -217,7 +217,7 @@ c_find_if(it, cvec_i, vec, *it.ref > 2); if (it.ref) printf("%d\n", *it.ref); // Search within a range: -c_find_in(it, csmap_str, it1, it2, cstr_contains(*it.ref, "hello")); +c_find_in(it, csmap_str, it1, it2, cstr_contains(it.ref, "hello")); if (it.ref) cmap_str_erase_at(&map, it); ``` diff --git a/docs/cstr_api.md b/docs/cstr_api.md index fffec64c..f5414f1b 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -30,16 +30,16 @@ cstr cstr_clone(cstr s); cstr* cstr_take(cstr* self, cstr s); // take ownership of s, i.e. don't drop s. cstr cstr_move(cstr* self); // move string to caller, leave self empty -void cstr_drop(cstr *self); // destructor +void cstr_drop(cstr* self); // destructor const char* cstr_str(const cstr* self); // cast to const char* char* cstr_data(cstr* self); // cast to mutable char* csview cstr_sv(const cstr* self); // cast to string view cstr_buf cstr_buffer(cstr* self); // cast to mutable buffer (with capacity) -size_t cstr_size(cstr s); -size_t cstr_capacity(cstr s); -bool cstr_empty(cstr s); +size_t cstr_size(const cstr* self); +size_t cstr_capacity(const cstr* self); +bool cstr_empty(const cstr* self); char* cstr_reserve(cstr* self, size_t capacity); // return pointer to buffer void cstr_resize(cstr* self, size_t len, char fill); @@ -57,7 +57,7 @@ char* cstr_append(cstr* self, const char* str); char* cstr_append_n(cstr* self, const char* str, size_t n); // append n first bytes of str char* cstr_append_sv(cstr* self, csview str); char* cstr_append_s(cstr* self, cstr str); -char* cstr_append_uninit(cstr *self, size_t len); // append len uninitialized bytes +char* cstr_append_uninit(cstr* self, size_t len); // append len uninitialized bytes void cstr_insert(cstr* self, size_t pos, const char* ins); void cstr_insert_sv(cstr* self, size_t pos, csview ins); @@ -72,19 +72,21 @@ void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* rep void cstr_replace_at_sv(cstr* self, size_t pos, size_t len, const csview repl); void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl); -bool cstr_equals(cstr s, const char* str); -bool cstr_equals_s(cstr s, cstr s2); -size_t cstr_find(cstr s, const char* search); -size_t cstr_find_at(cstr s, size_t pos, const char* search); // search from pos -bool cstr_contains(cstr s, const char* search); +bool cstr_equals(const cstr* self, const char* str); +bool cstr_equals_s(const cstr* self, cstr s); +bool cstr_equals_sv(const cstr* self, csview sv); -bool cstr_starts_with(cstr s, const char* str); -bool cstr_starts_with_sv(cstr s, csview sv); -bool cstr_starts_with_s(cstr s, cstr s); +size_t cstr_find(const cstr* self, const char* search); +size_t cstr_find_at(const cstr* self, size_t pos, const char* search); // search from pos +bool cstr_contains(const cstr* self, const char* search); -bool cstr_ends_with(cstr s, const char* str); -bool cstr_ends_with_sv(cstr s, csview sv); -bool cstr_ends_with_s(cstr s, cstr s); +bool cstr_starts_with(const cstr* self, const char* str); +bool cstr_starts_with_sv(const cstr* self, csview sv); +bool cstr_starts_with_s(const cstr* self, cstr s); + +bool cstr_ends_with(const cstr* self, const char* str); +bool cstr_ends_with_sv(const cstr* self, csview sv); +bool cstr_ends_with_s(const cstr* self, cstr s); bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) bool cstr_getdelim(cstr *self, int delim, FILE *stream); // does not append delim to result @@ -92,9 +94,9 @@ bool cstr_getdelim(cstr *self, int delim, FILE *stream); // does no #### UTF8 methods ```c -size_t cstr_u8_size(cstr s); // number of utf8 codepoints -size_t cstr_u8_size_n(cstr s, size_t nbytes); // utf8 size within n bytes -size_t cstr_u8_to_pos(cstr s, size_t u8idx); // byte pos offset at utf8 codepoint index +size_t cstr_u8_size(const cstr* self); // number of utf8 codepoints +size_t cstr_u8_size_n(const cstr self, size_t nbytes); // utf8 size within n bytes +size_t cstr_u8_to_pos(const cstr* self, size_t u8idx); // byte pos offset at utf8 codepoint index const char* cstr_u8_at(const cstr* self, size_t u8idx); // char* position at utf8 codepoint index csview cstr_u8_chr(const cstr* self, size_t u8idx); // get utf8 character as a csview void cstr_u8_replace_at(cstr* self, size_t u8pos, size_t u8len, csview repl); // replace at utf8 indices @@ -117,18 +119,18 @@ cstr cstr_toupper_sv(csview sv); // returns void cstr_uppercase(cstr* self); // transform cstr to uppercase utf8 int cstr_icmp(const cstr* s1, const cstr* s2); // utf8 case-insensitive comparison -bool cstr_iequals(cstr s, const char* str); // " -bool cstr_istarts_with(cstr s, const char* str); // " -bool cstr_iends_with(cstr s, const char* str); // " +bool cstr_iequals(const cstr* self, const char* str); // " +bool cstr_istarts_with(const cstr* self, const char* str); // " +bool cstr_iends_with(const cstr* self, const char* str); // " ``` Note that all methods with arguments `(..., const char* str, size_t n)`, `n` must be within the range of `str` length. #### Helper methods: ```c -int cstr_cmp(const cstr *s1, const cstr *s2); -bool cstr_eq(const cstr *s1, const cstr *s2); -bool cstr_hash(const cstr *s); +int cstr_cmp(const cstr* s1, const cstr* s2); +bool cstr_eq(const cstr* s1, const cstr* s2); +bool cstr_hash(const cstr* self); char* c_strnstrn(const char* str, const char* search, size_t slen, size_t nlen); ``` @@ -155,7 +157,7 @@ char* c_strnstrn(const char* str, const char* search, size_t slen, size_t int main() { cstr s0 = cstr_new("Initialization without using strlen()."); - printf("%s\nLength: %" PRIuMAX "\n\n", cstr_str(&s0), cstr_size(s0)); + printf("%s\nLength: %" PRIuMAX "\n\n", cstr_str(&s0), cstr_size(&s0)); cstr s1 = cstr_new("one-nine-three-seven-five."); printf("%s\n", cstr_str(&s1)); diff --git a/docs/csview_api.md b/docs/csview_api.md index 1e2ed408..79d108a3 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -92,11 +92,11 @@ uint64_t csview_hash(const csview* x); ## Types -| Type name | Type definition | Used to represent... | -|:----------------|:------------------------------------------|:-------------------------| -| `csview` | `struct { const char *str; size_t size }` | The string view type | -| `csview_value` | `char` | The string element type | -| `csview_iter` | `struct { csview_value *ref; }` | UTF8 iterator | +| Type name | Type definition | Used to represent... | +|:----------------|:-------------------------------------------|:-------------------------| +| `csview` | `struct { const char *str; size_t size; }` | The string view type | +| `csview_value` | `char` | The string element type | +| `csview_iter` | `struct { csview_value *ref; }` | UTF8 iterator | ## Constants and macros @@ -118,7 +118,7 @@ int main () // (quoting Alfred N. Whitehead) csview sv1 = cstr_substr(&str1, 3, 5); // "think" - size_t pos = cstr_find(str1, "live"); // position of "live" in str1 + size_t pos = cstr_find(&str1, "live"); // position of "live" in str1 csview sv2 = cstr_substr(&str1, pos, 4); // get "live" csview sv3 = cstr_slice(&str1, -8, -1); // get "details" printf("%" c_PRIsv "%" c_PRIsv "%" c_PRIsv "\n", diff --git a/examples/astar.c b/examples/astar.c index 7d90bf35..cb498b11 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -37,7 +37,7 @@ point_equal(const point* a, const point* b) point point_from(const cstr* maze, const char* c, int width) { - int index = cstr_find(*maze, c); + int index = cstr_find(maze, c); return point_init(index % width, index / width, width); } @@ -156,7 +156,7 @@ main(void) "# # # # # # #\n" "#########################################################################\n"), cstr_drop(&maze)) { - int width = cstr_find(maze, "\n") + 1; + int width = cstr_find(&maze, "\n") + 1; c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) { c_foreach (it, cdeq_point, path) cstr_data(&maze)[point_index(it.ref)] = 'x'; diff --git a/examples/cstr_match.c b/examples/cstr_match.c index 6927ed80..317ff986 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -5,18 +5,18 @@ int main() { c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { - size_t pos = cstr_find_at(ss, 0, "brown"); + size_t pos = cstr_find_at(&ss, 0, "brown"); printf("%" PRIuMAX " [%s]\n", pos, pos == cstr_npos ? "" : cstr_str(&ss) + pos); - printf("equals: %d\n", cstr_equals(ss, "The quick brown fox jumps over the lazy dog.JPG")); - printf("contains: %d\n", cstr_contains(ss, "umps ove")); - printf("starts_with: %d\n", cstr_starts_with(ss, "The quick brown")); - printf("ends_with: %d\n", cstr_ends_with(ss, ".jpg")); - printf("ends_with: %d\n", cstr_ends_with(ss, ".JPG")); + printf("equals: %d\n", cstr_equals(&ss, "The quick brown fox jumps over the lazy dog.JPG")); + printf("contains: %d\n", cstr_contains(&ss, "umps ove")); + printf("starts_with: %d\n", cstr_starts_with(&ss, "The quick brown")); + printf("ends_with: %d\n", cstr_ends_with(&ss, ".jpg")); + printf("ends_with: %d\n", cstr_ends_with(&ss, ".JPG")); cstr s1 = cstr_new("hell😀 w😀rl🐨"); csview ch1 = cstr_u8_chr(&s1, 7); csview ch2 = cstr_u8_chr(&s1, 10); - printf("%s\nsize: %" PRIuMAX ", %" PRIuMAX "\n", cstr_str(&s1), cstr_u8_size(s1), cstr_size(s1)); + printf("%s\nsize: %" PRIuMAX ", %" PRIuMAX "\n", cstr_str(&s1), cstr_u8_size(&s1), cstr_size(&s1)); printf("ch1: %.*s\n", c_ARGsv(ch1)); printf("ch2: %.*s\n", c_ARGsv(ch2)); } diff --git a/examples/demos.c b/examples/demos.c index 052c4e32..cd715d46 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -19,7 +19,7 @@ void stringdemo1() cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs))); printf("%s.\n", cstr_str(&cs)); - printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(cs, "four")); + printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(&cs, "four")); // reassign: cstr_assign(&cs, "one two three four five six seven"); diff --git a/examples/music_arc.c b/examples/music_arc.c index d933d125..02470b0f 100644 --- a/examples/music_arc.c +++ b/examples/music_arc.c @@ -40,7 +40,7 @@ void example3() }) SongVec_emplace(&vec, *v); c_foreach (s, SongVec, vec) - if (!cstr_equals(s.ref->get->artist, "Bob Dylan")) + if (!cstr_equals(&s.ref->get->artist, "Bob Dylan")) SongVec_push_back(&vec2, SongArc_clone(*s.ref)); SongVec_emplace(&vec2, Song_from("Michael Jackson", "Billie Jean")); diff --git a/examples/regex1.c b/examples/regex1.c index 5981e878..c8b3a4f5 100644 --- a/examples/regex1.c +++ b/examples/regex1.c @@ -19,7 +19,7 @@ int main(int argc, char* argv[]) cstr_getline(&input, stdin); // Exit when the user inputs q - if (cstr_equals(input, "q")) + if (cstr_equals(&input, "q")) break; if (cregex_is_match(cstr_str(&input), &float_expr)) diff --git a/examples/sso_map.c b/examples/sso_map.c index a32a9a3d..43bcb40b 100644 --- a/examples/sso_map.c +++ b/examples/sso_map.c @@ -11,7 +11,7 @@ int main() c_forpair (k, v, cmap_str, m) printf("%s: '%s' Len=%" PRIuMAX ", Is long: %s\n", - cstr_str(_.k), cstr_str(_.v), cstr_size(*_.v), + cstr_str(_.k), cstr_str(_.v), cstr_size(_.v), cstr_is_long(_.v)?"true":"false"); } } diff --git a/examples/sso_substr.c b/examples/sso_substr.c index b47512ea..098d9b4b 100644 --- a/examples/sso_substr.c +++ b/examples/sso_substr.c @@ -6,7 +6,7 @@ int main () { cstr str = cstr_new("We think in generalities, but we live in details."); csview sv1 = cstr_substr_ex(&str, 3, 5); // "think" - size_t pos = cstr_find(str, "live"); // position of "live" + size_t pos = cstr_find(&str, "live"); // position of "live" csview sv2 = cstr_substr_ex(&str, pos, 4); // "live" csview sv3 = cstr_slice_ex(&str, -8, -1); // "details" printf("%.*s, %.*s, %.*s\n", c_ARGsv(sv1), c_ARGsv(sv2), c_ARGsv(sv3)); diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index c669c620..a2233432 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -56,8 +56,8 @@ STC_API cstr* cstr_append_n(cstr* self, const char* str, size_t n); STC_API cstr cstr_replace_sv(csview str, csview find, csview repl, unsigned count); STC_DEF void cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl); 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_at(cstr s, size_t pos, const char* needle); +STC_API size_t cstr_find(const cstr* self, const char* needle); +STC_API size_t cstr_find_at(const cstr* self, size_t pos, const char* needle); STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream); STC_INLINE cstr cstr_init() { return cstr_null; } @@ -70,7 +70,7 @@ STC_INLINE csview cstr_sv(const cstr* self) STC_INLINE cstr cstr_from(const char* str) { return cstr_from_n(str, strlen(str)); } STC_INLINE char* cstr_data(cstr* self) { return self->str; } -STC_INLINE size_t cstr_size(cstr s) { return _cstr_p(&s)->size; } +STC_INLINE size_t cstr_size(const cstr* self) { return _cstr_p(self)->size; } STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_p(&s)->cap; } STC_INLINE bool cstr_empty(cstr s) { return _cstr_p(&s)->size == 0; } STC_INLINE void cstr_drop(cstr* self) @@ -106,12 +106,12 @@ STC_INLINE void cstr_erase(cstr* self, const size_t pos) STC_INLINE char* cstr_front(cstr* self) { return self->str; } STC_INLINE char* cstr_back(cstr* self) { return self->str + _cstr_p(self)->size - 1; } -STC_INLINE bool cstr_equals(cstr s, const char* str) - { return strcmp(s.str, str) == 0; } -STC_INLINE bool cstr_equals_s(cstr s1, cstr s2) - { return strcmp(s1.str, s2.str) == 0; } -STC_INLINE bool cstr_contains(cstr s, const char* needle) - { return strstr(s.str, needle) != NULL; } +STC_INLINE bool cstr_equals(const cstr* self, const char* str) + { return strcmp(self->str, str) == 0; } +STC_INLINE bool cstr_equals_s(const cstr* self, cstr s) + { return strcmp(self->str, s.str) == 0; } +STC_INLINE bool cstr_contains(const cstr* self, const char* needle) + { return strstr(self->str, needle) != NULL; } STC_INLINE bool cstr_getline(cstr *self, FILE *stream) { return cstr_getdelim(self, '\n', stream); } @@ -133,7 +133,7 @@ STC_INLINE cstr cstr_with_size(const size_t len, const char fill) { } STC_INLINE char* cstr_append_uninit(cstr *self, size_t n) { - size_t len = cstr_size(*self); char* d; + size_t len = cstr_size(self); char* d; if (!(d = cstr_reserve(self, len + n))) return NULL; _cstr_p(self)->size += n; return d + len; @@ -152,14 +152,15 @@ STC_INLINE cstr cstr_move(cstr* self) { return tmp; } -STC_INLINE bool cstr_starts_with(cstr s, const char* sub) { - while (*sub && *s.str == *sub) ++s.str, ++sub; +STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) { + const char* p = self->str; + while (*sub && *p == *sub) ++p, ++sub; return *sub == 0; } -STC_INLINE bool cstr_ends_with(cstr s, const char* sub) { - const size_t n = strlen(sub), sz = _cstr_p(&s)->size; - return n <= sz && !memcmp(s.str + sz - n, sub, n); +STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub) { + const size_t n = strlen(sub), sz = _cstr_p(self)->size; + return n <= sz && !memcmp(self->str + sz - n, sub, n); } STC_INLINE int c_strncasecmp(const char* s1, const char* s2, size_t nmax) { @@ -309,7 +310,7 @@ STC_INLINE void _cstr_internal_move(cstr* self, const size_t pos1, const size_t STC_DEF void cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl) { - const size_t sz = cstr_size(*self); + const size_t sz = cstr_size(self); if (len > sz - pos) len = sz - pos; c_autobuf (xstr, char, repl.size) { memcpy(xstr, repl.str, repl.size); @@ -366,16 +367,16 @@ cstr_getdelim(cstr *self, const int delim, FILE *fp) { } STC_DEF size_t -cstr_find(cstr s, const char* needle) { - char* res = strstr(s.str, needle); - return res ? res - s.str : cstr_npos; +cstr_find(const cstr* self, const char* needle) { + char* res = strstr(self->str, needle); + return res ? res - self->str : cstr_npos; } STC_DEF size_t -cstr_find_at(cstr s, const size_t pos, const char* needle) { - if (pos > _cstr_p(&s)->size) return cstr_npos; - char* res = strstr(s.str + pos, needle); - return res ? res - s.str : cstr_npos; +cstr_find_at(const cstr* self, const size_t pos, const char* needle) { + if (pos > _cstr_p(self)->size) return cstr_npos; + char* res = strstr(self->str + pos, needle); + return res ? res - self->str : cstr_npos; } #endif diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 7af54c58..0728b110 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -80,7 +80,7 @@ STC_API char* _cstr_internal_move(cstr* self, size_t pos1, size_t pos2); STC_API char* cstr_reserve(cstr* self, size_t cap); STC_API void cstr_shrink_to_fit(cstr* self); STC_API void cstr_resize(cstr* self, size_t size, char value); -STC_API size_t cstr_find_at(cstr s, size_t pos, const char* search); +STC_API size_t cstr_find_at(const cstr* self, size_t pos, const char* search); STC_API char* cstr_assign_n(cstr* self, const char* str, size_t len); STC_API char* cstr_append_n(cstr* self, const char* str, size_t len); STC_API bool cstr_getdelim(cstr *self, int delim, FILE *fp); @@ -161,14 +161,14 @@ STC_INLINE char* cstr_data(cstr* self) STC_INLINE const char* cstr_str(const cstr* self) { return SSO_CALL(self, data(self)); } -STC_INLINE bool cstr_empty(cstr s) - { return s.sml.last == cstr_s_cap; } +STC_INLINE bool cstr_empty(const cstr* self) + { return self->sml.last == cstr_s_cap; } -STC_INLINE size_t cstr_size(cstr s) - { return SSO_CALL(&s, size(&s)); } +STC_INLINE size_t cstr_size(const cstr* self) + { return SSO_CALL(self, size(self)); } -STC_INLINE size_t cstr_capacity(cstr s) - { return cstr_is_long(&s) ? cstr_l_cap(&s) : cstr_s_cap; } +STC_INLINE size_t cstr_capacity(const cstr* self) + { return cstr_is_long(self) ? cstr_l_cap(self) : cstr_s_cap; } // utf8 methods defined in/depending on src/utf8code.c: @@ -200,11 +200,11 @@ STC_INLINE bool cstr_valid_utf8(const cstr* self) // other utf8 -STC_INLINE size_t cstr_u8_size(cstr s) - { return utf8_size(cstr_str(&s)); } +STC_INLINE size_t cstr_u8_size(const cstr* self) + { return utf8_size(cstr_str(self)); } -STC_INLINE size_t cstr_u8_size_n(cstr s, size_t nbytes) - { return utf8_size_n(cstr_str(&s), nbytes); } +STC_INLINE size_t cstr_u8_size_n(const cstr* self, size_t nbytes) + { return utf8_size_n(cstr_str(self), nbytes); } STC_INLINE size_t cstr_u8_to_pos(const cstr* self, size_t u8idx) { return utf8_pos(cstr_str(self), u8idx); } @@ -242,7 +242,7 @@ STC_INLINE void cstr_clear(cstr* self) { _cstr_set_size(self, 0); } STC_INLINE char* cstr_append_uninit(cstr *self, size_t len) { - size_t sz = cstr_size(*self); + size_t sz = cstr_size(self); char* d = cstr_reserve(self, sz + len); if (!d) return NULL; _cstr_set_size(self, sz + len); @@ -261,75 +261,75 @@ STC_INLINE bool cstr_eq(const cstr* s1, const cstr* s2) { } -STC_INLINE bool cstr_equals(cstr s1, const char* str) - { return !strcmp(cstr_str(&s1), str); } +STC_INLINE bool cstr_equals(const cstr* self, const char* str) + { return !strcmp(cstr_str(self), str); } -STC_INLINE bool cstr_equals_sv(cstr s, csview sv) - { return sv.size == cstr_size(s) && !memcmp(cstr_str(&s), sv.str, sv.size); } +STC_INLINE bool cstr_equals_sv(const cstr* self, csview sv) + { return sv.size == cstr_size(self) && !memcmp(cstr_str(self), sv.str, sv.size); } -STC_INLINE bool cstr_equals_s(cstr s1, cstr s2) - { return !cstr_cmp(&s1, &s2); } +STC_INLINE bool cstr_equals_s(const cstr* self, cstr s) + { return !cstr_cmp(self, &s); } -STC_INLINE bool cstr_iequals(cstr s1, const char* str) - { return !utf8_icmp(cstr_str(&s1), str); } +STC_INLINE bool cstr_iequals(const cstr* self, const char* str) + { return !utf8_icmp(cstr_str(self), str); } -STC_INLINE size_t cstr_find(cstr s, const char* search) { - const char *str = cstr_str(&s), *res = strstr((char*)str, search); +STC_INLINE size_t cstr_find(const cstr* self, const char* search) { + const char *str = cstr_str(self), *res = strstr((char*)str, search); return res ? res - str : cstr_npos; } -STC_API size_t cstr_find_sv(cstr s, csview search); +STC_API size_t cstr_find_sv(const cstr* self, csview search); -STC_INLINE size_t cstr_find_s(cstr s, cstr search) - { return cstr_find(s, cstr_str(&search)); } +STC_INLINE size_t cstr_find_s(const cstr* self, cstr search) + { return cstr_find(self, cstr_str(&search)); } -STC_INLINE bool cstr_contains(cstr s, const char* search) - { return strstr(cstr_data(&s), search) != NULL; } +STC_INLINE bool cstr_contains(const cstr* self, const char* search) + { return strstr((char*)cstr_str(self), search) != NULL; } -STC_INLINE bool cstr_contains_sv(cstr s, csview search) - { return cstr_find_sv(s, search) != cstr_npos; } +STC_INLINE bool cstr_contains_sv(const cstr* self, csview search) + { return cstr_find_sv(self, search) != cstr_npos; } -STC_INLINE bool cstr_contains_s(cstr s, cstr search) - { return strstr(cstr_data(&s), cstr_str(&search)) != NULL; } +STC_INLINE bool cstr_contains_s(const cstr* self, cstr search) + { return strstr((char*)cstr_str(self), cstr_str(&search)) != NULL; } -STC_INLINE bool cstr_starts_with_sv(cstr s, csview sub) { - if (sub.size > cstr_size(s)) return false; - return !memcmp(cstr_str(&s), sub.str, sub.size); +STC_INLINE bool cstr_starts_with_sv(const cstr* self, csview sub) { + if (sub.size > cstr_size(self)) return false; + return !memcmp(cstr_str(self), sub.str, sub.size); } -STC_INLINE bool cstr_starts_with(cstr s, const char* sub) { - const char* str = cstr_str(&s); +STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) { + const char* str = cstr_str(self); while (*sub && *str == *sub) ++str, ++sub; return !*sub; } -STC_INLINE bool cstr_starts_with_s(cstr s, cstr sub) - { return cstr_starts_with_sv(s, cstr_sv(&sub)); } +STC_INLINE bool cstr_starts_with_s(const cstr* self, cstr sub) + { return cstr_starts_with_sv(self, cstr_sv(&sub)); } -STC_INLINE bool cstr_istarts_with(cstr s, const char* sub) { - csview sv = cstr_sv(&s); +STC_INLINE bool cstr_istarts_with(const cstr* self, const char* sub) { + csview sv = cstr_sv(self); size_t len = strlen(sub); return len <= sv.size && !utf8_icmp_sv(sv, c_sv(sub, len)); } -STC_INLINE bool cstr_ends_with_sv(cstr s, csview sub) { - csview sv = cstr_sv(&s); +STC_INLINE bool cstr_ends_with_sv(const cstr* self, csview sub) { + csview sv = cstr_sv(self); if (sub.size > sv.size) return false; return !memcmp(sv.str + sv.size - sub.size, sub.str, sub.size); } -STC_INLINE bool cstr_ends_with_s(cstr s, cstr sub) - { return cstr_ends_with_sv(s, cstr_sv(&sub)); } +STC_INLINE bool cstr_ends_with_s(const cstr* self, cstr sub) + { return cstr_ends_with_sv(self, cstr_sv(&sub)); } -STC_INLINE bool cstr_ends_with(cstr s, const char* sub) - { return cstr_ends_with_sv(s, c_sv(sub, strlen(sub))); } +STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub) + { return cstr_ends_with_sv(self, c_sv(sub, strlen(sub))); } -STC_INLINE bool cstr_iends_with(cstr s, const char* sub) { - csview sv = cstr_sv(&s); +STC_INLINE bool cstr_iends_with(const cstr* self, const char* sub) { + csview sv = cstr_sv(self); size_t n = strlen(sub); return n <= sv.size && !utf8_icmp(sv.str + sv.size - n, sub); } @@ -402,9 +402,9 @@ STC_DEF uint64_t cstr_hash(const cstr *self) { return c_fasthash(sv.str, sv.size); } -STC_DEF size_t cstr_find_sv(cstr s, csview search) { - char* res = c_strnstrn(cstr_str(&s), search.str, cstr_size(s), search.size); - return res ? res - cstr_str(&s) : cstr_npos; +STC_DEF size_t cstr_find_sv(const cstr* self, csview search) { + char* res = c_strnstrn(cstr_str(self), search.str, cstr_size(self), search.size); + return res ? res - cstr_str(self) : cstr_npos; } STC_DEF char* _cstr_internal_move(cstr* self, const size_t pos1, const size_t pos2) { @@ -474,8 +474,8 @@ STC_DEF void cstr_resize(cstr* self, const size_t size, const char value) { _cstr_set_size(self, size); } -STC_DEF size_t cstr_find_at(cstr s, const size_t pos, const char* search) { - csview sv = cstr_sv(&s); +STC_DEF size_t cstr_find_at(const cstr* self, const size_t pos, const char* search) { + csview sv = cstr_sv(self); if (pos > sv.size) return cstr_npos; const char* res = strstr((char*)sv.str + pos, search); return res ? res - sv.str : cstr_npos; -- cgit v1.2.3 From 9bdcf2090da121f8d0954dad35db48c7aa47b17e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 13 Aug 2022 19:02:50 +0200 Subject: Experimental: Renamed c_autovar => c_with, c_autoscope => c_scope, c_autodefer => c_defer. May or may not be reverted before V4.0 release. --- README.md | 2 +- benchmarks/misc/string_bench_STC.cpp | 2 +- benchmarks/misc/string_bench_STD.cpp | 2 +- docs/carray_api.md | 6 ++-- docs/ccommon_api.md | 59 +++++++++++++++++++----------------- docs/cmap_api.md | 4 +-- docs/csmap_api.md | 4 +-- docs/csview_api.md | 2 +- examples/arc_demo.c | 2 +- examples/astar.c | 4 +-- examples/bits.c | 4 +-- examples/box.c | 2 +- examples/cstr_match.c | 2 +- examples/demos.c | 8 ++--- examples/new_arr.c | 12 ++++---- examples/person_arc.c | 2 +- examples/prime.c | 2 +- examples/read.c | 6 ++-- examples/regex_replace.c | 2 +- examples/replace.c | 2 +- examples/splitstr.c | 2 +- include/stc/alt/csmap.h | 2 +- include/stc/carr2.h | 2 +- include/stc/carr3.h | 2 +- include/stc/cbits.h | 2 +- include/stc/ccommon.h | 22 ++++++++------ include/stc/cmap.h | 2 +- include/stc/csmap.h | 2 +- src/checkauto.l | 3 ++ 29 files changed, 90 insertions(+), 78 deletions(-) (limited to 'docs') diff --git a/README.md b/README.md index b2eb6094..afab8712 100644 --- a/README.md +++ b/README.md @@ -380,7 +380,7 @@ and non-emplace methods: #include // vector of string (cstr) ... c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_drop(&vec) -c_autovar (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_autovar is a more general c_auto. +c_with (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_with is a more general c_auto. { const char* hello = "Hello"; cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* diff --git a/benchmarks/misc/string_bench_STC.cpp b/benchmarks/misc/string_bench_STC.cpp index 065b6dd7..ae8e4c38 100644 --- a/benchmarks/misc/string_bench_STC.cpp +++ b/benchmarks/misc/string_bench_STC.cpp @@ -38,7 +38,7 @@ cvec_str read_file(const char* name) { cvec_str data = cvec_str_init(); c_auto (cstr, line) - c_autovar (FILE* f = fopen(name, "r"), fclose(f)) + c_with (FILE* f = fopen(name, "r"), fclose(f)) while (cstr_getline(&line, f)) cvec_str_emplace_back(&data, cstr_str(&line)); return data; diff --git a/benchmarks/misc/string_bench_STD.cpp b/benchmarks/misc/string_bench_STD.cpp index 5f033ca1..8bb87937 100644 --- a/benchmarks/misc/string_bench_STD.cpp +++ b/benchmarks/misc/string_bench_STD.cpp @@ -17,7 +17,7 @@ std::vector read_file(const char* name) { std::vector data; c_auto (cstr, line) - c_autovar (FILE* f = fopen(name, "r"), fclose(f)) + c_with (FILE* f = fopen(name, "r"), fclose(f)) while (cstr_getline(&line, f)) data.emplace_back(cstr_str(&line)); return data; diff --git a/docs/carray_api.md b/docs/carray_api.md index 579bf119..cede295e 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -91,8 +91,8 @@ int main() // Ex1 int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. - c_autovar (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), - carr3_f_drop(&arr3)) { + c_with (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; @@ -105,7 +105,7 @@ int main() // Ex2 int w = 256, h = 128; - c_autovar (carr2_i image = carr2_i_new_uninit(w, h), carr2_i_drop(&image)) { + c_with (carr2_i image = carr2_i_new_uninit(w, h), carr2_i_drop(&image)) { int n = 0; c_foreach (i, carr2_i, image) { uint32_t t = n++ % 256; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 6745317d..d37d4d04 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -2,38 +2,41 @@ The following macros are recommended to use, and they safe/have no side-effects. -### c_auto, c_autovar, c_autoscope, c_autodefer +### c_auto, c_with, c_scope, c_defer General ***defer*** mechanics for resource acquisition. These macros allows you to specify the freeing of the resources at the point where the acquisition takes place. The **checkauto** utility described below, ensures that the `c_auto*` macros are used correctly. -| Usage | Description | -|:---------------------------------------|:-----------------------------------------------------| -| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_drop(&var))` | -| `c_autovar (Type var=init, end...)` | Declare `var`. Defer `end...` to end of block | -| `c_autoscope (init, end...)` | Execute `init`. Defer `end...` to end of block | -| `c_autodefer (end...)` | Defer `end...` to end of block | -| `c_breakauto` or `continue` | Break out of a `c_auto*`-block/scope without memleak | - -For multiple variables, use either multiple **c_autovar** in sequence, or declare variable outside -scope and use **c_autoscope**. Also, **c_auto** support up to 4 variables. +| Usage | Description | +|:---------------------------------------|:----------------------------------------------------------| +| `c_auto (Type, var...)` | Same as `c_with (Type var=Type_init(), Type_drop(&var))` | +| `c_with (Type var=init, drop)` | Declare `var`. Defer `drop...` to end of scope | +| `c_with (Type var=init, pred, drop)` | Adds a predicate in order to exit early if init failed | +| `c_scope (init, drop...)` | Execute `init` and defer `drop...` to end of scope | +| `c_defer (drop...)` | Defer `drop...` to end of scope | +| `continue` | Exit a `c_auto/c_with/c_scope...` without memory leaks | + +For multiple variables, use either multiple **c_with** in sequence, or declare variable outside +scope and use **c_scope**. For convenience, **c_auto** support up to 4 variables. ```c -c_autovar (uint8_t* buf = malloc(BUF_SIZE), free(buf)) -c_autovar (FILE* f = fopen(fname, "rb"), fclose(f)) +// `c_with` is similar to python `with`: it declares and can drop a variable after going out of scope. +c_with (uint8_t* buf = malloc(BUF_SIZE), free(buf)) +c_with (FILE* fp = fopen(fname, "rb"), fclose(fp)) { int n = 0; - if (f && buf) { - n = fread(buf, 1, BUF_SIZE, f); + if (fp && buf) { + n = fread(buf, 1, BUF_SIZE, fp); doSomething(buf, n); } } -c_autovar (cstr s = cstr_new("Hello"), cstr_drop(&s)) +c_with (cstr str = cstr_new("Hello"), cstr_drop(&str)) { - cstr_append(&s, " world"); - printf("%s\n", cstr_str(&s)); + cstr_append(&str, " world"); + printf("%s\n", cstr_str(&str)); } +// `c_auto` automatically initialize and destruct up to 4 variables, like `c_with`. c_auto (cstr, s1, s2) { cstr_append(&s1, "Hello"); @@ -45,14 +48,16 @@ c_auto (cstr, s1, s2) printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } -MyData data; -c_autoscope (mydata_init(&data), mydata_destroy(&data)) +// `c_scope` is like `c_with` but works with an already declared variable. +static pthread_mutex_t mut; +c_scope (pthread_mutex_lock(&mut), pthread_mutex_unlock(&mut)) { - printf("%s\n", cstr_str(&mydata.name)); + /* Do syncronized work. */ } +// `c_defer` executes the expressions when leaving scope. cstr s1 = cstr_new("Hello"), s2 = cstr_new("world"); -c_autodefer (cstr_drop(&s1), cstr_drop(&s2)) +c_defer (cstr_drop(&s1), cstr_drop(&s2)) { printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } @@ -70,16 +75,16 @@ cvec_str readFile(const char* name) { cvec_str vec = cvec_str_init(); // returned - c_autovar (FILE* fp = fopen(name, "r"), fclose(fp)) - c_autovar (cstr line = cstr_null, cstr_drop(&line)) - while (cstr_getline(&line, fp)) - cvec_str_emplace_back(&vec, cstr_str(&line)); + c_with (FILE* fp = fopen(name, "r"), fclose(fp)) + c_with (cstr line = cstr_null, cstr_drop(&line)) + while (cstr_getline(&line, fp)) + cvec_str_emplace_back(&vec, cstr_str(&line)); return vec; } int main() { - c_autovar (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) + c_with (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) c_foreach (i, cvec_str, x) printf("%s\n", cstr_str(i.ref)); } diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 91c36def..792d6c8c 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -211,7 +211,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // Define map with defered destruct - c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) + c_with (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) { cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2); @@ -244,7 +244,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { - c_auto (cmap_iv, vecs) // shorthand for c_autovar with _init(), _drop(). + c_auto (cmap_iv, vecs) // shorthand for c_with with _init(), _drop(). { cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 3a1a5aa6..91abaae3 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -157,7 +157,7 @@ int main() { uint32_t col = 0xcc7744ff; csmap_id idnames = csmap_id_init(); - c_autodefer (csmap_id_drop(&idnames)) + c_defer (csmap_id_drop(&idnames)) { c_forarray (csmap_id_raw, v, { {100, "Red"}, {110, "Blue"} }) csmap_id_emplace(&idnames, v->first, v->second); @@ -238,7 +238,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // equivalent to: c_auto (csmap_iv, vecs) - c_autovar (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) + c_with (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) { csmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); csmap_iv_insert(&vecs, 2, (Vec3i){0, 100, 0}); diff --git a/docs/csview_api.md b/docs/csview_api.md index 79d108a3..d6bb4baf 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -199,7 +199,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_with (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) c_foreach (i, cstack_str, s) printf("[%s]\n", cstr_str(i.ref)); } diff --git a/examples/arc_demo.c b/examples/arc_demo.c index 85e3886f..688fe72f 100644 --- a/examples/arc_demo.c +++ b/examples/arc_demo.c @@ -47,7 +47,7 @@ int main() printf("\nset:"); c_foreach (i, csset_Arc, set) printf(" %d", *i.ref->get); - c_autovar (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { + c_with (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); } diff --git a/examples/astar.c b/examples/astar.c index cb498b11..4d9f2469 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -131,7 +131,7 @@ astar(cstr* maze, int width) int main(void) { - c_autovar (cstr maze = cstr_new( + c_with (cstr maze = cstr_new( "#########################################################################\n" "# # # # # # #\n" "# # ######### # ##### ######### ##### ##### ##### # ! #\n" @@ -157,7 +157,7 @@ main(void) "#########################################################################\n"), cstr_drop(&maze)) { int width = cstr_find(&maze, "\n") + 1; - c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) + c_with (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) { c_foreach (it, cdeq_point, path) cstr_data(&maze)[point_index(it.ref)] = 'x'; printf("%s", cstr_str(&maze)); diff --git a/examples/bits.c b/examples/bits.c index 8cce573e..c6e70517 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -3,7 +3,7 @@ int main() { - c_autovar (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { + c_with (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { printf("count %" PRIuMAX ", %" PRIuMAX "\n", cbits_count(&set), cbits_size(&set)); cbits s1 = cbits_from("1110100110111"); char buf[256]; @@ -36,7 +36,7 @@ int main() printf("%d", cbits_test(&set, i)); puts(""); - c_autovar (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { + c_with (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { cbits_flip_all(&s2); cbits_set(&s2, 16); cbits_set(&s2, 17); diff --git a/examples/box.c b/examples/box.c index c7e649bf..b12f1f71 100644 --- a/examples/box.c +++ b/examples/box.c @@ -59,7 +59,7 @@ int main() puts(""); // Look-up Audrey! Create a temporary Person for lookup. - c_autovar (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { + c_with (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { const PBox *v = Persons_get(&vec, a); // lookup if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); } diff --git a/examples/cstr_match.c b/examples/cstr_match.c index 317ff986..614af490 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -4,7 +4,7 @@ int main() { - c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { + c_with (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { size_t pos = cstr_find_at(&ss, 0, "brown"); printf("%" PRIuMAX " [%s]\n", pos, pos == cstr_npos ? "" : cstr_str(&ss) + pos); printf("equals: %d\n", cstr_equals(&ss, "The quick brown fox jumps over the lazy dog.JPG")); diff --git a/examples/demos.c b/examples/demos.c index cd715d46..331ef04f 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -3,7 +3,7 @@ void stringdemo1() { printf("\nSTRINGDEMO1\n"); - c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs)) + c_with (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs)) { printf("%s.\n", cstr_str(&cs)); @@ -35,7 +35,7 @@ void stringdemo1() void vectordemo1() { printf("\nVECTORDEMO1\n"); - c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) + c_with (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) { cvec_ix_reserve(&bignums, 100); for (size_t i = 10; i <= 100; i += 10) @@ -192,8 +192,8 @@ void mapdemo3() void arraydemo1() { printf("\nARRAYDEMO1\n"); - c_autovar (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), - carr3_f_drop(&arr3)) + c_with (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 10.2f; float **arr2 = arr3.data[5]; diff --git a/examples/new_arr.c b/examples/new_arr.c index 17a96062..598e5323 100644 --- a/examples/new_arr.c +++ b/examples/new_arr.c @@ -13,8 +13,8 @@ int main() { int w = 7, h = 5, d = 3; - c_autovar (carr2_int volume = carr2_int_new_uninit(w, h), - carr2_int_drop(&volume)) + c_with (carr2_int volume = carr2_int_new_uninit(w, h), + carr2_int_drop(&volume)) { int *dat = carr2_int_data(&volume); for (size_t i = 0; i < carr2_int_size(&volume); ++i) @@ -30,8 +30,8 @@ int main() puts("\n"); } - c_autovar (carr3_int volume = carr3_int_new_uninit(w, h, d), - carr3_int_drop(&volume)) + c_with (carr3_int volume = carr3_int_new_uninit(w, h, d), + carr3_int_drop(&volume)) { int *dat = carr3_int_data(&volume); for (size_t i = 0; i < carr3_int_size(&volume); ++i) @@ -48,8 +48,8 @@ int main() puts(""); } - c_autovar (carr2_str text2d = carr2_str_with_size(h, d, cstr_init()), - carr2_str_drop(&text2d)) + c_with (carr2_str text2d = carr2_str_with_size(h, d, cstr_init()), + carr2_str_drop(&text2d)) { cstr_assign(&text2d.data[2][1], "hello"); cstr_assign(&text2d.data[4][0], "world"); diff --git a/examples/person_arc.c b/examples/person_arc.c index 272a3f72..bddf7bd6 100644 --- a/examples/person_arc.c +++ b/examples/person_arc.c @@ -62,7 +62,7 @@ int main() puts(""); // Look-up Audrey! - c_autovar (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { + c_with (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { const PSPtr *v = Persons_get(&vec, a); if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); } diff --git a/examples/prime.c b/examples/prime.c index 85a66ee5..7af66f33 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -27,7 +27,7 @@ int main(void) printf("computing prime numbers up to %" PRIuMAX "\n", n); clock_t t1 = clock(); - c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { + c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { puts("done"); size_t np = cbits_count(&primes); clock_t t2 = clock(); diff --git a/examples/read.c b/examples/read.c index 26fc46dd..5a9a30d5 100644 --- a/examples/read.c +++ b/examples/read.c @@ -6,8 +6,8 @@ cvec_str read_file(const char* name) { cvec_str vec = cvec_str_init(); - c_autovar (FILE* f = fopen(name, "r"), fclose(f)) - c_autovar (cstr line = cstr_init(), cstr_drop(&line)) + c_with (FILE* f = fopen(name, "r"), fclose(f)) + c_with (cstr line = cstr_null, cstr_drop(&line)) while (cstr_getline(&line, f)) cvec_str_push(&vec, cstr_clone(line)); return vec; @@ -16,7 +16,7 @@ cvec_str read_file(const char* name) int main() { int n = 0; - c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) + c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) c_foreach (i, cvec_str, vec) printf("%5d: %s\n", ++n, cstr_str(i.ref)); diff --git a/examples/regex_replace.c b/examples/regex_replace.c index ccc90dba..2ccbfc3c 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -34,7 +34,7 @@ int main() printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ - c_autovar (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { + c_with (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { if (cregex_captures(&re) == 0) c_breakauto; /* European date format. */ diff --git a/examples/replace.c b/examples/replace.c index 13b6eaaf..c22c71ff 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -11,7 +11,7 @@ int main () // Ustring positions: 0123456789*123456789*12345 cstr s = cstr_from(base); // "this is a test string." cstr m = cstr_clone(s); - c_autodefer (cstr_drop(&s), cstr_drop(&m)) { + c_defer (cstr_drop(&s), cstr_drop(&m)) { cstr_append(&m, cstr_str(&m)); cstr_append(&m, cstr_str(&m)); printf("%s\n", cstr_str(&m)); diff --git a/examples/splitstr.c b/examples/splitstr.c index 68c36291..c483fbe0 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -33,7 +33,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_with (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) c_foreach (i, cstack_str, s) printf("[%s]\n", cstr_str(i.ref)); } diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h index 60a1b72a..4b90fb78 100644 --- a/include/stc/alt/csmap.h +++ b/include/stc/alt/csmap.h @@ -32,7 +32,7 @@ #include int main(void) { - c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) + c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) { csmap_sx_emplace(&m, "Testing one", 1.234); csmap_sx_emplace(&m, "Testing two", 12.34); diff --git a/include/stc/carr2.h b/include/stc/carr2.h index f55cdd17..ffedb07d 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -35,7 +35,7 @@ int main() { int w = 7, h = 5; - c_autovar (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image)) + c_with (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image)) { int *dat = carr2_int_data(&image); for (int i = 0; i < carr2_int_size(&image); ++i) diff --git a/include/stc/carr3.h b/include/stc/carr3.h index fdc29b6f..07eac2a1 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -35,7 +35,7 @@ int main() { int w = 7, h = 5, d = 3; - c_autovar (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image)) + c_with (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image)) { int *dat = carr3_int_data(&image); for (int i = 0; i < carr3_int_size(&image); ++i) diff --git a/include/stc/cbits.h b/include/stc/cbits.h index 3f75226d..a1b84acd 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -27,7 +27,7 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h" int main() { - c_autovar (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) + c_with (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) { cbits_reset(&bset, 9); cbits_resize(&bset, 43, false); diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index a4ae28aa..58d74ddf 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -176,24 +176,28 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, for (itype i=start, _inc=step, _end=(stop) - (0 < _inc) \ ; (i <= _end) == (0 < _inc); i += _inc) -#define c_autovar(...) c_MACRO_OVERLOAD(c_autovar, __VA_ARGS__) -#define c_autovar2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop) -#define c_autovar3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop) -#define c_autoscope(init, drop) for (int _c_i = (init, 0); !_c_i; ++_c_i, drop) -#define c_autodefer(...) for (int _c_i = 0; !_c_i; ++_c_i, __VA_ARGS__) +#define c_autovar c_with // [deprecated] +#define c_autoscope c_scope // [deprecated] +#define c_autodefer c_defer // [deprecated] + +#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) +#define c_with2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop) +#define c_with3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop) +#define c_scope(init, drop) for (int _c_i = (init, 0); !_c_i; ++_c_i, drop) +#define c_defer(...) for (int _c_i = 0; !_c_i; ++_c_i, __VA_ARGS__) #define c_breakauto continue #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) #define c_auto2(C, a) \ - c_autovar2(C a = C##_init(), C##_drop(&a)) + c_with2(C a = C##_init(), C##_drop(&a)) #define c_auto3(C, a, b) \ - c_autovar2(c_expand(C a = C##_init(), b = C##_init()), \ + c_with2(c_expand(C a = C##_init(), b = C##_init()), \ (C##_drop(&b), C##_drop(&a))) #define c_auto4(C, a, b, c) \ - c_autovar2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init()), \ + c_with2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init()), \ (C##_drop(&c), C##_drop(&b), C##_drop(&a))) #define c_auto5(C, a, b, c, d) \ - c_autovar2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ + c_with2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ (C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))) #define c_autobuf(b, type, n) c_autobuf_N(b, type, n, 256) diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 971d00a8..58774fb2 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -31,7 +31,7 @@ #include int main(void) { - c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m)) + c_with (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m)) { cmap_ichar_emplace(&m, 5, 'a'); cmap_ichar_emplace(&m, 8, 'b'); diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 97f1fce1..c773e70f 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -32,7 +32,7 @@ #include int main(void) { - c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) + c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) { csmap_sx_emplace(&m, "Testing one", 1.234); csmap_sx_emplace(&m, "Testing two", 12.34); diff --git a/src/checkauto.l b/src/checkauto.l index 5b4a9c68..384b3855 100644 --- a/src/checkauto.l +++ b/src/checkauto.l @@ -38,6 +38,9 @@ for | while | switch { block_type |= LOOP; state = BRACES; } do { block_type |= LOOP; state = BRACESDONE; } +c_with | +c_scope | +c_defer | c_autovar | c_autoscope | c_autodefer | -- cgit v1.2.3 From bf3c50da1a346b56b6846c0f7b9e7a222f602c2f Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 15 Aug 2022 16:54:56 +0200 Subject: More iterator fixes. Make sure cvec/cdeq find_in() return end() iterator if item not found. Small cstr API change to u8_replace*. --- docs/cdeq_api.md | 2 +- docs/cstr_api.md | 2 +- docs/csview_api.md | 2 +- docs/cvec_api.md | 4 ++-- examples/regex_replace.c | 2 +- examples/utf8replace_c.c | 2 +- include/stc/cdeq.h | 24 +++++++++++++----------- include/stc/cstr.h | 7 ++----- include/stc/cvec.h | 23 ++++++++++++----------- 9 files changed, 34 insertions(+), 34 deletions(-) (limited to 'docs') diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 79e6bf39..6a47313d 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -43,7 +43,7 @@ const cdeq_X_value* cdeq_X_at(const cdeq_X* self, size_t idx); const cdeq_X_value* cdeq_X_get(const cdeq_X* self, i_valraw raw); // return NULL if not found cdeq_X_value* cdeq_X_get_mut(cdeq_X* self, i_valraw raw); // mutable get cdeq_X_iter cdeq_X_find(const cdeq_X* self, i_valraw raw); -cdeq_X_iter cdeq_X_find_in(cdeq_X_iter i1, cdeq_X_iter i2, i_valraw raw); +cdeq_X_iter cdeq_X_find_in(cdeq_X_iter i1, cdeq_X_iter i2, i_valraw raw); // return cvec_X_end() if not found cdeq_X_value* cdeq_X_front(const cdeq_X* self); cdeq_X_value* cdeq_X_back(const cdeq_X* self); diff --git a/docs/cstr_api.md b/docs/cstr_api.md index f5414f1b..d4e292cd 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -99,7 +99,7 @@ size_t cstr_u8_size_n(const cstr self, size_t nbytes); // utf8 si size_t cstr_u8_to_pos(const cstr* self, size_t u8idx); // byte pos offset at utf8 codepoint index const char* cstr_u8_at(const cstr* self, size_t u8idx); // char* position at utf8 codepoint index csview cstr_u8_chr(const cstr* self, size_t u8idx); // get utf8 character as a csview -void cstr_u8_replace_at(cstr* self, size_t u8pos, size_t u8len, csview repl); // replace at utf8 indices +void cstr_u8_replace(cstr* self, size_t pos, size_t u8len, csview repl); // replace u8len utf8 chars // iterate utf8 codepoints cstr_iter cstr_begin(const cstr* self); diff --git a/docs/csview_api.md b/docs/csview_api.md index d6bb4baf..128a1c9d 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -146,7 +146,7 @@ int main() { c_auto (cstr, s1) { s1 = cstr_new("hell😀 w😀rld"); - cstr_u8_replace_at(&s1, 7, 1, c_sv("ø")); + cstr_u8_replace(&s1, cstr_find(&s1, "😀rld"), 1, c_sv("ø")); printf("%s\n", cstr_str(&s1)); c_foreach (i, cstr, s1) diff --git a/docs/cvec_api.md b/docs/cvec_api.md index a1d27a23..579f6eeb 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -49,9 +49,9 @@ size_t cvec_X_capacity(const cvec_X* self); const cvec_X_value* cvec_X_at(const cvec_X* self, size_t idx); const cvec_X_value* cvec_X_get(const cvec_X* self, i_valraw raw); // return NULL if not found cvec_X_value* cvec_X_at_mut(cvec_X* self, size_t idx); -cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // get mutable value +cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // find mutable value, return value ptr cvec_X_iter cvec_X_find(const cvec_X* self, i_valraw raw); -cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); +cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); // return cvec_X_end() if not found // On sorted vectors: cvec_X_iter cvec_X_binary_search(const cvec_X* self, i_valraw raw); // at elem == raw, else end cvec_X_iter cvec_X_lower_bound(const cvec_X* self, i_valraw raw); // at first elem >= raw, else end diff --git a/examples/regex_replace.c b/examples/regex_replace.c index 2ccbfc3c..8640ced1 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -36,7 +36,7 @@ int main() /* Shows how to compile RE separately */ c_with (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { if (cregex_captures(&re) == 0) - c_breakauto; + continue; // break c_with /* European date format. */ cstr_take(&str, cregex_replace(input, &re, "$3.$2.$1", 0)); printf("euros: %s\n", cstr_str(&str)); diff --git a/examples/utf8replace_c.c b/examples/utf8replace_c.c index 1bee9b44..e7659cfd 100644 --- a/examples/utf8replace_c.c +++ b/examples/utf8replace_c.c @@ -8,7 +8,7 @@ int main() { printf("%s\n", cstr_str(&hello)); /* replace second smiley at utf8 codepoint pos 7 */ - cstr_u8_replace_at(&hello, 7, 1, c_sv("🐨")); + cstr_u8_replace(&hello, cstr_find(&hello, "😀rld"), 1, c_sv("🐨")); printf("%s\n", cstr_str(&hello)); diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 128b85ee..0efbe064 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -29,7 +29,8 @@ struct cdeq_rep { size_t size, cap; unsigned base[1]; }; #define cdeq_rep_(self) c_unchecked_container_of((self)->_base, struct cdeq_rep, base) -#define it2_ref_(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it_ptr(it) (it.ref ? it.ref : it.end) #endif // CDEQ_H_INCLUDED #ifndef _i_prefix @@ -125,7 +126,7 @@ _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], con } STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { - return _cx_memb(_insert_range)(self, (it.ref ? it.ref : it.end), &value, &value + 1); + return _cx_memb(_insert_range)(self, _it_ptr(it), &value, &value + 1); } STC_INLINE _cx_iter @@ -138,7 +139,7 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { } STC_INLINE _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { - return _cx_memb(_erase_range_p)(self, i1.ref, it2_ref_(i1, i2)); + return _cx_memb(_erase_range_p)(self, i1.ref, _it2_ptr(i1, i2)); } @@ -172,7 +173,7 @@ _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], cons } STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); + return _cx_memb(_emplace_range)(self, _it_ptr(it), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -194,7 +195,7 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_raw raw) STC_INLINE void _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) { - qsort(i1.ref, it2_ref_(i1, i2) - i1.ref, sizeof *i1.ref, + qsort(i1.ref, _it2_ptr(i1, i2) - i1.ref, sizeof *i1.ref, (int(*)(const void*, const void*)) cmp); } @@ -407,8 +408,8 @@ STC_DEF _cx_iter _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) - for (_cx_iter j = it; p1 != p2; ++p1) - *j.ref++ = i_keyfrom((*p1)); + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyfrom((*p1)); return it; } #endif // !_i_no_emplace @@ -418,8 +419,9 @@ STC_DEF _cx_iter _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); - if (it.ref) for (_cx_iter j; p1 != p2; ++p1) - *j.ref++ = i_keyclone((*p1)); + if (it.ref) + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyclone((*p1)); return it; } #endif // !_i_no_clone @@ -428,13 +430,13 @@ _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) { - const _cx_value* p2 = it2_ref_(i1, i2); + const _cx_value* p2 = _it2_ptr(i1, i2); for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) return i1; } - return i2; + i2.ref = NULL; return i2; // NB! } STC_DEF int diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 0728b110..99b60e49 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -370,11 +370,8 @@ STC_INLINE void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* STC_INLINE void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl) { cstr_replace_at_sv(self, pos, len, cstr_sv(&repl)); } -STC_INLINE void cstr_u8_replace_at(cstr* self, size_t u8pos, size_t u8len, csview repl) { - csview sv = cstr_sv(self); - const char* p = utf8_at(sv.str, u8pos); - cstr_replace_at_sv(self, p - sv.str, utf8_pos(p, u8len), repl); -} +STC_INLINE void cstr_u8_replace(cstr* self, size_t pos, size_t u8len, csview repl) + { cstr_replace_at_sv(self, pos, utf8_pos(cstr_str(self) + pos, u8len), repl); } STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 92065619..1be7211d 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -66,7 +66,8 @@ int main() { struct cvec_rep { size_t size, cap; unsigned data[1]; }; #define cvec_rep_(self) c_unchecked_container_of((self)->data, struct cvec_rep, data) -#define it2_ref_(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it_ptr(it) (it.ref ? it.ref : it.end) #endif // CVEC_H_INCLUDED #ifndef _i_prefix @@ -107,7 +108,7 @@ _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], cons } STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); + return _cx_memb(_emplace_range)(self, _it_ptr(it), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -169,7 +170,7 @@ _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], con } STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { - return _cx_memb(_insert_range)(self, (it.ref ? it.ref : it.end), &value, &value + 1); + return _cx_memb(_insert_range)(self, _it_ptr(it), &value, &value + 1); } STC_INLINE _cx_iter @@ -182,7 +183,7 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { } STC_INLINE _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { - return _cx_memb(_erase_range_p)(self, i1.ref, it2_ref_(i1, i2)); + return _cx_memb(_erase_range_p)(self, i1.ref, _it2_ptr(i1, i2)); } STC_INLINE const _cx_value* @@ -243,7 +244,7 @@ _cx_memb(_lower_bound)(const _cx_self* self, _cx_raw raw) { STC_INLINE void _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) { - qsort(i1.ref, it2_ref_(i1, i2) - i1.ref, sizeof(_cx_value), + qsort(i1.ref, _it2_ptr(i1, i2) - i1.ref, sizeof(_cx_value), (int(*)(const void*, const void*)) cmp); } @@ -396,8 +397,8 @@ _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) - for (_cx_iter j = it; p1 != p2; ++p1) - *j.ref++ = i_keyfrom((*p1)); + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyfrom((*p1)); return it; } #endif // !_i_no_emplace @@ -405,19 +406,19 @@ _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, #if !c_option(c_no_cmp) STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) { - const _cx_value* p2 = it2_ref_(i1, i2); + const _cx_value* p2 = _it2_ptr(i1, i2); for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) return i1; } - return i2; + i2.ref = NULL; return i2; // NB! } STC_DEF _cx_iter _cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, _cx_iter* lower_bound) { - const _cx_value* p2 = it2_ref_(i1, i2); + const _cx_value* p2 = _it2_ptr(i1, i2); _cx_iter mid = i1; while (i1.ref != p2) { mid.ref = i1.ref + (p2 - i1.ref)/2; @@ -429,7 +430,7 @@ _cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, else i1.ref = mid.ref + 1; } *lower_bound = i1.ref == i2.end ? i2 : i1; - return i2; + i2.ref = NULL; return i2; // NB! } STC_DEF int -- cgit v1.2.3