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