128 lines
4.1 KiB
C
128 lines
4.1 KiB
C
/* This software is licensed by the MIT License, see LICENSE file */
|
|
/* Copyright © 2022 Gregory Lirent */
|
|
|
|
#include "__internal/assert.h"
|
|
#include "__internal/include.h"
|
|
|
|
#define max_align _Alignof(max_align_t)
|
|
#define max_size ((sizeof(ldbl_t) >= 8) ? sizeof(ldbl_t) : 8)
|
|
|
|
/*#####################################################################################################################*/
|
|
|
|
static vtype normalize_value(u64_t* d, const void* v, vtype t) {
|
|
if (t == VTYPE_BOOLEAN || t == VTYPE_UINT8) {
|
|
*d = *(u8_t*)v;
|
|
t = VTYPE_UINT64;
|
|
} else if (t == VTYPE_UINT16) {
|
|
*d = *(u16_t*)v;
|
|
t = VTYPE_UINT64;
|
|
} else if (t == VTYPE_UINT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) {
|
|
*d = *(u32_t*)v;
|
|
t = VTYPE_UINT64;
|
|
} else if (t == VTYPE_UINT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) {
|
|
*d = *(u64_t*)v;
|
|
t = VTYPE_UINT64;
|
|
} else if (t == VTYPE_INT8) {
|
|
*d = *(s8_t*)v;
|
|
t = (*(s8_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64;
|
|
} else if (t == VTYPE_INT16) {
|
|
*d = *(s16_t*)v;
|
|
t = (*(s16_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64;
|
|
} else if (t == VTYPE_INT32) {
|
|
*d = *(s32_t*)v;
|
|
t = (*(s32_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64;
|
|
} else if (t == VTYPE_INT64) {
|
|
*d = *(s64_t*)v;
|
|
t = (*(s64_t*)v >= 0) ? VTYPE_UINT64 : VTYPE_INT64;
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
int libcdsb_vtype_compare_values(const void* s0, vtype t0, const void* s1, vtype t1) {
|
|
if (t0 == t1) return libcdsb_vtype_compare_values_eq(s0, s1, t0);
|
|
|
|
if (is_integer(t0) && is_integer(t1)) {
|
|
u64_t v0, v1;
|
|
|
|
t0 = normalize_value(&v0, s0, t0);
|
|
t1 = normalize_value(&v1, s1, t1);
|
|
|
|
if (t0 == t1) {
|
|
if (t0 > VTYPE_UINT64)
|
|
return (s64_t)v0 - (s64_t)v1;
|
|
return v0 - v1;
|
|
}
|
|
|
|
return t1 - t0;
|
|
|
|
} else if (is_float(t0) && is_float(t1)) {
|
|
ldbl_t v;
|
|
|
|
if (t0 == VTYPE_FLOAT) v = *(fl_t*)s0;
|
|
else if (t0 == VTYPE_DOUBLE) v = *(dbl_t*)s0;
|
|
else v = *(ldbl_t*)s0;
|
|
|
|
if (t1 == VTYPE_FLOAT) v -= *(fl_t*)s1;
|
|
else if (t1 == VTYPE_DOUBLE) v -= *(dbl_t*)s1;
|
|
else v -= *(ldbl_t*)s1;
|
|
|
|
if (v < 0) return -1;
|
|
|
|
return (v > 0) ? 1 : 0;
|
|
} else return t0 - t1;
|
|
}
|
|
|
|
/*#####################################################################################################################*/
|
|
|
|
|
|
int libcdsb_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) {
|
|
|
|
ldbl_t v[1];
|
|
|
|
if (s0 == s1)
|
|
return 0;
|
|
|
|
switch (t) { default: abort();
|
|
|
|
case VTYPE_INT8: return *(s8_t*)s0 - *(s8_t*)s1;
|
|
case VTYPE_INT16: return *(s16_t*)s0 - *(s16_t*)s1;
|
|
case VTYPE_INT32: return *(s32_t*)s0 - *(s32_t*)s1;
|
|
case VTYPE_INT64: return *(s64_t*)s0 - *(s64_t*)s1;
|
|
|
|
case VTYPE_BOOLEAN:
|
|
case VTYPE_UINT8: return *(u8_t*)s0 - *(u8_t*)s1;
|
|
|
|
case VTYPE_UINT16: return *(u16_t*)s0 - *(u16_t*)s1;
|
|
case VTYPE_UINT32:
|
|
u32_: return *(u32_t*)s0 - *(u32_t*)s1;
|
|
|
|
case VTYPE_POINTER: if (sizeof(void*) != 8) goto u32_;
|
|
case VTYPE_UINT64: return *(u64_t*)s0 - *(u64_t*)s1;
|
|
|
|
case VTYPE_LDOUBLE: *(ldbl_t*)v = *(ldbl_t*)s0 - *(ldbl_t*)s1;
|
|
|
|
if (!*(ldbl_t*)v)
|
|
return 0;
|
|
return *(ldbl_t*)v < 0 ? -1 : 1;
|
|
|
|
case VTYPE_DOUBLE: *(dbl_t*)v = *(dbl_t*)s0 - *(dbl_t*)s1;
|
|
|
|
if (!*(dbl_t*)v)
|
|
return 0;
|
|
return *(dbl_t*)v < 0 ? -1 : 1;
|
|
|
|
case VTYPE_FLOAT: *(fl_t*)v = *(fl_t*)s0 - *(fl_t*)s1;
|
|
|
|
if (!*(fl_t*)v)
|
|
return 0;
|
|
return *(fl_t*)v < 0 ? -1 : 1;
|
|
|
|
case VTYPE_STRING: return string_compare(s0, s1);
|
|
case VTYPE_ARRAY: return array_compare(s0, s1);
|
|
case VTYPE_LIST: return list_compare(s0, s1);
|
|
case VTYPE_MAP: return map_compare(s0, s1);
|
|
case VTYPE_SET: return vset_compare(s0, s1);
|
|
}
|
|
}
|