enum_table/
intrinsics.rs

1macro_rules! const_operator {
2    ($T:ident,$left:ident ($operator:tt) $right:ident) => {
3        match const { core::mem::size_of::<$T>() } {
4            1 => unsafe { *($left as *const $T as *const u8) $operator *($right as *const $T as *const u8) },
5            2 => unsafe { *($left as *const $T as *const u16) $operator *($right as *const $T as *const u16) },
6            4 => unsafe { *($left as *const $T as *const u32) $operator *($right as *const $T as *const u32) },
7            8 => unsafe { *($left as *const $T as *const u64) $operator *($right as *const $T as *const u64) },
8            16 => unsafe { *($left as *const $T as *const u128) $operator *($right as *const $T as *const u128) },
9
10            _ => panic!(
11                "enum-table: Enum discriminants larger than 128 bits are not supported. This is likely due to an extremely large enum or invalid memory layout."
12            ),
13        }
14    };
15}
16
17#[inline(always)]
18pub(crate) const fn const_enum_eq<T>(left: &T, right: &T) -> bool {
19    const_operator!(T, left (==) right)
20}
21
22#[inline(always)]
23#[cfg(debug_assertions)]
24pub(crate) const fn const_enum_gt<T>(left: &T, right: &T) -> bool {
25    const_operator!(T, left (>) right)
26}
27
28#[inline(always)]
29pub(crate) const fn const_enum_lt<T>(left: &T, right: &T) -> bool {
30    const_operator!(T, left (<) right)
31}
32
33pub(crate) fn hash<T, H: core::hash::Hasher>(t: &T, state: &mut H) {
34    use core::hash::Hash;
35
36    macro_rules! hash_as {
37        ($type:ident) => {
38            unsafe { (*(t as *const T as *const $type)).hash(state) }
39        };
40    }
41
42    match core::mem::size_of::<T>() {
43        1 => hash_as!(u8),
44        2 => hash_as!(u16),
45        4 => hash_as!(u32),
46        8 => hash_as!(u64),
47        16 => hash_as!(u128),
48
49        _ => panic!(
50            "enum-table: Enum discriminants larger than 128 bits are not supported. This is likely due to an extremely large enum or invalid memory layout."
51        ),
52    }
53}
54
55pub const fn sort_variants<const N: usize, T>(mut arr: [T; N]) -> [T; N] {
56    let mut i = 1;
57    while i < N {
58        let mut j = i;
59        while j > 0 && const_enum_lt(&arr[j], &arr[j - 1]) {
60            arr.swap(j, j - 1);
61            j -= 1;
62        }
63        i += 1;
64    }
65    arr
66}
67
68#[cfg(debug_assertions)]
69pub(crate) const fn is_sorted<T>(arr: &[T]) -> bool {
70    let mut i = 0;
71    while i < arr.len() - 1 {
72        if const_enum_gt(&arr[i], &arr[i + 1]) {
73            return false;
74        }
75        i += 1;
76    }
77    true
78}