1use std::io::{Result, Write};
2
3use super::{Region, RegionCore, Serializable};
4use crate::ChrRef;
5
6pub trait GroupOps: RegionCore {
7 fn component(&self, idx: usize) -> &dyn RegionCore;
8 fn size(&self) -> usize;
9}
10
11pub trait DumpComponent: RegionCore {
12 fn dump_component<W: Write>(&self, idx: usize, fp: W) -> Result<()>;
13}
14
15macro_rules! impl_intersection_trait {
16 ($($t_name: ident),* => $($idx: tt),*) => {
17 impl <$($t_name: Region + Serializable),*> DumpComponent for ($($t_name),*) {
18 fn dump_component<W:Write>(&self, idx: usize, mut fp: W) -> Result<()> {
19 match idx {
20 $($idx => self.$idx.dump(&mut fp),)*
21 _ => panic!("Index out of range")
22 }
23 }
24 }
25 impl <$($t_name: Region),*> GroupOps for ($($t_name),*) {
26 fn component(&self, idx: usize) -> &dyn RegionCore {
27 match idx {
28 $($idx => &self.$idx,)*
29 _ => panic!("Index out of range")
30 }
31 }
32 fn size(&self) -> usize {
33 $(let _ret = $idx;)*
34 _ret + 1
35 }
36 }
37 }
38}
39
40macro_rules! impl_with_region_for_tuple {
41 (($($t_var:ident),*), ($($head:tt),*), $tail:tt) => {
42 impl <$($t_var: Region),*> RegionCore for ($($t_var),*) {
43 #[inline(always)]
44 fn start(&self) -> u32 {
45 if ($(&self . $head,)*).overlaps(&self.$tail) {
46 ($(&self . $head,)*).start().max(self.$tail.start())
47 } else {
48 0
49 }
50 }
51 #[inline(always)]
52 fn end(&self) -> u32 {
53 if ($(&self . $head,)*).overlaps(&self.$tail) {
54 ($(&self . $head,)*).end().min(self.$tail.end())
55 } else {
56 0
57 }
58 }
59 #[inline(always)]
60 fn chrom(&self) -> ChrRef<'static> {
61 self.0.chrom()
62 }
63 }
64 impl_intersection_trait!($($t_var),* => $($head,)* $tail);
65 };
66}
67
68impl_intersection_trait!(A, B => 0, 1);
69impl_with_region_for_tuple!((A, B, C), (0, 1), 2);
70impl_with_region_for_tuple!((A, B, C, D), (0, 1, 2), 3);
71impl_with_region_for_tuple!((A, B, C, D, E), (0, 1, 2, 3), 4);
72impl_with_region_for_tuple!((A, B, C, D, E, F), (0, 1, 2, 3, 4), 5);
73impl_with_region_for_tuple!((A, B, C, D, E, F, G), (0, 1, 2, 3, 4, 5), 6);
74impl_with_region_for_tuple!((A, B, C, D, E, F, G, H), (0, 1, 2, 3, 4, 5, 6), 7);
75impl_with_region_for_tuple!((A, B, C, D, E, F, G, H, I), (0, 1, 2, 3, 4, 5, 6, 7), 8);
76impl_with_region_for_tuple!(
77 (A, B, C, D, E, F, G, H, I, J),
78 (0, 1, 2, 3, 4, 5, 6, 7, 8),
79 9
80);
81impl_with_region_for_tuple!(
82 (A, B, C, D, E, F, G, H, I, J, K),
83 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
84 10
85);