#![allow(unsafe_code)]
#![allow(clippy::should_implement_trait, clippy::must_use_candidate)]
use core::mem;
use crate::map::{OccupiedEntry, VacantEntry};
#[cfg(test)]
mod tests;
pub struct SomeBucket<'a, T> {
outer: &'a mut Option<T>,
}
impl<'a, T> SomeBucket<'a, T> {
#[inline]
pub unsafe fn new_unchecked(opt: &'a mut Option<T>) -> Self {
debug_assert!(
opt.is_some(),
"Undefined Behavior: `None` value passed to `SomeBucket::new_unchecked`."
);
SomeBucket { outer: opt }
}
#[inline]
pub fn new(opt: &'a mut Option<T>) -> Option<Self> {
if opt.is_some() {
unsafe { Some(Self::new_unchecked(opt)) }
} else {
None
}
}
#[inline]
pub fn as_ref(&self) -> &T {
unsafe { self.outer.as_ref().unwrap_unchecked() }
}
#[inline]
pub fn as_mut(&mut self) -> &mut T {
unsafe { self.outer.as_mut().unwrap_unchecked() }
}
#[inline]
pub fn into_mut(self) -> &'a mut T {
unsafe { self.outer.as_mut().unwrap_unchecked() }
}
#[inline]
pub fn replace(&mut self, value: T) -> T {
mem::replace(self.as_mut(), value)
}
#[inline]
pub fn take(self) -> T {
unsafe { self.outer.take().unwrap_unchecked() }
}
}
impl<'a, K, V> OccupiedEntry<'a, K, V> for SomeBucket<'a, V>
where
K: Default,
{
#[inline]
fn key(&self) -> K {
K::default()
}
#[inline]
fn get(&self) -> &V {
SomeBucket::as_ref(self)
}
#[inline]
fn get_mut(&mut self) -> &mut V {
SomeBucket::as_mut(self)
}
#[inline]
fn into_mut(self) -> &'a mut V {
SomeBucket::into_mut(self)
}
#[inline]
fn insert(&mut self, value: V) -> V {
SomeBucket::replace(self, value)
}
#[inline]
fn remove(self) -> V {
SomeBucket::take(self)
}
}
pub struct NoneBucket<'a, T> {
outer: &'a mut Option<T>,
}
impl<'a, T> NoneBucket<'a, T> {
#[inline]
pub unsafe fn new_unchecked(opt: &'a mut Option<T>) -> Self {
debug_assert!(
opt.is_none(),
"Undefined Behavior: `Some` value passed to `NoneBucket::new_unchecked`."
);
NoneBucket { outer: opt }
}
#[inline]
pub fn new(opt: &'a mut Option<T>) -> Option<Self> {
if opt.is_none() {
unsafe { Some(Self::new_unchecked(opt)) }
} else {
None
}
}
#[inline]
pub fn insert(self, value: T) -> &'a mut T {
unsafe {
let outer: *mut Option<T> = self.outer;
outer.write(Some(value));
}
unsafe { self.outer.as_mut().unwrap_unchecked() }
}
}
impl<'a, K, V> VacantEntry<'a, K, V> for NoneBucket<'a, V>
where
K: Default,
{
#[inline]
fn key(&self) -> K {
K::default()
}
#[inline]
fn insert(self, value: V) -> &'a mut V {
NoneBucket::insert(self, value)
}
}
pub enum OptionBucket<'a, T> {
Some(SomeBucket<'a, T>),
None(NoneBucket<'a, T>),
}
impl<'a, T> OptionBucket<'a, T> {
#[inline]
pub fn new(opt: &'a mut Option<T>) -> Self {
if opt.is_some() {
unsafe { OptionBucket::Some(SomeBucket::new_unchecked(opt)) }
} else {
unsafe { OptionBucket::None(NoneBucket::new_unchecked(opt)) }
}
}
}