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}