diff --git a/docs/macos.md b/docs/macos.md index 576b3bc..9f1be3d 100644 --- a/docs/macos.md +++ b/docs/macos.md @@ -61,3 +61,12 @@ for (int i = 0; i < 10; i++) { } free(pd); ``` + +## reallocarray + +reallocarray is reimplemented for macOS because Apple doesn't expose their implementation. This is taken straight +from the OpenBSD source + +```c +void *reallocarray(void *optr, size_t nmemb, size_t size); +``` diff --git a/docs/math.md b/docs/math.md index 48f1146..37b50a2 100644 --- a/docs/math.md +++ b/docs/math.md @@ -57,3 +57,18 @@ Works the same as `bresenham()` but uses the `Point` struct instead of `int` ```c Point *bresenham_p(Point p1, Point p2, size_t *sz); ``` + +## Comparison Functions + +Comparison functions to compare two items. These functions must return `1` if `a > b`, `-1` if +`a < b`, or `0` if `a == b`. This follows the pattern defined by `compar` functions in the C standard +library, making these usuable in the standard sorting functions like `qsort` + +```c +int compar_int(const void *a, const void *b); +int compar_char(const void *a, const void *b); + +// Example +qsort(arr, arr_sz, sizeof(int), compar_int); +``` + diff --git a/docs/vector.md b/docs/vector.md index 28a73a8..ffe9872 100644 --- a/docs/vector.md +++ b/docs/vector.md @@ -137,16 +137,6 @@ comparison function to compare the data in the vector. This function must return const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b)); ``` -## Comparison Functions - -Comparison functions to compare data in a vector. These functions must return `1` if `a > b`, `-1` if -`a < b`, or `0` if `a == b`. - -```c -int vec_cmp_int(const void *a, const void *b); -int vec_cmp_char(const void *a, const void *b); -``` - ## Macros ### vec_at diff --git a/include/lfmath.h b/include/lfmath.h index 34542bb..5e8552a 100644 --- a/include/lfmath.h +++ b/include/lfmath.h @@ -15,4 +15,9 @@ Point *bresenham(int x0, int y0, int x1, int y1, size_t *sz); Point *bresenham_p(Point p1, Point p2, size_t *sz); +int compar_int(const void *a, const void *b); + +int compar_char(const void *a, const void *b); + + #endif // LIBFLINT_H_MATH diff --git a/include/lfvector.h b/include/lfvector.h index c0c7a63..a55d34a 100644 --- a/include/lfvector.h +++ b/include/lfvector.h @@ -30,9 +30,7 @@ const void *vec_min(const Vector *vec, int(*cmp)(const void *a, const void *b)); const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b)); -int vec_cmp_int(const void *a, const void *b); - -int vec_cmp_char(const void *a, const void *b); +int vec_sort(Vector *vec, int(*cmp)(const void *a, const void *b)); #define vec_at(v, i) (v)->elements[(i)] diff --git a/src/math.c b/src/math.c index 53efd33..372952b 100644 --- a/src/math.c +++ b/src/math.c @@ -77,3 +77,11 @@ Point *bresenham_p(Point p1, Point p2, size_t *sz) { return bresenham(p1.x, p1.y, p2.x, p2.y, sz); } + +int compar_int(const void *a, const void *b) { + return (*(int*)a - *(int*)b); +} + +int compar_char(const void *a, const void *b) { + return (*(char*)a - *(char*)b); +} diff --git a/src/vector.c b/src/vector.c index bab701f..f04d4a9 100644 --- a/src/vector.c +++ b/src/vector.c @@ -35,9 +35,7 @@ int vec_init_with_capacity(Vector *vec, void (*destroy)(void *data), size_t capa static int vec_grow(Vector *const vec) { vec->capacity *= 2; - vec->elements = reallocarray(vec->elements, vec->capacity, sizeof(void *)); - if (vec->elements == NULL) { return -1; } @@ -110,19 +108,11 @@ int vec_shrink(Vector *vec) { if (vec_len(vec) == vec_cap(vec)) { return 0; } - vec->capacity = vec_len(vec); - -#ifdef __OpenBSD__ vec->elements = reallocarray(vec->elements, vec->capacity, sizeof(void *)); -#else - vec->elements = reallocf(vec->elements, sizeof(void *) * vec->capacity); -#endif - if (vec->elements == NULL) { return -1; } - return 0; } @@ -146,28 +136,10 @@ const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b)) return a; } -int vec_cmp_int(const void *a, const void *b) { - const int x = *(int*)a; - const int y = *(int*)b; - - if (x > y) { - return 1; +int vec_sort(Vector *vec, int(*cmp)(const void *a, const void *b)) { + if (vec_len(vec) == 0) { + return 0; } - if (x < y) { - return -1; - } - return 0; -} - -int vec_cmp_char(const void *a, const void *b) { - const char x = *(int*)a; - const char y = *(int*)b; - - if (x > y) { - return 1; - } - if (x < y) { - return -1; - } - return 0; + qsort(vec->elements, vec->length, sizeof(void *), cmp); + return 1; } diff --git a/tests/tests.c b/tests/tests.c index 541550e..cc94884 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -239,8 +239,8 @@ void test_vector() { t = (int*)vec_at(v, 4); assert(*t == e4); - const int *min = vec_min(v, vec_cmp_int); - const int *max = vec_max(v, vec_cmp_int); + const int *min = vec_min(v, compar_int); + const int *max = vec_max(v, compar_int); printf("min: %d\n", *min); printf("max: %d\n", *max); assert(*min == e0); @@ -260,6 +260,19 @@ void test_vector() { assert(vec_len(v) == vec_cap(v)); printf("cap after shrink: %zu\n", vec_cap(v)); + int s1 = 10; + int s2 = 2; + int s3 = 1; + vec_push(v, &s1); + vec_push(v, &s2); + vec_push(v, &s3); + + printf("Before sort: "); + print_vector(v); + vec_sort(v, compar_int); + printf("After sort: "); + print_vector(v); + vec_destroy(v); free(v); }