Skip to main content

pui_arena/
slotmap.rs

1//! A reimplementation of [`slotmap`](https://docs.rs/slotmap/) in terms
2//! of the generic arenas in [`base`](crate::base)
3//!
4//! The module structure here is identical to [`crate::base`], and
5//! you can look there for detailed documentation about the types.
6//! Each implementation of `SlotMap` will have all the methods from the
7//! corrosponding `Arena`, and those that take or produce generic keys
8//! will instead take/produce a `Key`.
9//!
10//! In each module, you'll find an `SlotMap` newtype (with one public field),
11//! a `VacantEntry` newtype (again with one public field). These are thin
12//! wrappers around their generic counterparts. Their only serve the purpose
13//! of making error messages easier to parse, and use a default `Key`.
14//! You will also find a vareity of type aliases for various iterators, and
15//! for the default `Key` type for ease of use.
16//!
17//! If you want to access the raw backing `Arena`/`VacantEntry`, you still can,
18//! it is the only public field of each slotmap/vacant entry.
19
20macro_rules! imp_slot_map {
21    (
22        new $($const:ident)?: $new:expr,
23        slots: $slots:ident,
24        ($($value:ty)?)
25    ) => {
26        /// a slot map
27        #[derive(Debug, Clone)]
28        #[repr(transparent)]
29        pub struct SlotMap<T>(pub Arena<T, ()>);
30
31        /// a vacant entry into [`SlotMap`]
32        pub struct VacantEntry<'a, T>(pub imp::VacantEntry<'a, T, ()>);
33
34        /// The key for [`SlotMap`]
35        pub type Key = $crate::Key<usize>;
36
37        /// Returned from [`SlotMap::entries`]
38        pub type Entries<'a, T> = imp::Entries<'a, T, (), DefaultVersion, usize>;
39        /// Returned from [`SlotMap::entries_mut`]
40        pub type EntriesMut<'a, T> = imp::EntriesMut<'a, T, (), DefaultVersion, usize>;
41        /// Returned from [`SlotMap::into_entries`]
42        pub type IntoEntries<T> = imp::IntoEntries<T, (), DefaultVersion, usize>;
43
44        impl<T> VacantEntry<'_, T> {
45            /// see [`VacantEntry::key`](imp::VacantEntry::key)
46            pub fn key(&self) -> usize { self.0.key() }
47
48            /// see [`VacantEntry::insert`](imp::VacantEntry::insert)
49            pub fn insert(self, value: T) -> usize { self.0.insert(value) }
50        }
51
52        impl<T> Default for SlotMap<T> {
53            fn default() -> Self { Self::new() }
54        }
55
56        impl<T> SlotMap<T> {
57            /// Create a new slab
58            pub $($const)? fn new() -> Self { Self($new) }
59            /// see [`Arena::is_empty`](imp::Arena::is_empty)
60            pub fn is_empty(&self) -> bool { self.0.is_empty() }
61            /// see [`Arena::len`](imp::Arena::is_empty)
62            pub fn len(&self) -> usize { self.0.len() }
63            /// see [`Arena::capacity`](imp::Arena::capacity)
64            pub fn capacity(&self) -> usize { self.0.capacity() }
65            /// see [`Arena::reserve`](imp::Arena::reserve)
66            pub fn reserve(&mut self, additional: usize) { self.0.reserve(additional) }
67            /// see [`Arena::clear`](imp::Arena::reserve)
68            pub fn clear(&mut self) { self.0.clear(); }
69            /// see [`Arena::vacant_entry`](imp::Arena::vacant_entry)
70            pub fn vacant_entry(&mut self) -> VacantEntry<'_, T> { VacantEntry(self.0.vacant_entry()) }
71            /// see [`Arena::insert`](imp::Arena::insert)
72            pub fn insert(&mut self, value: T) -> Key { self.0.insert(value) }
73            /// see [`Arena::contains`](imp::Arena::contains)
74            pub fn contains(&self, key: Key) -> bool { self.0.contains(key) }
75            /// see [`Arena::remove`](imp::Arena::remove)
76            pub fn remove(&mut self, key: Key) -> T { self.0.remove(key) }
77            /// see [`Arena::try_remove`](imp::Arena::try_remove)
78            pub fn try_remove(&mut self, key: Key) -> Option<T> { self.0.try_remove(key) }
79            /// see [`Arena::delete`](imp::Arena::delete)
80            pub fn delete(&mut self, key: Key) -> bool { self.0.delete(key) }
81            /// see [`Arena::get`](imp::Arena::get)
82            pub fn get(&self, key: Key) -> Option<&T> { self.0.get(key) }
83            /// see [`Arena::get_mut`](imp::Arena::get_mut)
84            pub fn get_mut(&mut self, key: Key) -> Option<&mut T> { self.0.get_mut(key) }
85            /// see [`Arena::get_unchecked`](imp::Arena::get_unchecked)
86            #[allow(clippy::missing_safety_doc)]
87            pub unsafe fn get_unchecked(&self, index: usize) -> &T { self.0.get_unchecked(index) }
88            /// see [`Arena::get_unchecked_mut`](imp::Arena::get_unchecked_mut)
89            #[allow(clippy::missing_safety_doc)]
90            pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { self.0.get_unchecked_mut(index) }
91            /// see [`Arena::delete_all`](imp::Arena::delete_all)
92            pub fn delete_all(&mut self) { self.0.delete_all() }
93            /// see [`Arena::retain`](imp::Arena::retain)
94            pub fn retain<F: FnMut(&mut T) -> bool>(&mut self, f: F) { self.0.retain(f) }
95            /// see [`Arena::keys`](imp::Arena::keys)
96            pub fn keys(&self) -> Keys<'_ $(, $value)?> { self.0.keys() }
97            /// see [`Arena::iter`](imp::Arena::iter)
98            pub fn iter(&self) -> Iter<'_, T> { self.0.iter() }
99            /// see [`Arena::iter_mut`](imp::Arena::iter_mut)
100            pub fn iter_mut(&mut self) -> IterMut<'_, T> { self.0.iter_mut() }
101            /// see [`Arena::drain`](imp::Arena::drain)
102            pub fn drain(&mut self) -> Drain<'_, T> { self.0.drain() }
103            /// see [`Arena::drain_filter`](imp::Arena::drain_filter)
104            pub fn drain_filter<F: FnMut(&mut T) -> bool>(&mut self, filter: F) -> DrainFilter<'_, T, F> { self.0.drain_filter(filter) }
105            /// see [`Arena::entries`](imp::Arena::entries)
106            pub fn entries(&self) -> Entries<'_, T> { self.0.entries() }
107            /// see [`Arena::entries_mut`](imp::Arena::entries_mut)
108            pub fn entries_mut(&mut self) -> EntriesMut<'_, T> { self.0.entries_mut() }
109            /// see [`Arena::into_entries`](imp::Arena::into_entries)
110            pub fn into_entries(self) -> IntoEntries<T> { self.0.into_entries() }
111        }
112
113        impl<T> IntoIterator for SlotMap<T> {
114            type IntoIter = IntoIter<T>;
115            type Item = T;
116
117            fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
118        }
119
120        impl<T> Index<Key> for SlotMap<T> {
121            type Output = T;
122
123            fn index(&self, key: Key) -> &Self::Output { &self.0[key] }
124        }
125
126        impl<T> IndexMut<Key> for SlotMap<T> {
127            fn index_mut(&mut self, key: Key) -> &mut Self::Output { &mut self.0[key] }
128        }
129    };
130}
131
132/// a dense slot_map
133///
134/// see [`base::dense`](crate::base::dense) for details
135pub mod dense {
136    use core::ops::{Index, IndexMut};
137
138    use crate::{
139        base::dense::{self as imp, Arena},
140        version::DefaultVersion,
141    };
142
143    /// Returned from [`SlotMap::iter`]
144    pub type Iter<'a, T> = core::slice::Iter<'a, T>;
145    /// Returned from [`SlotMap::iter_mut`]
146    pub type IterMut<'a, T> = core::slice::IterMut<'a, T>;
147    /// Returned from [`SlotMap::into_iter`]
148    pub type IntoIter<T> = std::vec::IntoIter<T>;
149
150    /// Returned from [`SlotMap::drain`]
151    pub type Drain<'a, T> = imp::Drain<'a, T, (), DefaultVersion>;
152    /// Returned from [`SlotMap::drain_filter`]
153    pub type DrainFilter<'a, T, F> = imp::DrainFilter<'a, T, (), DefaultVersion, F>;
154
155    /// Returned from [`SlotMap::keys`]
156    pub type Keys<'a> = imp::Keys<'a, (), DefaultVersion, Key>;
157
158    imp_slot_map! {
159        new: Arena::with_ident(()),
160        slots: len,
161        ()
162    }
163}
164
165/// a hop slot_map
166///
167/// see [`base::hop`](crate::base::hop) for details
168pub mod hop {
169    use core::ops::{Index, IndexMut};
170
171    use crate::{
172        base::hop::{self as imp, Arena},
173        version::DefaultVersion,
174    };
175
176    /// Returned from [`SlotMap::iter`]
177    pub type Iter<'a, T> = imp::Iter<'a, T, DefaultVersion>;
178    /// Returned from [`SlotMap::iter_mut`]
179    pub type IterMut<'a, T> = imp::IterMut<'a, T, DefaultVersion>;
180    /// Returned from [`SlotMap::into_iter`]
181    pub type IntoIter<T> = imp::IntoIter<T, DefaultVersion>;
182
183    /// Returned from [`SlotMap::drain`]
184    pub type Drain<'a, T> = imp::Drain<'a, T, DefaultVersion>;
185    /// Returned from [`SlotMap::drain_filter`]
186    pub type DrainFilter<'a, T, F> = imp::DrainFilter<'a, T, DefaultVersion, F>;
187
188    /// Returned from [`SlotMap::keys`]
189    pub type Keys<'a, T> = imp::Keys<'a, T, (), DefaultVersion, Key>;
190
191    imp_slot_map! {
192        new: Arena::with_ident(()),
193        slots: len,
194        (T)
195    }
196}
197
198/// a sparse slot_map
199///
200/// see [`base::sparse`](crate::base::sparse) for details
201pub mod sparse {
202    use core::ops::{Index, IndexMut};
203
204    use crate::{
205        base::sparse::{self as imp, Arena},
206        version::DefaultVersion,
207    };
208
209    /// Returned from [`SlotMap::iter`]
210    pub type Iter<'a, T> = imp::Iter<'a, T, DefaultVersion>;
211    /// Returned from [`SlotMap::iter_mut`]
212    pub type IterMut<'a, T> = imp::IterMut<'a, T, DefaultVersion>;
213    /// Returned from [`SlotMap::into_iter`]
214    pub type IntoIter<T> = imp::IntoIter<T, DefaultVersion>;
215
216    /// Returned from [`SlotMap::drain`]
217    pub type Drain<'a, T> = imp::Drain<'a, T, DefaultVersion>;
218    /// Returned from [`SlotMap::drain_filter`]
219    pub type DrainFilter<'a, T, F> = imp::DrainFilter<'a, T, DefaultVersion, F>;
220
221    /// Returned from [`SlotMap::keys`]
222    pub type Keys<'a, T> = imp::Keys<'a, T, (), DefaultVersion, Key>;
223
224    imp_slot_map! {
225        new const: Arena::INIT,
226        slots: slots,
227        (T)
228    }
229}