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}