diff options
| -rw-r--r-- | stc/carray.h | 221 | ||||
| -rw-r--r-- | stc/cdefs.h | 4 | ||||
| -rw-r--r-- | 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; i<xdim; ++i) m[i] = val; \
- carray1##X a = {m, xdim | _carray_OWN}; \
- return a; \
- } \
- STC_INLINE carray2##X \
- carray2##X##_make(size_t ydim, size_t xdim, Value val) { \
- const size_t n = ydim * xdim; \
- Value* m = c_new_n(Value, n); \
- for (size_t i=0; i<n; ++i) m[i] = val; \
- carray2##X a = {m, xdim | _carray_OWN, ydim * xdim}; \
- return a; \
- } \
- STC_INLINE carray3##X \
- carray3##X##_make(size_t zdim, size_t ydim, size_t xdim, Value val) { \
- const size_t n = zdim * ydim * xdim; \
- Value* m = c_new_n(Value, n); \
- for (size_t i=0; i<n; ++i) m[i] = val; \
- carray3##X a = {m, xdim | _carray_OWN, ydim * xdim, zdim}; \
- return a; \
- } \
- \
- STC_INLINE carray1##X \
- carray1##X##_from(size_t xdim, Value* array, bool own) { \
- carray1##X a = {array, xdim | (own ? _carray_OWN : 0)}; \
- return a; \
- } \
- STC_INLINE carray2##X \
- carray2##X##_from(size_t ydim, size_t xdim, Value* array, bool own) { \
- carray2##X a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim}; \
- return a; \
- } \
- STC_INLINE carray3##X \
- carray3##X##_from(size_t zdim, size_t ydim, size_t xdim, Value* array, bool own) { \
- carray3##X a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim, zdim}; \
- return a; \
- } \
- \
- STC_INLINE Value* \
- carray1##X##_at(carray1##X *a, size_t x) { return a->data + 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; i<xdim; ++i) m[i] = val; \
+ carray1##X a = {m, xdim | _carray_OWN}; \
+ return a; \
+} \
+STC_INLINE carray2##X \
+carray2##X##_make(size_t ydim, size_t xdim, Value val) { \
+ const size_t n = ydim * xdim; \
+ Value* m = c_new_n(Value, n); \
+ for (size_t i=0; i<n; ++i) m[i] = val; \
+ carray2##X a = {m, xdim | _carray_OWN, ydim * xdim}; \
+ return a; \
+} \
+STC_INLINE carray3##X \
+carray3##X##_make(size_t zdim, size_t ydim, size_t xdim, Value val) { \
+ const size_t n = zdim * ydim * xdim; \
+ Value* m = c_new_n(Value, n); \
+ for (size_t i=0; i<n; ++i) m[i] = val; \
+ carray3##X a = {m, xdim | _carray_OWN, ydim * xdim, zdim}; \
+ return a; \
+} \
+\
+STC_INLINE carray1##X \
+carray1##X##_from(size_t xdim, Value* array, bool own) { \
+ carray1##X a = {array, xdim | (own ? _carray_OWN : 0)}; \
+ return a; \
+} \
+STC_INLINE carray2##X \
+carray2##X##_from(size_t ydim, size_t xdim, Value* array, bool own) { \
+ carray2##X a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim}; \
+ return a; \
+} \
+STC_INLINE carray3##X \
+carray3##X##_from(size_t zdim, size_t ydim, size_t xdim, Value* array, bool own) { \
+ carray3##X a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim, zdim}; \
+ return a; \
+} \
+\
+STC_INLINE Value* \
+carray1##X##_at(carray1##X *a, size_t x) { return a->data + 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; i<sizeof(__arr)/sizeof(__arr[0]); ++i) \
@@ -44,7 +44,7 @@ #define declare_cvec_7(X, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw, valueFromRaw) \
- \
+\
typedef struct cvec_##X { \
Value* data; \
} cvec_##X; \
@@ -52,7 +52,7 @@ typedef Value cvec_##X##_value_t; \ typedef RawValue cvec_##X##_rawvalue_t; \
typedef cvec_##X##_rawvalue_t cvec_##X##_input_t; \
typedef struct { Value *item; } cvec_##X##_iter_t; \
- \
+\
STC_INLINE cvec_##X \
cvec_##X##_init(void) {cvec_##X v = cvec_ini; return v;} \
STC_INLINE bool \
@@ -79,14 +79,53 @@ STC_INLINE void \ cvec_##X##_emplace_back(cvec_##X* self, RawValue rawValue) { \
cvec_##X##_push_back(self, valueFromRaw(rawValue)); \
} \
-STC_API void \
-cvec_##X##_insert(cvec_##X* self, size_t pos, Value value); \
-STC_INLINE void \
-cvec_##X##_emplace(cvec_##X* self, size_t pos, RawValue rawValue) { \
+\
+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); \
+\
+STC_INLINE cvec_##X##_iter_t \
+cvec_##X##_insert_irange(cvec_##X* self, size_t ipos, Value* pfirst, Value* plast) { \
+ cvec_##X##_iter_t pos = {self->data + 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; i<size; ++i) self->data[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); i<size; ++i) self->data[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); \
|
