use std::hint::unreachable_unchecked;
#[derive(PartialEq, Debug, Clone)]
pub(super) enum Slot<T> {
Value(T),
Next(usize),
Empty
}
impl <T>Slot<T> {
#[inline(always)]
pub(super) unsafe fn to_some_unchecked(self) -> Option<T> {
match self {
Slot::Value(value) => Some(value),
_ => unsafe { unreachable_unchecked() }
}
}
#[inline(always)]
pub(super) unsafe fn as_value_unchecked(&self) -> &T {
match self {
Slot::Value(value) => value,
_ => unsafe { unreachable_unchecked() }
}
}
#[inline(always)]
pub(super) unsafe fn as_value_unchecked_mut(&mut self) -> &mut T {
match self {
Slot::Value(value) => value,
_ => unsafe { unreachable_unchecked() }
}
}
}
impl <T> From<T> for Slot<T> {
#[inline(always)]
fn from(value: T) -> Self { Self::Value(value) }
}
impl <T> From<Slot<T>> for Option<T> {
#[inline]
fn from(value: Slot<T>) -> Self {
match value {
Slot::Value(value) => Some(value),
_ => None
}
}
}
impl <'a, T> From<&'a Slot<T>> for Option<&'a T> {
#[inline]
fn from(value: &'a Slot<T>) -> Self {
match value {
Slot::Value(value) => Some(value),
_ => None
}
}
}
impl <'a, T: 'a> From<&'a mut Slot<T>> for Option<&'a mut T> {
#[inline]
fn from(value: &'a mut Slot<T>) -> Self {
match value {
Slot::Value(value) => Some(value),
_ => None
}
}
}
#[cfg(test)]
mod slot {
use super::Slot;
#[test]
fn to_some_unchecked() {
let slot = Slot::Value(5);
assert_eq!(unsafe { slot.to_some_unchecked() }, Some(5));
}
#[test]
fn as_value_unchecked() {
let slot = Slot::Value(5);
assert_eq!(unsafe { slot.as_value_unchecked() }, &5);
}
#[test]
fn as_value_unchecked_mut() {
let mut slot = Slot::Value(5);
assert_eq!(unsafe { slot.as_value_unchecked_mut() }, &mut 5);
}
#[test]
fn from_t() {
let slot = Slot::from(5i32);
assert_eq!(slot, Slot::Value(5));
}
#[test]
fn from_slot() {
let slot = Slot::Value(5);
let none_slot = Slot::<i32>::Empty;
assert_eq!(Option::from(slot), Some(5));
assert_eq!(Option::<i32>::from(none_slot), None);
}
}