From b78558b71f0f340ff8a3f6adf46f04cf7ffc3857 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 8 Aug 2020 14:55:31 +0200 Subject: Enhanced cvec sorting. --- stc/cpqueue.h | 6 +++--- stc/cvec.h | 38 +++++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/stc/cpqueue.h b/stc/cpqueue.h index 771c7b87..b0dab7ed 100644 --- a/stc/cpqueue.h +++ b/stc/cpqueue.h @@ -77,9 +77,9 @@ STC_INLINE void \ _cvec_##tag##_pqueue_sift_down(cvec_##tag##_value_t* arr, size_t i, size_t n) { \ size_t r = i, c = i << 1; \ while (c <= n) { \ - if (c < n && cvec_##tag##_sort_compare(&arr[c], &arr[c + 1]) cmpOpr 0) \ + if (c < n && cvec_##tag##_value_compare(&arr[c], &arr[c + 1]) cmpOpr 0) \ ++c; \ - if (cvec_##tag##_sort_compare(&arr[r], &arr[c]) cmpOpr 0) { \ + if (cvec_##tag##_value_compare(&arr[r], &arr[c]) cmpOpr 0) { \ cvec_##tag##_value_t t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; \ } else \ return; \ @@ -108,7 +108,7 @@ cvec_##tag##_pqueue_push(cvec_##tag* self, cvec_##tag##_value_t value) { \ cvec_##tag##_push_back(self, value); /* sift-up the value */ \ size_t n = cvec_size(*self), c = n; \ cvec_##tag##_value_t *arr = self->data - 1; \ - for (; c > 1 && cvec_##tag##_sort_compare(&arr[c >> 1], &value) cmpOpr 0; c >>= 1) \ + for (; c > 1 && cvec_##tag##_value_compare(&arr[c >> 1], &value) cmpOpr 0; c >>= 1) \ arr[c] = arr[c >> 1]; \ if (c != n) arr[c] = value; \ } \ diff --git a/stc/cvec.h b/stc/cvec.h index 60f44d35..062be92b 100644 --- a/stc/cvec.h +++ b/stc/cvec.h @@ -45,7 +45,7 @@ declare_cvec_6(str, cstr_t, cstr_destroy, cstr_compare_raw, const char*, cstr_to_raw) -#define declare_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \ +#define declare_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw) \ \ typedef struct cvec_##tag { \ Value* data; \ @@ -67,8 +67,12 @@ STC_API void \ cvec_##tag##_erase(cvec_##tag* self, size_t pos, size_t size); \ STC_API void \ cvec_##tag##_sort(cvec_##tag* self); \ +STC_API void \ +cvec_##tag##_sort_with(cvec_##tag* self, int(*cmp)(const Value*, const Value*)); \ STC_API size_t \ cvec_##tag##_find(const cvec_##tag* self, RawValue rawValue); \ +STC_API int \ +cvec_##tag##_value_compare(const Value* x, const Value* y); \ \ STC_INLINE cvec_##tag \ cvec_##tag##_init(void) { \ @@ -104,6 +108,14 @@ cvec_##tag##_at(cvec_##tag* self, size_t i) {return self->data + i;} \ STC_INLINE void \ cvec_##tag##_swap(cvec_##tag* a, cvec_##tag* b) { \ c_swap(Value*, a->data, b->data); \ +} \ +STC_INLINE void \ +cvec_##tag##_sort(cvec_##tag* self) { \ + qsort(self->data, cvec_size(*self), sizeof(Value), (_cvec_cmp) cvec_##tag##_value_compare); \ +} \ +STC_INLINE void \ +cvec_##tag##_sort_with(cvec_##tag* self, int(*cmp)(const Value*, const Value*)) { \ + qsort(self->data, cvec_size(*self), sizeof(Value), (_cvec_cmp) cmp); \ } \ \ typedef struct { \ @@ -120,14 +132,14 @@ cvec_##tag##_next(cvec_##tag##_iter_t* it) { \ ++it->item; \ } \ \ -implement_cvec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \ +implement_cvec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw) \ typedef Value cvec_##tag##_value_t, cvec_##tag##_input_t; \ typedef RawValue cvec_##tag##_rawvalue_t /* -------------------------- IMPLEMENTATION ------------------------- */ #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_cvec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \ +#define implement_cvec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw) \ \ STC_API void \ cvec_##tag##_push_n(cvec_##tag *self, const Value in[], size_t size) { \ @@ -195,27 +207,21 @@ STC_API size_t \ cvec_##tag##_find(const cvec_##tag* self, RawValue rawValue) { \ const Value *p = self->data, *end = p + cvec_size(*self); \ for (; p != end; ++p) { \ - RawValue r = valueGetRaw(p); \ + RawValue r = valueToRaw(p); \ if (valueCompareRaw(&r, &rawValue) == 0) return p - self->data; \ } \ return SIZE_MAX; /*(size_t) (-1)*/ \ } \ \ STC_API int \ -cvec_##tag##_sort_compare(const void* x, const void* y) { \ - RawValue rx = valueGetRaw((const Value *) x); \ - RawValue ry = valueGetRaw((const Value *) y); \ +cvec_##tag##_value_compare(const Value* x, const Value* y) { \ + RawValue rx = valueToRaw(x); \ + RawValue ry = valueToRaw(y); \ return valueCompareRaw(&rx, &ry); \ -} \ -STC_EXTERN_IMPORT void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)); \ -STC_API void \ -cvec_##tag##_sort(cvec_##tag* self) { \ - size_t len = cvec_size(*self); \ - if (len) qsort(self->data, len, sizeof(Value), cvec_##tag##_sort_compare); \ } #else -#define implement_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) +#define implement_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueToRaw) #endif #if defined(_WIN32) && defined(_DLL) @@ -224,6 +230,9 @@ cvec_##tag##_sort(cvec_##tag* self) { \ #define STC_EXTERN_IMPORT extern #endif +typedef int(*_cvec_cmp)(const void*, const void*); +STC_EXTERN_IMPORT void qsort(void *base, size_t nitems, size_t size, _cvec_cmp cmp); + #define _cvec_size(cv) ((size_t *)(cv).data)[-2] #define _cvec_capacity(cv) ((size_t *)(cv).data)[-1] @@ -237,5 +246,4 @@ STC_INLINE size_t _cvec_safe_capacity(const void* data) { return data ? ((const size_t *) data)[-1] : 0; } - #endif -- cgit v1.2.3