From b21ca36c05906ca97bb9402531640ea6d6f7a40f Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 10 Sep 2020 09:41:16 +0200 Subject: Updated and corrected cvec_insert and cvec_erase functions. --- stc/carray.h | 221 ++++++++++++++++++++++++++++++----------------------------- stc/cdefs.h | 4 ++ stc/cvec.h | 115 +++++++++++++++++++++---------- 3 files changed, 197 insertions(+), 143 deletions(-) diff --git a/stc/carray.h b/stc/carray.h index 28993e4a..ca18b8d9 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -67,28 +67,30 @@ STC_INLINE size_t _carray3_size(const size_t* zdim) { return zdim[0] * zdim[-1]; } + #define declare_carray_common(D, X, Value, valueDestroy) \ - typedef struct { Value *item; } carray##D##X##_iter_t; \ - \ - STC_INLINE carray##D##X##_iter_t \ - carray##D##X##_begin(carray##D##X* a) { \ - carray##D##X##_iter_t it = {a->data}; return it; \ - } \ - STC_INLINE carray##D##X##_iter_t \ - carray##D##X##_end(carray##D##X* a) { \ - carray##D##X##_iter_t it = {a->data + carray##D##_size(*a)}; return it; \ +\ +typedef struct { Value *item; } carray##D##X##_iter_t; \ +\ +STC_INLINE carray##D##X##_iter_t \ +carray##D##X##_begin(carray##D##X* a) { \ + carray##D##X##_iter_t it = {a->data}; return it; \ +} \ +STC_INLINE carray##D##X##_iter_t \ +carray##D##X##_end(carray##D##X* a) { \ + carray##D##X##_iter_t it = {a->data + carray##D##_size(*a)}; return it; \ +} \ +STC_INLINE void \ +carray##D##X##_next(carray##D##X##_iter_t* it) {++it->item;} \ +\ +STC_INLINE void \ +carray##D##X##_destroy(carray##D##X* self) { \ + if (self->_xdim & _carray_OWN) { \ + c_foreach_3 (i, carray##D##X, *self) \ + valueDestroy(i.item); \ + free(self->data); \ } \ - STC_INLINE void \ - carray##D##X##_next(carray##D##X##_iter_t* it) {++it->item;} \ - \ - STC_INLINE void \ - carray##D##X##_destroy(carray##D##X* self) { \ - if (self->_xdim & _carray_OWN) { \ - c_foreach_3 (i, carray##D##X, *self) \ - valueDestroy(i.item); \ - free(self->data); \ - } \ - } +} #define declare_carray(...) c_MACRO_OVERLOAD(declare_carray, __VA_ARGS__) #define declare_carray_2(X, Value) \ @@ -96,93 +98,96 @@ STC_INLINE size_t _carray3_size(const size_t* zdim) { #define declare_carray_3(X, Value, valueDestroy) \ - typedef struct carray1##X { \ - Value *data; \ - size_t _xdim; \ - } carray1##X; \ - \ - typedef struct carray2##X { \ - Value *data; \ - size_t _xdim, _yxdim; \ - } carray2##X; \ - \ - typedef struct carray3##X { \ - Value *data; \ - size_t _xdim, _yxdim, _zdim; \ - } carray3##X; \ - \ - declare_carray_common(1, X, Value, valueDestroy) \ - declare_carray_common(2, X, Value, valueDestroy) \ - declare_carray_common(3, X, Value, valueDestroy) \ - \ - STC_INLINE carray1##X \ - carray1##X##_make(size_t xdim, Value val) { \ - Value* m = c_new_n(Value, xdim); \ - for (size_t i=0; idata + x; } \ - \ - STC_INLINE carray1##X \ - carray2##X##_at1(carray2##X *a, size_t y) { \ - carray1##X sub = {a->data + y*carray2_xdim(*a), carray2_xdim(*a)}; \ - return sub; \ - } \ - STC_INLINE Value* \ - carray2##X##_at(carray2##X *a, size_t y, size_t x) { \ - return a->data + y*carray2_xdim(*a) + x; \ - } \ - \ - STC_INLINE carray2##X \ - carray3##X##_at1(carray3##X *a, size_t z) { \ - carray2##X sub = {a->data + z*a->_yxdim, carray3_xdim(*a), a->_yxdim}; \ - return sub; \ - } \ - STC_INLINE carray1##X \ - carray3##X##_at2(carray3##X *a, size_t z, size_t y) { \ - carray1##X sub = {a->data + z*a->_yxdim + y*carray3_xdim(*a), carray3_xdim(*a)}; \ - return sub; \ - } \ - STC_INLINE Value* \ - carray3##X##_at(carray3##X *a, size_t z, size_t y, size_t x) { \ - return a->data + z*a->_yxdim + y*carray3_xdim(*a) + x; \ - } \ - typedef Value carray1##X##_value_t; \ - typedef carray1##X##_value_t carray2##X##_value_t, carray3##X##_value_t +\ +typedef Value carray1##X##_value_t; \ +typedef carray1##X##_value_t carray2##X##_value_t, carray3##X##_value_t; \ +\ +typedef struct carray1##X { \ + Value *data; \ + size_t _xdim; \ +} carray1##X; \ +\ +typedef struct carray2##X { \ + Value *data; \ + size_t _xdim, _yxdim; \ +} carray2##X; \ +\ +typedef struct carray3##X { \ + Value *data; \ + size_t _xdim, _yxdim, _zdim; \ +} carray3##X; \ +\ +declare_carray_common(1, X, Value, valueDestroy) \ +declare_carray_common(2, X, Value, valueDestroy) \ +declare_carray_common(3, X, Value, valueDestroy) \ +\ +STC_INLINE carray1##X \ +carray1##X##_make(size_t xdim, Value val) { \ + Value* m = c_new_n(Value, xdim); \ + for (size_t i=0; idata + x; } \ +\ +STC_INLINE carray1##X \ +carray2##X##_at1(carray2##X *a, size_t y) { \ + carray1##X sub = {a->data + y*carray2_xdim(*a), carray2_xdim(*a)}; \ + return sub; \ +} \ +STC_INLINE Value* \ +carray2##X##_at(carray2##X *a, size_t y, size_t x) { \ + return a->data + y*carray2_xdim(*a) + x; \ +} \ +\ +STC_INLINE carray2##X \ +carray3##X##_at1(carray3##X *a, size_t z) { \ + carray2##X sub = {a->data + z*a->_yxdim, carray3_xdim(*a), a->_yxdim}; \ + return sub; \ +} \ +STC_INLINE carray1##X \ +carray3##X##_at2(carray3##X *a, size_t z, size_t y) { \ + carray1##X sub = {a->data + z*a->_yxdim + y*carray3_xdim(*a), carray3_xdim(*a)}; \ + return sub; \ +} \ +STC_INLINE Value* \ +carray3##X##_at(carray3##X *a, size_t z, size_t y, size_t x) { \ + return a->data + z*a->_yxdim + y*carray3_xdim(*a) + x; \ +} \ +typedef int carray1##X##_dud #endif diff --git a/stc/cdefs.h b/stc/cdefs.h index b5ae4a45..33178872 100644 --- a/stc/cdefs.h +++ b/stc/cdefs.h @@ -90,6 +90,10 @@ ctype##_push_n(&cnt, __arr, sizeof(__arr)/sizeof(__arr[0])); \ } +#define c_make(arr, init, n) do { \ + for (size_t __i = 0; __i < n; ++__i) (arr)[__i] = init; \ +} while (0) + #define c_destroy(ctype, ...) do { \ struct ctype* __arr[] = {__VA_ARGS__}; \ for (size_t i=0; idata + ipos}, first = {pfirst}, last = {plast}; \ + return cvec_##X##_insert_range(self, pos, first, last); \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_insert(cvec_##X* self, cvec_##X##_iter_t pos, Value value) { \ + cvec_##X##_iter_t first = {&value}, last = {&value + 1}; \ + return cvec_##X##_insert_range(self, pos, first, last); \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_insert_ipos(cvec_##X* self, size_t ipos, Value value) { \ + cvec_##X##_iter_t pos = {self->data + ipos}, first = {&value}, last = {&value + 1}; \ + return cvec_##X##_insert_range(self, pos, first, last); \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_emplace(cvec_##X* self, cvec_##X##_iter_t pos, RawValue rawValue) { \ cvec_##X##_insert(self, pos, valueFromRaw(rawValue)); \ } \ -STC_API void \ -cvec_##X##_erase(cvec_##X* self, size_t pos, size_t size); \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_emplace_ipos(cvec_##X* self, size_t ipos, RawValue rawValue) { \ + cvec_##X##_insert_ipos(self, ipos, valueFromRaw(rawValue)); \ +} \ +\ +STC_API cvec_##X##_iter_t \ +cvec_##X##_erase_range(cvec_##X* self, cvec_##X##_iter_t first, cvec_##X##_iter_t last); \ +\ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_erase(cvec_##X* self, cvec_##X##_iter_t pos) { \ + cvec_##X##_iter_t next = {pos.item + 1}; \ + return cvec_##X##_erase_range(self, pos, next); \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_erase_ipos(cvec_##X* self, size_t ipos) { \ + cvec_##X##_iter_t first = {self->data + ipos}, last = {first.item + 1}; \ + return cvec_##X##_erase_range(self, first, last); \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_erase_irange(cvec_##X* self, size_t ifirst, size_t ilast) { \ + cvec_##X##_iter_t first = {self->data + ifirst}, last = {self->data + ilast}; \ + return cvec_##X##_erase_range(self, first, last); \ +} \ +\ STC_API void \ cvec_##X##_sort(cvec_##X* self); \ STC_API void \ @@ -97,7 +136,7 @@ STC_API cvec_##X##_iter_t \ cvec_##X##_find_in_range(const cvec_##X* self, cvec_##X##_iter_t first, cvec_##X##_iter_t last, RawValue rawValue); \ STC_API int \ cvec_##X##_value_compare(const Value* x, const Value* y); \ - \ +\ STC_INLINE cvec_##X \ cvec_##X##_with_size(size_t size, Value null_val) { \ cvec_##X x = cvec_ini; \ @@ -132,7 +171,7 @@ STC_INLINE void \ cvec_##X##_sort_with(cvec_##X* self, int(*cmp)(const Value*, const Value*)) { \ qsort(self->data, cvec_size(*self), sizeof(Value), (_cvec_cmp) cmp); \ } \ - \ +\ STC_INLINE cvec_##X##_iter_t \ cvec_##X##_begin(const cvec_##X* self) { \ cvec_##X##_iter_t it = {self->data}; return it; \ @@ -145,21 +184,21 @@ STC_INLINE void \ cvec_##X##_next(cvec_##X##_iter_t* it) {++it->item;} \ STC_INLINE cvec_##X##_value_t* \ cvec_##X##_itval(cvec_##X##_iter_t it) {return it.item;} \ - \ +\ implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) #define implement_cvec_7(X, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ - \ +\ STC_API 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 \ cvec_##X##_clear(cvec_##X* self) { \ Value* p = self->data; if (p) { \ @@ -172,7 +211,7 @@ cvec_##X##_destroy(cvec_##X* self) { \ cvec_##X##_clear(self); \ if (self->data) free(_cvec_alloced(self->data)); \ } \ - \ +\ STC_API void \ cvec_##X##_reserve(cvec_##X* self, size_t cap) { \ size_t len = cvec_size(*self); \ @@ -189,7 +228,7 @@ cvec_##X##_resize(cvec_##X* self, size_t size, Value null_val) { \ for (size_t i=cvec_size(*self); idata[i] = null_val; \ if (self->data) _cvec_size(self) = size; \ } \ - \ +\ STC_API void \ cvec_##X##_push_back(cvec_##X* self, Value value) { \ size_t len = cvec_size(*self); \ @@ -197,28 +236,34 @@ cvec_##X##_push_back(cvec_##X* self, Value value) { \ cvec_##X##_reserve(self, 4 + len * 3 / 2); \ self->data[_cvec_size(self)++] = value; \ } \ - \ -STC_API void \ -cvec_##X##_insert(cvec_##X* self, size_t pos, Value value) { \ - size_t len = cvec_size(*self); \ - if (len == cvec_capacity(*self)) \ - cvec_##X##_reserve(self, 4 + len * 3 / 2); \ - memmove(&self->data[pos + 1], &self->data[pos], (len - pos) * sizeof(Value)); \ - self->data[pos] = value; \ - ++_cvec_size(self); \ +\ +STC_API 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 last) { \ + enum {max_buf = c_max_alloca / sizeof(Value) + 1}; Value buf[max_buf]; \ + size_t len = last.item - first.item, ipos = pos.item - self->data, size = cvec_size(*self); \ + Value* xbuf = (Value *) memcpy(len > max_buf ? c_new_n(Value, len) : buf, first.item, len); \ + if (size + len > cvec_capacity(*self)) \ + cvec_##X##_reserve(self, 4 + (size + len) * 3 / 2); \ + pos.item = self->data + ipos; \ + memmove(pos.item + len, pos.item, (size - ipos) * sizeof(Value)); \ + memcpy(pos.item, xbuf, len * sizeof(Value)); \ + _cvec_size(self) += len; \ + if (len > max_buf) free(xbuf); \ + return pos; \ } \ - \ -STC_API void \ -cvec_##X##_erase(cvec_##X* self, size_t pos, size_t size) { \ - size_t len = cvec_size(*self); \ - if (len) { \ - Value* p = &self->data[pos], *start = p, *end = p + size; \ - while (p != end) valueDestroy(p++); \ - memmove(start, end, (len - pos - size) * sizeof(Value)); \ - _cvec_size(self) -= size; \ +\ +STC_API cvec_##X##_iter_t \ +cvec_##X##_erase_range(cvec_##X* self, cvec_##X##_iter_t first, cvec_##X##_iter_t last) { \ + intptr_t len = last.item - first.item; \ + if (len > 0) { \ + Value* p = first.item, *end = p + _cvec_size(self); \ + while (p != last.item) valueDestroy(p++); \ + memmove(first.item, last.item, (end - last.item) * sizeof(Value)); \ + _cvec_size(self) -= len; \ } \ + return first; \ } \ - \ +\ STC_API cvec_##X##_iter_t \ cvec_##X##_find_in_range(const cvec_##X* self, cvec_##X##_iter_t first, cvec_##X##_iter_t last, RawValue rawValue) { \ for (; first.item != last.item; cvec_##X##_next(&first)) { \ @@ -231,7 +276,7 @@ STC_API 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 \ cvec_##X##_value_compare(const Value* x, const Value* y) { \ RawValue rx = valueToRaw(x); \ -- cgit v1.2.3