any_trait/
typeidconst.rs

1//! Internal implementation of a const-comparable TypeId
2//!
3//! We are missing a const Ord implementation,
4//! and we don't have a sound way of doing it.
5//! Order is only used for performance,
6//! but it's might make a difference when you have > 100 subtraits
7//!
8//! You should not be here. go away.
9
10/// TypeId, but const-comparable
11/// TODO: Make sortable somehow? soundness problems on order. plz help
12#[derive(Copy, Clone)]
13pub struct TypeIdConst {
14    t: ::core::any::TypeId,
15}
16
17impl TypeIdConst {
18    pub const fn of<T: ?Sized + 'static>() -> TypeIdConst {
19        return TypeIdConst {
20            t: ::core::any::TypeId::of::<T>(),
21        };
22    }
23    pub const fn eq(&self, other: &Self) -> bool {
24        return self.t.eq(&other.t);
25    }
26    /* Waiting for const Ord on TypeId, or other trick...
27    pub const fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
28        if self.t.eq(&other.t) {
29            return ::core::cmp::Ordering::Equal;
30        }
31        const TYPEID_SIZE: usize =
32            ::core::mem::size_of::<::core::any::TypeId>();
33        // This is unsound.
34        //
35        // any trick to do Ord on TypeID?
36        let self_bytes: [u8; TYPEID_SIZE];
37        let other_bytes: [u8; TYPEID_SIZE];
38        unsafe {
39            self_bytes = ::core::mem::transmute_copy::<
40                ::core::any::TypeId,
41                [u8; TYPEID_SIZE],
42            >(&self.t);
43            other_bytes = ::core::mem::transmute_copy::<
44                ::core::any::TypeId,
45                [u8; TYPEID_SIZE],
46            >(&other.t);
47        };
48        let mut i = 0;
49        while i < TYPEID_SIZE {
50            if self_bytes[i] < other_bytes[i] {
51                return ::core::cmp::Ordering::Less;
52            }
53            if self_bytes[i] > other_bytes[i] {
54                return ::core::cmp::Ordering::Greater;
55            }
56            i = i + 1;
57        }
58        return ::core::cmp::Ordering::Equal;
59    }
60    */
61}
62impl ::core::cmp::PartialEq for TypeIdConst {
63    fn eq(&self, other: &Self) -> bool {
64        self.t.eq(&other.t)
65    }
66}
67impl ::core::cmp::Eq for TypeIdConst {}
68
69/* Waiting for const Cmp on TypeID
70impl ::core::cmp::PartialOrd for TypeIdConst {
71    fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
72        Some(self.cmp(other))
73    }
74}
75impl ::core::cmp::Ord for TypeIdConst {
76    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
77        self.cmp(other)
78    }
79}
80/// const sort with insertionsort.
81pub const fn sort_array<const N: usize>(
82    array: [TypeIdConst; N],
83) -> [TypeIdConst; N] {
84    return array;
85    // come and tell me this is not performant
86    // and I'll implement random_sort
87    // joking, but I'm not wasting time on this
88    let mut i: usize = 0;
89    let mut j: usize = 0;
90    let mut out: [TypeIdConst; N] = array;
91    while i < N {
92        let mut min: usize = i;
93        while j < N {
94            if array[j].cmp(&array[i]).is_lt() {
95                min = j;
96            }
97            j = j + 1
98        }
99        if min != i {
100            let old = out[i];
101            out[i] = out[j];
102            out[j] = old;
103        }
104        i = i + 1;
105    }
106    out
107}
108*/
109
110/// get `[TypeIdConst;N]` in input and return `[TypeIdConst;N + 2]`
111///
112/// we add the first two elements, and they always are:
113/// * `TypeIdConst::of::<dyn AnyTrait>`
114/// * `TypeIdConst::of::<T>`
115pub const fn append_array<T: 'static, const N: usize, const M: usize>(
116    array: [TypeIdConst; N],
117) -> [TypeIdConst; M] {
118    assert!(N + 2 == M, "M needs to be N + 2");
119    let mut out: [TypeIdConst; M] = [TypeIdConst::of::<T>(); M];
120    out[0] = TypeIdConst::of::<dyn super::AnyTrait>();
121    let mut i: usize = 2;
122    while i < M {
123        out[i] = array[i - 2];
124        i = i + 1;
125    }
126
127    out
128}
129
130/// const-find the `TypeIdConst` of `T` inside the given array.
131/// return its index or panic
132pub const fn find_in<T: ?Sized + 'static, const N: usize>(
133    array: [TypeIdConst; N],
134) -> usize {
135    let mut i: usize = 0;
136    while i < N {
137        if array[i].eq(&TypeIdConst::of::<T>()) {
138            return i;
139        }
140        i = i + 1;
141    }
142    panic!("TypeIDConst find_in: called with non-member");
143}