1use crate::*;
2use std::{any::TypeId, sync::OnceLock};
3
4macro_rules! create_sets {
5 ($(
6 $n:literal $set:ident<$($gen:ident),*> $(:)? $($sub_sets:path),*;
7 )*) => {
8 $(
9 #[doc = concat!("A set containing ", $n, " types.")]
11 pub trait $set<$($gen),*>: $($sub_sets +)* {}
16 impl<$($gen,)* S: ?Sized> $set<$($gen),*> for S where S: $($sub_sets +)* {}
17
18 unsafe impl<$($gen,)* S> SubsetOf<S> for Set<dyn $set<$($gen),*>>
20 where
21 S: $set<$($gen),*>
22 {}
23
24 unsafe impl<$($gen: 'static,)*> Members for Set<dyn $set<$($gen),*>>
25 {
26 fn members() -> Vec<TypeId> {
27 vec![ $(TypeId::of::<$gen>()),* ]
28 }
29 }
30 )*
31 };
32}
33
34create_sets!(
35 0 Zero<>;
36 1 One<T1>: Zero, Contains<T1>;
37 2 Two<T1, T2>: One<T1>, Contains<T2>;
38 3 Three<T1, T2, T3>: Two<T1, T2>, Contains<T3>;
39 4 Four<T1, T2, T3, T4>: Three<T1, T2, T3>, Contains<T4>;
40 5 Five<T1, T2, T3, T4, T5>: Four<T1, T2, T3, T4>, Contains<T5>;
41 6 Six<T1, T2, T3, T4, T5, T6>: Five<T1, T2, T3, T4, T5>, Contains<T6>;
42 7 Seven<T1, T2, T3, T4, T5, T6, T7>: Six<T1, T2, T3, T4, T5, T6>, Contains<T7>;
43 8 Eight<T1, T2, T3, T4, T5, T6, T7, T8>: Seven<T1, T2, T3, T4, T5, T6, T7>, Contains<T8>;
44 9 Nine<T1, T2, T3, T4, T5, T6, T7, T8, T9>: Eight<T1, T2, T3, T4, T5, T6, T7, T8>, Contains<T9>;
45 10 Ten<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>: Nine<T1, T2, T3, T4, T5, T6, T7, T8, T9>, Contains<T10>;
46 11 Eleven<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>: Ten<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, Contains<T11>;
47 12 Twelve<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>: Eleven<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, Contains<T12>;
48);
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn members() {
56 assert_eq!(<Set![]>::members(), &[]);
57 assert_eq!(<Set![u8]>::members(), &[TypeId::of::<u8>()]);
58 assert_eq!(
59 <Set![u8, u16]>::members(),
60 &[TypeId::of::<u8>(), TypeId::of::<u16>()]
61 );
62 assert_eq!(
63 <Set![u8, u16, u32]>::members(),
64 &[TypeId::of::<u8>(), TypeId::of::<u16>(), TypeId::of::<u32>()]
65 );
66 }
67
68 #[test]
69 fn consequtive_members() {
70 assert_eq!(<Set![u32]>::members(), &[TypeId::of::<u32>()]);
71 assert_eq!(<Set![u8]>::members(), &[TypeId::of::<u8>()]);
72 }
73}