libcdsb/src/array/sort.c

96 lines
3.5 KiB
C
Raw Normal View History

2022-06-02 15:52:43 +03:00
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
#include "../__internal/assert.h"
static_assert((
VTYPE_UINT8 == 2 &&
VTYPE_UINT16 == 3 &&
VTYPE_UINT32 == 4 &&
VTYPE_UINT64 == 5 &&
VTYPE_INT8 == 6 &&
VTYPE_INT16 == 7 &&
VTYPE_INT32 == 8 &&
VTYPE_INT64 == 9 &&
VTYPE_FLOAT == 10 &&
VTYPE_DOUBLE == 11 &&
VTYPE_LDOUBLE == 12 &&
VTYPE_STRING == 13 &&
VTYPE_MAP == 14 &&
VTYPE_ARRAY == 15 &&
VTYPE_LIST == 16 &&
VTYPE_SET == 17
), "enum values assertion");
static int uint8_compare (const u8_t* s0, const u8_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int uint16_compare (const u16_t* s0, const u16_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int uint32_compare (const u32_t* s0, const u32_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int uint64_compare (const u64_t* s0, const u64_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int int8_compare (const s8_t* s0, const s8_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int int16_compare (const s16_t* s0, const s16_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int int32_compare (const s32_t* s0, const s32_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int int64_compare (const s64_t* s0, const s64_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int float_compare (const fl_t* s0, const fl_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int double_compare (const dbl_t* s0, const dbl_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int ldouble_compare(const ldbl_t* s0, const ldbl_t* s1) { if (*s0 == *s1) return 0; return *s0 < *s1 ? -1 : 1; }
static int (*COMPARE[16])(const void*, const void*) = {
(void*) uint8_compare,
(void*) uint16_compare,
(void*) uint32_compare,
(void*) uint64_compare,
(void*) int8_compare,
(void*) int16_compare,
(void*) int32_compare,
(void*) int64_compare,
(void*) float_compare,
(void*) double_compare,
(void*) ldouble_compare,
(void*) string_compare,
(void*) map_compare,
(void*) array_compare,
(void*) list_compare,
(void*) vset_compare
};
/*#####################################################################################################################*/
ainline(int get_compare_index(vtype t)) {
if (t == VTYPE_POINTER) {
if (is_x64) t = VTYPE_UINT64;
else t = VTYPE_UINT32;
} else if (t == VTYPE_BOOLEAN) t = VTYPE_UINT8;
return t - VTYPE_UINT8;
}
/*#####################################################################################################################*/
void array_sort(arr_t* x) {
int i = get_compare_index(x->type);
if (x->size > 1)
qsort(x->mem, x->size, vtype_size(x->type), COMPARE[i]);
}
void array_reverse(arr_t* x) {
if (x->size >= 2) {
void *l = x->mem;
void *r = array_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);
}
}