naga/arena/
mod.rs
1mod handle;
23mod handle_set;
24mod handlevec;
25mod range;
26mod unique_arena;
27
28pub use handle::{BadHandle, Handle};
29pub(crate) use handle_set::HandleSet;
30pub(crate) use handlevec::HandleVec;
31pub use range::{BadRangeError, Range};
32pub use unique_arena::UniqueArena;
33
34use alloc::vec::Vec;
35use core::{fmt, ops};
36
37use crate::Span;
38
39use handle::Index;
40
41#[derive(Clone)]
48#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
49#[cfg_attr(feature = "serialize", serde(transparent))]
50#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
51#[cfg_attr(test, derive(PartialEq))]
52pub struct Arena<T> {
53 data: Vec<T>,
55 #[cfg_attr(feature = "serialize", serde(skip))]
56 span_info: Vec<Span>,
57}
58
59impl<T> Default for Arena<T> {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl<T: fmt::Debug> fmt::Debug for Arena<T> {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 f.debug_map().entries(self.iter()).finish()
68 }
69}
70
71impl<T> Arena<T> {
72 pub const fn new() -> Self {
74 Arena {
75 data: Vec::new(),
76 span_info: Vec::new(),
77 }
78 }
79
80 #[allow(clippy::missing_const_for_fn)] pub fn into_inner(self) -> Vec<T> {
83 self.data
84 }
85
86 pub fn len(&self) -> usize {
88 self.data.len()
89 }
90
91 pub fn is_empty(&self) -> bool {
93 self.data.is_empty()
94 }
95
96 pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99 self.data
100 .iter()
101 .enumerate()
102 .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103 }
104
105 pub fn iter_mut_span(
108 &mut self,
109 ) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T, &Span)> + ExactSizeIterator {
110 self.data
111 .iter_mut()
112 .zip(self.span_info.iter())
113 .enumerate()
114 .map(|(i, (v, span))| unsafe { (Handle::from_usize_unchecked(i), v, span) })
115 }
116
117 pub fn drain(&mut self) -> impl DoubleEndedIterator<Item = (Handle<T>, T, Span)> {
119 let arena = core::mem::take(self);
120 arena
121 .data
122 .into_iter()
123 .zip(arena.span_info)
124 .enumerate()
125 .map(|(i, (v, span))| unsafe { (Handle::from_usize_unchecked(i), v, span) })
126 }
127
128 pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T)> {
131 self.data
132 .iter_mut()
133 .enumerate()
134 .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
135 }
136
137 pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139 let index = self.data.len();
140 self.data.push(value);
141 self.span_info.push(span);
142 Handle::from_usize(index)
143 }
144
145 pub fn fetch_if<F: Fn(&T) -> bool>(&self, fun: F) -> Option<Handle<T>> {
147 self.data
148 .iter()
149 .position(fun)
150 .map(|index| unsafe { Handle::from_usize_unchecked(index) })
151 }
152
153 pub fn fetch_if_or_append<F: Fn(&T, &T) -> bool>(
158 &mut self,
159 value: T,
160 span: Span,
161 fun: F,
162 ) -> Handle<T> {
163 if let Some(index) = self.data.iter().position(|d| fun(d, &value)) {
164 unsafe { Handle::from_usize_unchecked(index) }
165 } else {
166 self.append(value, span)
167 }
168 }
169
170 pub fn fetch_or_append(&mut self, value: T, span: Span) -> Handle<T>
172 where
173 T: PartialEq,
174 {
175 self.fetch_if_or_append(value, span, T::eq)
176 }
177
178 pub fn try_get(&self, handle: Handle<T>) -> Result<&T, BadHandle> {
179 self.data
180 .get(handle.index())
181 .ok_or_else(|| BadHandle::new(handle))
182 }
183
184 pub fn get_mut(&mut self, handle: Handle<T>) -> &mut T {
186 self.data.get_mut(handle.index()).unwrap()
187 }
188
189 pub fn range_from(&self, old_length: usize) -> Range<T> {
191 let range = old_length as u32..self.data.len() as u32;
192 Range::from_index_range(range, self)
193 }
194
195 pub fn clear(&mut self) {
197 self.data.clear()
198 }
199
200 pub fn get_span(&self, handle: Handle<T>) -> Span {
201 *self
202 .span_info
203 .get(handle.index())
204 .unwrap_or(&Span::default())
205 }
206
207 pub fn check_contains_handle(&self, handle: Handle<T>) -> Result<(), BadHandle> {
209 if handle.index() < self.data.len() {
210 Ok(())
211 } else {
212 Err(BadHandle::new(handle))
213 }
214 }
215
216 pub fn check_contains_range(&self, range: &Range<T>) -> Result<(), BadRangeError> {
218 if range.inner.start > range.inner.end {
221 return Err(BadRangeError::new(range.clone()));
222 }
223
224 if range.inner.start == range.inner.end {
226 return Ok(());
227 }
228
229 let last_handle = Handle::new(Index::new(range.inner.end - 1).unwrap());
230 if self.check_contains_handle(last_handle).is_err() {
231 return Err(BadRangeError::new(range.clone()));
232 }
233
234 Ok(())
235 }
236
237 pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238 where
239 P: FnMut(Handle<T>, &mut T) -> bool,
240 {
241 let mut index = 0;
242 let mut retained = 0;
243 self.data.retain_mut(|elt| {
244 let handle = Handle::from_usize(index);
245 let keep = predicate(handle, elt);
246
247 if keep {
251 self.span_info[retained] = self.span_info[index];
252 retained += 1;
253 }
254
255 index += 1;
256 keep
257 });
258
259 self.span_info.truncate(retained);
260 }
261}
262
263#[cfg(feature = "deserialize")]
264impl<'de, T> serde::Deserialize<'de> for Arena<T>
265where
266 T: serde::Deserialize<'de>,
267{
268 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
269 where
270 D: serde::Deserializer<'de>,
271 {
272 let data = Vec::deserialize(deserializer)?;
273 let span_info = core::iter::repeat_n(Span::default(), data.len()).collect();
274
275 Ok(Self { data, span_info })
276 }
277}
278
279impl<T> ops::Index<Handle<T>> for Arena<T> {
280 type Output = T;
281 fn index(&self, handle: Handle<T>) -> &T {
282 &self.data[handle.index()]
283 }
284}
285
286impl<T> ops::IndexMut<Handle<T>> for Arena<T> {
287 fn index_mut(&mut self, handle: Handle<T>) -> &mut T {
288 &mut self.data[handle.index()]
289 }
290}
291
292impl<T> ops::Index<Range<T>> for Arena<T> {
293 type Output = [T];
294 fn index(&self, range: Range<T>) -> &[T] {
295 &self.data[range.inner.start as usize..range.inner.end as usize]
296 }
297}
298
299#[cfg(test)]
300mod tests {
301 use super::*;
302
303 #[test]
304 fn append_non_unique() {
305 let mut arena: Arena<u8> = Arena::new();
306 let t1 = arena.append(0, Default::default());
307 let t2 = arena.append(0, Default::default());
308 assert!(t1 != t2);
309 assert!(arena[t1] == arena[t2]);
310 }
311
312 #[test]
313 fn append_unique() {
314 let mut arena: Arena<u8> = Arena::new();
315 let t1 = arena.append(0, Default::default());
316 let t2 = arena.append(1, Default::default());
317 assert!(t1 != t2);
318 assert!(arena[t1] != arena[t2]);
319 }
320
321 #[test]
322 fn fetch_or_append_non_unique() {
323 let mut arena: Arena<u8> = Arena::new();
324 let t1 = arena.fetch_or_append(0, Default::default());
325 let t2 = arena.fetch_or_append(0, Default::default());
326 assert!(t1 == t2);
327 assert!(arena[t1] == arena[t2])
328 }
329
330 #[test]
331 fn fetch_or_append_unique() {
332 let mut arena: Arena<u8> = Arena::new();
333 let t1 = arena.fetch_or_append(0, Default::default());
334 let t2 = arena.fetch_or_append(1, Default::default());
335 assert!(t1 != t2);
336 assert!(arena[t1] != arena[t2]);
337 }
338}