regalloc2/
index.rs

1#[macro_export]
2macro_rules! define_index {
3    ($ix:ident, $storage:ident, $elem:ident) => {
4        define_index!($ix);
5
6        #[derive(Clone, Debug)]
7        pub struct $storage {
8            storage: Vec<$elem>,
9        }
10
11        impl $storage {
12            #[inline(always)]
13            pub fn with_capacity(n: usize) -> Self {
14                Self {
15                    storage: Vec::with_capacity(n),
16                }
17            }
18
19            #[inline(always)]
20            pub fn len(&self) -> usize {
21                self.storage.len()
22            }
23
24            #[inline(always)]
25            pub fn iter(&self) -> impl Iterator<Item = &$elem> {
26                self.storage.iter()
27            }
28
29            #[inline(always)]
30            pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut $elem> {
31                self.storage.iter_mut()
32            }
33
34            #[inline(always)]
35            pub fn push(&mut self, value: $elem) -> $ix {
36                let idx = $ix(self.storage.len() as u32);
37                self.storage.push(value);
38                idx
39            }
40        }
41
42        impl core::ops::Index<$ix> for $storage {
43            type Output = $elem;
44
45            #[inline(always)]
46            fn index(&self, i: $ix) -> &Self::Output {
47                &self.storage[i.index()]
48            }
49        }
50
51        impl core::ops::IndexMut<$ix> for $storage {
52            #[inline(always)]
53            fn index_mut(&mut self, i: $ix) -> &mut Self::Output {
54                &mut self.storage[i.index()]
55            }
56        }
57
58        impl<'a> IntoIterator for &'a $storage {
59            type Item = &'a $elem;
60            type IntoIter = core::slice::Iter<'a, $elem>;
61
62            #[inline(always)]
63            fn into_iter(self) -> Self::IntoIter {
64                self.storage.iter()
65            }
66        }
67
68        impl<'a> IntoIterator for &'a mut $storage {
69            type Item = &'a mut $elem;
70            type IntoIter = core::slice::IterMut<'a, $elem>;
71
72            #[inline(always)]
73            fn into_iter(self) -> Self::IntoIter {
74                self.storage.iter_mut()
75            }
76        }
77    };
78
79    ($ix:ident) => {
80        #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
81        #[cfg_attr(
82            feature = "enable-serde",
83            derive(::serde::Serialize, ::serde::Deserialize)
84        )]
85        pub struct $ix(pub u32);
86        impl $ix {
87            #[inline(always)]
88            pub fn new(i: usize) -> Self {
89                Self(i as u32)
90            }
91            #[inline(always)]
92            pub fn index(self) -> usize {
93                debug_assert!(self.is_valid());
94                self.0 as usize
95            }
96            #[inline(always)]
97            pub fn invalid() -> Self {
98                Self(u32::MAX)
99            }
100            #[inline(always)]
101            pub fn is_invalid(self) -> bool {
102                self == Self::invalid()
103            }
104            #[inline(always)]
105            pub fn is_valid(self) -> bool {
106                self != Self::invalid()
107            }
108            #[inline(always)]
109            pub fn next(self) -> $ix {
110                debug_assert!(self.is_valid());
111                Self(self.0 + 1)
112            }
113            #[inline(always)]
114            pub fn prev(self) -> $ix {
115                debug_assert!(self.is_valid());
116                Self(self.0 - 1)
117            }
118
119            #[inline(always)]
120            pub fn raw_u32(self) -> u32 {
121                self.0
122            }
123        }
124
125        impl crate::index::ContainerIndex for $ix {}
126    };
127}
128
129pub trait ContainerIndex: Clone + Copy + core::fmt::Debug + PartialEq + Eq {}
130
131pub trait ContainerComparator {
132    type Ix: ContainerIndex;
133    fn compare(&self, a: Self::Ix, b: Self::Ix) -> core::cmp::Ordering;
134}
135
136define_index!(Inst);
137define_index!(Block);
138
139#[derive(Clone, Copy, Debug)]
140#[cfg_attr(
141    feature = "enable-serde",
142    derive(::serde::Serialize, ::serde::Deserialize)
143)]
144pub struct InstRange(Inst, Inst);
145
146impl InstRange {
147    #[inline(always)]
148    pub fn new(from: Inst, to: Inst) -> Self {
149        debug_assert!(from.index() <= to.index());
150        InstRange(from, to)
151    }
152
153    #[inline(always)]
154    pub fn first(self) -> Inst {
155        debug_assert!(self.len() > 0);
156        self.0
157    }
158
159    #[inline(always)]
160    pub fn last(self) -> Inst {
161        debug_assert!(self.len() > 0);
162        self.1.prev()
163    }
164
165    #[inline(always)]
166    pub fn rest(self) -> InstRange {
167        debug_assert!(self.len() > 0);
168        InstRange::new(self.0.next(), self.1)
169    }
170
171    #[inline(always)]
172    pub fn len(self) -> usize {
173        self.1.index() - self.0.index()
174    }
175
176    #[inline(always)]
177    pub fn iter(self) -> impl DoubleEndedIterator<Item = Inst> {
178        (self.0.index()..self.1.index()).map(|i| Inst::new(i))
179    }
180}
181
182#[cfg(test)]
183mod test {
184    use alloc::vec;
185    use alloc::vec::Vec;
186
187    use super::*;
188
189    #[test]
190    fn test_inst_range() {
191        let range = InstRange::new(Inst::new(0), Inst::new(0));
192        debug_assert_eq!(range.len(), 0);
193
194        let range = InstRange::new(Inst::new(0), Inst::new(5));
195        debug_assert_eq!(range.first().index(), 0);
196        debug_assert_eq!(range.last().index(), 4);
197        debug_assert_eq!(range.len(), 5);
198        debug_assert_eq!(
199            range.iter().collect::<Vec<_>>(),
200            vec![
201                Inst::new(0),
202                Inst::new(1),
203                Inst::new(2),
204                Inst::new(3),
205                Inst::new(4)
206            ]
207        );
208    }
209}