From 6749cc21a2045d307c239d82891cb860687dfd2a Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 14 Dec 2021 19:50:10 +0100 Subject: Added and renamed some examples. --- include/stc/alt/cstr.h | 113 +++++++++++++++++++++++-------------------------- include/stc/cstr.h | 18 ++++---- 2 files changed, 63 insertions(+), 68 deletions(-) (limited to 'include') diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 1dc895ff..76b3a800 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -32,31 +32,27 @@ #include #include -#ifndef cstr_size_t -typedef size_t cstr_size_t; -#endif -typedef struct { char* data; cstr_size_t size, cap; } cstr_rep_t; -typedef const char cstr_literal_t[]; +typedef struct { char* data; size_t size, cap; } _cstr_rep_t; typedef union { - struct { char* data; cstr_size_t size, ncap; } lon; - struct { char data[sizeof(cstr_rep_t)]; } sso; + 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 = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 }; -#define cstr_is_long(s) (bool)((s)->sso.data[SSO_CAP] & 128) +#define cstr_is_long(s) (bool)((s)->sso.cap_len & 128) #define cstr_select_(s, memb) (cstr_is_long(s) ? cstr_l_##memb : cstr_s_##memb) #define cstr_s_cap(s) SSO_CAP -#define cstr_s_size(s) ((cstr_size_t)(SSO_CAP - (s)->sso.data[SSO_CAP])) -#define cstr_s_set_size(s, len) ((s)->sso.data[SSO_CAP] = SSO_CAP - (len), (s)->sso.data[len] = 0) +#define cstr_s_size(s) ((size_t)(SSO_CAP - (s)->sso.cap_len)) +#define cstr_s_set_size(s, len) ((s)->sso.cap_len = SSO_CAP - (len), (s)->sso.data[len] = 0) #define cstr_s_data(s) (s)->sso.data #define cstr_s_end(s) ((s)->sso.data + cstr_s_size(s)) #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8) +#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8) #define cstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1)) #define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1)) #else @@ -69,42 +65,41 @@ enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 }; #define cstr_l_end(s) ((s)->lon.data + cstr_l_size(s)) #define cstr_l_del(s) free((s)->lon.data) -STC_API char* cstr_init_(cstr* self, cstr_size_t len, cstr_size_t cap); +STC_API char* cstr_init_(cstr* self, size_t len, size_t cap); STC_API void cstr_internal_move_(cstr* self, size_t pos1, size_t pos2); -STC_INLINE void cstr_set_size_(cstr* self, cstr_size_t len) { +STC_INLINE void cstr_set_size_(cstr* self, size_t len) { cstr_select_(self, set_size(self, len)); } -STC_INLINE cstr_rep_t cstr_rep_(cstr* self) { +STC_INLINE _cstr_rep_t cstr_rep_(cstr* self) { return cstr_is_long(self) - ? c_make(cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)} - : c_make(cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)}; + ? c_make(_cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)} + : c_make(_cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)}; } /**************************** PUBLIC API **********************************/ -#define cstr_new(lit) cstr_from_n(lit, sizeof((cstr_literal_t){lit}) - 1) -#define cstr_npos (~(cstr_size_t)0 >> 1) +#define cstr_new(literal) cstr_from_n(literal, sizeof((c_strlit){literal}) - 1) +#define cstr_npos (SIZE_MAX >> 1) +#define cstr_null (cstr){.sso = {.cap_len = SSO_CAP}} -STC_API char* cstr_reserve(cstr* self, cstr_size_t cap); +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, cstr_size_t size, char value); +STC_API void cstr_resize(cstr* self, size_t size, char value); STC_API char* strnstrn(const char *s, const char *needle, size_t slen, size_t nlen); -STC_API cstr_size_t cstr_find_n(cstr s, const char* needle, cstr_size_t pos, cstr_size_t nmax); -STC_API void cstr_assign_n(cstr* self, const char* str, cstr_size_t n); -STC_API void cstr_append_n(cstr* self, const char* str, cstr_size_t n); +STC_API size_t cstr_find_n(cstr s, const char* needle, size_t pos, size_t nmax); +STC_API void cstr_assign_n(cstr* self, const char* str, size_t n); +STC_API void cstr_append_n(cstr* self, const char* str, size_t n); STC_API bool cstr_getdelim(cstr *self, int delim, FILE *fp); STC_API void cstr_erase_n(cstr* self, size_t pos, size_t n); STC_INLINE cstr cstr_init(void) { - cstr s; - cstr_s_set_size(&s, 0); - return s; + return cstr_null; } -STC_INLINE cstr cstr_from_n(const char* str, cstr_size_t n) { +STC_INLINE cstr cstr_from_n(const char* str, size_t n) { cstr s; memcpy(cstr_init_(&s, n, n), str, n); return s; @@ -114,20 +109,20 @@ STC_INLINE cstr cstr_from(const char* str) { return cstr_from_n(str, strlen(str)); } -STC_INLINE cstr cstr_with_size(cstr_size_t size, char value) { +STC_INLINE cstr cstr_with_size(size_t size, char value) { cstr s; memset(cstr_init_(&s, size, size), value, size); return s; } -STC_INLINE cstr cstr_with_capacity(cstr_size_t cap) { +STC_INLINE cstr cstr_with_capacity(size_t cap) { cstr s; cstr_init_(&s, 0, cap); return s; } STC_INLINE cstr cstr_clone(cstr s) { - cstr_rep_t rep = cstr_rep_(&s); + _cstr_rep_t rep = cstr_rep_(&s); return cstr_from_n(rep.data, rep.size); } @@ -151,15 +146,15 @@ STC_INLINE bool cstr_empty(cstr s) { return cstr_select_(&s, size(&s)) == 0; } -STC_INLINE cstr_size_t cstr_size(cstr s) { +STC_INLINE size_t cstr_size(cstr s) { return cstr_select_(&s, size(&s)); } -STC_INLINE cstr_size_t cstr_length(cstr s) { +STC_INLINE size_t cstr_length(cstr s) { return cstr_select_(&s, size(&s)); } -STC_INLINE cstr_size_t cstr_capacity(cstr s) { +STC_INLINE size_t cstr_capacity(cstr s) { return cstr_select_(&s, cap(&s)); } @@ -179,7 +174,7 @@ STC_INLINE int cstr_compare(const cstr* s1, const cstr* s2) { return strcmp(cstr_str(s1), cstr_str(s2)); } -STC_INLINE cstr_size_t cstr_find(cstr s, const char* needle) { +STC_INLINE size_t cstr_find(cstr s, const char* needle) { const char *str = cstr_str(&s), *res = strstr(str, needle); return res ? res - str : cstr_npos; } @@ -207,7 +202,7 @@ STC_INLINE bool cstr_starts_with_s(cstr s, cstr sub) { } STC_INLINE bool cstr_ends_with(cstr s, const char* sub) { - cstr_rep_t rep = cstr_rep_(&s); cstr_size_t n = strlen(sub); + _cstr_rep_t rep = cstr_rep_(&s); size_t n = strlen(sub); return n <= rep.size && memcmp(rep.data + rep.size - n, sub, n) == 0; } @@ -220,7 +215,7 @@ STC_INLINE void cstr_assign(cstr* self, const char* str) { } STC_INLINE void cstr_copy(cstr* self, cstr s) { - cstr_rep_t rep = cstr_rep_(&s); + _cstr_rep_t rep = cstr_rep_(&s); cstr_assign_n(self, rep.data, rep.size); } @@ -229,7 +224,7 @@ STC_INLINE void cstr_append(cstr* self, const char* str) { } STC_INLINE void cstr_append_s(cstr* self, cstr s) { - cstr_rep_t rep = cstr_rep_(&s); + _cstr_rep_t rep = cstr_rep_(&s); cstr_append_n(self, rep.data, rep.size); } @@ -243,7 +238,7 @@ STC_INLINE void cstr_replace(cstr* self, size_t pos, size_t len, const char* str } STC_INLINE void cstr_replace_s(cstr* self, size_t pos, size_t len, cstr s) { - cstr_rep_t rep = cstr_rep_(&s); + _cstr_rep_t rep = cstr_rep_(&s); cstr_replace_n(self, pos, len, rep.data, rep.size); } @@ -256,7 +251,7 @@ STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str) { } STC_INLINE void cstr_insert_s(cstr* self, size_t pos, cstr s) { - cstr_rep_t rep = cstr_rep_(&s); + _cstr_rep_t rep = cstr_rep_(&s); cstr_replace_n(self, pos, 0, rep.data, rep.size); } @@ -271,15 +266,15 @@ STC_INLINE bool cstr_getline(cstr *self, FILE *fp) { STC_DEF void cstr_internal_move_(cstr* self, size_t pos1, size_t pos2) { if (pos1 == pos2) return; - cstr_rep_t rep = cstr_rep_(self); - cstr_size_t newlen = rep.size + pos2 - pos1; + _cstr_rep_t rep = cstr_rep_(self); + size_t newlen = rep.size + pos2 - pos1; if (newlen > rep.cap) rep.data = cstr_reserve(self, (rep.size*3 >> 1) + pos2 - pos1); memmove(&rep.data[pos2], &rep.data[pos1], rep.size - pos1); cstr_set_size_(self, newlen); } -STC_DEF char* cstr_init_(cstr* self, cstr_size_t len, cstr_size_t cap) { +STC_DEF char* cstr_init_(cstr* self, size_t len, size_t cap) { if (cap > SSO_CAP) { self->lon.data = (char *)malloc(cap + 1); cstr_l_set_size(self, len); @@ -291,7 +286,7 @@ STC_DEF char* cstr_init_(cstr* self, cstr_size_t len, cstr_size_t cap) { } STC_DEF void cstr_shrink_to_fit(cstr* self) { - cstr_rep_t rep = cstr_rep_(self); + _cstr_rep_t rep = cstr_rep_(self); if (rep.size == rep.cap) return; if (rep.size > SSO_CAP) { @@ -304,7 +299,7 @@ STC_DEF void cstr_shrink_to_fit(cstr* self) { } } -STC_DEF char* cstr_reserve(cstr* self, cstr_size_t cap) { +STC_DEF char* cstr_reserve(cstr* self, size_t cap) { if (cstr_is_long(self)) { if (cap > cstr_l_cap(self)) { self->lon.data = (char *)realloc(self->lon.data, cap + 1); @@ -315,7 +310,7 @@ STC_DEF char* cstr_reserve(cstr* self, cstr_size_t cap) { /* from short to long: */ if (cap > cstr_s_cap(self)) { char* data = (char *)malloc(cap + 1); - cstr_size_t len = cstr_s_size(self); + size_t len = cstr_s_size(self); memcpy(data, self->sso.data, len); self->lon.data = data; cstr_l_set_size(self, len); @@ -325,8 +320,8 @@ STC_DEF char* cstr_reserve(cstr* self, cstr_size_t cap) { return self->sso.data; } -STC_DEF void cstr_resize(cstr* self, cstr_size_t size, char value) { - cstr_rep_t rep = cstr_rep_(self); +STC_DEF void cstr_resize(cstr* self, size_t size, char value) { + _cstr_rep_t rep = cstr_rep_(self); if (size > rep.size) { if (size > rep.cap) rep.data = cstr_reserve(self, size); memset(rep.data + rep.size, value, size - rep.size); @@ -345,17 +340,17 @@ STC_DEF char* strnstrn(const char *s, const char *needle, size_t slen, size_t nl return NULL; } -STC_DEF cstr_size_t -cstr_find_n(cstr s, const char* needle, cstr_size_t pos, cstr_size_t nmax) { - cstr_rep_t rep = cstr_rep_(&s); - cstr_size_t nlen = (cstr_size_t) strlen(needle); +STC_DEF size_t +cstr_find_n(cstr s, const char* needle, size_t pos, size_t nmax) { + _cstr_rep_t rep = cstr_rep_(&s); + size_t nlen = (size_t) strlen(needle); if (pos > rep.size) return cstr_npos; char* res = strnstrn(rep.data + pos, needle, rep.size, nmax < nlen ? nmax : nlen); return res ? res - rep.data : cstr_npos; } -STC_DEF void cstr_assign_n(cstr* self, const char* str, cstr_size_t n) { - cstr_rep_t rep = cstr_rep_(self); +STC_DEF void cstr_assign_n(cstr* self, const char* str, size_t n) { + _cstr_rep_t rep = cstr_rep_(self); if (n > rep.cap) { rep.data = (char *)realloc(cstr_is_long(self) ? rep.data : NULL, n + 1); cstr_l_set_cap(self, n); @@ -364,10 +359,10 @@ STC_DEF void cstr_assign_n(cstr* self, const char* str, cstr_size_t n) { cstr_set_size_(self, n); } -STC_DEF void cstr_append_n(cstr* self, const char* str, cstr_size_t n) { - cstr_rep_t rep = cstr_rep_(self); +STC_DEF void cstr_append_n(cstr* self, const char* str, size_t n) { + _cstr_rep_t rep = cstr_rep_(self); if (rep.size + n > rep.cap) { - cstr_size_t off = (cstr_size_t)(str - rep.data); /* handle self append */ + size_t off = (size_t)(str - rep.data); /* handle self append */ rep.data = cstr_reserve(self, (rep.size*3 >> 1) + n); if (off <= rep.size) str = rep.data + off; } @@ -379,8 +374,8 @@ STC_DEF bool cstr_getdelim(cstr *self, int delim, FILE *fp) { int c = fgetc(fp); if (c == EOF) return false; - cstr_size_t pos = 0; - cstr_rep_t rep = cstr_rep_(self); + size_t pos = 0; + _cstr_rep_t rep = cstr_rep_(self); for (;;) { if (c == delim || c == EOF) { cstr_set_size_(self, pos); @@ -396,7 +391,7 @@ STC_DEF bool cstr_getdelim(cstr *self, int delim, FILE *fp) { } STC_DEF void cstr_erase_n(cstr* self, size_t pos, size_t n) { - cstr_rep_t rep = cstr_rep_(self); + _cstr_rep_t rep = cstr_rep_(self); if (n > rep.size - pos) n = rep.size - pos; memmove(&rep.data[pos], &rep.data[pos + n], rep.size - (pos + n)); cstr_set_size_(self, rep.size - n); diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 3d8d3097..a46de3c3 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -37,14 +37,14 @@ typedef char cstr_value; #define cstr_npos (SIZE_MAX >> 1) STC_LIBRARY_ONLY( extern const cstr cstr_null; ) -struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; }; -#define _cstr_rep(self) c_container_of((self)->str, struct cstr_rep, str) -STC_STATIC_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}}; +typedef struct { size_t size, cap; char str[sizeof(size_t)]; } _cstr_rep_t; +#define _cstr_rep(self) c_container_of((self)->str, _cstr_rep_t, str) +STC_STATIC_ONLY( static _cstr_rep_t _cstr_nullrep = {0, 0, {0}}; static const cstr cstr_null = {_cstr_nullrep.str}; ) /* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ -#define _cstr_opt_mem(cap) ((((offsetof(struct cstr_rep, str) + (cap) + 8)>>4)<<4) + 8) +#define _cstr_opt_mem(cap) ((((offsetof(_cstr_rep_t, str) + (cap) + 8)>>4)<<4) + 8) /* optimal string capacity: 7, 23, 39, ... */ -#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(struct cstr_rep, str) - 1) +#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(_cstr_rep_t, str) - 1) STC_API cstr cstr_from_n(const char* str, size_t n); STC_API cstr cstr_from_fmt(const char* fmt, ...); @@ -174,15 +174,15 @@ cstr_ends_with(cstr s, const char* sub) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -STC_LIBRARY_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}}; +STC_LIBRARY_ONLY( static _cstr_rep_t _cstr_nullrep = {0, 0, {0}}; const cstr cstr_null = {_cstr_nullrep.str}; ) STC_DEF size_t cstr_reserve(cstr* self, const size_t cap) { - struct cstr_rep* rep = _cstr_rep(self); + _cstr_rep_t* rep = _cstr_rep(self); const size_t oldcap = rep->cap; if (cap > oldcap) { - rep = (struct cstr_rep*) c_realloc(oldcap ? rep : NULL, _cstr_opt_mem(cap)); + rep = (_cstr_rep_t*) c_realloc(oldcap ? rep : NULL, _cstr_opt_mem(cap)); self->str = rep->str; if (oldcap == 0) self->str[rep->size = 0] = '\0'; return (rep->cap = _cstr_opt_cap(cap)); @@ -201,7 +201,7 @@ cstr_resize(cstr* self, const size_t len, const char fill) { STC_DEF cstr cstr_from_n(const char* str, const size_t n) { if (n == 0) return cstr_null; - struct cstr_rep* rep = (struct cstr_rep*) c_malloc(_cstr_opt_mem(n)); + _cstr_rep_t* rep = (_cstr_rep_t*) c_malloc(_cstr_opt_mem(n)); cstr s = {(char *) memcpy(rep->str, str, n)}; s.str[rep->size = n] = '\0'; rep->cap = _cstr_opt_cap(n); -- cgit v1.2.3