Skip to main content

wasmer_types/entity/
boxed_slice.rs

1// This file contains code from external sources.
2// Attributions: https://github.com/wasmerio/wasmer/blob/main/docs/ATTRIBUTIONS.md
3
4//! Boxed slices for `PrimaryMap`.
5
6use crate::entity::EntityRef;
7use crate::entity::iter::{Iter, IterMut};
8use crate::entity::keys::Keys;
9use crate::lib::std::boxed::Box;
10use crate::lib::std::marker::PhantomData;
11use crate::lib::std::ops::{Index, IndexMut};
12use crate::lib::std::slice;
13
14/// A slice mapping `K -> V` allocating dense entity references.
15///
16/// The `BoxedSlice` data structure uses the dense index space to implement a map with a boxed
17/// slice.
18#[derive(Debug, Clone)]
19pub struct BoxedSlice<K, V>
20where
21    K: EntityRef,
22{
23    elems: Box<[V]>,
24    unused: PhantomData<K>,
25}
26
27#[cfg(feature = "artifact-size")]
28impl<K, V> loupe::MemoryUsage for BoxedSlice<K, V>
29where
30    K: EntityRef,
31    V: loupe::MemoryUsage,
32{
33    fn size_of_val(&self, tracker: &mut dyn loupe::MemoryUsageTracker) -> usize {
34        std::mem::size_of_val(self)
35            + self
36                .elems
37                .iter()
38                .map(|value| value.size_of_val(tracker) - std::mem::size_of_val(value))
39                .sum::<usize>()
40    }
41}
42
43impl<K, V> BoxedSlice<K, V>
44where
45    K: EntityRef,
46{
47    /// Create a new slice from a raw pointer. A safer way to create slices is
48    /// to use `PrimaryMap::into_boxed_slice()`.
49    ///
50    /// # Safety
51    ///
52    /// This relies on `raw` pointing to a valid slice of `V`s.
53    pub unsafe fn from_raw(raw: *mut [V]) -> Self {
54        unsafe {
55            Self {
56                elems: Box::from_raw(raw),
57                unused: PhantomData,
58            }
59        }
60    }
61
62    /// Check if `k` is a valid key in the map.
63    pub fn is_valid(&self, k: K) -> bool {
64        k.index() < self.elems.len()
65    }
66
67    /// Get the element at `k` if it exists.
68    pub fn get(&self, k: K) -> Option<&V> {
69        self.elems.get(k.index())
70    }
71
72    /// Get the element at `k` if it exists, mutable version.
73    pub fn get_mut(&mut self, k: K) -> Option<&mut V> {
74        self.elems.get_mut(k.index())
75    }
76
77    /// Is this map completely empty?
78    pub fn is_empty(&self) -> bool {
79        self.elems.is_empty()
80    }
81
82    /// Get the total number of entity references created.
83    pub fn len(&self) -> usize {
84        self.elems.len()
85    }
86
87    /// Iterate over all the keys in this map.
88    pub fn keys(&self) -> Keys<K> {
89        Keys::with_len(self.elems.len())
90    }
91
92    /// Iterate over all the values in this map.
93    pub fn values(&self) -> slice::Iter<'_, V> {
94        self.elems.iter()
95    }
96
97    /// Iterate over all the values in this map, mutable edition.
98    pub fn values_mut(&mut self) -> slice::IterMut<'_, V> {
99        self.elems.iter_mut()
100    }
101
102    /// Iterate over all the keys and values in this map.
103    pub fn iter(&self) -> Iter<'_, K, V> {
104        Iter::new(self.elems.iter())
105    }
106
107    /// Iterate over all the keys and values in this map, mutable edition.
108    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
109        IterMut::new(self.elems.iter_mut())
110    }
111
112    /// Returns the last element that was inserted in the map.
113    pub fn last(&self) -> Option<&V> {
114        self.elems.last()
115    }
116}
117
118/// Immutable indexing into a `BoxedSlice`.
119/// The indexed value must be in the map.
120impl<K, V> Index<K> for BoxedSlice<K, V>
121where
122    K: EntityRef,
123{
124    type Output = V;
125
126    fn index(&self, k: K) -> &V {
127        &self.elems[k.index()]
128    }
129}
130
131/// Mutable indexing into a `BoxedSlice`.
132impl<K, V> IndexMut<K> for BoxedSlice<K, V>
133where
134    K: EntityRef,
135{
136    fn index_mut(&mut self, k: K) -> &mut V {
137        &mut self.elems[k.index()]
138    }
139}
140
141impl<'a, K, V> IntoIterator for &'a BoxedSlice<K, V>
142where
143    K: EntityRef,
144{
145    type Item = (K, &'a V);
146    type IntoIter = Iter<'a, K, V>;
147
148    fn into_iter(self) -> Self::IntoIter {
149        Iter::new(self.elems.iter())
150    }
151}
152
153impl<'a, K, V> IntoIterator for &'a mut BoxedSlice<K, V>
154where
155    K: EntityRef,
156{
157    type Item = (K, &'a mut V);
158    type IntoIter = IterMut<'a, K, V>;
159
160    fn into_iter(self) -> Self::IntoIter {
161        IterMut::new(self.elems.iter_mut())
162    }
163}
164
165#[cfg(test)]
166mod tests {
167    use super::*;
168    use crate::entity::PrimaryMap;
169    use crate::lib::std::vec::Vec;
170
171    // `EntityRef` impl for testing.
172    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
173    struct E(u32);
174
175    impl EntityRef for E {
176        fn new(i: usize) -> Self {
177            Self(i as u32)
178        }
179        fn index(self) -> usize {
180            self.0 as usize
181        }
182    }
183
184    #[test]
185    fn basic() {
186        let r0 = E(0);
187        let r1 = E(1);
188        let p = PrimaryMap::<E, isize>::new();
189        let m = p.into_boxed_slice();
190
191        let v: Vec<E> = m.keys().collect();
192        assert_eq!(v, []);
193
194        assert!(!m.is_valid(r0));
195        assert!(!m.is_valid(r1));
196    }
197
198    #[test]
199    fn iter() {
200        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
201        p.push(12);
202        p.push(33);
203        let mut m = p.into_boxed_slice();
204
205        let mut i = 0;
206        for (key, value) in &m {
207            assert_eq!(key.index(), i);
208            match i {
209                0 => assert_eq!(*value, 12),
210                1 => assert_eq!(*value, 33),
211                _ => panic!(),
212            }
213            i += 1;
214        }
215        i = 0;
216        for (key_mut, value_mut) in m.iter_mut() {
217            assert_eq!(key_mut.index(), i);
218            match i {
219                0 => assert_eq!(*value_mut, 12),
220                1 => assert_eq!(*value_mut, 33),
221                _ => panic!(),
222            }
223            i += 1;
224        }
225    }
226
227    #[test]
228    fn iter_rev() {
229        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
230        p.push(12);
231        p.push(33);
232        let mut m = p.into_boxed_slice();
233
234        let mut i = 2;
235        for (key, value) in m.iter().rev() {
236            i -= 1;
237            assert_eq!(key.index(), i);
238            match i {
239                0 => assert_eq!(*value, 12),
240                1 => assert_eq!(*value, 33),
241                _ => panic!(),
242            }
243        }
244
245        i = 2;
246        for (key, value) in m.iter_mut().rev() {
247            i -= 1;
248            assert_eq!(key.index(), i);
249            match i {
250                0 => assert_eq!(*value, 12),
251                1 => assert_eq!(*value, 33),
252                _ => panic!(),
253            }
254        }
255    }
256    #[test]
257    fn keys() {
258        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
259        p.push(12);
260        p.push(33);
261        let m = p.into_boxed_slice();
262
263        for (i, key) in m.keys().enumerate() {
264            assert_eq!(key.index(), i);
265        }
266    }
267
268    #[test]
269    fn keys_rev() {
270        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
271        p.push(12);
272        p.push(33);
273        let m = p.into_boxed_slice();
274
275        let mut i = 2;
276        for key in m.keys().rev() {
277            i -= 1;
278            assert_eq!(key.index(), i);
279        }
280    }
281
282    #[test]
283    fn values() {
284        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
285        p.push(12);
286        p.push(33);
287        let mut m = p.into_boxed_slice();
288
289        let mut i = 0;
290        for value in m.values() {
291            match i {
292                0 => assert_eq!(*value, 12),
293                1 => assert_eq!(*value, 33),
294                _ => panic!(),
295            }
296            i += 1;
297        }
298        i = 0;
299        for value_mut in m.values_mut() {
300            match i {
301                0 => assert_eq!(*value_mut, 12),
302                1 => assert_eq!(*value_mut, 33),
303                _ => panic!(),
304            }
305            i += 1;
306        }
307    }
308
309    #[test]
310    fn values_rev() {
311        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
312        p.push(12);
313        p.push(33);
314        let mut m = p.into_boxed_slice();
315
316        let mut i = 2;
317        for value in m.values().rev() {
318            i -= 1;
319            match i {
320                0 => assert_eq!(*value, 12),
321                1 => assert_eq!(*value, 33),
322                _ => panic!(),
323            }
324        }
325        i = 2;
326        for value_mut in m.values_mut().rev() {
327            i -= 1;
328            match i {
329                0 => assert_eq!(*value_mut, 12),
330                1 => assert_eq!(*value_mut, 33),
331                _ => panic!(),
332            }
333        }
334    }
335}