use std::marker::PhantomData;
use std::mem;
use std::num::NonZeroUsize;
pub struct Reservation<K> {
pub(crate) key: Key,
_marker: PhantomData<K>,
}
impl<K> Reservation<K> {
pub(crate) fn new(key: Key) -> Self {
Self { key, _marker: PhantomData }
}
}
impl<K> Reservation<K>
where
K: From<Key>,
{
pub fn key(&self) -> K {
K::from(self.key)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct Generation(NonZeroUsize);
impl Generation {
pub(crate) const FIRST: Self = Self(NonZeroUsize::MIN);
pub(crate) fn next(&self) -> Option<Self> {
let n = self.0.get().checked_add(1)?;
Some(Self(NonZeroUsize::new(n).unwrap()))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Key {
pub(crate) index: usize,
pub(crate) generation: Generation,
}
const _NON_ZERO_OPTION_SIZE_OPTIMIZATION: () = {
assert!(mem::size_of::<Key>() == mem::size_of::<Option<Key>>());
};
#[macro_export]
macro_rules! key_newtype_impls {
($name:ident) => {
impl From<$crate::key::Key> for $name {
fn from(key: $crate::key::Key) -> $name {
$name(key)
}
}
impl From<$name> for $crate::key::Key {
fn from(val: $name) -> $crate::key::Key {
val.0
}
}
};
}