1use crate::prelude::*;
2
3macro_rules! stripped {
4 (+ $($rest: tt)*) => {
5 $($rest)*
6 };
7 (* $($rest: tt)*) => {
8 $($rest)*
9 };
10 (&& $($rest: tt)*) => {
11 $($rest)*
12 };
13}
14
15macro_rules! impl_tuple {
16 ($n:literal; $(($tp:ident, $vp:ident)::$i:tt),+) => {
17 impl<$($tp: Space),+> Space for ($($tp),+) {
18 const DIM: usize = $n;
19
20 type Value = ($($tp::Value),+);
21
22 fn card(&self) -> Card {
23 stripped!($(* self.$i.card())+)
24 }
25
26 fn contains(&self, val: &Self::Value) -> bool {
27 stripped!($(&& self.$i.contains(&val.$i))+)
28 }
29 }
30
31 impl<$($tp: Union),+> Union for ($($tp),+) {
32 fn union(self, other: &Self) -> Self {
33 ($(self.$i.union(&other.$i)),+).into()
34 }
35 }
36
37 impl<$($tp: Intersect),+> Intersect for ($($tp),+) {
38 fn intersect(self, other: &Self) -> Self {
39 ($(self.$i.intersect(&other.$i)),+).into()
40 }
41 }
42 }
43}
44
45impl_tuple!(2; (D1, X1)::0, (D2, X2)::1);
46impl_tuple!(3; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2);
47impl_tuple!(4; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3);
48impl_tuple!(5; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4);
49impl_tuple!(6; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5);
50impl_tuple!(7; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5, (D7, X7)::6);
51impl_tuple!(8; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5, (D7, X7)::6, (D8, X8)::7);
52impl_tuple!(9; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5, (D7, X7)::6, (D8, X8)::7, (D9, X9)::8);
53impl_tuple!(10; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5, (D7, X7)::6, (D8, X8)::7, (D9, X9)::8, (D10, X10)::9);
54impl_tuple!(11; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5, (D7, X7)::6, (D8, X8)::7, (D9, X9)::8, (D10, X10)::9, (D11, X11)::10);
55impl_tuple!(12; (D1, X1)::0, (D2, X2)::1, (D3, X3)::2, (D4, X4)::3, (D5, X5)::4, (D6, X6)::5, (D7, X7)::6, (D8, X8)::7, (D9, X9)::8, (D10, X10)::9, (D11, X11)::10, (D12, X12)::11);
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 type S = (::std::ops::Range<usize>, ::std::ops::Range<usize>);
62
63 #[test]
64 fn test_dim() {
65 assert_eq!(S::DIM, 2);
66 }
67
68 #[test]
69 fn test_card() {
70 assert_eq!((0..2, 0..2).card(), Card::Finite(4));
71 }
72}