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}