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. --- docs/cstr_api.md | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'docs/cstr_api.md') 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)); -- cgit v1.2.3 From bf3c50da1a346b56b6846c0f7b9e7a222f602c2f Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 15 Aug 2022 16:54:56 +0200 Subject: More iterator fixes. Make sure cvec/cdeq find_in() return end() iterator if item not found. Small cstr API change to u8_replace*. --- docs/cdeq_api.md | 2 +- docs/cstr_api.md | 2 +- docs/csview_api.md | 2 +- docs/cvec_api.md | 4 ++-- examples/regex_replace.c | 2 +- examples/utf8replace_c.c | 2 +- include/stc/cdeq.h | 24 +++++++++++++----------- include/stc/cstr.h | 7 ++----- include/stc/cvec.h | 23 ++++++++++++----------- 9 files changed, 34 insertions(+), 34 deletions(-) (limited to 'docs/cstr_api.md') 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