From 7b85cf6e734fe312dd4b762282ff33010fe24bf3 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 23 Apr 2021 16:25:22 +0200 Subject: Internal restructure of methods declarations. Backported others/clist_v1.h. --- benchmarks/others/clist_v1.h | 373 +++++++++++++++++++++---------------------- stc/cstr.h | 266 ++++++++++++------------------ 2 files changed, 279 insertions(+), 360 deletions(-) diff --git a/benchmarks/others/clist_v1.h b/benchmarks/others/clist_v1.h index c1f76d0b..42532612 100644 --- a/benchmarks/others/clist_v1.h +++ b/benchmarks/others/clist_v1.h @@ -52,237 +52,217 @@ clist_ix_del(&list); } */ -#include "ccommon.h" +#include #include -#define using_clist(...) c_MACRO_OVERLOAD(using_clist, __VA_ARGS__) +#define using_clist(...) c_MACRO_OVERLOAD(using_clist, __VA_ARGS__) + #define using_clist_2(X, Value) \ - using_clist_3(X, Value, c_default_compare) + using_clist_3(X, Value, c_default_compare) #define using_clist_3(X, Value, valueCompare) \ - using_clist_5(X, Value, valueCompare, c_trivial_del, c_trivial_fromraw) + using_clist_5(X, Value, valueCompare, c_trivial_del, c_trivial_fromraw) #define using_clist_4(X, Value, valueCompare, valueDel) \ - using_clist_5(X, Value, valueCompare, valueDel, c_no_clone) + using_clist_5(X, Value, valueCompare, valueDel, c_no_clone) #define using_clist_5(X, Value, valueCompare, valueDel, valueClone) \ - using_clist_7(X, Value, valueCompare, valueDel, valueClone, c_trivial_toraw, Value) + _c_using_clist(clist_##X, Value, valueCompare, valueDel, valueClone, c_trivial_toraw, Value) +#define using_clist_7(X, Value, valueCompare, valueDel, valueFromRaw, valueToRaw, RawValue) \ + _c_using_clist(clist_##X, Value, valueCompare, valueDel, valueFromRaw, valueToRaw, RawValue) + #define using_clist_str() \ - using_clist_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) + _c_using_clist(clist_str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) + -#define using_clist_types(X, Value) \ - typedef Value clist_##X##_value_t; \ +#define _c_using_clist_types(CX, Value) \ + typedef Value CX##_value_t; \ \ - typedef struct clist_##X##_node { \ - struct clist_##X##_node* next; \ - clist_##X##_value_t value; \ - } clist_##X##_node_t; \ + typedef struct CX##_node { \ + struct CX##_node* next; \ + CX##_value_t value; \ + } CX##_node_t; \ \ typedef struct { \ - clist_##X##_node_t* last; \ - } clist_##X; \ + CX##_node_t* last; \ + } CX; \ \ typedef struct { \ - clist_##X##_node_t* const* _last; \ - clist_##X##_value_t* ref; \ + CX##_node_t* const* _last; \ + CX##_value_t* ref; \ int _state; \ - } clist_##X##_iter_t + } CX##_iter_t -using_clist_types(void, int); -STC_API size_t _clist_size(const clist_void* self); -#define _clist_node(X, vp) c_container_of(vp, clist_##X##_node_t, value) +_c_using_clist_types(clist_VOID, int); +STC_API size_t _clist_count(const clist_VOID* self); +#define _clist_node(CX, vp) c_container_of(vp, CX##_node_t, value) -#define using_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ +#define _c_using_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ \ - using_clist_types(X, Value); \ - typedef RawValue clist_##X##_rawvalue_t; \ + _c_using_clist_types(CX, Value); \ + typedef RawValue CX##_rawvalue_t; \ \ - STC_INLINE clist_##X \ - clist_##X##_init(void) {clist_##X x = {NULL}; return x;} \ - STC_INLINE bool \ - clist_##X##_empty(clist_##X ls) {return ls.last == NULL;} \ - STC_INLINE size_t \ - clist_##X##_size(clist_##X ls) {return _clist_size((const clist_void*) &ls);} \ - STC_INLINE Value \ - clist_##X##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ - STC_INLINE clist_##X##_value_t \ - clist_##X##_value_clone(clist_##X##_value_t val) {return valueFromRaw(valueToRaw(&val));} \ + STC_API CX CX##_clone(CX lst); \ + STC_API void CX##_del(CX* self); \ + STC_API void CX##_push_back(CX* self, Value value); \ + STC_API void CX##_push_front(CX* self, Value value); \ + STC_API void CX##_emplace_n(CX *self, const CX##_rawvalue_t arr[], size_t n); \ + STC_API CX CX##_split_after(CX* self, CX##_iter_t pos1, CX##_iter_t pos2); \ + STC_API void CX##_splice_after(CX* self, CX##_iter_t pos, CX* other); \ + STC_DEF void CX##_splice_after_range(CX* self, CX##_iter_t pos, CX* other, CX##_iter_t i1, CX##_iter_t i2); \ + STC_API CX##_iter_t CX##_find_before_in(const CX* self, CX##_iter_t first, CX##_iter_t finish, RawValue val); \ + STC_API CX##_iter_t CX##_find_before(const CX* self, RawValue val); \ + STC_API CX##_iter_t CX##_find(const CX* self, RawValue val); \ + STC_API void CX##_sort(CX* self); \ + STC_API size_t CX##_remove(CX* self, RawValue val); \ + STC_API CX##_iter_t CX##_insert_after(CX* self, CX##_iter_t pos, Value value); \ + STC_API CX##_iter_t CX##_erase_after(CX* self, CX##_iter_t pos); \ + STC_API CX##_iter_t CX##_erase_range_after(CX* self, CX##_iter_t pos, CX##_iter_t finish); \ + STC_API CX##_node_t* CX##_erase_after_(CX* self, CX##_node_t* node); \ \ - STC_API void \ - clist_##X##_del(clist_##X* self); \ - STC_API clist_##X \ - clist_##X##_clone(clist_##X list); \ - STC_INLINE void \ - clist_##X##_clear(clist_##X* self) {clist_##X##_del(self);} \ + STC_INLINE CX CX##_init(void) {CX lst = {NULL}; return lst;} \ + STC_INLINE bool CX##_empty(CX lst) {return lst.last == NULL;} \ + STC_INLINE size_t CX##_count(CX lst) {return _clist_count((const clist_VOID*) &lst);} \ + STC_INLINE Value CX##_value_fromraw(RawValue raw) {return valueFromRaw(raw);} \ + STC_INLINE Value CX##_value_clone(Value val) {return valueFromRaw(valueToRaw(&val));} \ + STC_INLINE void CX##_clear(CX* self) {CX##_del(self);} \ + STC_INLINE void CX##_emplace_back(CX* self, RawValue raw) \ + {CX##_push_back(self, valueFromRaw(raw));} \ + STC_INLINE void CX##_emplace_front(CX* self, RawValue raw) \ + {CX##_push_front(self, valueFromRaw(raw));} \ + STC_INLINE CX##_value_t* \ + CX##_front(const CX* self) {return &self->last->next->value;} \ + STC_INLINE CX##_value_t* \ + CX##_back(const CX* self) {return &self->last->value;} \ + STC_INLINE void CX##_pop_front(CX* self) {CX##_erase_after_(self, self->last);} \ + STC_INLINE void CX##_splice_front(CX* self, CX* other) \ + {CX##_splice_after(self, CX##_before_begin(self), other);} \ + STC_INLINE void CX##_splice_back(CX* self, CX* other) \ + {CX##_splice_after(self, CX##_last(self), other);} \ \ - STC_API void \ - clist_##X##_emplace_n(clist_##X *self, const clist_##X##_rawvalue_t arr[], size_t n); \ - STC_API void \ - clist_##X##_push_back(clist_##X* self, Value value); \ - STC_INLINE void \ - clist_##X##_emplace_back(clist_##X* self, RawValue raw) { \ - clist_##X##_push_back(self, valueFromRaw(raw)); \ - } \ - STC_API void \ - clist_##X##_push_front(clist_##X* self, Value value); \ - STC_INLINE void \ - clist_##X##_emplace_front(clist_##X* self, RawValue raw) { \ - clist_##X##_push_front(self, valueFromRaw(raw)); \ + STC_INLINE CX##_iter_t \ + CX##_emplace_after(CX* self, CX##_iter_t pos, RawValue raw) { \ + return CX##_insert_after(self, pos, valueFromRaw(raw)); \ } \ \ - STC_API clist_##X##_node_t* \ - _clist_##X##_erase_after(clist_##X* self, clist_##X##_node_t* node); \ - STC_INLINE void \ - clist_##X##_pop_front(clist_##X* self) { \ - _clist_##X##_erase_after(self, self->last); \ - } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_before_begin(const clist_##X* self) { \ - clist_##X##_value_t *last = self->last ? &self->last->value : NULL; \ - clist_##X##_iter_t it = {&self->last, last, -1}; return it; \ + STC_INLINE CX##_iter_t \ + CX##_before_begin(const CX* self) { \ + CX##_value_t *last = self->last ? &self->last->value : NULL; \ + CX##_iter_t it = {&self->last, last, -1}; return it; \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_begin(const clist_##X* self) { \ - clist_##X##_value_t* head = self->last ? &self->last->next->value : NULL; \ - clist_##X##_iter_t it = {&self->last, head, 0}; return it; \ +\ + STC_INLINE CX##_iter_t \ + CX##_begin(const CX* self) { \ + CX##_value_t* head = self->last ? &self->last->next->value : NULL; \ + CX##_iter_t it = {&self->last, head, 0}; return it; \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_last(const clist_##X* self) { \ - clist_##X##_value_t *last = self->last ? &self->last->value : NULL; \ - clist_##X##_iter_t it = {&self->last, last, 0}; return it; \ +\ + STC_INLINE CX##_iter_t \ + CX##_last(const CX* self) { \ + CX##_value_t *last = self->last ? &self->last->value : NULL; \ + CX##_iter_t it = {&self->last, last, 0}; return it; \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_end(const clist_##X* self) { \ - clist_##X##_iter_t it = {NULL, NULL}; return it; \ +\ + STC_INLINE CX##_iter_t \ + CX##_end(const CX* self) { \ + CX##_iter_t it = {NULL, NULL}; return it; \ } \ +\ STC_INLINE void \ - clist_##X##_next(clist_##X##_iter_t* it) { \ - clist_##X##_node_t* node = _clist_node(X, it->ref); \ + CX##_next(CX##_iter_t* it) { \ + CX##_node_t* node = _clist_node(CX, it->ref); \ it->ref = ((it->_state += node == *it->_last) == 1) ? NULL : &node->next->value; \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_fwd(clist_##X##_iter_t it, size_t n) { \ - while (n-- && it.ref) clist_##X##_next(&it); return it; \ - } \ - STC_INLINE clist_##X##_value_t* \ - clist_##X##_itval(clist_##X##_iter_t it) {return it.ref;} \ - \ - STC_API clist_##X##_iter_t \ - clist_##X##_insert_after(clist_##X* self, clist_##X##_iter_t pos, Value value); \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_emplace_after(clist_##X* self, clist_##X##_iter_t pos, RawValue raw) { \ - return clist_##X##_insert_after(self, pos, valueFromRaw(raw)); \ - } \ - STC_API clist_##X##_iter_t \ - clist_##X##_erase_after(clist_##X* self, clist_##X##_iter_t pos); \ - STC_API clist_##X##_iter_t \ - clist_##X##_erase_range_after(clist_##X* self, clist_##X##_iter_t pos, clist_##X##_iter_t finish); \ \ - STC_API clist_##X##_iter_t \ - clist_##X##_splice_after(clist_##X* self, clist_##X##_iter_t pos, clist_##X* other); \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_splice_front(clist_##X* self, clist_##X* other) { \ - return clist_##X##_splice_after(self, clist_##X##_before_begin(self), other); \ + STC_INLINE CX##_iter_t \ + CX##_fwd(CX##_iter_t it, size_t n) { \ + while (n-- && it.ref) CX##_next(&it); return it; \ } \ - STC_INLINE clist_##X##_iter_t \ - clist_##X##_splice_back(clist_##X* self, clist_##X* other) { \ - return clist_##X##_splice_after(self, clist_##X##_last(self), other); \ - } \ -\ - STC_API clist_##X##_iter_t \ - clist_##X##_find_before_in(const clist_##X* self, clist_##X##_iter_t first, clist_##X##_iter_t finish, RawValue val); \ - STC_API clist_##X##_iter_t \ - clist_##X##_find_before(const clist_##X* self, RawValue val); \ - STC_API clist_##X##_iter_t \ - clist_##X##_find(const clist_##X* self, RawValue val); \ - STC_API size_t \ - clist_##X##_remove(clist_##X* self, RawValue val); \ - STC_API void \ - clist_##X##_sort(clist_##X* self); \ -\ - STC_INLINE Value* \ - clist_##X##_front(const clist_##X* self) {return &self->last->next->value;} \ - STC_INLINE Value* \ - clist_##X##_back(const clist_##X* self) {return &self->last->value;} \ -\ - _c_implement_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ - typedef clist_##X clist_##X##_t + \ + _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ + struct stc_trailing_semicolon /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define _c_implement_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ +#define _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \ \ - STC_DEF clist_##X \ - clist_##X##_clone(clist_##X list) { \ - clist_##X out = clist_##X##_init(); \ - c_foreach_3 (i, clist_##X, list) \ - clist_##X##_emplace_back(&out, valueToRaw(i.ref)); \ + STC_DEF CX \ + CX##_clone(CX lst) { \ + CX out = CX##_init(); \ + c_foreach_3 (i, CX, lst) \ + CX##_emplace_back(&out, valueToRaw(i.ref)); \ return out; \ } \ +\ STC_DEF void \ - clist_##X##_del(clist_##X* self) { \ - while (self->last) _clist_##X##_erase_after(self, self->last); \ + CX##_del(CX* self) { \ + while (self->last) CX##_erase_after_(self, self->last); \ } \ \ STC_DEF void \ - clist_##X##_push_back(clist_##X* self, Value value) { \ - _c_clist_insert_after(self, X, self->last, value); \ + CX##_push_back(CX* self, Value value) { \ + _c_clist_insert_after(self, CX, self->last, value); \ self->last = entry; \ } \ STC_DEF void \ - clist_##X##_push_front(clist_##X* self, Value value) { \ - _c_clist_insert_after(self, X, self->last, value); \ + CX##_push_front(CX* self, Value value) { \ + _c_clist_insert_after(self, CX, self->last, value); \ if (!self->last) self->last = entry; \ } \ +\ STC_DEF void \ - clist_##X##_emplace_n(clist_##X *self, const clist_##X##_rawvalue_t arr[], size_t n) { \ - for (size_t i=0; ilast && pos._state == 0) self->last = entry; \ pos.ref = &entry->value, pos._state = 0; return pos; \ } \ - STC_DEF 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.ref)); \ - clist_##X##_next(&pos); return pos; \ +\ + STC_DEF CX##_iter_t \ + CX##_erase_after(CX* self, CX##_iter_t pos) { \ + CX##_erase_after_(self, _clist_node(CX, pos.ref)); \ + CX##_next(&pos); return pos; \ } \ - STC_DEF 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.ref), *done = finish.ref ? _clist_node(X, finish.ref) : NULL; \ +\ + STC_DEF CX##_iter_t \ + CX##_erase_range_after(CX* self, CX##_iter_t first, CX##_iter_t finish) { \ + CX##_node_t* node = _clist_node(CX, first.ref), *done = finish.ref ? _clist_node(CX, finish.ref) : NULL; \ while (node && node->next != done) \ - node = _clist_##X##_erase_after(self, node); \ - clist_##X##_next(&first); return first; \ + node = CX##_erase_after_(self, node); \ + CX##_next(&first); return first; \ } \ \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_find_before_in(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.ref != finish.ref; clist_##X##_next(&i)) { \ + STC_DEF CX##_iter_t \ + CX##_find_before_in(const CX* self, CX##_iter_t first, CX##_iter_t finish, RawValue val) { \ + CX##_iter_t i = first; \ + for (CX##_next(&i); i.ref != finish.ref; CX##_next(&i)) { \ RawValue r = valueToRaw(i.ref); \ if (valueCompareRaw(&r, &val) == 0) return first; \ first = i; \ } \ - return clist_##X##_end(self); \ + return CX##_end(self); \ } \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_find_before(const clist_##X* self, RawValue val) { \ - clist_##X##_iter_t it = clist_##X##_find_before_in(self, clist_##X##_before_begin(self), clist_##X##_end(self), val); \ +\ + STC_DEF CX##_iter_t \ + CX##_find_before(const CX* self, RawValue val) { \ + CX##_iter_t it = CX##_find_before_in(self, CX##_before_begin(self), CX##_end(self), val); \ return it; \ } \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_find(const clist_##X* self, RawValue val) { \ - clist_##X##_iter_t it = clist_##X##_find_before_in(self, clist_##X##_before_begin(self), clist_##X##_end(self), val); \ - if (it.ref != clist_##X##_end(self).ref) clist_##X##_next(&it); \ +\ + STC_DEF CX##_iter_t \ + CX##_find(const CX* self, RawValue val) { \ + CX##_iter_t it = CX##_find_before_in(self, CX##_before_begin(self), CX##_end(self), val); \ + if (it.ref != CX##_end(self).ref) CX##_next(&it); \ return it; \ } \ \ - STC_DEF 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; \ + STC_DEF CX##_node_t* \ + CX##_erase_after_(CX* self, CX##_node_t* node) { \ + CX##_node_t* del = node->next, *next = del->next; \ node->next = next; \ if (del == next) self->last = node = NULL; \ else if (self->last == del) self->last = node, node = NULL; \ @@ -291,79 +271,84 @@ STC_API size_t _clist_size(const clist_void* self); } \ \ STC_DEF size_t \ - clist_##X##_remove(clist_##X* self, RawValue val) { \ + CX##_remove(CX* self, RawValue val) { \ size_t n = 0; \ - clist_##X##_node_t* prev = self->last, *node; \ + CX##_node_t* prev = self->last, *node; \ while (prev) { \ node = prev->next; \ RawValue r = valueToRaw(&node->value); \ if (valueCompareRaw(&r, &val) == 0) \ - prev = _clist_##X##_erase_after(self, prev), ++n; \ + prev = CX##_erase_after_(self, prev), ++n; \ else \ prev = (node == self->last ? NULL : node); \ } \ return n; \ } \ \ - STC_DEF clist_##X##_iter_t \ - clist_##X##_splice_after(clist_##X* self, clist_##X##_iter_t pos, clist_##X* other) { \ - clist_##X##_iter_t it = clist_##X##_last(other); \ + STC_DEF CX \ + CX##_split_after(CX* self, CX##_iter_t pos1, CX##_iter_t pos2) { \ + CX##_node_t *node1 = _clist_node(CX, pos1.ref), *next1 = node1->next, \ + *node2 = _clist_node(CX, pos2.ref); \ + node1->next = node2->next, node2->next = next1; \ + if (self->last == node2) self->last = node1; \ + CX lst = {node2}; return lst; \ + } \ +\ + STC_DEF void \ + CX##_splice_after(CX* self, CX##_iter_t pos, CX* other) { \ if (!pos.ref) \ self->last = other->last; \ else if (other->last) { \ - clist_##X##_node_t *node = _clist_node(X, pos.ref), *next = node->next; \ + CX##_node_t *node = _clist_node(CX, pos.ref), *next = node->next; \ node->next = other->last->next; \ other->last->next = next; \ if (node == self->last && pos._state == 0) self->last = other->last; \ } \ other->last = NULL; \ - it._last = &self->last; return it; \ } \ \ - STC_DEF clist_##X \ - clist_##X##_splice_out(clist_##X* self, clist_##X##_iter_t pos1, clist_##X##_iter_t pos2) { \ - clist_##X##_node_t *node1 = _clist_node(X, pos1.ref), *next1 = node1->next, \ - *node2 = _clist_node(X, pos2.ref); \ - node1->next = node2->next, node2->next = next1; \ - if (self->last == node2) self->last = node1; \ - clist_##X list = {node2}; return list; \ + STC_DEF void \ + CX##_splice_after_range(CX* self, CX##_iter_t pos, CX* other, CX##_iter_t pos1, CX##_iter_t pos2) { \ + CX tmp = CX##_split_after(other, pos1, pos2); \ + CX##_splice_after(self, pos, &tmp); \ } \ \ - 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); \ + STC_DEF int \ + CX##_sort_cmp_(const void* x, const void* y) { \ + RawValue a = valueToRaw(&((CX##_node_t *) x)->value); \ + RawValue b = valueToRaw(&((CX##_node_t *) y)->value); \ return valueCompareRaw(&a, &b); \ } \ +\ STC_DEF void \ - clist_##X##_sort(clist_##X* self) { \ + CX##_sort(CX* self) { \ if (self->last) \ - self->last = (clist_##X##_node_t *) _clist_mergesort((clist_void_node_t *) self->last->next, clist_##X##_sort_compare); \ + self->last = (CX##_node_t *) _clist_mergesort((clist_VOID_node_t *) self->last->next, CX##_sort_cmp_); \ } -#define _c_clist_insert_after(self, X, node, val) \ - clist_##X##_node_t *entry = c_new_1 (clist_##X##_node_t); \ +#define _c_clist_insert_after(self, CX, node, val) \ + CX##_node_t *entry = c_new_1 (CX##_node_t); \ if (node) entry->next = node->next, node->next = entry; \ else entry->next = entry; \ entry->value = val /* +: set self->last based on node */ STC_DEF size_t -_clist_size(const clist_void* self) { - const clist_void_node_t *i = self->last; - if (!i) return 0; +_clist_count(const clist_VOID* self) { + const clist_VOID_node_t *nd = self->last; + if (!nd) return 0; size_t n = 1; - while ((i = i->next) != self->last) ++n; + while ((nd = nd->next) != self->last) ++n; return n; } /* Singly linked list Mergesort implementation by Simon Tatham. O(n*log n). * https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html */ -STC_DEF 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; +STC_DEF 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; while (1) { @@ -410,7 +395,7 @@ _clist_mergesort(clist_void_node_t *list, int (*cmp)(const void*, const void*)) } #else -#define _c_implement_clist_7(X, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) +#define _c_implement_clist(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) #endif #endif diff --git a/stc/cstr.h b/stc/cstr.h index ed069d4a..44d79c72 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -30,48 +30,100 @@ #include /* vsnprintf */ #include -typedef struct cstr { char* str; } cstr_t, cstr; -typedef struct { char *ref; } cstr_iter_t; -typedef char cstr_value_t; -#define cstr_npos ((size_t) (-1)) - -STC_API cstr_t cstr_from_n(const char* str, size_t n); -STC_API cstr_t cstr_from_fmt(const char* fmt, ...); -STC_API void cstr_fmt(cstr_t* self, const char* fmt, ...); -STC_API size_t cstr_reserve(cstr_t* self, size_t cap); -STC_API void cstr_resize(cstr_t* self, size_t len, char fill); -STC_API cstr_t* cstr_assign_n(cstr_t* self, const char* str, size_t n); -STC_API cstr_t* cstr_append_n(cstr_t* self, const char* str, size_t n); -STC_API void cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n); -STC_API void cstr_erase_n(cstr_t* self, size_t pos, size_t n); -STC_API bool cstr_getdelim(cstr_t *self, int delim, FILE *stream); -STC_API size_t cstr_find(cstr_t s, const char* needle); -STC_API size_t cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t n); -STC_API size_t cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t n); - -STC_API int c_strncasecmp(const char* s1, const char* s2, size_t n); -STC_API char* c_strnstr(const char* s, const char* needle, size_t nmax); -STC_API char* c_strncasestr(const char* s, const char* needle, size_t nmax); - -struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; }; +typedef struct { char* str; } cstr, cstr_t; +typedef struct { char *ref; } cstr_iter_t; +typedef char cstr_value_t; +#define cstr_npos ((size_t) (-1)) + +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_LIBRARY_ONLY( extern const cstr_t cstr_inits; ) +STC_STATIC_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}}; + static const cstr_t cstr_inits = {_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) /* optimal string capacity: 7, 23, 39, ... */ #define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(struct cstr_rep, str) - 1) -STC_LIBRARY_ONLY( extern const cstr_t cstr_inits; ) -STC_STATIC_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}}; - static const cstr_t cstr_inits = {_cstr_nullrep.str}; ) - -STC_INLINE cstr_t -cstr_init() { return cstr_inits; } - -STC_INLINE void -cstr_del(cstr_t* self) { - if (_cstr_rep(self)->cap) - c_free(_cstr_rep(self)); -} +STC_API cstr_t cstr_from_n(const char* str, size_t n); +STC_API cstr_t cstr_from_fmt(const char* fmt, ...); +STC_API void cstr_fmt(cstr_t* self, const char* fmt, ...); +STC_API size_t cstr_reserve(cstr_t* self, size_t cap); +STC_API void cstr_resize(cstr_t* self, size_t len, char fill); +STC_API cstr_t* cstr_assign_n(cstr_t* self, const char* str, size_t n); +STC_API cstr_t* cstr_append_n(cstr_t* self, const char* str, size_t n); +STC_API void cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n); +STC_API void cstr_erase_n(cstr_t* self, size_t pos, size_t n); +STC_API size_t cstr_find(cstr_t s, const char* needle); +STC_API size_t cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t n); +STC_API size_t cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t n); +STC_API bool cstr_getdelim(cstr_t *self, int delim, FILE *stream); +STC_API int c_strncasecmp(const char* s1, const char* s2, size_t n); +STC_API char* c_strnstr(const char* s, const char* needle, size_t nmax); +STC_API char* c_strncasestr(const char* s, const char* needle, size_t nmax); + +STC_INLINE cstr_t cstr_init() { return cstr_inits; } +STC_INLINE size_t cstr_size(cstr_t s) { return _cstr_rep(&s)->size; } +STC_INLINE size_t cstr_capacity(cstr_t s) { return _cstr_rep(&s)->cap; } +STC_INLINE size_t cstr_empty(cstr_t s) { return _cstr_rep(&s)->size == 0; } +STC_INLINE size_t cstr_length(cstr_t s) { return _cstr_rep(&s)->size; } +STC_INLINE void cstr_del(cstr_t* self) + { if (_cstr_rep(self)->cap) c_free(_cstr_rep(self)); } +STC_INLINE cstr_t cstr_from(const char* str) + { return cstr_from_n(str, strlen(str)); } +STC_INLINE cstr_t cstr_clone(cstr_t s) + { return cstr_from_n(s.str, _cstr_rep(&s)->size); } +STC_INLINE void cstr_clear(cstr_t* self) + { self->str[_cstr_rep(self)->size = 0] = '\0'; } +STC_INLINE cstr_t* cstr_assign(cstr_t* self, const char* str) + { return cstr_assign_n(self, str, strlen(str)); } +STC_INLINE cstr_t* cstr_assign_s(cstr_t* self, cstr s) + { return cstr_assign_n(self, s.str, _cstr_rep(&s)->size); } +STC_INLINE cstr_t* cstr_append(cstr_t* self, const char* str) + { return cstr_append_n(self, str, strlen(str)); } +STC_INLINE cstr_t* cstr_append_s(cstr_t* self, cstr s) + { return cstr_append_n(self, s.str, _cstr_rep(&s)->size); } +STC_INLINE void cstr_push_back(cstr_t* self, char value) + { cstr_append_n(self, &value, 1); } +STC_INLINE void cstr_pop_back(cstr_t* self) + { self->str[ --_cstr_rep(self)->size ] = '\0'; } +STC_INLINE void cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n) + { cstr_replace_n(self, pos, 0, str, n); } +STC_INLINE void cstr_insert(cstr_t* self, size_t pos, const char* str) + { cstr_replace_n(self, pos, 0, str, strlen(str)); } +STC_INLINE void cstr_insert_s(cstr_t* self, size_t pos, cstr s) + { cstr_replace_n(self, pos, 0, s.str, _cstr_rep(&s)->size); } +STC_INLINE void cstr_replace(cstr_t* self, size_t pos, size_t len, const char* str) + { cstr_replace_n(self, pos, len, str, strlen(str)); } +STC_INLINE void cstr_replace_s(cstr_t* self, size_t pos, size_t len, cstr s) + { cstr_replace_n(self, pos, len, s.str, _cstr_rep(&s)->size); } +STC_INLINE void cstr_erase(cstr_t* self, size_t pos) + { cstr_erase_n(self, pos, 1); } +STC_INLINE char* cstr_front(cstr_t* self) { return self->str; } +STC_INLINE char* cstr_back(cstr_t* self) + { return self->str + _cstr_rep(self)->size - 1; } +STC_INLINE cstr_iter_t cstr_begin(cstr_t* self) + { cstr_iter_t it = {self->str}; return it; } +STC_INLINE cstr_iter_t cstr_end(cstr_t* self) + { cstr_iter_t it = {self->str + _cstr_rep(self)->size}; return it; } +STC_INLINE void cstr_next(cstr_iter_t* it) {++it->ref; } +STC_INLINE bool cstr_equals(cstr_t s1, const char* str) + { return strcmp(s1.str, str) == 0; } +STC_INLINE bool cstr_equals_s(cstr_t s1, cstr_t s2) + { return strcmp(s1.str, s2.str) == 0; } +STC_INLINE bool cstr_iequals(cstr_t s1, const char* str) + { return c_strncasecmp(s1.str, str, cstr_npos) == 0; } +STC_INLINE bool cstr_contains(cstr_t s, const char* needle) + { return strstr(s.str, needle) != NULL; } +STC_INLINE bool cstr_icontains(cstr_t s, const char* needle) + { return c_strncasestr(s.str, needle, cstr_npos) != NULL; } +STC_INLINE bool cstr_begins_with(cstr_t s, const char* needle) + { return strncmp(s.str, needle, strlen(needle)) == 0; } +STC_INLINE bool cstr_ibegins_with(cstr_t s, const char* needle) + { return c_strncasecmp(s.str, needle, strlen(needle)) == 0; } +STC_INLINE bool cstr_getline(cstr_t *self, FILE *stream) + { return cstr_getdelim(self, '\n', stream); } STC_INLINE cstr_t cstr_with_capacity(size_t cap) { @@ -79,46 +131,13 @@ cstr_with_capacity(size_t cap) { cstr_reserve(&s, cap); return s; } + STC_INLINE cstr_t cstr_with_size(size_t len, char fill) { cstr_t s = cstr_inits; cstr_resize(&s, len, fill); return s; } -STC_INLINE cstr_t -cstr_from(const char* str) { - return cstr_from_n(str, strlen(str)); -} -STC_INLINE cstr_t -cstr_clone(cstr_t s) { - return cstr_from_n(s.str, _cstr_rep(&s)->size); -} -STC_INLINE void -cstr_clear(cstr_t* self) { - self->str[_cstr_rep(self)->size = 0] = '\0'; -} - -STC_INLINE char* -cstr_front(cstr_t* self) {return self->str;} -STC_INLINE char* -cstr_back(cstr_t* self) {return self->str + _cstr_rep(self)->size - 1;} - -STC_INLINE cstr_iter_t -cstr_begin(cstr_t* self) {cstr_iter_t it = {self->str}; return it;} -STC_INLINE cstr_iter_t -cstr_end(cstr_t* self) { - cstr_iter_t it = {self->str + _cstr_rep(self)->size}; return it; -} -STC_INLINE void cstr_next(cstr_iter_t* it) { ++it->ref; } - -STC_INLINE cstr_t* -cstr_assign(cstr_t* self, const char* str) { - return cstr_assign_n(self, str, strlen(str)); -} -STC_INLINE cstr_t* -cstr_assign_s(cstr_t* self, cstr s) { - return cstr_assign_n(self, s.str, _cstr_rep(&s)->size); -} STC_INLINE cstr_t* cstr_take(cstr_t* self, cstr_t s) { @@ -127,6 +146,7 @@ cstr_take(cstr_t* self, cstr_t s) { self->str = s.str; return self; } + STC_INLINE cstr_t cstr_move(cstr_t* self) { cstr_t tmp = *self; @@ -134,101 +154,12 @@ cstr_move(cstr_t* self) { return tmp; } -STC_INLINE cstr_t* -cstr_append(cstr_t* self, const char* str) { - return cstr_append_n(self, str, strlen(str)); -} -STC_INLINE cstr_t* -cstr_append_s(cstr_t* self, cstr s) { - return cstr_append_n(self, s.str, _cstr_rep(&s)->size); -} - -STC_INLINE void -cstr_push_back(cstr_t* self, char value) { - cstr_append_n(self, &value, 1); -} -STC_INLINE void -cstr_pop_back(cstr_t* self) { - self->str[ --_cstr_rep(self)->size ] = '\0'; -} - -STC_INLINE void -cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n) { - cstr_replace_n(self, pos, 0, str, n); -} -STC_INLINE void -cstr_insert(cstr_t* self, size_t pos, const char* str) { - cstr_replace_n(self, pos, 0, str, strlen(str)); -} -STC_INLINE void -cstr_insert_s(cstr_t* self, size_t pos, cstr s) { - cstr_replace_n(self, pos, 0, s.str, _cstr_rep(&s)->size); -} - -STC_INLINE void -cstr_replace(cstr_t* self, size_t pos, size_t len, const char* str) { - cstr_replace_n(self, pos, len, str, strlen(str)); -} -STC_INLINE void -cstr_replace_s(cstr_t* self, size_t pos, size_t len, cstr s) { - cstr_replace_n(self, pos, len, s.str, _cstr_rep(&s)->size); -} - -STC_INLINE void -cstr_erase(cstr_t* self, size_t pos) {cstr_erase_n(self, pos, 1);} - -STC_INLINE bool -cstr_getline(cstr_t *self, FILE *stream) { - return cstr_getdelim(self, '\n', stream); -} - -/* readonly */ - -STC_INLINE size_t -cstr_size(cstr_t s) {return _cstr_rep(&s)->size;} -STC_INLINE size_t -cstr_capacity(cstr_t s) {return _cstr_rep(&s)->cap;} -STC_INLINE size_t -cstr_empty(cstr_t s) {return _cstr_rep(&s)->size == 0;} -STC_INLINE size_t -cstr_length(cstr_t s) { return _cstr_rep(&s)->size; } - -STC_INLINE bool -cstr_equals(cstr_t s1, const char* str) { - return strcmp(s1.str, str) == 0; -} -STC_INLINE bool -cstr_iequals(cstr_t s1, const char* str) { - return c_strncasecmp(s1.str, str, cstr_npos) == 0; -} -STC_INLINE bool -cstr_equals_s(cstr_t s1, cstr_t s2) { - return strcmp(s1.str, s2.str) == 0; -} - -STC_INLINE bool -cstr_contains(cstr_t s, const char* needle) { - return strstr(s.str, needle) != NULL; -} -STC_INLINE bool -cstr_icontains(cstr_t s, const char* needle) { - return c_strncasestr(s.str, needle, cstr_npos) != NULL; -} - -STC_INLINE bool -cstr_begins_with(cstr_t s, const char* needle) { - return strncmp(s.str, needle, strlen(needle)) == 0; -} -STC_INLINE bool -cstr_ibegins_with(cstr_t s, const char* needle) { - return c_strncasecmp(s.str, needle, strlen(needle)) == 0; -} - STC_INLINE bool cstr_ends_with(cstr_t s, const char* needle) { size_t n = strlen(needle), sz = _cstr_rep(&s)->size; return n <= sz ? memcmp(s.str + sz - n, needle, n) == 0 : false; } + STC_INLINE bool cstr_iends_with(cstr_t s, const char* needle) { size_t n = strlen(needle), sz = _cstr_rep(&s)->size; @@ -292,6 +223,7 @@ cstr_from_n(const char* str, size_t n) { # pragma warning(push) # pragma warning(disable: 4996) #endif +/// STC_DEF void cstr_vfmt(cstr_t* self, const char* fmt, va_list args) { va_list args2; @@ -302,6 +234,12 @@ cstr_vfmt(cstr_t* self, const char* fmt, va_list args) { _cstr_rep(self)->size = len; va_end(args2); } +/// +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(_MSC_VER) +# pragma warning(pop) +#endif STC_DEF void cstr_fmt(cstr_t* self, const char* fmt, ...) { @@ -318,11 +256,6 @@ cstr_from_fmt(const char* fmt, ...) { va_end(args); return ret; } -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif STC_DEF cstr_t* cstr_assign_n(cstr_t* self, const char* str, size_t n) { @@ -400,12 +333,14 @@ cstr_find(cstr_t s, const char* needle) { char* res = strstr(s.str, needle); return res ? res - s.str : cstr_npos; } + STC_DEF size_t cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t n) { if (pos > _cstr_rep(&s)->size) return cstr_npos; char* res = c_strnstr(s.str + pos, needle, n); return res ? res - s.str : cstr_npos; } + STC_DEF size_t cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t n) { if (pos > _cstr_rep(&s)->size) return cstr_npos; @@ -413,7 +348,6 @@ cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t n) { return res ? res - s.str : cstr_npos; } - STC_DEF int c_strncasecmp(const char* s1, const char* s2, size_t n) { int ret = 0; -- cgit v1.2.3