summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authortylov <[email protected]>2023-07-10 10:53:30 +0200
committertylov <[email protected]>2023-07-10 10:53:30 +0200
commit6fe1ec0e0e3dbce71797873f71a5f306b046319f (patch)
tree329869548de3cc19c4137f4632761af3fa8756da /include
parentbe5864d5f658d544ad5c2af9f1c5b37b4d96bde8 (diff)
downloadSTC-modified-6fe1ec0e0e3dbce71797873f71a5f306b046319f.tar.gz
STC-modified-6fe1ec0e0e3dbce71797873f71a5f306b046319f.zip
- Fixed meta-programming bug in carc and cbox hash function def (regression).
- Reverted to allow static linking of cstr and csview. Still defaults to shared linking + inlines.
Diffstat (limited to 'include')
-rw-r--r--include/stc/carc.h2
-rw-r--r--include/stc/cbox.h2
-rw-r--r--include/stc/cspan.h2
-rw-r--r--include/stc/cstr.h137
-rw-r--r--include/stc/csview.h27
-rw-r--r--include/stc/priv/template.h9
6 files changed, 95 insertions, 84 deletions
diff --git a/include/stc/carc.h b/include/stc/carc.h
index db0cdcec..b77b7dfb 100644
--- a/include/stc/carc.h
+++ b/include/stc/carc.h
@@ -213,7 +213,7 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) {
{ return i_hash(rx); }
STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self)
- { return i_hash(self->get); }
+ { _cx_raw rx = i_keyto(self->get); return i_hash(&rx); }
#else
STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx)
{ return c_default_hash(&rx); }
diff --git a/include/stc/cbox.h b/include/stc/cbox.h
index c8d919b2..86d5a6a6 100644
--- a/include/stc/cbox.h
+++ b/include/stc/cbox.h
@@ -196,7 +196,7 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self* moved) {
{ return i_hash(rx); }
STC_INLINE uint64_t _cx_MEMB(_hash)(const _cx_Self* self)
- { return i_hash(self->get); }
+ { _cx_raw rx = i_keyto(self->get); return i_hash(&rx); }
#else
STC_INLINE uint64_t _cx_MEMB(_raw_hash)(const _cx_raw* rx)
{ return c_default_hash(&rx); }
diff --git a/include/stc/cspan.h b/include/stc/cspan.h
index 715efea8..7a0e9c8d 100644
--- a/include/stc/cspan.h
+++ b/include/stc/cspan.h
@@ -189,7 +189,7 @@ typedef struct { int32_t d[6]; } cspan_tuple6;
STC_INLINE intptr_t _cspan_size(const int32_t shape[], int rank) {
intptr_t sz = shape[0];
- while (rank-- > 1) sz *= shape[rank];
+ while (--rank > 0) sz *= shape[rank];
return sz;
}
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index 0f217f53..17943ad5 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -24,6 +24,7 @@
/* A string type with short string optimization in C99 with good small-string
* optimization (22 characters with 24 bytes string).
*/
+#define i_header // external linkage by default. override with i_static.
#define _i_inc_utf8
#include "utf8.h"
@@ -61,8 +62,8 @@ enum { cstr_s_cap = sizeof(cstr_buf) - 2 };
#define cstr_l_drop(s) c_free((s)->lon.data)
#define cstr_is_long(s) ((s)->sml.size > 127)
-extern char* _cstr_init(cstr* self, intptr_t len, intptr_t cap);
-extern char* _cstr_internal_move(cstr* self, intptr_t pos1, intptr_t pos2);
+STC_API char* _cstr_init(cstr* self, intptr_t len, intptr_t cap);
+STC_API char* _cstr_internal_move(cstr* self, intptr_t pos1, intptr_t pos2);
/**************************** PUBLIC API **********************************/
@@ -70,22 +71,22 @@ extern char* _cstr_internal_move(cstr* self, intptr_t pos1, intptr_t pos2);
#define cstr_null (c_LITERAL(cstr){0})
#define cstr_toraw(self) cstr_str(self)
-extern char* cstr_reserve(cstr* self, intptr_t cap);
-extern void cstr_shrink_to_fit(cstr* self);
-extern char* cstr_resize(cstr* self, intptr_t size, char value);
-extern intptr_t cstr_find_at(const cstr* self, intptr_t pos, const char* search);
-extern intptr_t cstr_find_sv(const cstr* self, csview search);
-extern char* cstr_assign_n(cstr* self, const char* str, intptr_t len);
-extern char* cstr_append_n(cstr* self, const char* str, intptr_t len);
-extern char* cstr_append_uninit(cstr *self, intptr_t len);
-extern bool cstr_getdelim(cstr *self, int delim, FILE *fp);
-extern void cstr_erase(cstr* self, intptr_t pos, intptr_t len);
-extern void cstr_u8_erase(cstr* self, intptr_t bytepos, intptr_t u8len);
-extern cstr cstr_from_fmt(const char* fmt, ...);
-extern intptr_t cstr_append_fmt(cstr* self, const char* fmt, ...);
-extern intptr_t cstr_printf(cstr* self, const char* fmt, ...);
-extern cstr cstr_replace_sv(csview sv, csview search, csview repl, int32_t count);
-extern uint64_t cstr_hash(const cstr *self);
+STC_API char* cstr_reserve(cstr* self, intptr_t cap);
+STC_API void cstr_shrink_to_fit(cstr* self);
+STC_API char* cstr_resize(cstr* self, intptr_t size, char value);
+STC_API intptr_t cstr_find_at(const cstr* self, intptr_t pos, const char* search);
+STC_API intptr_t cstr_find_sv(const cstr* self, csview search);
+STC_API char* cstr_assign_n(cstr* self, const char* str, intptr_t len);
+STC_API char* cstr_append_n(cstr* self, const char* str, intptr_t len);
+STC_API char* cstr_append_uninit(cstr *self, intptr_t len);
+STC_API bool cstr_getdelim(cstr *self, int delim, FILE *fp);
+STC_API void cstr_erase(cstr* self, intptr_t pos, intptr_t len);
+STC_API void cstr_u8_erase(cstr* self, intptr_t bytepos, intptr_t u8len);
+STC_API cstr cstr_from_fmt(const char* fmt, ...);
+STC_API intptr_t cstr_append_fmt(cstr* self, const char* fmt, ...);
+STC_API intptr_t cstr_printf(cstr* self, const char* fmt, ...);
+STC_API cstr cstr_replace_sv(csview sv, csview search, csview repl, int32_t count);
+STC_API uint64_t cstr_hash(const cstr *self);
STC_INLINE cstr_buf cstr_buffer(cstr* s) {
return cstr_is_long(s)
@@ -169,31 +170,14 @@ STC_INLINE intptr_t cstr_capacity(const cstr* self)
// utf8 methods defined in/depending on src/utf8code.c:
-extern cstr cstr_tocase(csview sv, int k);
-
-STC_INLINE cstr cstr_casefold_sv(csview sv)
- { return cstr_tocase(sv, 0); }
-
-STC_INLINE cstr cstr_tolower_sv(csview sv)
- { return cstr_tocase(sv, 1); }
-
-STC_INLINE cstr cstr_toupper_sv(csview sv)
- { return cstr_tocase(sv, 2); }
-
-STC_INLINE cstr cstr_tolower(const char* str)
- { return cstr_tolower_sv(c_sv(str, c_strlen(str))); }
-
-STC_INLINE cstr cstr_toupper(const char* str)
- { return cstr_toupper_sv(c_sv(str, c_strlen(str))); }
-
-STC_INLINE void cstr_lowercase(cstr* self)
- { cstr_take(self, cstr_tolower_sv(cstr_sv(self))); }
-
-STC_INLINE void cstr_uppercase(cstr* self)
- { cstr_take(self, cstr_toupper_sv(cstr_sv(self))); }
-
-STC_INLINE bool cstr_valid_utf8(const cstr* self)
- { return utf8_valid(cstr_str(self)); }
+STC_API cstr cstr_casefold_sv(csview sv);
+STC_API cstr cstr_tolower_sv(csview sv);
+STC_API cstr cstr_toupper_sv(csview sv);
+STC_API cstr cstr_tolower(const char* str);
+STC_API cstr cstr_toupper(const char* str);
+STC_API void cstr_lowercase(cstr* self);
+STC_API void cstr_uppercase(cstr* self);
+STC_API bool cstr_valid_utf8(const cstr* self);
// other utf8
@@ -410,7 +394,7 @@ fn_tocase[] = {{tolower, utf8_casefold},
{tolower, utf8_tolower},
{toupper, utf8_toupper}};
-cstr cstr_tocase(csview sv, int k) {
+STC_DEF cstr cstr_tocase(csview sv, int k) {
cstr out = cstr_init();
char *buf = cstr_reserve(&out, sv.size*3/2);
const char *end = sv.str + sv.size;
@@ -430,25 +414,49 @@ cstr cstr_tocase(csview sv, int k) {
cstr_shrink_to_fit(&out);
return out;
}
+
+STC_DEF cstr cstr_casefold_sv(csview sv)
+ { return cstr_tocase(sv, 0); }
+
+STC_DEF cstr cstr_tolower_sv(csview sv)
+ { return cstr_tocase(sv, 1); }
+
+STC_DEF cstr cstr_toupper_sv(csview sv)
+ { return cstr_tocase(sv, 2); }
+
+STC_DEF cstr cstr_tolower(const char* str)
+ { return cstr_tolower_sv(c_sv(str, c_strlen(str))); }
+
+STC_DEF cstr cstr_toupper(const char* str)
+ { return cstr_toupper_sv(c_sv(str, c_strlen(str))); }
+
+STC_DEF void cstr_lowercase(cstr* self)
+ { cstr_take(self, cstr_tolower_sv(cstr_sv(self))); }
+
+STC_DEF void cstr_uppercase(cstr* self)
+ { cstr_take(self, cstr_toupper_sv(cstr_sv(self))); }
+
+STC_DEF bool cstr_valid_utf8(const cstr* self)
+ { return utf8_valid(cstr_str(self)); }
#endif // i_import
/* -------------------------- IMPLEMENTATION ------------------------- */
-#if defined i_implement
+#if defined i_implement || defined i_static
#ifndef CSTR_C_INCLUDED
#define CSTR_C_INCLUDED
-uint64_t cstr_hash(const cstr *self) {
+STC_DEF uint64_t cstr_hash(const cstr *self) {
csview sv = cstr_sv(self);
return cfasthash(sv.str, sv.size);
}
-intptr_t cstr_find_sv(const cstr* self, csview search) {
+STC_DEF intptr_t cstr_find_sv(const cstr* self, csview search) {
csview sv = cstr_sv(self);
char* res = cstrnstrn(sv.str, search.str, sv.size, search.size);
return res ? (res - sv.str) : c_NPOS;
}
-char* _cstr_internal_move(cstr* self, const intptr_t pos1, const intptr_t pos2) {
+STC_DEF char* _cstr_internal_move(cstr* self, const intptr_t pos1, const intptr_t pos2) {
cstr_buf r = cstr_buffer(self);
if (pos1 != pos2) {
const intptr_t newlen = (r.size + pos2 - pos1);
@@ -460,7 +468,7 @@ char* _cstr_internal_move(cstr* self, const intptr_t pos1, const intptr_t pos2)
return r.data;
}
-char* _cstr_init(cstr* self, const intptr_t len, const intptr_t cap) {
+STC_DEF char* _cstr_init(cstr* self, const intptr_t len, const intptr_t cap) {
if (cap > cstr_s_cap) {
self->lon.data = (char *)c_malloc(cap + 1);
cstr_l_set_size(self, len);
@@ -471,7 +479,7 @@ char* _cstr_init(cstr* self, const intptr_t len, const intptr_t cap) {
return self->sml.data;
}
-void cstr_shrink_to_fit(cstr* self) {
+STC_DEF void cstr_shrink_to_fit(cstr* self) {
cstr_buf r = cstr_buffer(self);
if (r.size == r.cap)
return;
@@ -485,7 +493,7 @@ void cstr_shrink_to_fit(cstr* self) {
}
}
-char* cstr_reserve(cstr* self, const intptr_t cap) {
+STC_DEF char* cstr_reserve(cstr* self, const intptr_t cap) {
if (cstr_is_long(self)) {
if (cap > cstr_l_cap(self)) {
self->lon.data = (char *)c_realloc(self->lon.data, cap + 1);
@@ -507,7 +515,7 @@ char* cstr_reserve(cstr* self, const intptr_t cap) {
return self->sml.data;
}
-char* cstr_resize(cstr* self, const intptr_t size, const char value) {
+STC_DEF char* cstr_resize(cstr* self, const intptr_t size, const char value) {
cstr_buf r = cstr_buffer(self);
if (size > r.size) {
if (size > r.cap && !(r.data = cstr_reserve(self, size)))
@@ -518,20 +526,20 @@ char* cstr_resize(cstr* self, const intptr_t size, const char value) {
return r.data;
}
-intptr_t cstr_find_at(const cstr* self, const intptr_t pos, const char* search) {
+STC_DEF intptr_t cstr_find_at(const cstr* self, const intptr_t pos, const char* search) {
csview sv = cstr_sv(self);
if (pos > sv.size) return c_NPOS;
const char* res = strstr((char*)sv.str + pos, search);
return res ? (res - sv.str) : c_NPOS;
}
-char* cstr_assign_n(cstr* self, const char* str, const intptr_t len) {
+STC_DEF char* cstr_assign_n(cstr* self, const char* str, const intptr_t len) {
char* d = cstr_reserve(self, len);
if (d) { c_memmove(d, str, len); _cstr_set_size(self, len); }
return d;
}
-char* cstr_append_n(cstr* self, const char* str, const intptr_t len) {
+STC_DEF char* cstr_append_n(cstr* self, const char* str, const intptr_t len) {
cstr_buf r = cstr_buffer(self);
if (r.size + len > r.cap) {
const size_t off = (size_t)(str - r.data);
@@ -544,7 +552,7 @@ char* cstr_append_n(cstr* self, const char* str, const intptr_t len) {
return r.data;
}
-char* cstr_append_uninit(cstr *self, intptr_t len) {
+STC_DEF char* cstr_append_uninit(cstr *self, intptr_t len) {
cstr_buf r = cstr_buffer(self);
if (r.size + len > r.cap && !(r.data = cstr_reserve(self, r.size*3/2 + len)))
return NULL;
@@ -552,7 +560,7 @@ char* cstr_append_uninit(cstr *self, intptr_t len) {
return r.data + r.size;
}
-bool cstr_getdelim(cstr *self, const int delim, FILE *fp) {
+STC_DEF bool cstr_getdelim(cstr *self, const int delim, FILE *fp) {
int c = fgetc(fp);
if (c == EOF)
return false;
@@ -572,8 +580,7 @@ bool cstr_getdelim(cstr *self, const int delim, FILE *fp) {
}
}
-cstr
-cstr_replace_sv(csview in, csview search, csview repl, int32_t count) {
+STC_DEF cstr cstr_replace_sv(csview in, csview search, csview repl, int32_t count) {
cstr out = cstr_null;
intptr_t from = 0; char* res;
if (!count) count = INT32_MAX;
@@ -588,14 +595,14 @@ cstr_replace_sv(csview in, csview search, csview repl, int32_t count) {
return out;
}
-void cstr_erase(cstr* self, const intptr_t pos, intptr_t len) {
+STC_DEF void cstr_erase(cstr* self, const intptr_t pos, intptr_t len) {
cstr_buf r = cstr_buffer(self);
if (len > r.size - pos) len = r.size - pos;
c_memmove(&r.data[pos], &r.data[pos + len], r.size - (pos + len));
_cstr_set_size(self, r.size - len);
}
-void cstr_u8_erase(cstr* self, const intptr_t bytepos, const intptr_t u8len) {
+STC_DEF void cstr_u8_erase(cstr* self, const intptr_t bytepos, const intptr_t u8len) {
cstr_buf r = cstr_buffer(self);
intptr_t len = utf8_pos(r.data + bytepos, u8len);
c_memmove(&r.data[bytepos], &r.data[bytepos + len], r.size - (bytepos + len));
@@ -610,7 +617,7 @@ void cstr_u8_erase(cstr* self, const intptr_t bytepos, const intptr_t u8len) {
# pragma warning(disable: 4996)
#endif
-intptr_t cstr_vfmt(cstr* self, intptr_t start, const char* fmt, va_list args) {
+STC_DEF intptr_t cstr_vfmt(cstr* self, intptr_t start, const char* fmt, va_list args) {
va_list args2;
va_copy(args2, args);
const int n = vsnprintf(NULL, 0ULL, fmt, args);
@@ -625,7 +632,7 @@ intptr_t cstr_vfmt(cstr* self, intptr_t start, const char* fmt, va_list args) {
# pragma warning(pop)
#endif
-cstr cstr_from_fmt(const char* fmt, ...) {
+STC_DEF cstr cstr_from_fmt(const char* fmt, ...) {
cstr s = cstr_null;
va_list args;
va_start(args, fmt);
@@ -634,7 +641,7 @@ cstr cstr_from_fmt(const char* fmt, ...) {
return s;
}
-intptr_t cstr_append_fmt(cstr* self, const char* fmt, ...) {
+STC_DEF intptr_t cstr_append_fmt(cstr* self, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
const intptr_t n = cstr_vfmt(self, cstr_size(self), fmt, args);
@@ -643,7 +650,7 @@ intptr_t cstr_append_fmt(cstr* self, const char* fmt, ...) {
}
/* NB! self-data in args is UB */
-intptr_t cstr_printf(cstr* self, const char* fmt, ...) {
+STC_DEF intptr_t cstr_printf(cstr* self, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
const intptr_t n = cstr_vfmt(self, 0, fmt, args);
diff --git a/include/stc/csview.h b/include/stc/csview.h
index f960968c..85965928 100644
--- a/include/stc/csview.h
+++ b/include/stc/csview.h
@@ -20,6 +20,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#define i_header // external linkage by default. override with i_static.
#define _i_inc_utf8
#include "utf8.h"
@@ -33,12 +34,12 @@
#define csview_lit(literal) c_sv_1(literal)
#define csview_from_n(str, n) c_sv_2(str, n)
-extern csview_iter csview_advance(csview_iter it, intptr_t pos);
-extern intptr_t csview_find_sv(csview sv, csview search);
-extern uint64_t csview_hash(const csview *self);
-extern csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2);
-extern csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n);
-extern csview csview_token(csview sv, const char* sep, intptr_t* start);
+STC_API csview_iter csview_advance(csview_iter it, intptr_t pos);
+STC_API intptr_t csview_find_sv(csview sv, csview search);
+STC_API uint64_t csview_hash(const csview *self);
+STC_API csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2);
+STC_API csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n);
+STC_API csview csview_token(csview sv, const char* sep, intptr_t* start);
STC_INLINE csview csview_from(const char* str)
{ return c_LITERAL(csview){str, c_strlen(str)}; }
@@ -150,11 +151,11 @@ STC_INLINE csview cstr_u8_substr(const cstr* self , intptr_t bytepos, intptr_t u
#endif
/* -------------------------- IMPLEMENTATION ------------------------- */
-#if defined i_implement
+#if defined i_implement || defined i_static
#ifndef CSVIEW_C_INCLUDED
#define CSVIEW_C_INCLUDED
-csview_iter csview_advance(csview_iter it, intptr_t pos) {
+STC_DEF csview_iter csview_advance(csview_iter it, intptr_t pos) {
int inc = -1;
if (pos > 0) pos = -pos, inc = 1;
while (pos && it.ref != it.u8.end) pos += (*(it.ref += inc) & 0xC0) != 0x80;
@@ -163,15 +164,15 @@ csview_iter csview_advance(csview_iter it, intptr_t pos) {
return it;
}
-intptr_t csview_find_sv(csview sv, csview search) {
+STC_DEF intptr_t csview_find_sv(csview sv, csview search) {
char* res = cstrnstrn(sv.str, search.str, sv.size, search.size);
return res ? (res - sv.str) : c_NPOS;
}
-uint64_t csview_hash(const csview *self)
+STC_DEF uint64_t csview_hash(const csview *self)
{ return cfasthash(self->str, self->size); }
-csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n) {
+STC_DEF csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n) {
if (pos < 0) {
pos += sv.size;
if (pos < 0) pos = 0;
@@ -182,7 +183,7 @@ csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n) {
return sv;
}
-csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2) {
+STC_DEF csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2) {
if (p1 < 0) {
p1 += sv.size;
if (p1 < 0) p1 = 0;
@@ -193,7 +194,7 @@ csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2) {
return sv;
}
-csview csview_token(csview sv, const char* sep, intptr_t* start) {
+STC_DEF csview csview_token(csview sv, const char* sep, intptr_t* start) {
intptr_t sep_size = c_strlen(sep);
csview slice = {sv.str + *start, sv.size - *start};
const char* res = cstrnstrn(slice.str, sep, slice.size, sep_size);
diff --git a/include/stc/priv/template.h b/include/stc/priv/template.h
index 03c27bdb..7138a87c 100644
--- a/include/stc/priv/template.h
+++ b/include/stc/priv/template.h
@@ -102,6 +102,9 @@
#if c_option(c_no_emplace)
#define i_no_emplace
#endif
+#if c_option(c_native_cmp)
+ #define i_native_cmp
+#endif
#if defined i_key_str
#define i_keyclass cstr
@@ -194,10 +197,10 @@
#endif
#ifndef i_no_cmp
- #if c_option(c_native_cmp) || defined i_native_cmp || defined i_cmp || defined i_less
+ #if defined i_cmp || defined i_less || defined i_native_cmp
#define _i_has_cmp
#endif
- #if defined i_eq
+ #if defined i_eq || defined i_native_cmp
#define _i_has_eq
#endif
@@ -219,7 +222,7 @@
#endif
#endif
-#if !(defined i_hash || defined _i_cbox || defined _i_carc)
+#if !defined i_hash && (!(defined _i_cbox || defined _i_carc) || defined i_native_cmp)
#define i_hash c_default_hash
#endif