1mod handle;
2mod map;
3mod secondary;
4mod slot;
5mod utils;
6
7use std::fmt::Debug;
8use std::hash::Hash;
9
10use std::fmt;
11use std::num::NonZeroU32;
12use std::ops::Deref;
13
14use crate::utils::unlikely;
15
16#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub struct Generation(NonZeroU32);
22
23impl fmt::Display for Generation {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 fmt::Display::fmt(&self.0, f)
26 }
27}
28
29impl Generation {
30 pub const MIN: Self = unsafe { Self(NonZeroU32::new_unchecked(1)) };
31
32 #[inline(always)]
33 #[cfg(feature = "serde")]
34 pub const fn new(val: NonZeroU32) -> Self {
35 Self(val)
36 }
37
38 #[inline(always)]
39 pub const unsafe fn new_unchecked(val: u32) -> Self {
40 unsafe { Self(NonZeroU32::new_unchecked(val)) }
41 }
42}
43
44impl Deref for Generation {
45 type Target = NonZeroU32;
46
47 #[inline(always)]
48 fn deref(&self) -> &Self::Target {
49 &self.0
50 }
51}
52
53#[derive(Clone, Copy, PartialEq, Eq, Debug)]
71#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
72pub struct Version(NonZeroU32);
73
74impl Version {
75 #[inline(always)]
79 pub fn new(generation: Generation, state: u32) -> Self {
80 debug_assert!(state <= 0b11);
81 let g = generation.0.get();
82 let v = (g << 2) | (state & 0b11);
86 unsafe { Self(NonZeroU32::new_unchecked(v)) }
87 }
88
89 #[inline(always)]
93 pub fn sentinel() -> Self {
94 Self::new(Generation::MIN, 0b00)
95 }
96
97 #[inline(always)]
101 pub fn generation(&self) -> Generation {
102 unsafe { Generation::new_unchecked(self.0.get() >> 2) }
104 }
105
106 #[inline(always)]
110 pub fn state(&self) -> u32 {
111 self.0.get() & 0b11
112 }
113
114 #[inline(always)]
118 pub fn is_vacant(&self) -> bool {
119 self.state() == 0b00
120 }
121
122 #[inline(always)]
126 pub fn is_reserved(&self) -> bool {
127 self.state() == 0b01
128 }
129
130 #[inline(always)]
134 pub fn is_occupied(&self) -> bool {
135 self.state() == 0b11
136 }
137
138 #[inline(always)]
146 pub fn vacant_to_reserved(&mut self) {
147 debug_assert!(self.is_vacant());
148 unsafe {
150 self.0 = NonZeroU32::new_unchecked(self.0.get() + 1);
151 }
152 }
153
154 #[inline(always)]
162 pub fn reserved_to_occupied(&mut self) {
163 debug_assert!(self.is_reserved());
164 unsafe {
166 self.0 = NonZeroU32::new_unchecked(self.0.get() + 2);
167 }
168 }
169
170 #[inline(always)]
178 pub fn occupied_to_vacant(&mut self) {
179 debug_assert!(self.is_occupied());
180 let mut v = self.0.get();
181 v = v.wrapping_add(1);
183
184 if unlikely(v >> 2 == 0) {
186 v = v.wrapping_add(1 << 2);
187 }
188
189 unsafe {
191 self.0 = NonZeroU32::new_unchecked(v);
192 }
193 }
194
195 #[inline(always)]
205 pub fn reserved_to_vacant(&mut self) {
206 debug_assert!(self.is_reserved());
207 let mut v = self.0.get();
208 v = v.wrapping_add(3);
210
211 if unlikely(v >> 2 == 0) {
213 v = v.wrapping_add(1 << 2);
214 }
215
216 unsafe {
217 self.0 = NonZeroU32::new_unchecked(v);
218 }
219 }
220}
221
222pub trait Key: Copy + Clone + PartialEq + Eq + Hash + Debug {
223 fn from_parts(index: u32, generation: Generation, #[cfg(debug_assertions)] map_id: u64)
224 -> Self;
225 fn index(&self) -> u32;
226 fn generation(&self) -> Generation;
227 #[cfg(debug_assertions)]
228 fn map_id(&self) -> u64;
229}
230
231#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
232pub struct DefaultKey {
233 pub(crate) raw: u64,
234 #[cfg(debug_assertions)]
235 pub(crate) map_id: u64,
236}
237
238impl Key for DefaultKey {
239 #[inline(always)]
240 fn from_parts(
241 index: u32,
242 generation: Generation,
243 #[cfg(debug_assertions)] map_id: u64,
244 ) -> Self {
245 Self {
246 raw: ((generation.get() as u64) << 32) | (index as u64),
247 #[cfg(debug_assertions)]
248 map_id,
249 }
250 }
251
252 #[inline(always)]
253 fn index(&self) -> u32 {
254 self.raw as u32
255 }
256
257 #[inline(always)]
258 fn generation(&self) -> Generation {
259 unsafe { Generation(NonZeroU32::new_unchecked((self.raw >> 32) as u32)) }
261 }
262
263 #[cfg(debug_assertions)]
264 #[inline(always)]
265 fn map_id(&self) -> u64 {
266 self.map_id
267 }
268}
269
270impl DefaultKey {
271 #[inline(always)]
275 pub fn new(index: u32, generation: Generation, #[cfg(debug_assertions)] map_id: u64) -> Self {
276 <Self as Key>::from_parts(
277 index,
278 generation,
279 #[cfg(debug_assertions)]
280 map_id,
281 )
282 }
283
284 #[inline(always)]
288 pub fn decode(&self) -> (u32, Generation) {
289 (self.index(), self.generation())
290 }
291}
292
293pub use handle::Handle;
294pub use map::DeferredMap;
295pub use secondary::SecondaryMap;
296
297#[cfg(test)]
298mod tests {
299 mod debug_safety;
302 mod edge_cases;
303 mod handle;
304 mod insertion;
305 mod new_features;
306 mod removal;
307 mod secondary_test;
308}