use core::{
hash::{Hash, Hasher},
mem::forget,
};
use crate::common::ref_mut::RefMut;
use super::{optional_block::OptionalBlock, ref_counter_update::RefCounterUpdate};
#[derive(Debug)]
#[repr(transparent)]
pub struct OptionalRef<T: OptionalBlock> {
value: T,
}
impl<T: OptionalBlock> PartialEq for OptionalRef<T> {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: OptionalBlock> Eq for OptionalRef<T> {}
impl<T: OptionalBlock> Hash for OptionalRef<T> {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.hash(state)
}
}
impl<T: OptionalBlock> OptionalRef<T> {
#[inline(always)]
pub const unsafe fn from_internal(value: T) -> Self {
Self { value }
}
#[inline(always)]
pub const unsafe fn internal(&self) -> T {
self.value
}
#[inline(always)]
pub fn is_ref(&self) -> bool {
self.value.is_ref()
}
#[inline(always)]
pub unsafe fn move_to_internal(mut self) -> T {
let result = self.value.to_mut_ptr().read();
forget(self);
result
}
}
impl<T: OptionalBlock> Clone for OptionalRef<T> {
#[inline(always)]
fn clone(&self) -> Self {
unsafe { self.value.ref_counter_update(RefCounterUpdate::AddRef) };
Self { value: self.value }
}
}
impl<T: OptionalBlock> Drop for OptionalRef<T> {
fn drop(&mut self) {
unsafe {
if let Some(header) = self.value.ref_counter_update(RefCounterUpdate::Release) {
self.value.delete(header);
}
}
}
}