mod handle;
mod map;
mod secondary;
mod slot;
mod utils;
use std::fmt::Debug;
use std::hash::Hash;
use std::fmt;
use std::num::NonZeroU32;
use std::ops::Deref;
use crate::utils::unlikely;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Generation(NonZeroU32);
impl fmt::Display for Generation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl Generation {
pub const MIN: Self = unsafe { Self(NonZeroU32::new_unchecked(1)) };
#[inline(always)]
#[cfg(feature = "serde")]
pub const fn new(val: NonZeroU32) -> Self {
Self(val)
}
#[inline(always)]
pub const unsafe fn new_unchecked(val: u32) -> Self {
unsafe { Self(NonZeroU32::new_unchecked(val)) }
}
}
impl Deref for Generation {
type Target = NonZeroU32;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Version(NonZeroU32);
impl Version {
#[inline(always)]
pub fn new(generation: Generation, state: u32) -> Self {
debug_assert!(state <= 0b11);
let g = generation.0.get();
let v = (g << 2) | (state & 0b11);
unsafe { Self(NonZeroU32::new_unchecked(v)) }
}
#[inline(always)]
pub fn sentinel() -> Self {
Self::new(Generation::MIN, 0b00)
}
#[inline(always)]
pub fn generation(&self) -> Generation {
unsafe { Generation::new_unchecked(self.0.get() >> 2) }
}
#[inline(always)]
pub fn state(&self) -> u32 {
self.0.get() & 0b11
}
#[inline(always)]
pub fn is_vacant(&self) -> bool {
self.state() == 0b00
}
#[inline(always)]
pub fn is_reserved(&self) -> bool {
self.state() == 0b01
}
#[inline(always)]
pub fn is_occupied(&self) -> bool {
self.state() == 0b11
}
#[inline(always)]
pub fn vacant_to_reserved(&mut self) {
debug_assert!(self.is_vacant());
unsafe {
self.0 = NonZeroU32::new_unchecked(self.0.get() + 1);
}
}
#[inline(always)]
pub fn reserved_to_occupied(&mut self) {
debug_assert!(self.is_reserved());
unsafe {
self.0 = NonZeroU32::new_unchecked(self.0.get() + 2);
}
}
#[inline(always)]
pub fn occupied_to_vacant(&mut self) {
debug_assert!(self.is_occupied());
let mut v = self.0.get();
v = v.wrapping_add(1);
if unlikely(v >> 2 == 0) {
v = v.wrapping_add(1 << 2);
}
unsafe {
self.0 = NonZeroU32::new_unchecked(v);
}
}
#[inline(always)]
pub fn reserved_to_vacant(&mut self) {
debug_assert!(self.is_reserved());
let mut v = self.0.get();
v = v.wrapping_add(3);
if unlikely(v >> 2 == 0) {
v = v.wrapping_add(1 << 2);
}
unsafe {
self.0 = NonZeroU32::new_unchecked(v);
}
}
}
pub trait Key: Copy + Clone + PartialEq + Eq + Hash + Debug {
type Raw: Copy + Clone + PartialEq + Eq + Hash + Debug;
unsafe fn from_raw(raw: Self::Raw, #[cfg(debug_assertions)] map_id: u64) -> Self;
fn from_parts(index: u32, generation: Generation, #[cfg(debug_assertions)] map_id: u64)
-> Self;
fn index(&self) -> u32;
fn generation(&self) -> Generation;
fn raw(&self) -> Self::Raw;
#[cfg(debug_assertions)]
fn map_id(&self) -> u64;
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct DefaultKey {
pub(crate) raw: u64,
#[cfg(debug_assertions)]
pub(crate) map_id: u64,
}
impl Key for DefaultKey {
type Raw = u64;
#[inline(always)]
unsafe fn from_raw(raw: Self::Raw, #[cfg(debug_assertions)] map_id: u64) -> Self {
Self {
raw,
#[cfg(debug_assertions)]
map_id,
}
}
#[inline(always)]
fn from_parts(
index: u32,
generation: Generation,
#[cfg(debug_assertions)] map_id: u64,
) -> Self {
Self {
raw: ((generation.get() as u64) << 32) | (index as u64),
#[cfg(debug_assertions)]
map_id,
}
}
#[inline(always)]
fn index(&self) -> u32 {
self.raw as u32
}
#[inline(always)]
fn generation(&self) -> Generation {
unsafe { Generation(NonZeroU32::new_unchecked((self.raw >> 32) as u32)) }
}
#[inline(always)]
fn raw(&self) -> Self::Raw {
self.raw
}
#[cfg(debug_assertions)]
#[inline(always)]
fn map_id(&self) -> u64 {
self.map_id
}
}
impl DefaultKey {
#[inline(always)]
pub fn new(index: u32, generation: Generation, #[cfg(debug_assertions)] map_id: u64) -> Self {
<Self as Key>::from_parts(
index,
generation,
#[cfg(debug_assertions)]
map_id,
)
}
#[inline(always)]
pub fn decode(&self) -> (u32, Generation) {
(self.index(), self.generation())
}
}
pub use handle::Handle;
pub use map::DeferredMap;
pub use secondary::SecondaryMap;
#[cfg(test)]
mod tests {
mod debug_safety;
mod edge_cases;
mod handle;
mod insertion;
mod new_features;
mod removal;
mod secondary_test;
}