grass_runtime/property/
group.rs

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);