From 490e03ae9f2007ef1da38a141479770e1c4a61c0 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 16 Oct 2020 15:58:38 +0200 Subject: Fixed compiling as lib (-DSTC_HEADER) and added c_withbuffer() and c_break_with macros. --- stc/cbitset.h | 18 +++++++++--------- stc/ccommon.h | 15 +++++++++++++-- stc/clist.h | 39 +++++++++++++++++++-------------------- stc/cmap.h | 35 +++++++++++++++++------------------ stc/cptr.h | 12 ++++++------ stc/crandom.h | 12 ++++++------ stc/cstr.h | 37 ++++++++++++++++++++----------------- stc/cvec.h | 54 ++++++++++++++++++++++++++---------------------------- 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> 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 (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; ilast && 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_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 - 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; idata[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); idata[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 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 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) -- cgit v1.2.3