60 lines
3.3 KiB
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);
|
|
}
|
|
}
|