libcdsb/src/array/sort.c

60 lines
3.3 KiB
C

/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
#include "../__internal/assert.h"
typedef int (*compare_f)(const void*, const void*);
static int libcdsb_builtin_compare_uint8 (const u8_t* s0, const u8_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_uint16 (const u16_t* s0, const u16_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_uint32 (const u32_t* s0, const u32_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_uint64 (const u64_t* s0, const u64_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_int8 (const s8_t* s0, const s8_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_int16 (const s16_t* s0, const s16_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_int32 (const s32_t* s0, const s32_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_int64 (const s64_t* s0, const s64_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_float (const fl_t* s0, const fl_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_double (const dbl_t* s0, const dbl_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int libcdsb_builtin_compare_ldouble(const ldbl_t* s0, const ldbl_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static compare_f libcdsb_builtin_get_comparator(vtype t) {
static void* comparators[17] = { libcdsb_builtin_compare_uint8, libcdsb_builtin_compare_uint16,
libcdsb_builtin_compare_uint32, libcdsb_builtin_compare_uint64,
libcdsb_builtin_compare_int8, libcdsb_builtin_compare_int16,
libcdsb_builtin_compare_int32, libcdsb_builtin_compare_int64,
libcdsb_builtin_compare_float, libcdsb_builtin_compare_double,
libcdsb_builtin_compare_ldouble, string_compare, map_compare,
array_compare, list_compare, vset_compare, dict_compare };
if (t == VTYPE_POINTER) {
if (is_x64) t = VTYPE_UINT64;
else t = VTYPE_UINT32;
} else if (t == VTYPE_BOOLEAN) t = VTYPE_UINT8;
return comparators[t - VTYPE_UINT8];
}
/*#####################################################################################################################*/
void array_sort(arr_t* x) {
if (x->size > 1)
qsort(x->mem, x->size, vtype_size(x->type), libcdsb_builtin_get_comparator(x->type));
}
void array_reverse(arr_t* x) {
if (x->size >= 2) {
void *l = x->mem;
void *r = array_internal_at(x, x->size-1);
char b[vtype_size(x->type)];
do {
memcpy(b, l, vtype_size(x->type));
memcpy(l, r, vtype_size(x->type));
memcpy(r, b, vtype_size(x->type));
l += vtype_size(x->type);
r -= vtype_size(x->type);
} while (l < r);
}
}