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 +- examples/mmap.c | 29 +++++++++++++---------------- examples/regex_replace.c | 2 +- examples/utf8replace_c.c | 2 +- include/stc/cmap.h | 18 ++++++++++-------- include/stc/cstack.h | 6 +++--- include/stc/cstr.h | 6 +++--- include/stc/csview.h | 4 ++-- include/stc/cvec.h | 29 ++++++++++++----------------- include/stc/forward.h | 14 +++++++------- 10 files changed, 53 insertions(+), 59 deletions(-) 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)); } } ``` diff --git a/examples/mmap.c b/examples/mmap.c index 5ca2f92a..ed78d2af 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -4,6 +4,7 @@ // Multimap entries #include #define i_val_str +//#define i_valdrop(x) (printf("drop %s\n", cstr_str(x)), cstr_drop(x)) #define i_extern // define _clist_mergesort() once #include @@ -34,10 +35,11 @@ int main() { c_auto (Multimap, mmap) { + typedef struct {int a; const char* b;} pair; + // list-initialize - struct { int first; const char* second; } vals[] = - {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}; - c_forrange (i, c_arraylen(vals)) insert(&mmap, c_pair(&vals[i])); + c_forarray (pair, v, {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}) + insert(&mmap, v->a, v->b); print("#1", mmap); // insert using value_type @@ -52,24 +54,19 @@ int main() print("#4", mmap); // insert using initialization_list - insert(&mmap, 5, "one"); - insert(&mmap, 5, "two"); + c_forarray (pair, v, {{5, "one"}, {5, "two"}}) + insert(&mmap, v->a, v->b); print("#5", mmap); // FOLLOWING NOT IN ORIGINAL EXAMPLE: - // erase all entries with key 5 Multimap_erase(&mmap, 5); - print("+6", mmap); + print("+5", mmap); + - // find and erase first entry containing "bar" - clist_str_iter pos; - c_foreach (e, Multimap, mmap) { - if ((pos = clist_str_find(&e.ref->second, "bar")).ref != clist_str_end(&e.ref->second).ref) { - clist_str_erase_at(&e.ref->second, pos); - break; - } - } - print("+7", mmap); + Multimap_clear(&mmap); + c_forarray (pair, v, {{1, "ä"}, {2, "ё"}, {2, "ö"}, {3, "ü"}}) + insert(&mmap, v->a, v->b); + print("#6", mmap); } } diff --git a/examples/regex_replace.c b/examples/regex_replace.c index 1b140676..ccc90dba 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -36,7 +36,7 @@ int main() /* Shows how to compile RE separately */ c_autovar (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { if (cregex_captures(&re) == 0) - continue; + c_breakauto; /* 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 792654b6..1bee9b44 100644 --- a/examples/utf8replace_c.c +++ b/examples/utf8replace_c.c @@ -16,7 +16,7 @@ int main() { printf("%s\n", cstr_str(&hello)); c_foreach (c, cstr, hello) - printf("%.*s,", c_ARGsv(c.chr)); + printf("%.*s,", c_ARGsv(c.u8.chr)); puts(""); } } diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 84957e69..1394b3a7 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -192,8 +192,8 @@ STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, _cx_rawkey rkey) { i_size idx; if (!(self->size && self->_hashx[idx = _cx_memb(_bucket_)(self, &rkey).idx])) - idx = self->bucket_count; - return c_make(_cx_iter){self->table+idx, self->_hashx+idx}; + return c_make(_cx_iter){NULL}; + return c_make(_cx_iter){self->table+idx, self->table+self->bucket_count, self->_hashx+idx}; } STC_INLINE const _cx_value* @@ -210,25 +210,27 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_rawkey rkey) STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { - _cx_iter it = {self->table, self->_hashx}; + _cx_iter it = {self->table, self->table+self->bucket_count, self->_hashx}; if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; + if (it.ref == it._end) it.ref = NULL; return it; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){self->table + self->bucket_count}; } + { return c_make(_cx_iter){NULL}; } STC_INLINE void -_cx_memb(_next)(_cx_iter* it) - { while ((++it->ref, *++it->_hx == 0)) ; } +_cx_memb(_next)(_cx_iter* it) { + while ((++it->ref, *++it->_hx == 0)) ; + if (it->ref == it->_end) it->ref = NULL; +} STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) { - // UB if n > elements left - while (n--) _cx_memb(_next)(&it); + while (n-- && it.ref) _cx_memb(_next)(&it); return it; } diff --git a/include/stc/cstack.h b/include/stc/cstack.h index 46d209ca..3986e366 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -170,12 +170,12 @@ STC_INLINE i_keyraw _cx_memb(_value_toraw)(const _cx_value* val) #endif // !_i_no_clone STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { return c_make(_cx_iter){(_cx_value*)self->data}; } + { return c_make(_cx_iter){self->size ? (_cx_value*)self->data : NULL, (_cx_value*)self->data + self->size}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){(_cx_value*)self->data + self->size}; } + { return c_make(_cx_iter){NULL}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; } +STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs) { it.ref += offs; return it; } diff --git a/include/stc/cstr.h b/include/stc/cstr.h index aae52ea0..2dbea85a 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -224,15 +224,15 @@ STC_INLINE csview cstr_u8_chr(const cstr* self, size_t u8idx) { STC_INLINE cstr_iter cstr_begin(const cstr* self) { const char* str = cstr_str(self); - return c_make(cstr_iter){.chr = {str, utf8_chr_size(str)}}; + return c_make(cstr_iter){.u8 = {{str, utf8_chr_size(str)}}}; } STC_INLINE cstr_iter cstr_end(const cstr* self) { csview sv = cstr_sv(self); return c_make(cstr_iter){sv.str + sv.size}; } STC_INLINE void cstr_next(cstr_iter* it) { - it->ref += it->chr.size; - it->chr.size = utf8_chr_size(it->ref); + it->ref += it->u8.chr.size; + it->u8.chr.size = utf8_chr_size(it->ref); } diff --git a/include/stc/csview.h b/include/stc/csview.h index 2efeff5b..ef545bf2 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -71,13 +71,13 @@ STC_INLINE csview csview_slice(csview sv, size_t p1, size_t p2) { /* iterator */ STC_INLINE csview_iter csview_begin(const csview* self) - { return c_make(csview_iter){.chr = {self->str, utf8_chr_size(self->str)}}; } + { return c_make(csview_iter){.u8 = {{self->str, utf8_chr_size(self->str)}}}; } STC_INLINE csview_iter csview_end(const csview* self) { return c_make(csview_iter){self->str + self->size}; } STC_INLINE void csview_next(csview_iter* it) - { it->ref += it->chr.size; it->chr.size = utf8_chr_size(it->ref); } + { it->ref += it->u8.chr.size; it->u8.chr.size = utf8_chr_size(it->ref); } /* utf8 */ STC_INLINE size_t csview_u8_size(csview sv) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 81678293..a4308628 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -141,12 +141,11 @@ STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value) { return _cx_memb(_push)(self, value); } STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) { _cx_memb(_pop)(self); } STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { return c_make(_cx_iter){self->data}; } -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){self->data + cvec_rep_(self)->size}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; } -STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs) - { it.ref += offs; return it; } + { size_t n = cvec_rep_(self)->size; return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; } +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL}; } +STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } +STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) + { if ((it.ref += offs) >= it._end) it.ref = NULL; return it; } STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it) { return it.ref - cx->data; } STC_INLINE _cx_self @@ -217,9 +216,7 @@ _cx_memb(_find)(const _cx_self* self, _cx_raw raw) { STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, _cx_raw raw) { - _cx_iter end = _cx_memb(_end)(self); - _cx_value* val = _cx_memb(_find)(self, raw).ref; - return val == end.ref ? NULL : val; + return _cx_memb(_find)(self, raw).ref; } STC_INLINE _cx_value* @@ -354,14 +351,12 @@ _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { intptr_t len = p2 - p1; - if (len > 0) { - _cx_value* p = p1, *end = self->data + cvec_rep_(self)->size; - for (; p != p2; ++p) - { i_keydrop(p); } - memmove(p1, p2, (end - p2) * sizeof(i_key)); - cvec_rep_(self)->size -= len; - } - return c_make(_cx_iter){.ref = p1}; + _cx_value* p = p1, *end = self->data + cvec_rep_(self)->size; + for (; p != p2; ++p) + { i_keydrop(p); } + memmove(p1, p2, (end - p2) * sizeof *p1); + cvec_rep_(self)->size -= len; + return c_make(_cx_iter){.ref = p2 == end ? NULL : p1, end - len}; } #if !defined _i_no_clone diff --git a/include/stc/forward.h b/include/stc/forward.h index 04566b98..1a85f1ed 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -57,7 +57,7 @@ typedef struct { const char* str; size_t size; } csview; typedef char csview_value; typedef union { const char *ref; - csview chr; + struct { csview chr; const char *_end; } u8; } csview_iter, cstr_iter; #define c_true(...) __VA_ARGS__ @@ -73,12 +73,12 @@ typedef union { #define _c_carr2_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ typedef struct { SELF##_value **data; size_t xdim, ydim; } SELF #define _c_carr3_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ typedef struct { SELF##_value ***data; size_t xdim, ydim, zdim; } SELF #define _c_cbox_types(SELF, VAL) \ @@ -89,7 +89,7 @@ typedef union { #define _c_cdeq_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct {SELF##_value *ref; } SELF##_iter; \ + typedef struct {SELF##_value *ref, *_end; } SELF##_iter; \ typedef struct {SELF##_value *_base, *data;} SELF #define _c_clist_types(SELF, VAL) \ @@ -120,7 +120,7 @@ typedef union { } SELF##_result; \ \ typedef struct { \ - SELF##_value *ref; \ + SELF##_value *ref, *_end; \ uint8_t* _hx; \ } SELF##_iter; \ \ @@ -186,7 +186,7 @@ typedef union { #endif #define _c_cstack_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ typedef struct SELF { \ SELF##_value* data; \ size_t size, capacity; \ @@ -209,7 +209,7 @@ typedef union { #define _c_cvec_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ typedef struct { SELF##_value *data; } SELF #endif // STC_FORWARD_H_INCLUDED -- cgit v1.2.3 From 1756309078f4c09765bde898e50b8a3078cebc7d Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 10 Aug 2022 12:59:20 +0200 Subject: Fixed cdeq, cvec, cmap and cstack: iterators .ref is now NULL when it is end(). clist and csmap/cset already has this property. --- include/stc/cdeq.h | 54 +++++++++++++++++++++------------------------------ include/stc/cmap.h | 35 +++++++++++++++++---------------- include/stc/cstack.h | 6 +++--- include/stc/cvec.h | 40 +++++++++++++++++++------------------- include/stc/forward.h | 2 +- 5 files changed, 64 insertions(+), 73 deletions(-) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index c5e08393..da7f258f 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -95,10 +95,10 @@ STC_INLINE void _cx_memb(_pop_front)(_cx_self* self) // == _pop() when _ STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { return c_make(_cx_iter){self->data}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){self->data + cdeq_rep_(self)->size}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; } -STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs) - { it.ref += offs; return it; } + { return c_make(_cx_iter){NULL, self->data + cdeq_rep_(self)->size}; } +STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } +STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) + { if ((it.ref += offs) >= it._end) it.ref = NULL; return it; } #if !defined _i_queue @@ -127,7 +127,7 @@ _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], con } STC_INLINE _cx_value* _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_p)(self, (it.ref ? it.ref : it._end), &value, &value + 1); } STC_INLINE _cx_iter @@ -139,16 +139,10 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { return _cx_memb(_erase_range_p)(self, it.ref, it.ref + 1); } STC_INLINE _cx_iter -_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { - return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref); +_cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { + return _cx_memb(_erase_range_p)(self, i1.ref, (i2.ref ? i2.ref : i2._end)); } -#if !defined _i_no_clone -STC_INLINE _cx_value* -_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) { - return _cx_memb(_clone_range_p)(self, it.ref, it1.ref, it2.ref); -} -#endif // !_i_no_clone #if !defined _i_no_emplace STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, _cx_raw raw) { @@ -165,7 +159,7 @@ _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], cons } STC_INLINE _cx_value* _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1); + return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it._end), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -178,9 +172,7 @@ _cx_memb(_find)(const _cx_self* self, _cx_raw raw) { STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, _cx_raw raw) { - _cx_iter end = _cx_memb(_end)(self); - _cx_value* val = _cx_memb(_find_in)(_cx_memb(_begin)(self), end, raw).ref; - return val == end.ref ? NULL : val; + return _cx_memb(_find_in)(_cx_memb(_begin)(self), _cx_memb(_end)(self), raw).ref; } STC_INLINE _cx_value* @@ -188,9 +180,9 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_raw raw) { return (_cx_value *) _cx_memb(_get)(self, 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, i2.ref - i1.ref, sizeof *i1.ref, (int(*)(const void*, const void*)) _cmp_); +_cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) { + qsort(i1.ref, (i2.ref ? i2.ref : i2._end) - i1.ref, sizeof *i1.ref, + (int(*)(const void*, const void*)) cmp); } STC_INLINE void @@ -379,16 +371,13 @@ _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { - const size_t n = p2 - p1; - if (n > 0) { - _cx_value* p = p1, *end = self->data + cdeq_rep_(self)->size; - for (; p != p2; ++p) { i_keydrop(p); } - if (p1 == self->data) - self->data += n; - else memmove(p1, p2, (end - p2) * sizeof(i_key)); - cdeq_rep_(self)->size -= n; - } - return c_make(_cx_iter){p1}; + intptr_t len = p2 - p1; + _cx_value* p = p1, *end = self->data + cdeq_rep_(self)->size; + for (; p != p2; ++p) + { i_keydrop(p); } + memmove(p1, p2, (end - p2) * sizeof *p1); + cdeq_rep_(self)->size -= len; + return c_make(_cx_iter){p2 == end ? NULL : p1, end - len}; } #if !defined _i_no_emplace @@ -418,8 +407,9 @@ _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) { - for (; i1.ref != i2.ref; ++i1.ref) { - _cx_raw r = i_keyto(i1.ref); + const _cx_value* p2 = i2.ref ? i2.ref : i2._end; + for (; i1.ref != p2; ++i1.ref) { + const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) return i1; } diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 1394b3a7..0d1c13d9 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -188,11 +188,28 @@ _cx_memb(_push)(_cx_self* self, _cx_value _val) { return _res; } + +STC_INLINE _cx_iter +_cx_memb(_end)(const _cx_self* self) + { return c_make(_cx_iter){NULL}; } + +STC_INLINE void +_cx_memb(_next)(_cx_iter* it) { + while ((++it->ref, *++it->_hx == 0)) ; + if (it->ref == it->_end) it->ref = NULL; +} + +STC_INLINE _cx_iter +_cx_memb(_advance)(_cx_iter it, size_t n) { + while (n-- && it.ref) _cx_memb(_next)(&it); + return it; +} + STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, _cx_rawkey rkey) { i_size idx; if (!(self->size && self->_hashx[idx = _cx_memb(_bucket_)(self, &rkey).idx])) - return c_make(_cx_iter){NULL}; + return _cx_memb(_end)(self); return c_make(_cx_iter){self->table+idx, self->table+self->bucket_count, self->_hashx+idx}; } @@ -218,22 +235,6 @@ _cx_memb(_begin)(const _cx_self* self) { return it; } -STC_INLINE _cx_iter -_cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){NULL}; } - -STC_INLINE void -_cx_memb(_next)(_cx_iter* it) { - while ((++it->ref, *++it->_hx == 0)) ; - if (it->ref == it->_end) it->ref = NULL; -} - -STC_INLINE _cx_iter -_cx_memb(_advance)(_cx_iter it, size_t n) { - while (n-- && it.ref) _cx_memb(_next)(&it); - return it; -} - STC_INLINE size_t _cx_memb(_erase)(_cx_self* self, _cx_rawkey rkey) { if (self->size == 0) diff --git a/include/stc/cstack.h b/include/stc/cstack.h index 3986e366..811479c4 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -173,11 +173,11 @@ STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { return c_make(_cx_iter){self->size ? (_cx_value*)self->data : NULL, (_cx_value*)self->data + self->size}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){NULL}; } + { return c_make(_cx_iter){NULL, (_cx_value*)self->data + self->size}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } -STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs) - { it.ref += offs; return it; } +STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) + { if ((it.ref += offs) >= it._end) it.ref = NULL ; return it; } #include "template.h" diff --git a/include/stc/cvec.h b/include/stc/cvec.h index a4308628..99df920c 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -106,7 +106,7 @@ _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], cons } STC_INLINE _cx_value* _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1); + return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it._end), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -121,10 +121,6 @@ STC_INLINE void _cx_memb(_copy)(_cx_self* self, const _cx_self* other) { _cx_memb(_drop)(self); *self = _cx_memb(_clone)(*other); } -STC_INLINE _cx_value* -_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) { - return _cx_memb(_clone_range_p)(self, it.ref, it1.ref, it2.ref); -} #endif // !_i_no_clone STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return cvec_rep_(cx)->size; } @@ -142,7 +138,8 @@ STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value) STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) { _cx_memb(_pop)(self); } STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { size_t n = cvec_rep_(self)->size; return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; } -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL}; } +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_make(_cx_iter){NULL, self->data + cvec_rep_(self)->size}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) { if ((it.ref += offs) >= it._end) it.ref = NULL; return it; } @@ -182,7 +179,7 @@ _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], con } STC_INLINE _cx_value* _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_p)(self, (it.ref ? it.ref : it._end), &value, &value + 1); } STC_INLINE _cx_iter @@ -194,8 +191,8 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { return _cx_memb(_erase_range_p)(self, it.ref, it.ref + 1); } STC_INLINE _cx_iter -_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { - return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref); +_cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { + return _cx_memb(_erase_range_p)(self, i1.ref, (i2.ref ? i2.ref : i2._end)); } STC_INLINE const _cx_value* @@ -237,10 +234,11 @@ _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, i2.ref - i1.ref, sizeof(_cx_value), (int(*)(const void*, const void*)) _cmp_); +_cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) { + qsort(i1.ref, (i2.ref ? i2.ref : i2._end) - i1.ref, sizeof(_cx_value), + (int(*)(const void*, const void*)) cmp); } + STC_INLINE void _cx_memb(_sort)(_cx_self* self) { _cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_cmp)); @@ -356,7 +354,7 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { { i_keydrop(p); } memmove(p1, p2, (end - p2) * sizeof *p1); cvec_rep_(self)->size -= len; - return c_make(_cx_iter){.ref = p2 == end ? NULL : p1, end - len}; + return c_make(_cx_iter){p2 == end ? NULL : p1, end - len}; } #if !defined _i_no_clone @@ -395,7 +393,8 @@ _cx_memb(_emplace_range_p)(_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) { - for (; i1.ref != i2.ref; ++i1.ref) { + const _cx_value* p2 = i2.ref ? i2.ref : i2._end; + for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) return i1; @@ -405,18 +404,19 @@ _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_iter mid, last = i2; - while (i1.ref != i2.ref) { - mid.ref = i1.ref + (i2.ref - i1.ref)/2; + const _cx_value* p2 = i2.ref ? i2.ref : i2._end; + _cx_iter mid = i1; + while (i1.ref != p2) { + mid.ref = i1.ref + (p2 - i1.ref)/2; const _cx_raw m = i_keyto(mid.ref); const int c = i_cmp((&raw), (&m)); if (!c) return *lower_bound = mid; - else if (c < 0) i2.ref = mid.ref; + else if (c < 0) p2 = mid.ref; else i1.ref = mid.ref + 1; } - *lower_bound = i1; - return last; + *lower_bound = i1.ref == i2._end ? i2 : i1; + return i2; } STC_DEF int diff --git a/include/stc/forward.h b/include/stc/forward.h index 1a85f1ed..9be399af 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -194,7 +194,7 @@ typedef union { #define _c_cstack_fixed(SELF, VAL, CAP) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ typedef struct SELF { \ SELF##_value data[CAP]; \ size_t size; \ -- cgit v1.2.3 From 8eea6dfb61e9922de5940be975f4a51dcf4a62a3 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 10 Aug 2022 13:43:25 +0200 Subject: Fixed cdeq_begin(). Optimized c_foreach: only use one iter. --- examples/csmap_erase.c | 5 +++++ include/stc/ccommon.h | 7 +++---- include/stc/cdeq.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/csmap_erase.c b/examples/csmap_erase.c index 1c533a99..cbcc2607 100644 --- a/examples/csmap_erase.c +++ b/examples/csmap_erase.c @@ -49,6 +49,11 @@ int main() printmap(m2); mymap_iter it1 = mymap_advance(mymap_begin(&m2), 1); mymap_iter it2 = mymap_find(&m2, mymap_back(&m2)->first); + + puts("to remove:"); + c_foreach (i, mymap, it1, it2) + printf(" [%d, %s]", i.ref->first, cstr_str(&i.ref->second)); + puts(""); // The 2nd member function removes elements // in the range [First, Last) mymap_erase_range(&m2, it1, it2); diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index e2c63b8c..7a60b045 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -157,11 +157,10 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, #define c_foreach(...) c_MACRO_OVERLOAD(c_foreach, __VA_ARGS__) #define c_foreach3(it, C, cnt) \ - for (C##_iter it = C##_begin(&cnt), it##_end_ = C##_end(&cnt) \ - ; it.ref != it##_end_.ref; C##_next(&it)) + for (C##_iter it = C##_begin(&cnt); it.ref; C##_next(&it)) #define c_foreach4(it, C, start, finish) \ - for (C##_iter it = start, it##_end_ = finish \ - ; it.ref != it##_end_.ref; C##_next(&it)) + for (C##_iter it = start, *_end_ref = (C##_iter*)(finish).ref \ + ; it.ref != (C##_value*)_end_ref; C##_next(&it)) #define c_forpair(key, val, C, cnt) /* structured binding */ \ for (struct {C##_iter _it; C##_value* _endref; const C##_key* key; C##_mapped* val;} \ diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index da7f258f..d08e0155 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -93,7 +93,7 @@ STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self) STC_INLINE void _cx_memb(_pop_front)(_cx_self* self) // == _pop() when _i_queue { i_keydrop(self->data); ++self->data; --cdeq_rep_(self)->size; } STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { return c_make(_cx_iter){self->data}; } + { size_t n = cdeq_rep_(self)->size; return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, self->data + cdeq_rep_(self)->size}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } -- cgit v1.2.3 From 4fe41778b4429c4974166e5ae531577dba22bed5 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 10 Aug 2022 14:55:01 +0200 Subject: Fixed iters for carr2/carr3 and cstr/csview. --- include/stc/carr2.h | 8 ++++---- include/stc/carr3.h | 8 ++++---- include/stc/cstr.h | 8 +++++--- include/stc/csview.h | 20 +++++++++++++------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/include/stc/carr2.h b/include/stc/carr2.h index 66a98f58..f15c6034 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -89,13 +89,13 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) { } STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { return c_make(_cx_iter){*self->data}; } + { size_t n = self->xdim*self->ydim; return c_make(_cx_iter){n ? *self->data : NULL, *self->data + n}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){*self->data + self->xdim*self->ydim}; } + { return c_make(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { ++it->ref; } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) diff --git a/include/stc/carr3.h b/include/stc/carr3.h index 8ff1670e..ec67645c 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -92,13 +92,13 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_ } STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { return c_make(_cx_iter){**self->data}; } + { size_t n = _cx_memb(_size)(self); return c_make(_cx_iter){n ? **self->data : NULL, **self->data + n}; } STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){**self->data + _cx_memb(_size)(self)}; } + { return c_make(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { ++it->ref; } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 2dbea85a..509811eb 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -223,16 +223,18 @@ STC_INLINE csview cstr_u8_chr(const cstr* self, size_t u8idx) { // utf8 iterator STC_INLINE cstr_iter cstr_begin(const cstr* self) { - const char* str = cstr_str(self); - return c_make(cstr_iter){.u8 = {{str, utf8_chr_size(str)}}}; + csview sv = cstr_sv(self); + if (!sv.size) return c_make(cstr_iter){NULL}; + return c_make(cstr_iter){.u8 = {{sv.str, utf8_chr_size(sv.str)}, sv.str + sv.size}}; } STC_INLINE cstr_iter cstr_end(const cstr* self) { csview sv = cstr_sv(self); - return c_make(cstr_iter){sv.str + sv.size}; + return c_make(cstr_iter){.u8 = {{NULL}, sv.str + sv.size}}; } STC_INLINE void cstr_next(cstr_iter* it) { it->ref += it->u8.chr.size; it->u8.chr.size = utf8_chr_size(it->ref); + if (it->ref == it->u8._end) it->ref = NULL; } diff --git a/include/stc/csview.h b/include/stc/csview.h index ef545bf2..c48c6ae6 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -69,15 +69,21 @@ STC_INLINE csview csview_slice(csview sv, size_t p1, size_t p2) { return sv; } -/* iterator */ -STC_INLINE csview_iter csview_begin(const csview* self) - { return c_make(csview_iter){.u8 = {{self->str, utf8_chr_size(self->str)}}}; } +/* utf8 iterator */ +STC_INLINE csview_iter csview_begin(const csview* self) { + if (!self->size) return c_make(csview_iter){NULL}; + return c_make(csview_iter){.u8 = {{self->str, utf8_chr_size(self->str)}, self->str + self->size}}; +} + +STC_INLINE csview_iter csview_end(const csview* self) + { return c_make(csview_iter){.u8 = {{NULL}, self->str + self->size}}; } -STC_INLINE csview_iter csview_end(const csview* self) - { return c_make(csview_iter){self->str + self->size}; } +STC_INLINE void csview_next(csview_iter* it) { + it->ref += it->u8.chr.size; + it->u8.chr.size = utf8_chr_size(it->ref); + if (it->ref == it->u8._end) it->ref = NULL; +} -STC_INLINE void csview_next(csview_iter* it) - { it->ref += it->u8.chr.size; it->u8.chr.size = utf8_chr_size(it->ref); } /* utf8 */ STC_INLINE size_t csview_u8_size(csview sv) -- cgit v1.2.3 From 0604d29a95d77f5dc9aeb4813e126a3831062648 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 10 Aug 2022 15:16:58 +0200 Subject: Simplified c_foreach macro. --- include/stc/ccommon.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 7a60b045..8ea58314 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -159,13 +159,12 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, #define c_foreach3(it, C, cnt) \ for (C##_iter it = C##_begin(&cnt); it.ref; C##_next(&it)) #define c_foreach4(it, C, start, finish) \ - for (C##_iter it = start, *_end_ref = (C##_iter*)(finish).ref \ - ; it.ref != (C##_value*)_end_ref; C##_next(&it)) + for (C##_iter it = start, *_endref = (C##_iter*)(finish).ref \ + ; it.ref != (C##_value*)_endref; C##_next(&it)) #define c_forpair(key, val, C, cnt) /* structured binding */ \ - for (struct {C##_iter _it; C##_value* _endref; const C##_key* key; C##_mapped* val;} \ - _ = {C##_begin(&cnt), C##_end(&cnt).ref} \ - ; _._it.ref != _._endref && (_.key = &_._it.ref->first, _.val = &_._it.ref->second) \ + for (struct {C##_iter _it; const C##_key* key; C##_mapped* val;} _ = {C##_begin(&cnt)} \ + ; _._it.ref && (_.key = &_._it.ref->first, _.val = &_._it.ref->second) \ ; C##_next(&_._it)) #define c_forrange(...) c_MACRO_OVERLOAD(c_forrange, __VA_ARGS__) -- cgit v1.2.3 From 35f63cb6d76f47a00daa5929808d75f715566657 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 00:05:39 +0200 Subject: Code formatting only. --- include/stc/carr2.h | 11 +++++++---- include/stc/carr3.h | 11 +++++++---- include/stc/cdeq.h | 22 +++++++++++++++------- include/stc/clist.h | 5 ++--- include/stc/cstack.h | 13 ++++++++----- include/stc/cvec.h | 26 ++++++++++++++++++-------- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/include/stc/carr2.h b/include/stc/carr2.h index f15c6034..1762b8ad 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -88,14 +88,17 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) { return self->ydim*x + y; } -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { size_t n = self->xdim*self->ydim; return c_make(_cx_iter){n ? *self->data : NULL, *self->data + n}; } + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = self->xdim*self->ydim; + return c_make(_cx_iter){n ? *self->data : NULL, *self->data + n}; +} STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } - +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->_end) it->ref = NULL; } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) diff --git a/include/stc/carr3.h b/include/stc/carr3.h index ec67645c..4de21208 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -91,14 +91,17 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_ return self->zdim*(self->ydim*x + y) + z; } -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { size_t n = _cx_memb(_size)(self); return c_make(_cx_iter){n ? **self->data : NULL, **self->data + n}; } + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = _cx_memb(_size)(self); + return c_make(_cx_iter){n ? **self->data : NULL, **self->data + n}; +} STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } - +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->_end) it->ref = NULL; } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index d08e0155..644af838 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -92,13 +92,6 @@ STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self) { return self->data + cdeq_rep_(self)->size - 1; } STC_INLINE void _cx_memb(_pop_front)(_cx_self* self) // == _pop() when _i_queue { i_keydrop(self->data); ++self->data; --cdeq_rep_(self)->size; } -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { size_t n = cdeq_rep_(self)->size; return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; } -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){NULL, self->data + cdeq_rep_(self)->size}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } -STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) - { if ((it.ref += offs) >= it._end) it.ref = NULL; return it; } #if !defined _i_queue @@ -143,6 +136,21 @@ _cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { return _cx_memb(_erase_range_p)(self, i1.ref, (i2.ref ? i2.ref : i2._end)); } + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = cdeq_rep_(self)->size; + return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; +} + +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_make(_cx_iter){NULL, self->data + cdeq_rep_(self)->size}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->_end) it->ref = NULL; } + +STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) + { if ((it.ref += n) >= it._end) it.ref = NULL; return it; } + #if !defined _i_no_emplace STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, _cx_raw raw) { diff --git a/include/stc/clist.h b/include/stc/clist.h index 229db32c..5b9cf0d3 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -159,9 +159,8 @@ _cx_memb(_begin)(const _cx_self* self) { } STC_INLINE _cx_iter -_cx_memb(_end)(const _cx_self* self) { - return c_make(_cx_iter){NULL}; -} +_cx_memb(_end)(const _cx_self* self) + { return c_make(_cx_iter){NULL}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) { diff --git a/include/stc/cstack.h b/include/stc/cstack.h index 811479c4..a524b71c 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -169,15 +169,18 @@ STC_INLINE i_keyraw _cx_memb(_value_toraw)(const _cx_value* val) { return i_keyto(val); } #endif // !_i_no_clone -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { return c_make(_cx_iter){self->size ? (_cx_value*)self->data : NULL, (_cx_value*)self->data + self->size}; } +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + return c_make(_cx_iter){self->size ? (_cx_value*)self->data : NULL, + (_cx_value*)self->data + self->size}; +} STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, (_cx_value*)self->data + self->size}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->_end) it->ref = NULL; } -STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) - { if ((it.ref += offs) >= it._end) it.ref = NULL ; return it; } +STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) + { if ((it.ref += n) >= it._end) it.ref = NULL ; return it; } #include "template.h" diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 99df920c..a457c3dc 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -136,14 +136,6 @@ STC_INLINE void _cx_memb(_pop)(_cx_self* self) STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value) { return _cx_memb(_push)(self, value); } STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) { _cx_memb(_pop)(self); } -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) - { size_t n = cvec_rep_(self)->size; return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; } -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_make(_cx_iter){NULL, self->data + cvec_rep_(self)->size}; } -STC_INLINE void _cx_memb(_next)(_cx_iter* it) { if (++it->ref == it->_end) it->ref = NULL; } -STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t offs) - { if ((it.ref += offs) >= it._end) it.ref = NULL; return it; } -STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it) { return it.ref - cx->data; } STC_INLINE _cx_self _cx_memb(_with_size)(const size_t size, i_key null) { @@ -204,6 +196,24 @@ _cx_memb(_at_mut)(_cx_self* self, const size_t idx) { assert(idx < cvec_rep_(self)->size); return self->data + idx; } + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = cvec_rep_(self)->size; + return c_make(_cx_iter){n ? self->data : NULL, self->data + n}; +} + +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_make(_cx_iter){NULL, self->data + cvec_rep_(self)->size}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->_end) it->ref = NULL; } + +STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) + { if ((it.ref += n) >= it._end) it.ref = NULL; return it; } + +STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it) + { return it.ref - cx->data; } + #if !c_option(c_no_cmp) STC_INLINE _cx_iter -- 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(-) 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 65199590def8459198f9460c5d975a1df22d00a8 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 08:31:53 +0200 Subject: Renamed all iter members ._end to .end, to make them "public". --- include/stc/carr2.h | 2 +- include/stc/carr3.h | 2 +- include/stc/cdeq.h | 14 +++++++------- include/stc/cmap.h | 4 ++-- include/stc/cstack.h | 4 ++-- include/stc/cstr.h | 2 +- include/stc/csview.h | 2 +- include/stc/cvec.h | 18 +++++++++--------- include/stc/forward.h | 16 ++++++++-------- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/include/stc/carr2.h b/include/stc/carr2.h index 1762b8ad..f55cdd17 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -98,7 +98,7 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->_end) it->ref = NULL; } + { if (++it->ref == it->end) it->ref = NULL; } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) diff --git a/include/stc/carr3.h b/include/stc/carr3.h index 4de21208..fdc29b6f 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -101,7 +101,7 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->_end) it->ref = NULL; } + { if (++it->ref == it->end) it->ref = NULL; } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 179959fd..d3c7fede 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -120,7 +120,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_p)(self, (it.ref ? it.ref : it._end), &value, &value + 1); + return _cx_memb(_insert_range_p)(self, (it.ref ? it.ref : it.end), &value, &value + 1); } STC_INLINE _cx_iter @@ -133,7 +133,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, (i2.ref ? i2.ref : i2._end)); + return _cx_memb(_erase_range_p)(self, i1.ref, (i2.ref ? i2.ref : i2.end)); } @@ -146,10 +146,10 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, self->data + cdeq_rep_(self)->size}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->_end) it->ref = NULL; } + { if (++it->ref == it->end) it->ref = NULL; } STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) - { if ((it.ref += n) >= it._end) it.ref = NULL; return it; } + { if ((it.ref += n) >= it.end) it.ref = NULL; return it; } #if !defined _i_no_emplace STC_INLINE _cx_value* @@ -167,7 +167,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_p)(self, (it.ref ? it.ref : it._end), &raw, &raw + 1); + return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -189,7 +189,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, (i2.ref ? i2.ref : i2._end) - i1.ref, sizeof *i1.ref, + qsort(i1.ref, (i2.ref ? i2.ref : i2.end) - i1.ref, sizeof *i1.ref, (int(*)(const void*, const void*)) cmp); } @@ -416,7 +416,7 @@ _cx_memb(_clone_range_p)(_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 = i2.ref ? i2.ref : i2._end; + const _cx_value* p2 = i2.ref ? i2.ref : i2.end; for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 0d1c13d9..971d00a8 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -196,7 +196,7 @@ _cx_memb(_end)(const _cx_self* self) STC_INLINE void _cx_memb(_next)(_cx_iter* it) { while ((++it->ref, *++it->_hx == 0)) ; - if (it->ref == it->_end) it->ref = NULL; + if (it->ref == it->end) it->ref = NULL; } STC_INLINE _cx_iter @@ -231,7 +231,7 @@ _cx_memb(_begin)(const _cx_self* self) { if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; - if (it.ref == it._end) it.ref = NULL; + if (it.ref == it.end) it.ref = NULL; return it; } diff --git a/include/stc/cstack.h b/include/stc/cstack.h index a524b71c..e1839d37 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -178,9 +178,9 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, (_cx_value*)self->data + self->size}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->_end) it->ref = NULL; } + { if (++it->ref == it->end) it->ref = NULL; } STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) - { if ((it.ref += n) >= it._end) it.ref = NULL ; return it; } + { if ((it.ref += n) >= it.end) it.ref = NULL ; return it; } #include "template.h" diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 509811eb..7af54c58 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -234,7 +234,7 @@ STC_INLINE cstr_iter cstr_end(const cstr* self) { STC_INLINE void cstr_next(cstr_iter* it) { it->ref += it->u8.chr.size; it->u8.chr.size = utf8_chr_size(it->ref); - if (it->ref == it->u8._end) it->ref = NULL; + if (it->ref == it->u8.end) it->ref = NULL; } diff --git a/include/stc/csview.h b/include/stc/csview.h index c48c6ae6..5db23a01 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -81,7 +81,7 @@ STC_INLINE csview_iter csview_end(const csview* self) STC_INLINE void csview_next(csview_iter* it) { it->ref += it->u8.chr.size; it->u8.chr.size = utf8_chr_size(it->ref); - if (it->ref == it->u8._end) it->ref = NULL; + if (it->ref == it->u8.end) it->ref = NULL; } diff --git a/include/stc/cvec.h b/include/stc/cvec.h index a5e1fac6..86646026 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -106,7 +106,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_p)(self, (it.ref ? it.ref : it._end), &raw, &raw + 1); + return _cx_memb(_emplace_range_p)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -171,7 +171,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_p)(self, (it.ref ? it.ref : it._end), &value, &value + 1); + return _cx_memb(_insert_range_p)(self, (it.ref ? it.ref : it.end), &value, &value + 1); } STC_INLINE _cx_iter @@ -184,7 +184,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, (i2.ref ? i2.ref : i2._end)); + return _cx_memb(_erase_range_p)(self, i1.ref, (i2.ref ? i2.ref : i2.end)); } STC_INLINE const _cx_value* @@ -206,10 +206,10 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) { return c_make(_cx_iter){NULL, self->data + cvec_rep_(self)->size}; } STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->_end) it->ref = NULL; } + { if (++it->ref == it->end) it->ref = NULL; } STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n) - { if ((it.ref += n) >= it._end) it.ref = NULL; return it; } + { if ((it.ref += n) >= it.end) it.ref = NULL; return it; } STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it) { return it.ref - cx->data; } @@ -245,7 +245,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, (i2.ref ? i2.ref : i2._end) - i1.ref, sizeof(_cx_value), + qsort(i1.ref, (i2.ref ? i2.ref : i2.end) - i1.ref, sizeof(_cx_value), (int(*)(const void*, const void*)) cmp); } @@ -402,7 +402,7 @@ _cx_memb(_emplace_range_p)(_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 = i2.ref ? i2.ref : i2._end; + const _cx_value* p2 = i2.ref ? i2.ref : i2.end; for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) @@ -413,7 +413,7 @@ _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) { - const _cx_value* p2 = i2.ref ? i2.ref : i2._end; + const _cx_value* p2 = i2.ref ? i2.ref : i2.end; _cx_iter mid = i1; while (i1.ref != p2) { mid.ref = i1.ref + (p2 - i1.ref)/2; @@ -424,7 +424,7 @@ _cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, _cx_ite else if (c < 0) p2 = mid.ref; else i1.ref = mid.ref + 1; } - *lower_bound = i1.ref == i2._end ? i2 : i1; + *lower_bound = i1.ref == i2.end ? i2 : i1; return i2; } diff --git a/include/stc/forward.h b/include/stc/forward.h index 9be399af..8a0278a5 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -57,7 +57,7 @@ typedef struct { const char* str; size_t size; } csview; typedef char csview_value; typedef union { const char *ref; - struct { csview chr; const char *_end; } u8; + struct { csview chr; const char *end; } u8; } csview_iter, cstr_iter; #define c_true(...) __VA_ARGS__ @@ -73,12 +73,12 @@ typedef union { #define _c_carr2_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ typedef struct { SELF##_value **data; size_t xdim, ydim; } SELF #define _c_carr3_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ typedef struct { SELF##_value ***data; size_t xdim, ydim, zdim; } SELF #define _c_cbox_types(SELF, VAL) \ @@ -89,7 +89,7 @@ typedef union { #define _c_cdeq_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct {SELF##_value *ref, *_end; } SELF##_iter; \ + typedef struct {SELF##_value *ref, *end; } SELF##_iter; \ typedef struct {SELF##_value *_base, *data;} SELF #define _c_clist_types(SELF, VAL) \ @@ -120,7 +120,7 @@ typedef union { } SELF##_result; \ \ typedef struct { \ - SELF##_value *ref, *_end; \ + SELF##_value *ref, *end; \ uint8_t* _hx; \ } SELF##_iter; \ \ @@ -186,7 +186,7 @@ typedef union { #endif #define _c_cstack_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ typedef struct SELF { \ SELF##_value* data; \ size_t size, capacity; \ @@ -194,7 +194,7 @@ typedef union { #define _c_cstack_fixed(SELF, VAL, CAP) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ typedef struct SELF { \ SELF##_value data[CAP]; \ size_t size; \ @@ -209,7 +209,7 @@ typedef union { #define _c_cvec_types(SELF, VAL) \ typedef VAL SELF##_value; \ - typedef struct { SELF##_value *ref, *_end; } SELF##_iter; \ + typedef struct { SELF##_value *ref, *end; } SELF##_iter; \ typedef struct { SELF##_value *data; } SELF #endif // STC_FORWARD_H_INCLUDED -- cgit v1.2.3 From f7fbc7727b8ceab54ef1ae1744cc378225a36d02 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 08:50:36 +0200 Subject: Minor formatting. --- include/stc/cdeq.h | 3 ++- include/stc/cregex.h | 5 +++-- include/stc/csview.h | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index d3c7fede..d09c43ae 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -231,7 +231,8 @@ _cx_memb(_shrink_to_fit)(_cx_self *self) { struct cdeq_rep* rep = cdeq_rep_(self); const size_t sz = rep->size; memmove(self->_base, self->data, sz*sizeof(i_key)); - rep = (struct cdeq_rep*) c_realloc(rep, offsetof(struct cdeq_rep, base) + sz*sizeof(i_key)); + rep = (struct cdeq_rep*) c_realloc(rep, offsetof(struct cdeq_rep, base) + + sz*sizeof(i_key)); if (rep) { self->_base = self->data = (_cx_value*)rep->base; rep->cap = sz; diff --git a/include/stc/cregex.h b/include/stc/cregex.h index d19d518f..4812bff2 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -76,8 +76,9 @@ typedef struct { csview ref[cre_MAXCAPTURES]; } cregex_iter; -#define c_foreach_match(i, _re, _input) \ - for (cregex_iter i = {_re, _input}; cregex_find(i.input, i.re, i.ref, cre_m_next) == cre_success;) +#define c_foreach_match(it, Re, Input) \ + for (cregex_iter it = {Re, Input}; \ + cregex_find(it.input, it.re, it.ref, cre_m_next) == cre_success;) static inline cregex cregex_init(void) { diff --git a/include/stc/csview.h b/include/stc/csview.h index 5db23a01..dbff8620 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -72,7 +72,8 @@ STC_INLINE csview csview_slice(csview sv, size_t p1, size_t p2) { /* utf8 iterator */ STC_INLINE csview_iter csview_begin(const csview* self) { if (!self->size) return c_make(csview_iter){NULL}; - return c_make(csview_iter){.u8 = {{self->str, utf8_chr_size(self->str)}, self->str + self->size}}; + return c_make(csview_iter){.u8 = {{self->str, utf8_chr_size(self->str)}, + self->str + self->size}}; } STC_INLINE csview_iter csview_end(const csview* self) -- cgit v1.2.3 From f225ba90a4497d91ed3934574a304aad4158af91 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 11 Aug 2022 11:38:14 +0200 Subject: cvec/cdeq insert/erase ranges fixes. --- include/stc/cdeq.h | 27 ++++++++++++++++----------- include/stc/cvec.h | 22 +++++++++++++--------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index d09c43ae..afe26f4b 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -120,7 +120,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_p)(self, (it.ref ? it.ref : it.end), &value, &value + 1); + return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1); } STC_INLINE _cx_iter @@ -347,16 +347,20 @@ _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, 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) - rep->size += n; /* do only if size > 0 */ - return c_make(_cx_iter){self->data + idx, self->data + rep->size}; +_cx_memb(_insert_uninit_p)(_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; + const size_t idx = pos - self->data; + if (idx*2 < r->size) + _cx_memb(_expand_left_half_)(self, idx, n); + else + _cx_memb(_expand_right_half_)(self, idx, n); + r = cdeq_rep_(self); + r->size += n; + pos = self->data + idx; + } + return c_make(_cx_iter){pos, self->data + r->size}; } STC_DEF _cx_value* @@ -381,6 +385,7 @@ _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { + assert(p1 && p2); intptr_t len = p2 - p1; struct cdeq_rep* r = cdeq_rep_(self); _cx_value* p = p1, *end = self->data + r->size; diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 86646026..be838360 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -171,7 +171,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_p)(self, (it.ref ? it.ref : it.end), &value, &value + 1); + return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1); } STC_INLINE _cx_iter @@ -332,16 +332,19 @@ _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) { - const size_t idx = pos - self->data; struct cvec_rep* r = cvec_rep_(self); - if (r->size + n > r->cap) { - if (!_cx_memb(_reserve)(self, r->size*3/2 + n)) - return _cx_memb(_end)(self); - r = cvec_rep_(self); - pos = self->data + idx; + if (n) { + if (!pos) pos = self->data + r->size; + const size_t idx = pos - self->data; + if (r->size + n > r->cap) { + if (!_cx_memb(_reserve)(self, r->size*3/2 + n)) + 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; } - memmove(pos + n, pos, (r->size - idx)*sizeof *pos); - r->size += n; return c_make(_cx_iter){pos, self->data + r->size}; } @@ -356,6 +359,7 @@ _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { + assert(p1 && p2); intptr_t len = p2 - p1; struct cvec_rep* r = cvec_rep_(self); _cx_value* p = p1, *end = self->data + r->size; -- cgit v1.2.3 From 989253176e8359280ffbfff546c382d559e66b27 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 11 Aug 2022 11:47:50 +0200 Subject: removed fn. --- include/stc/cvec.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index be838360..371d6a29 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -156,10 +156,6 @@ _cx_memb(_shrink_to_fit)(_cx_self* self) { _cx_memb(_reserve)(self, _cx_memb(_size)(self)); } -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_iter _cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) { -- cgit v1.2.3 From 9831e8d6ee6772a4f9899cf9e3d36e3de47bbaf5 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 11 Aug 2022 14:36:40 +0200 Subject: Completed support for i_less(). --- include/stc/cpque.h | 12 ++++++------ include/stc/template.h | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/stc/cpque.h b/include/stc/cpque.h index bb7c207e..79d12b95 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -110,9 +110,9 @@ STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_raw raw) STC_DEF void _cx_memb(_sift_down_)(_cx_value* arr, const size_t idx, const size_t n) { - for (size_t r = idx, c = idx << 1; c <= n; c <<= 1) { - c += (c < n && (i_cmp((&arr[c]), (&arr[c + 1]))) < 0); - if ((i_cmp((&arr[r]), (&arr[c]))) >= 0) return; + for (size_t r = idx, c = idx*2; c <= n; c *= 2) { + c += (c < n && (i_less((&arr[c]), (&arr[c + 1])))); + if (!(i_less((&arr[r]), (&arr[c])))) return; _cx_value t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; } } @@ -121,7 +121,7 @@ STC_DEF void _cx_memb(_make_heap)(_cx_self* self) { size_t n = self->size; _cx_value *arr = self->data - 1; - for (size_t k = n >> 1; k != 0; --k) + for (size_t k = n/2; k != 0; --k) _cx_memb(_sift_down_)(arr, k, n); } @@ -148,8 +148,8 @@ _cx_memb(_push)(_cx_self* self, _cx_value value) { _cx_memb(_reserve)(self, self->size*3/2 + 4); _cx_value *arr = self->data - 1; /* base 1 */ size_t c = ++self->size; - for (; c > 1 && (i_cmp((&arr[c >> 1]), (&value))) < 0; c >>= 1) - arr[c] = arr[c >> 1]; + for (; c > 1 && (i_less((&arr[c/2]), (&value))); c /= 2) + arr[c] = arr[c/2]; arr[c] = value; } diff --git a/include/stc/template.h b/include/stc/template.h index cb0c7ef2..ac9d5b5e 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -167,7 +167,7 @@ #define i_keydrop c_default_drop #endif -// i_eq, i_less, i_cmp, i_hash +// i_eq, i_less, i_cmp #if !defined i_eq && (defined i_cmp || defined i_less) #define i_eq(x, y) !(i_cmp(x, y)) #elif !defined i_eq @@ -175,10 +175,13 @@ #endif #if !defined i_less && !defined i_cmp #define i_less c_default_less +#elif !defined i_less + #define i_less(x, y) (i_cmp(x, y)) < 0 #endif #ifndef i_cmp #define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y)) #endif + #ifndef i_hash #define i_hash c_default_hash #endif -- 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(-) 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 3c110651771642cf28d6998e101a197b0cb02a4b Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 11 Aug 2022 22:21:17 +0200 Subject: Added cmp, eq, hash to carc/cbox. --- examples/music_arc.c | 19 +++++++++++-------- include/stc/carc.h | 10 ++++++++++ include/stc/cbox.h | 10 ++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/examples/music_arc.c b/examples/music_arc.c index 8cbcbb59..d933d125 100644 --- a/examples/music_arc.c +++ b/examples/music_arc.c @@ -8,6 +8,9 @@ struct Song cstr title; } typedef Song; +int Song_cmp(const Song* x, const Song* y) + { return cstr_cmp(&x->title, &y->title); } + Song Song_from(const char* artist, const char* title) { return (Song){cstr_from(artist), cstr_from(title)}; } @@ -19,7 +22,7 @@ void Song_drop(Song* s) { #define i_type SongArc #define i_val Song #define i_valdrop Song_drop -#define i_opt c_no_cmp +#define i_cmp Song_cmp #include #define i_type SongVec @@ -30,18 +33,18 @@ void example3() { c_auto (SongVec, vec, vec2) { - 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_forarray (Song, v, { + Song_from("Bob Dylan", "The Times They Are A Changing"), + Song_from("Aretha Franklin", "Bridge Over Troubled Water"), + Song_from("Thalia", "Entre El Mar y Una Estrella") + }) SongVec_emplace(&vec, *v); c_foreach (s, SongVec, vec) if (!cstr_equals(s.ref->get->artist, "Bob Dylan")) 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"))); + SongVec_emplace(&vec2, Song_from("Michael Jackson", "Billie Jean")); + SongVec_emplace(&vec2, Song_from("Rihanna", "Stay")); c_forarray (SongVec, v, {vec, vec2}) { puts("VEC:"); diff --git a/include/stc/carc.h b/include/stc/carc.h index 62b33bed..20ba26b0 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -197,6 +197,16 @@ STC_INLINE bool _cx_memb(_value_eq)(const _cx_value* x, const _cx_value* y) { return i_eq((&rx), (&ry)); #endif } + +STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* x) + { return _cx_memb(_value_hash)(x->get); } + +STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) + { return _cx_memb(_value_cmp)(x->get, y->get); } + +STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) + { return _cx_memb(_value_eq)(x->get, y->get); } + #undef _i_atomic_inc #undef _i_atomic_dec_and_test #include "template.h" diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 467dd645..d26a63c8 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -182,4 +182,14 @@ STC_INLINE bool _cx_memb(_value_eq)(const _cx_value* x, const _cx_value* y) { return i_eq((&rx), (&ry)); #endif } + +STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* x) + { return _cx_memb(_value_hash)(x->get); } + +STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y) + { return _cx_memb(_value_cmp)(x->get, y->get); } + +STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y) + { return _cx_memb(_value_eq)(x->get, y->get); } + #include "template.h" -- 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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 dd6e6a60b8d1af9127f2694efc314e810b71c9b1 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 14 Aug 2022 18:07:10 +0200 Subject: Updated README.md, V4.0 description. --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index afab8712..d3d79f4e 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,18 @@ STC - Smart Template Containers for C ===================================== -News: Version 4.0 BETA (Aug 2022) +News: Version 4.0 (Aug 2022) --------------------------------------- -- Removed macro `c_apply` - usage was not intuitive. -- `c_forarray` macro replaces usages of `c_apply`. -- Minor changes in API of **cregex**, and improved documentation. -- Version 3.9: - - "ccommon API: `c_forrange` with 3 to 5 args swapped 1st <-> 2nd. -- Version 3.8: - - "Officially" added **cregex** - powerful regular expressions. - - Added back **coption** - command line argument parsing. - - Some changes in **cstr** and **csview** API. +API changes summary V3.8 - V4.0: +- Added **cregex** with documentation - powerful regular expressions. +- Updated **cstr**, now always takes self as pointer, like all containers except csview. +- Updated **cvec**, **cdeq**, changed `*_range*` function names. +- `c_with`: macro renamed from `c_autovar`, which is deprecated. Like Python **with** statement. +- `c_scope`: macro renamed from `c_autoscope`, which is deprecated. +- `c_defer`: macro renamed from `c_autodefer`, which is deprecated. Like Go's, Zig's **defer**. +- `c_forrange` with 3 to 5 args swapped 1st <-> 2nd arg. +- New `c_forarray` macro to replace usages of `c_apply`, which is removed. +- Added back **coption** - command line argument parsing. - [See detailed changes for version 3](#version-3). Introduction -- cgit v1.2.3 From 2cfad29db0fda313873f2b4a809ff60aca897785 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Mon, 15 Aug 2022 08:17:01 +0200 Subject: Improved docs/ex. Fix range bug when container is empty cvec/cdeq. --- README.md | 22 +++++++++++----------- examples/music_arc.c | 11 +++++++++-- include/stc/cdeq.h | 7 ++++--- include/stc/cvec.h | 9 +++++---- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d3d79f4e..1a5cbdc6 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,16 @@ STC - Smart Template Containers for C ===================================== -News: Version 4.0 (Aug 2022) +News: Version 4.0 Release Candidate (Aug 2022) --------------------------------------- API changes summary V3.8 - V4.0: - Added **cregex** with documentation - powerful regular expressions. - Updated **cstr**, now always takes self as pointer, like all containers except csview. - Updated **cvec**, **cdeq**, changed `*_range*` function names. -- `c_with`: macro renamed from `c_autovar`, which is deprecated. Like Python **with** statement. +- `c_with`: macro renamed from `c_autovar`, which is deprecated. Like Python's **with** statement. - `c_scope`: macro renamed from `c_autoscope`, which is deprecated. -- `c_defer`: macro renamed from `c_autodefer`, which is deprecated. Like Go's, Zig's **defer**. -- `c_forrange` with 3 to 5 args swapped 1st <-> 2nd arg. +- `c_defer`: macro renamed from `c_autodefer`, which is deprecated. Like Go's and Zig's **defer**. +- `c_forrange` with 3 to 5 args: swapped 1st <-> 2nd arg. - New `c_forarray` macro to replace usages of `c_apply`, which is removed. - Added back **coption** - command line argument parsing. - [See detailed changes for version 3](#version-3). @@ -21,7 +21,7 @@ Introduction ------------ STC is a *modern*, *templated*, *user-friendly*, *type-safe*, *very fast* and *compact* container library for C99. The API is fairly similar to c++ STL, but a bit more uniform across the containers and takes -inspiration from Rust and Python too. It is an advantage to know how these containers work in other languages, like +inspiration from Rust and Python as well. It is an advantage to know how these containers work in other languages, like Java, C# or C++, but it's not required. This library allows you to manage both trivial to very complex data in a wide variety of containers @@ -68,7 +68,7 @@ Highlights - **Fully memory managed** - All containers will destruct keys/values via destructor defined as macro parameters before including the container header. Also, shared pointers are supported and can be stored in containers, see ***carc***. - **Fully type safe** - Because of templating, it avoids error-prone casting of container types and elements back and forth from the containers. - **Uniform, easy-to-learn API** - Methods to ***construct***, ***initialize***, ***iterate*** and ***destruct*** have uniform and intuitive usage across the various containers. -- **Small footprint** - Small source code and generated executables. The executable from the example below with six different containers is *22 kb in size* compiled with gcc -Os on linux. +- **Small footprint** - Small source code and generated executables. The executable from the example below with six different containers is *22 kb in size* compiled with gcc -Os -s on linux. - **Dual mode compilation** - By default it is a simple header-only library with inline and static methods only, but you can easily switch to create a traditional library with shared symbols, without changing existing source files. See the Installation section. - **No callback functions** - All passed template argument functions/macros are directly called from the implementation, no slow callbacks which requires storage. - **Compiles with C++ and C99** - C code can be compiled with C++ (container element types must be POD). @@ -80,7 +80,7 @@ You may specify a number of "standard" template arguments for each container, bu required (two for maps). In the latter case, STC assumes the elements are basic types. For more complex types, additional template arguments must be defined. 2. the general "heterogeneous lookup"-like feature: Allows specification of an alternative type to use -for lookup in containers. E.g. for containers with string type (**cstr**) elements, `const char*` may be used +for lookup in containers. E.g. for containers with string type (**cstr**) elements, `const char*` is used as lookup type. It will then use the input `const char*` directly when comparing with the string data in the container. This avoids the construction of a new `cstr` (which possible allocates memory) for the lookup. Finally, destruction of the lookup key (i.e. string literal) after usage is not needed (or allowed), which @@ -340,13 +340,13 @@ Specials: - `i_key_str` - Define key type *cstr* and container i_tag = *str*. It binds type convertion from/to *const char*\*, and the ***cmp***, ***eq***, ***hash***, and ***keydrop*** functions. - `i_key_ssv` - Define key type *cstr* and container i_tag = *ssv*. It binds type convertion from/to *csview*, and its ***cmp***, ***eq***, ***hash***, and ***keydrop*** functions. - `i_key_arcbox TYPE` - Define container key type where TYPE is a smart pointer **carc** or **cbox**. NB: not to be used when defining carc/cbox types themselves. -- `i_key_bind TYPE` - General version of the two above - will auto-bind to standard named functions: *TYPE_clone*, *TYPE_drop*, *TYPE_cmp*, *TYPE_eq*, *TYPE_hash*. If `i_keyraw` is defined, *TYPE_toraw* func. is bound to `i_keyto`. Only functions required by the particular container need to be defined. E.g., only **cmap** and **cset** and smart pointers uses *TYPE_hash* and *TYPE_eq*. **cstack** does not use *TYPE_cmp*. *TYPE_clone* is not used if *#define i_opt c_no_clone* is specified. Likewise, *TYPE_cmp* is not used if *#define i_opt c_no_cmp* is specified. +- `i_key_bind TYPE` - General version of the three above - will auto-bind to standard named functions: *TYPE_clone*, *TYPE_drop*, *TYPE_cmp*, *TYPE_eq*, *TYPE_hash*. If `i_keyraw` is defined, *TYPE_toraw* function is bound to `i_keyto`. Only functions required by the particular container need to be defined. E.g., only **cmap** and **cset** and smart pointers uses *TYPE_hash* and *TYPE_eq*. **cstack** does not use *TYPE_cmp*. *TYPE_clone* is not used if *#define i_opt c_no_clone* is specified. Likewise, *TYPE_cmp* is not used if *#define i_opt c_no_cmp* is specified. - `i_val_str`, `i_val_bind`, `i_val_arcbox` - Similar rules as for ***key***. **Notes**: -- Instead of defining `i_cmp`, you may define *i_opt c_no_cmp* to disable searching and sorting functions. -- Instead of defining `i_*clone`, you may define *i_opt c_no_clone* to disable emplace and clone-functions. -- `i_keyraw RAWTYPE` - If defined along with *i_key_bind*, the two functions *TYPE TYPE_from(RAWTYPE)* and *RAWTYPE TYPE_toraw(TYPE\*)* are expected in addition to *TYPE TYPE_clone(TYPE)*. Note the signature for ***cmp***, ***eq***, ***hash*** now: *int RAWTYPE_cmp(const RAWTYPE\*, const RAWTYPE\*)*, and similar for the two others. +- Instead of defining `i_cmp`, you may define *i_opt c_no_cmp* to disable *searching and sorting* functions. +- Instead of defining `i_*clone`, you may define *i_opt c_no_clone* to disable *clone* functionality. +- For `i_key_bind`, if *i_keyraw RAWTYPE* is defined along with it, *i_keyfrom* may also be defined to enable the *emplace*-functions. Note: the signature for ***cmp***, ***eq***, and ***hash*** uses *RAWTYPE* as input. The *emplace* versus non-emplace container methods -------------------------------------------------- diff --git a/examples/music_arc.c b/examples/music_arc.c index 02470b0f..6f9c1c72 100644 --- a/examples/music_arc.c +++ b/examples/music_arc.c @@ -19,12 +19,14 @@ void Song_drop(Song* s) { c_drop(cstr, &s->artist, &s->title); } +// Define the reference counted type #define i_type SongArc #define i_val Song #define i_valdrop Song_drop #define i_cmp Song_cmp #include +// ... and a vector of it #define i_type SongVec #define i_val_arcbox SongArc #include @@ -39,13 +41,18 @@ void example3() Song_from("Thalia", "Entre El Mar y Una Estrella") }) SongVec_emplace(&vec, *v); + // Share all entries in vec with vec2, except Bob Dylan. c_foreach (s, SongVec, vec) if (!cstr_equals(&s.ref->get->artist, "Bob Dylan")) - SongVec_push_back(&vec2, SongArc_clone(*s.ref)); + SongVec_push(&vec2, SongArc_clone(*s.ref)); + // Add a few more to vec2. We can use emplace when creating new entries SongVec_emplace(&vec2, Song_from("Michael Jackson", "Billie Jean")); SongVec_emplace(&vec2, Song_from("Rihanna", "Stay")); + // If we use push, we would need to construct the Arc explicitly (as in c++, make_shared): + // SongVec_push(&vec2, SongArc_from(Song_from("Rihanna", "Stay"))); + // We now have two vectors with some shared, some unique entries. c_forarray (SongVec, v, {vec, vec2}) { puts("VEC:"); c_foreach (s, SongVec, *v) @@ -53,7 +60,7 @@ void example3() cstr_str(&s.ref->get->title), *s.ref->use_count); } - } + } // because the shared elem. are ref. counted, they are only dropped once here. } int main() diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 4bef2f38..1d75408c 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -29,6 +29,7 @@ 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) #endif // CDEQ_H_INCLUDED #ifndef _i_prefix @@ -137,7 +138,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, (i2.ref ? i2.ref : i2.end)); + return _cx_memb(_erase_range_p)(self, i1.ref, it2_ref_(i1, i2)); } @@ -193,7 +194,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, (i2.ref ? i2.ref : i2.end) - i1.ref, sizeof *i1.ref, + qsort(i1.ref, it2_ref_(i1, i2) - i1.ref, sizeof *i1.ref, (int(*)(const void*, const void*)) cmp); } @@ -427,7 +428,7 @@ _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 = i2.ref ? i2.ref : i2.end; + const _cx_value* p2 = it2_ref_(i1, i2); for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index c734abb6..170bf741 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -66,6 +66,7 @@ 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) #endif // CVEC_H_INCLUDED #ifndef _i_prefix @@ -181,7 +182,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, (i2.ref ? i2.ref : i2.end)); + return _cx_memb(_erase_range_p)(self, i1.ref, it2_ref_(i1, i2)); } STC_INLINE const _cx_value* @@ -242,7 +243,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, (i2.ref ? i2.ref : i2.end) - i1.ref, sizeof(_cx_value), + qsort(i1.ref, it2_ref_(i1, i2) - i1.ref, sizeof(_cx_value), (int(*)(const void*, const void*)) cmp); } @@ -404,7 +405,7 @@ _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 = i2.ref ? i2.ref : i2.end; + const _cx_value* p2 = it2_ref_(i1, i2); for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) @@ -416,7 +417,7 @@ _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) { - const _cx_value* p2 = i2.ref ? i2.ref : i2.end; + const _cx_value* p2 = it2_ref_(i1, i2); _cx_iter mid = i1; while (i1.ref != p2) { mid.ref = i1.ref + (p2 - i1.ref)/2; -- cgit v1.2.3 From e9e405dbe1ec3eb51ce2e3398b3c24583293892e Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Mon, 15 Aug 2022 08:30:31 +0200 Subject: Two more iter bugs fix. --- include/stc/cdeq.h | 2 +- include/stc/cvec.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 1d75408c..128b85ee 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -125,7 +125,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, &value, &value + 1); + return _cx_memb(_insert_range)(self, (it.ref ? it.ref : it.end), &value, &value + 1); } STC_INLINE _cx_iter diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 170bf741..92065619 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -169,7 +169,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, &value, &value + 1); + return _cx_memb(_insert_range)(self, (it.ref ? it.ref : it.end), &value, &value + 1); } STC_INLINE _cx_iter -- 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(-) 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 From a06463c2f0747bc142a9d5b2bf455c64aaf39890 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 16 Aug 2022 09:56:48 +0200 Subject: Minor polishing. --- include/stc/cdeq.h | 27 ++++++++++++++------------- include/stc/cvec.h | 9 ++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 0efbe064..a8c880f2 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -324,10 +324,10 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self cx) { const size_t sz = cdeq_rep_(&cx)->size; _cx_self out = _cx_memb(_with_capacity)(sz); - if (cdeq_rep_(&out)->cap) { - cdeq_rep_(&out)->size = sz; - for (size_t i = 0; i < sz; ++i) - out.data[i] = i_keyclone(cx.data[i]); + struct cdeq_rep* r = cdeq_rep_(&out); + if (r->cap) { + for (size_t i = 0; i < sz; ++i) out.data[i] = i_keyclone(cx.data[i]); + r->size = sz; } return out; } @@ -403,28 +403,29 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { return c_make(_cx_iter){p2 == end ? NULL : p1, end - len}; } -#if !defined _i_no_emplace +#if !defined _i_no_clone STC_DEF _cx_iter -_cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { +_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_value* p = it.ref; p1 != p2; ++p1) - *p++ = i_keyfrom((*p1)); + *p++ = i_keyclone((*p1)); return it; } -#endif // !_i_no_emplace +#endif // !_i_no_clone -#if !defined _i_no_clone +#if !defined _i_no_emplace STC_DEF _cx_iter -_cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, - const _cx_value* p1, const _cx_value* p2) { +_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_value* p = it.ref; p1 != p2; ++p1) - *p++ = i_keyclone((*p1)); + *p++ = i_keyfrom((*p1)); return it; } -#endif // !_i_no_clone +#endif // !_i_no_emplace #if !c_option(c_no_cmp) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 1be7211d..6b120ff0 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -374,9 +374,8 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { STC_DEF _cx_self _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)(&out, out.data, cx.data, cx.data + len); + _cx_self out = _cx_memb(_init)(); + _cx_memb(_copy_range)(&out, out.data, cx.data, cx.data + len); return out; } @@ -385,8 +384,8 @@ _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)); + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyclone((*p1)); return it; } #endif // !_i_no_clone -- cgit v1.2.3