summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-10-16 15:58:38 +0200
committerTyge Løvset <[email protected]>2020-10-16 15:58:38 +0200
commit490e03ae9f2007ef1da38a141479770e1c4a61c0 (patch)
tree67550601fa36dcbdc69023df0b40bb193499e81d
parent47190a51588341d0ab715398ded6a480bc4fa95a (diff)
downloadSTC-modified-490e03ae9f2007ef1da38a141479770e1c4a61c0.tar.gz
STC-modified-490e03ae9f2007ef1da38a141479770e1c4a61c0.zip
Fixed compiling as lib (-DSTC_HEADER) and added c_withbuffer() and c_break_with macros.
-rw-r--r--stc/cbitset.h18
-rw-r--r--stc/ccommon.h15
-rw-r--r--stc/clist.h39
-rw-r--r--stc/cmap.h35
-rw-r--r--stc/cptr.h12
-rw-r--r--stc/crandom.h12
-rw-r--r--stc/cstr.h37
-rw-r--r--stc/cvec.h54
8 files changed, 116 insertions, 106 deletions
diff --git a/stc/cbitset.h b/stc/cbitset.h
index f932325a..4eb0c7f5 100644
--- a/stc/cbitset.h
+++ b/stc/cbitset.h
@@ -168,7 +168,7 @@ STC_INLINE bool cbitset_itval(cbitset_iter_t it) {
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value) {
+STC_IMP void cbitset_resize(cbitset_t* self, size_t size, bool value) {
size_t new_n = (size + 63) >> 6, osize = self->size, old_n = (osize + 63) >> 6;
self->_arr = (uint64_t *) c_realloc(self->_arr, new_n * 8);
self->size = size;
@@ -181,28 +181,28 @@ STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value) {
}
}
-STC_API cbitset_t cbitset_with_size(size_t size, bool value) {
+STC_IMP cbitset_t cbitset_with_size(size_t size, bool value) {
cbitset_t set = {(uint64_t *) c_malloc(((size + 63) >> 6) * 8), size};
cbitset_set_all(&set, value);
return set;
}
-STC_API cbitset_t cbitset_from_str(const char* str) {
+STC_IMP cbitset_t cbitset_from_str(const char* str) {
const char* p = str; while (*p) ++p;
cbitset_t set = cbitset_with_size(p - str, false);
for (size_t i=0; i<set.size; ++i) if (str[i] == '1') cbitset_set(&set, i);
return set;
}
-STC_API cstr_t cbitset_to_str(cbitset_t set) {
+STC_IMP cstr_t cbitset_to_str(cbitset_t set) {
cstr_t out = cstr_with_size(set.size, '0');
for (size_t i=0; i<set.size; ++i) if (cbitset_test(set, i)) out.str[i] = '1';
return out;
}
-STC_API cbitset_t cbitset_clone(cbitset_t other) {
+STC_IMP cbitset_t cbitset_clone(cbitset_t other) {
size_t bytes = ((other.size + 63) >> 6) * 8;
cbitset_t set = {(uint64_t *) memcpy(c_malloc(bytes), other._arr, bytes), other.size};
return set;
}
-STC_API size_t cbitset_count(cbitset_t s) {
+STC_IMP size_t cbitset_count(cbitset_t s) {
size_t count = 0, n = ((s.size + 63) >> 6) - 1;
if (s.size > 0) {
for (size_t i=0; i<n; ++i) count += cpopcount64(s._arr[i]);
@@ -221,9 +221,9 @@ STC_API size_t cbitset_count(cbitset_t s) {
uint64_t m = (1ull << (s.size & 63)) - 1, last = s._arr[n] & m; \
return (last OPR (other._arr[n] & m)) == last
-STC_API bool cbitset_is_disjoint(cbitset_t s, cbitset_t other) { _cbitset_SETOP(^); }
-STC_API bool cbitset_is_subset(cbitset_t s, cbitset_t other) { _cbitset_SETOP(|); }
-STC_API bool cbitset_is_superset(cbitset_t s, cbitset_t other) { _cbitset_SETOP(&); }
+STC_IMP bool cbitset_is_disjoint(cbitset_t s, cbitset_t other) { _cbitset_SETOP(^); }
+STC_IMP bool cbitset_is_subset(cbitset_t s, cbitset_t other) { _cbitset_SETOP(|); }
+STC_IMP bool cbitset_is_superset(cbitset_t s, cbitset_t other) { _cbitset_SETOP(&); }
#endif
#endif
diff --git a/stc/ccommon.h b/stc/ccommon.h
index f9e3d871..1eb50432 100644
--- a/stc/ccommon.h
+++ b/stc/ccommon.h
@@ -39,11 +39,16 @@
#if defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
# define STC_API extern
+# define STC_IMP
+# define STC_APIV extern
+# define STC_IMPV
#else
-# define STC_API STC_INLINE
+# define STC_API static inline
+# define STC_IMP static inline
+# define STC_APIV static
+# define STC_IMPV static
#endif
-enum {_c_max_buffer = 512};
/* Macro overloading feature support: https://rextester.com/ONP80107 */
#define _c_CAT( A, B ) A ## B
#define _c_EXPAND(...) __VA_ARGS__
@@ -94,7 +99,13 @@ enum {_c_max_buffer = 512};
#define c_forrange_5(i, type, start, stop, step) \
for (type i=start, i##_inc_=step, i##_end_=(stop) - (0 < i##_inc_); (i <= i##_end_) == (0 < i##_inc_); i += i##_inc_)
+#define c_break_with continue
#define c_withfile(f, open) for (FILE *f = open; f; fclose(f), f = NULL)
+#define c_withbuffer(type, b, n) c_withbuffer_x(type, b, n, 512)
+#define c_withbuffer_x(type, b, n, BYTES) \
+ for (type __b[((BYTES) - 1) / sizeof(type) + 1], \
+ *b = (n) * sizeof *b > (BYTES) ? c_new_2(type, n) : __b; \
+ b; b != __b ? c_free(b) : (void)0, b = NULL)
#define c_push_items(self, ctype, ...) do { \
const ctype##_input_t __arr[] = __VA_ARGS__; \
diff --git a/stc/clist.h b/stc/clist.h
index 5e52c55d..9375405b 100644
--- a/stc/clist.h
+++ b/stc/clist.h
@@ -205,47 +205,47 @@ STC_API size_t _clist_size(const clist_void* self);
STC_INLINE Value* \
clist_##X##_back(clist_##X* self) {return &self->last->value;} \
\
- _c_implement_clist_7(X, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw)
-
+ _c_implement_clist_7(X, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw) \
+ typedef clist_##X clist_##X##_t
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
#define _c_implement_clist_7(X, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw) \
\
- STC_API void \
+ STC_IMP void \
clist_##X##_del(clist_##X* self) { \
while (self->last) _clist_##X##_erase_after(self, self->last); \
} \
\
- STC_API void \
+ STC_IMP void \
clist_##X##_push_back(clist_##X* self, Value value) { \
_c_clist_insert_after(self, X, self->last, value); \
self->last = entry; \
} \
- STC_API void \
+ STC_IMP void \
clist_##X##_push_front(clist_##X* self, Value value) { \
_c_clist_insert_after(self, X, self->last, value); \
if (!self->last) self->last = entry; \
} \
- STC_API void \
+ STC_IMP void \
clist_##X##_push_n(clist_##X *self, const clist_##X##_input_t in[], size_t size) { \
for (size_t i=0; i<size; ++i) clist_##X##_push_back(self, valueFromRaw(in[i])); \
} \
\
- STC_API clist_##X##_iter_t \
+ STC_IMP clist_##X##_iter_t \
clist_##X##_insert_after(clist_##X* self, clist_##X##_iter_t pos, Value value) { \
clist_##X##_node_t* node = pos.val ? _clist_node(X, pos.val) : NULL; \
_c_clist_insert_after(self, X, node, value); \
if (!node || node == self->last && pos._state == 0) self->last = entry; \
pos.val = &entry->value, pos._state = 0; return pos; \
} \
- STC_API clist_##X##_iter_t \
+ STC_IMP clist_##X##_iter_t \
clist_##X##_erase_after(clist_##X* self, clist_##X##_iter_t pos) { \
_clist_##X##_erase_after(self, _clist_node(X, pos.val)); \
clist_##X##_next(&pos); return pos; \
} \
- STC_API clist_##X##_iter_t \
+ STC_IMP clist_##X##_iter_t \
clist_##X##_erase_range_after(clist_##X* self, clist_##X##_iter_t first, clist_##X##_iter_t finish) { \
clist_##X##_node_t* node = _clist_node(X, first.val), *done = finish.val ? _clist_node(X, finish.val) : NULL; \
while (node && node->next != done) \
@@ -253,7 +253,7 @@ STC_API size_t _clist_size(const clist_void* self);
clist_##X##_next(&first); return first; \
} \
\
- STC_API clist_##X##_iter_t \
+ STC_IMP clist_##X##_iter_t \
clist_##X##_find_before(const clist_##X* self, clist_##X##_iter_t first, clist_##X##_iter_t finish, RawValue val) { \
clist_##X##_iter_t i = first; \
for (clist_##X##_next(&i); i.val != finish.val; clist_##X##_next(&i)) { \
@@ -264,13 +264,13 @@ STC_API size_t _clist_size(const clist_void* self);
return clist_##X##_end(self); \
} \
\
- STC_API clist_##X##_iter_t \
+ STC_IMP clist_##X##_iter_t \
clist_##X##_find(const clist_##X* self, RawValue val) { \
clist_##X##_iter_t it = clist_##X##_find_before(self, clist_##X##_before_begin(self), clist_##X##_end(self), val); \
if (it.val != clist_##X##_end(self).val) clist_##X##_next(&it); \
return it; \
} \
- STC_API clist_##X##_node_t* \
+ STC_IMP clist_##X##_node_t* \
_clist_##X##_erase_after(clist_##X* self, clist_##X##_node_t* node) { \
clist_##X##_node_t* del = node->next, *next = del->next; \
node->next = next; \
@@ -280,7 +280,7 @@ STC_API size_t _clist_size(const clist_void* self);
return node; \
} \
\
- STC_API size_t \
+ STC_IMP size_t \
clist_##X##_remove(clist_##X* self, RawValue val) { \
size_t n = 0; \
clist_##X##_node_t* prev = self->last, *node; \
@@ -295,7 +295,7 @@ STC_API size_t _clist_size(const clist_void* self);
return n; \
} \
\
- STC_API void \
+ STC_IMP void \
clist_##X##_splice_after(clist_##X* self, clist_##X##_iter_t pos, clist_##X* other) { \
if (!pos.val) \
self->last = other->last; \
@@ -308,18 +308,17 @@ STC_API size_t _clist_size(const clist_void* self);
other->last = NULL; \
} \
\
- static inline int \
+ STC_INLINE int \
clist_##X##_sort_compare(const void* x, const void* y) { \
RawValue a = valueToRaw(&((clist_##X##_node_t *) x)->value); \
RawValue b = valueToRaw(&((clist_##X##_node_t *) y)->value); \
return valueCompareRaw(&a, &b); \
} \
- STC_API void \
+ STC_IMP void \
clist_##X##_sort(clist_##X* self) { \
clist_void_node_t* last = _clist_mergesort((clist_void_node_t *) self->last->next, clist_##X##_sort_compare); \
self->last = (clist_##X##_node_t *) last; \
- } \
- typedef clist_##X clist_##X##_t
+ }
#define _c_clist_insert_after(self, X, node, val) \
@@ -330,7 +329,7 @@ STC_API size_t _clist_size(const clist_void* self);
if (node) node->next = entry
/* +: set self->last based on node */
-STC_API size_t
+STC_IMP size_t
_clist_size(const clist_void* self) {
const clist_void_node_t *i = self->last;
if (!i) return 0;
@@ -342,7 +341,7 @@ _clist_size(const clist_void* self) {
/* Singly linked list Mergesort implementation by Simon Tatham. O(n*log n).
* https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
*/
-STC_API clist_void_node_t *
+STC_IMP clist_void_node_t *
_clist_mergesort(clist_void_node_t *list, int (*cmp)(const void*, const void*)) {
clist_void_node_t *p, *q, *e, *tail, *oldhead;
int insize = 1, nmerges, psize, qsize, i;
diff --git a/stc/cmap.h b/stc/cmap.h
index fda00bad..1a8782c1 100644
--- a/stc/cmap.h
+++ b/stc/cmap.h
@@ -259,7 +259,7 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
if (!res.second) valueDestroy(&res.first->second); \
res.first->second = valueFromRaw(rawVal); return res; \
} \
- STC_API ctype##_##X##_mapped_t* \
+ STC_INLINE ctype##_##X##_mapped_t* \
ctype##_##X##_at(const ctype##_##X* self, RawKey rawKey) { \
ctype##_bucket_t b = ctype##_##X##_bucket(self, &rawKey); \
assert(self->_hashx[b.idx]); \
@@ -311,20 +311,21 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
STC_API uint32_t c_default_hash32(const void* data, size_t len); \
\
_c_implement_CHASH(X, ctype, Key, Mapped, valueDestroy, keyEqualsRaw, keyHashRaw, \
- keyDestroy, RawKey, keyToRaw, keyFromRaw, RawVal, valueFromRaw)
+ keyDestroy, RawKey, keyToRaw, keyFromRaw, RawVal, valueFromRaw) \
+ typedef ctype##_##X ctype##_##X##_t
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
#define _c_implement_CHASH(X, ctype, Key, Mapped, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyToRaw, keyFromRaw, RawVal, valueFromRaw) \
- STC_API ctype##_##X \
+ STC_IMP ctype##_##X \
ctype##_##X##_with_capacity(size_t cap) { \
ctype##_##X h = ctype##_INIT; \
ctype##_##X##_reserve(&h, cap); \
return h; \
} \
- STC_API void \
+ STC_IMP void \
ctype##_##X##_push_n(ctype##_##X* self, const ctype##_##X##_input_t in[], size_t n) { \
for (size_t i=0; i<n; ++i) CMAP_ONLY_##ctype(ctype##_##X##_put(self, in[i].first, in[i].second)) \
CSET_ONLY_##ctype(ctype##_##X##_insert(self, in[i])) ; \
@@ -337,19 +338,19 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
for (; e != end; ++e) if (*hx++) ctype##_##X##_entry_del(e); \
} \
\
- STC_API void ctype##_##X##_del(ctype##_##X* self) { \
+ STC_IMP void ctype##_##X##_del(ctype##_##X* self) { \
ctype##_##X##_wipe_(self); \
c_free(self->_hashx); \
c_free(self->table); \
} \
\
- STC_API void ctype##_##X##_clear(ctype##_##X* self) { \
+ STC_IMP void ctype##_##X##_clear(ctype##_##X* self) { \
ctype##_##X##_wipe_(self); \
self->size = 0; \
memset(self->_hashx, 0, self->bucket_count); \
} \
\
- STC_API ctype##_bucket_t \
+ STC_IMP ctype##_bucket_t \
ctype##_##X##_bucket(const ctype##_##X* self, const ctype##_##X##_rawkey_t* rawKeyPtr) { \
uint32_t sx, hash = keyHashRaw(rawKeyPtr, sizeof(ctype##_##X##_rawkey_t)); \
size_t cap = self->bucket_count; \
@@ -365,7 +366,7 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
return b; \
} \
\
- STC_API ctype##_##X##_value_t* \
+ STC_IMP ctype##_##X##_value_t* \
ctype##_##X##_find(const ctype##_##X* self, RawKey rawKey) { \
if (self->size == 0) return NULL; \
ctype##_bucket_t b = ctype##_##X##_bucket(self, &rawKey); \
@@ -376,12 +377,12 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
if (self->size + 1 >= self->bucket_count * self->max_load_factor) \
ctype##_##X##_reserve(self, 5 + self->size * 3 / 2); \
} \
- STC_API bool \
+ STC_IMP bool \
ctype##_##X##_contains(const ctype##_##X* self, RawKey rawKey) { \
return self->size && self->_hashx[ctype##_##X##_bucket(self, &rawKey).idx]; \
} \
\
- STC_API ctype##_##X##_result_t \
+ STC_IMP ctype##_##X##_result_t \
ctype##_##X##_insert_key_(ctype##_##X* self, RawKey rawKey) { \
ctype##_##X##_reserve_expand(self); \
ctype##_bucket_t b = ctype##_##X##_bucket(self, &rawKey); \
@@ -394,7 +395,7 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
return res; \
} \
\
- STC_API void \
+ STC_IMP void \
ctype##_##X##_reserve(ctype##_##X* self, size_t newcap) { \
size_t oldcap = self->bucket_count; \
if (self->size > newcap) return; \
@@ -420,7 +421,7 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
c_free(tmp.table); \
} \
\
- STC_API void \
+ STC_IMP void \
ctype##_##X##_erase_entry(ctype##_##X* self, ctype##_##X##_value_t* val) { \
size_t i = chash_entry_index(*self, val), j = i, k, cap = self->bucket_count; \
ctype##_##X##_value_t* slot = self->table; \
@@ -437,19 +438,17 @@ typedef struct {size_t idx; uint32_t hx;} cmap_bucket_t, cset_bucket_t;
} while (true); \
hashx[i] = 0; \
--self->size; \
- } \
-\
- typedef ctype##_##X ctype##_##X##_t
+ }
/* https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/ */
-STC_API uint32_t c_default_hash16(const void *data, size_t len) {
+STC_IMP uint32_t c_default_hash16(const void *data, size_t len) {
const volatile uint16_t *key = (const uint16_t *) data;
uint64_t x = *key++ * 0xc613fc15u;
while (len -= 2) x = (*key++ + x) * 2654435769ull;
return (uint32_t) x;
}
-STC_API uint32_t c_default_hash32(const void* data, size_t len) {
+STC_IMP uint32_t c_default_hash32(const void* data, size_t len) {
const volatile uint32_t *key = (const uint32_t *) data;
uint64_t x = *key++ * 2654435769ull;
while (len -= 4) x = (*key++ + x) * 2654435769ull;
@@ -458,7 +457,7 @@ STC_API uint32_t c_default_hash32(const void* data, size_t len) {
#else
#define _c_implement_CHASH(X, ctype, Key, Mapped, valueDestroy, keyEqualsRaw, keyHashRaw, \
- keyDestroy, RawKey, keyToRaw, keyFromRaw)
+ keyDestroy, RawKey, keyToRaw, keyFromRaw, RawVal, valueFromRaw)
#endif
#endif
diff --git a/stc/cptr.h b/stc/cptr.h
index 571c269c..0ef01450 100644
--- a/stc/cptr.h
+++ b/stc/cptr.h
@@ -120,14 +120,14 @@ int main() {
*/
typedef long atomic_count_t;
#if defined(__GNUC__) || defined(__clang__)
- static inline void atomic_increment(atomic_count_t* pw) {__atomic_add_fetch(pw, 1, __ATOMIC_SEQ_CST);}
- static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return __atomic_sub_fetch(pw, 1, __ATOMIC_SEQ_CST);}
+ STC_INLINE void atomic_increment(atomic_count_t* pw) {__atomic_add_fetch(pw, 1, __ATOMIC_SEQ_CST);}
+ STC_INLINE atomic_count_t atomic_decrement(atomic_count_t* pw) {return __atomic_sub_fetch(pw, 1, __ATOMIC_SEQ_CST);}
#elif defined(_MSC_VER)
#include <intrin.h>
- static inline void atomic_increment(atomic_count_t* pw) {_InterlockedIncrement(pw);}
- static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {return _InterlockedDecrement(pw);}
+ STC_INLINE void atomic_increment(atomic_count_t* pw) {_InterlockedIncrement(pw);}
+ STC_INLINE atomic_count_t atomic_decrement(atomic_count_t* pw) {return _InterlockedDecrement(pw);}
#elif defined(__i386__) || defined(__x86_64__)
- static inline void atomic_increment(atomic_count_t* pw) {
+ STC_INLINE void atomic_increment(atomic_count_t* pw) {
__asm__ (
"lock\n\t"
"incl %0":
@@ -136,7 +136,7 @@ typedef long atomic_count_t;
"cc" // clobbers
);
}
- static inline atomic_count_t atomic_decrement(atomic_count_t* pw) {
+ STC_INLINE atomic_count_t atomic_decrement(atomic_count_t* pw) {
int r;
__asm__ __volatile__ (
"lock\n\t"
diff --git a/stc/crandom.h b/stc/crandom.h
index 89793c94..a52bbc79 100644
--- a/stc/crandom.h
+++ b/stc/crandom.h
@@ -138,14 +138,14 @@ STC_API double crand_normal_f64(crand_rng64_t* rng, crand_normal_f64_t* dist);
#endif
/* PRNG PCG32 https://www.pcg-random.org/download.html */
-STC_API crand_rng32_t crand_rng32_with_seq(uint64_t seed, uint64_t seq) {
+STC_IMP crand_rng32_t crand_rng32_with_seq(uint64_t seed, uint64_t seq) {
crand_rng32_t rng = {{0u, (seq << 1u) | 1u}}; /* inc must be odd */
crand_i32(&rng);
rng.state[0] += seed;
crand_i32(&rng);
return rng;
}
-STC_API uint32_t crand_i32(crand_rng32_t* rng) {
+STC_IMP uint32_t crand_i32(crand_rng32_t* rng) {
uint64_t old = rng->state[0];
rng->state[0] = old * 6364136223846793005ull + rng->state[1];
uint32_t xors = (uint32_t) (((old >> 18u) ^ old) >> 27u);
@@ -158,12 +158,12 @@ STC_API uint32_t crand_i32(crand_rng32_t* rng) {
/* Even faster than sfc64: updates only 192bit state. Better for parallel processing: */
/* Guarantees 2^63 unique threads with minimum 2^64 period length ~ 2^160 average period. */
/* Tested with PractRand to 8 TB output: no issues */
-STC_API crand_rng64_t crand_rng64_with_seq(uint64_t seed, uint64_t seq) {
+STC_IMP crand_rng64_t crand_rng64_with_seq(uint64_t seed, uint64_t seq) {
crand_rng64_t rng = {{seed, seed, seed, (seq << 1u) | 1u}}; /* increment must be odd */
for (int i = 0; i < 12; ++i) crand_i64(&rng);
return rng;
}
-STC_API uint64_t crand_i64(crand_rng64_t* rng) {
+STC_IMP uint64_t crand_i64(crand_rng64_t* rng) {
enum {LROT = 24, RSHIFT = 11, LSHIFT = 3};
uint64_t *s = rng->state;
const uint64_t b = s[1], result = s[0] ^ (s[2] += s[3]|1);
@@ -173,7 +173,7 @@ STC_API uint64_t crand_i64(crand_rng64_t* rng) {
}
/* Unbiased uniform https://github.com/lemire/fastrange */
-STC_API uint32_t crand_unbiased_i32(crand_rng32_t* rng, crand_uniform_i32_t* dist) {
+STC_IMP uint32_t crand_unbiased_i32(crand_rng32_t* rng, crand_uniform_i32_t* dist) {
uint32_t r = dist->range;
uint64_t m = (uint64_t) crand_i32(rng) * r;
uint32_t l = (uint32_t) m;
@@ -186,7 +186,7 @@ STC_API uint32_t crand_unbiased_i32(crand_rng32_t* rng, crand_uniform_i32_t* dis
}
/* Marsaglia polar method for gaussian distribution. */
-STC_API double crand_normal_f64(crand_rng64_t* rng, crand_normal_f64_t* dist) {
+STC_IMP double crand_normal_f64(crand_rng64_t* rng, crand_normal_f64_t* dist) {
double u1, u2, s, m;
if (dist->has_next) {
dist->has_next = false;
diff --git a/stc/cstr.h b/stc/cstr.h
index 79a204d4..fb824852 100644
--- a/stc/cstr.h
+++ b/stc/cstr.h
@@ -33,9 +33,9 @@ typedef struct cstr { char* str; } cstr_t;
typedef struct { char *val; } cstr_iter_t;
typedef char cstr_value_t;
-static size_t _cstr_nullrep[] = {0, 0, 0};
+STC_APIV size_t _cstr_nullrep[];
+STC_APIV cstr_t cstr_INIT;
-static cstr_t cstr_INIT = {(char* ) &_cstr_nullrep[2]};
#define cstr_size(s) ((const size_t *) (s).str)[-2]
#define cstr_capacity(s) ((const size_t *) (s).str)[-1]
#define cstr_empty(s) (cstr_size(s) == 0)
@@ -215,7 +215,10 @@ STC_INLINE uint32_t cstr_hash_raw(const char* const* spp, size_t ignored) {
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-STC_API size_t
+STC_IMPV size_t _cstr_nullrep[] = {0, 0, 0};
+STC_IMPV cstr_t cstr_INIT = {(char* ) &_cstr_nullrep[2]};
+
+STC_IMP size_t
cstr_reserve(cstr_t* self, size_t cap) {
size_t len = cstr_size(*self), oldcap = cstr_capacity(*self);
if (cap > oldcap) {
@@ -227,7 +230,7 @@ cstr_reserve(cstr_t* self, size_t cap) {
return oldcap;
}
-STC_API void
+STC_IMP void
cstr_resize(cstr_t* self, size_t len, char fill) {
size_t n = cstr_size(*self);
cstr_reserve(self, len);
@@ -235,7 +238,7 @@ cstr_resize(cstr_t* self, size_t len, char fill) {
if (len | n) self->str[_cstr_size(*self) = len] = '\0';
}
-STC_API cstr_t
+STC_IMP cstr_t
cstr_n(const char* str, size_t len) {
if (len == 0) return cstr_INIT;
size_t *rep = (size_t *) c_malloc(_cstr_mem(len));
@@ -245,7 +248,7 @@ cstr_n(const char* str, size_t len) {
return s;
}
-STC_API cstr_t
+STC_IMP cstr_t
cstr_from_fmt(const char* fmt, ...) {
#if defined(__clang__)
# pragma clang diagnostic push
@@ -274,7 +277,7 @@ cstr_from_fmt(const char* fmt, ...) {
#endif
}
-STC_API cstr_t*
+STC_IMP cstr_t*
cstr_assign_n(cstr_t* self, const char* str, size_t len) {
if (len || cstr_capacity(*self)) {
cstr_reserve(self, len);
@@ -284,7 +287,7 @@ cstr_assign_n(cstr_t* self, const char* str, size_t len) {
return self;
}
-STC_API cstr_t*
+STC_IMP cstr_t*
cstr_append_n(cstr_t* self, const char* str, size_t len) {
if (len) {
size_t oldlen = cstr_size(*self), newlen = oldlen + len;
@@ -310,16 +313,16 @@ STC_INLINE void _cstr_internal_move(cstr_t* self, size_t pos1, size_t pos2) {
self->str[_cstr_size(*self) = newlen] = '\0';
}
-STC_API void
+STC_IMP void
cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n) {
- char buf[_c_max_buffer];
- char* xstr = (char *) memcpy(n > _c_max_buffer ? c_malloc(n) : buf, str, n);
- _cstr_internal_move(self, pos + len, pos + n);
- memcpy(&self->str[pos], xstr, n);
- if (n > _c_max_buffer) c_free(xstr);
+ c_withbuffer (char, xstr, n) {
+ memcpy(xstr, str, n);
+ _cstr_internal_move(self, pos + len, pos + n);
+ memcpy(&self->str[pos], xstr, n);
+ }
}
-STC_API void
+STC_IMP void
cstr_erase(cstr_t* self, size_t pos, size_t n) {
size_t len = cstr_size(*self);
if (len) {
@@ -328,7 +331,7 @@ cstr_erase(cstr_t* self, size_t pos, size_t n) {
}
}
-STC_API bool
+STC_IMP bool
cstr_getdelim(cstr_t *self, int delim, FILE *stream) {
size_t pos = 0, cap = cstr_capacity(*self);
for (;;) {
@@ -347,7 +350,7 @@ cstr_getdelim(cstr_t *self, int delim, FILE *stream) {
}
}
-STC_API char*
+STC_IMP char*
c_strnstr(const char* x, const char* needle, size_t n) {
ptrdiff_t sum = 0;
const char *y = x, *p = needle, *q = needle + n;
diff --git a/stc/cvec.h b/stc/cvec.h
index 16c344a3..d9f1abb4 100644
--- a/stc/cvec.h
+++ b/stc/cvec.h
@@ -101,10 +101,10 @@
valueDestroy(&self->data[--_cvec_size(self)]); \
} \
\
- STC_INLINE cvec_##X##_iter_t \
+ STC_API cvec_##X##_iter_t \
cvec_##X##_insert_range_p(cvec_##X* self, cvec_##X##_value_t* pos, cvec_##X##_value_t* pfirst, cvec_##X##_value_t* pfinish); \
\
- STC_API cvec_##X##_iter_t \
+ STC_INLINE cvec_##X##_iter_t \
cvec_##X##_insert_range(cvec_##X* self, cvec_##X##_iter_t pos, cvec_##X##_iter_t first, cvec_##X##_iter_t finish) { \
return cvec_##X##_insert_range_p(self, pos.val, first.val, finish.val); \
} \
@@ -186,34 +186,35 @@
STC_INLINE size_t \
cvec_##X##_idx(cvec_##X v, cvec_##X##_iter_t it) {return it.val - v.data;} \
\
- _c_implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw)
+ _c_implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \
+ typedef cvec_##X cvec_##X##_t
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
#define _c_implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \
\
- STC_API void \
+ STC_IMP void \
cvec_##X##_push_n(cvec_##X *self, const cvec_##X##_input_t in[], size_t size) { \
cvec_##X##_reserve(self, cvec_size(*self) + size); \
_cvec_size(self) += size; \
for (size_t i=0; i<size; ++i) self->data[i] = valueFromRaw(in[i]); \
} \
\
- STC_API void \
+ STC_IMP void \
cvec_##X##_clear(cvec_##X* self) { \
cvec_##X##_value_t* p = self->data; if (p) { \
for (cvec_##X##_value_t* q = p + _cvec_size(self); p != q; ++p) valueDestroy(p); \
_cvec_size(self) = 0; \
} \
} \
- STC_API void \
+ STC_IMP void \
cvec_##X##_del(cvec_##X* self) { \
cvec_##X##_clear(self); \
if (self->data) c_free(_cvec_alloced(self->data)); \
} \
\
- STC_API void \
+ STC_IMP void \
cvec_##X##_reserve(cvec_##X* self, size_t cap) { \
size_t len = cvec_size(*self); \
if (cap >= len) { \
@@ -223,14 +224,14 @@
rep[1] = cap; \
} \
} \
- STC_API void \
+ STC_IMP void \
cvec_##X##_resize(cvec_##X* self, size_t size, Value null_val) { \
cvec_##X##_reserve(self, size); \
for (size_t i=cvec_size(*self); i<size; ++i) self->data[i] = null_val; \
if (self->data) _cvec_size(self) = size; \
} \
\
- STC_API void \
+ STC_IMP void \
cvec_##X##_push_back(cvec_##X* self, Value value) { \
size_t len = cvec_size(*self); \
if (len == cvec_capacity(*self)) \
@@ -238,25 +239,23 @@
self->data[_cvec_size(self)++] = value; \
} \
\
- STC_API cvec_##X##_iter_t \
+ STC_IMP cvec_##X##_iter_t \
cvec_##X##_insert_range_p(cvec_##X* self, cvec_##X##_value_t* pos, cvec_##X##_value_t* first, cvec_##X##_value_t* finish) { \
- enum {max_buf = _c_max_buffer / sizeof(Value) + 1}; \
- Value buf[max_buf]; \
size_t len = finish - first, idx = pos - self->data, size = cvec_size(*self); \
- cvec_##X##_value_t* xbuf = (len > max_buf ? c_new_2(cvec_##X##_value_t, len) : &buf[0]); \
- for (size_t i=0; i<len; ++i, ++first) \
- xbuf[i] = valueFromRaw(valueToRaw(first)); \
- if (size + len > cvec_capacity(*self)) \
- cvec_##X##_reserve(self, 4 + (size + len) * 3 / 2); \
- pos = self->data + idx; \
- memmove(pos + len, pos, (size - idx) * sizeof(Value)); \
- memcpy(pos, xbuf, len * sizeof(Value)); \
- _cvec_size(self) += len; \
- if (len > max_buf) c_free(xbuf); \
+ c_withbuffer (cvec_##X##_value_t, buf, len) { \
+ for (size_t i=0; i<len; ++i, ++first) \
+ buf[i] = valueFromRaw(valueToRaw(first)); \
+ if (size + len > cvec_capacity(*self)) \
+ cvec_##X##_reserve(self, 4 + (size + len) * 3 / 2); \
+ pos = self->data + idx; \
+ memmove(pos + len, pos, (size - idx) * sizeof(Value)); \
+ memcpy(pos, buf, len * sizeof(Value)); \
+ _cvec_size(self) += len; \
+ } \
cvec_##X##_iter_t it = {pos}; return it; \
} \
\
- STC_API cvec_##X##_iter_t \
+ STC_IMP cvec_##X##_iter_t \
cvec_##X##_erase_range_p(cvec_##X* self, cvec_##X##_value_t* first, cvec_##X##_value_t* finish) { \
intptr_t len = finish - first; \
if (len > 0) { \
@@ -268,7 +267,7 @@
cvec_##X##_iter_t it = {first}; return it; \
} \
\
- STC_API cvec_##X##_iter_t \
+ STC_IMP cvec_##X##_iter_t \
cvec_##X##_find_in_range(const cvec_##X* self, cvec_##X##_iter_t first, cvec_##X##_iter_t finish, RawValue rawValue) { \
for (; first.val != finish.val; cvec_##X##_next(&first)) { \
RawValue r = valueToRaw(first.val); \
@@ -276,18 +275,17 @@
} \
return cvec_##X##_end(self); \
} \
- STC_API cvec_##X##_iter_t \
+ STC_IMP cvec_##X##_iter_t \
cvec_##X##_find(const cvec_##X* self, RawValue rawValue) { \
return cvec_##X##_find_in_range(self, cvec_##X##_begin(self), cvec_##X##_end(self), rawValue); \
} \
\
- STC_API int \
+ STC_IMP int \
cvec_##X##_value_compare(const cvec_##X##_value_t* x, const cvec_##X##_value_t* y) { \
RawValue rx = valueToRaw(x); \
RawValue ry = valueToRaw(y); \
return valueCompareRaw(&rx, &ry); \
- } \
- typedef cvec_##X cvec_##X##_t
+ }
#else
#define _c_implement_cvec_7(X, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw)