From 920a55280a28ce38b98045f797067e285395bb6e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 26 Mar 2022 16:21:39 +0100 Subject: Fixed alt/cstr.h (short string optimized), so that it can be used in containers. Had to change some API in csview to make it play with that. --- examples/sso_map.c | 19 +++++++++++++++++++ examples/utf8replace_c.c | 2 +- include/stc/alt/cstr.h | 9 ++------- include/stc/csview.h | 26 +++++++++++++------------- include/stc/forward.h | 10 +++++++++- 5 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 examples/sso_map.c diff --git a/examples/sso_map.c b/examples/sso_map.c new file mode 100644 index 00000000..6022572f --- /dev/null +++ b/examples/sso_map.c @@ -0,0 +1,19 @@ +#include + +#define i_key_str +#define i_val_str +#include + + +int main() +{ + c_auto (cmap_str, m) { + cmap_str_emplace(&m, "Test short", "This is a short string."); + cmap_str_emplace(&m, "Test long ", "This is a longer string."); + + 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_is_long(&_.v)?"true":"false"); + } +} diff --git a/examples/utf8replace_c.c b/examples/utf8replace_c.c index e04f2cb8..49680ecd 100644 --- a/examples/utf8replace_c.c +++ b/examples/utf8replace_c.c @@ -14,7 +14,7 @@ int main() { ); printf("%s\n", hello.str); - csview sv = csview_from_s(hello); + csview sv = csview_from_s(&hello); c_foreach (c, csview, sv) printf(c_PRIsv ",", c_ARGsv(c.codep)); } diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 82ebae91..211e169a 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -26,21 +26,16 @@ */ #ifndef CSTR_H_INCLUDED #define CSTR_H_INCLUDED +#define CSTR_IS_SSO #include +#include #include /* malloc */ #include #include #include /* vsnprintf */ #include -typedef struct { char* data; size_t size, cap; } _cstr_rep_t; - -typedef union { - struct { char data[sizeof(_cstr_rep_t) - 1], cap_len; } sso; - struct { char* data; size_t size, ncap; } lon; -} cstr; - /**************************** PRIVATE API **********************************/ enum { SSO_CAP = sizeof(_cstr_rep_t) - 1 }; diff --git a/include/stc/csview.h b/include/stc/csview.h index cd482b2c..0d445623 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -89,8 +89,8 @@ STC_INLINE csview utf8_substr(const char* str, size_t pos, size_t n) { /* csview interaction with cstr: */ #ifdef CSTR_H_INCLUDED -STC_INLINE csview csview_from_s(cstr s) - { return c_make(csview){s.str, _cstr_rep(&s)->size}; } +STC_INLINE csview csview_from_s(const cstr* self) + { return c_make(csview){cstr_str(self), cstr_size(*self)}; } STC_INLINE cstr cstr_from_sv(csview sv) { return cstr_from_n(sv.str, sv.size); } @@ -98,11 +98,11 @@ STC_INLINE cstr cstr_from_replace_all_sv(csview sv, csview find, csview { return cstr_from_replace_all(sv.str, sv.size, find.str, find.size, repl.str, repl.size); } STC_INLINE csview cstr_to_sv(const cstr* self) - { return c_make(csview){self->str, _cstr_rep(self)->size}; } -STC_INLINE csview cstr_substr(cstr s, intptr_t pos, size_t n) - { return csview_substr(csview_from_s(s), pos, n); } -STC_INLINE csview cstr_slice(cstr s, intptr_t p1, intptr_t p2) - { return csview_slice(csview_from_s(s), p1, p2); } + { return c_make(csview){cstr_str(self), cstr_size(*self)}; } +STC_INLINE csview cstr_substr(const cstr* self, intptr_t pos, size_t n) + { return csview_substr(csview_from_s(self), pos, n); } +STC_INLINE csview cstr_slice(const cstr* self, intptr_t p1, intptr_t p2) + { return csview_slice(csview_from_s(self), p1, p2); } STC_INLINE cstr* cstr_assign_sv(cstr* self, csview sv) { return cstr_assign_n(self, sv.str, sv.size); } STC_INLINE cstr* cstr_append_sv(cstr* self, csview sv) @@ -112,18 +112,18 @@ STC_INLINE void cstr_insert_sv(cstr* self, size_t pos, csview sv) STC_INLINE void cstr_replace_sv(cstr* self, csview sub, csview with) { cstr_replace_n(self, sub.str - self->str, sub.size, with.str, with.size); } STC_INLINE bool cstr_equals_sv(cstr s, csview sv) - { return sv.size == cstr_size(s) && !memcmp(s.str, sv.str, sv.size); } + { return sv.size == cstr_size(s) && !memcmp(cstr_str(&s), sv.str, sv.size); } STC_INLINE size_t cstr_find_sv(cstr s, csview needle) - { char* res = c_strnstrn(s.str, needle.str, cstr_size(s), needle.size); - return res ? res - s.str : cstr_npos; } + { char* res = c_strnstrn(cstr_str(&s), needle.str, cstr_size(s), needle.size); + return res ? res - cstr_str(&s) : cstr_npos; } STC_INLINE bool cstr_contains_sv(cstr s, csview needle) - { return c_strnstrn(s.str, needle.str, cstr_size(s), needle.size) != NULL; } + { return c_strnstrn(cstr_str(&s), needle.str, cstr_size(s), needle.size) != NULL; } STC_INLINE bool cstr_starts_with_sv(cstr s, csview sub) { if (sub.size > cstr_size(s)) return false; - return !memcmp(s.str, sub.str, sub.size); } + return !memcmp(cstr_str(&s), sub.str, sub.size); } STC_INLINE bool cstr_ends_with_sv(cstr s, csview sub) { if (sub.size > cstr_size(s)) return false; - return !memcmp(s.str + cstr_size(s) - sub.size, sub.str, sub.size); } + return !memcmp(cstr_str(&s) + cstr_size(s) - sub.size, sub.str, sub.size); } #endif /* ---- Container helper functions ---- */ diff --git a/include/stc/forward.h b/include/stc/forward.h index bffdf154..ea552204 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -42,7 +42,15 @@ #define forward_cqueue(CX, VAL) _c_cdeq_types(CX, VAL) #define forward_cvec(CX, VAL) _c_cvec_types(CX, VAL) -typedef struct cstr { char* str; } cstr; +#ifdef CSTR_IS_SSO +typedef struct { char* data; size_t size, cap; } _cstr_rep_t; +typedef union { + struct { char data[sizeof(_cstr_rep_t) - 1], cap_len; } sso; + struct { char* data; size_t size, ncap; } lon; +} cstr; +#else + typedef struct cstr { char* str; } cstr; +#endif typedef char cstr_value; typedef struct csview { const char* str; size_t size; } csview; -- cgit v1.2.3