use std::{mem, num::NonZero};
#[repr(C)]
pub struct StagedValue<Key, Queued, Parked> {
pub(in crate::depot) key: mem::ManuallyDrop<Key>,
value: Value<Queued, Parked>,
}
#[repr(C)]
union Value<Queued, Parked> {
queued: mem::ManuallyDrop<Queued>,
parked: mem::ManuallyDrop<Parked>,
}
impl<Key, Queued, Parked> StagedValue<Key, Queued, Parked> {
pub fn queued(key: Key, value: Queued) -> Self {
Self {
key: mem::ManuallyDrop::new(key),
value: Value {
queued: mem::ManuallyDrop::new(value),
},
}
}
pub fn parked(key: Key, value: Parked) -> Self {
Self {
key: mem::ManuallyDrop::new(key),
value: Value {
parked: mem::ManuallyDrop::new(value),
},
}
}
pub fn key(&self) -> &Key {
&self.key
}
pub(in crate::depot) unsafe fn queued_ref(&self) -> &Queued {
unsafe { &self.value.queued }
}
pub(in crate::depot) unsafe fn queued_mut(&mut self) -> &mut Queued {
unsafe { &mut self.value.queued }
}
pub(in crate::depot) unsafe fn parked_mut(&mut self) -> &mut Parked {
unsafe { &mut self.value.parked }
}
pub unsafe fn parked_ref(&self) -> &Parked {
unsafe { &self.value.parked }
}
pub(in crate::depot) unsafe fn take_key(&mut self) -> Key {
unsafe { mem::ManuallyDrop::take(&mut self.key) }
}
pub(in crate::depot) unsafe fn take_queued(&mut self) -> Queued {
unsafe { mem::ManuallyDrop::take(&mut self.value.queued) }
}
pub(in crate::depot) unsafe fn take_parked(&mut self) -> Parked {
unsafe { mem::ManuallyDrop::take(&mut self.value.parked) }
}
pub(in crate::depot) unsafe fn clear_queued(&mut self) {
unsafe {
mem::ManuallyDrop::drop(&mut self.key);
mem::ManuallyDrop::drop(&mut self.value.queued);
}
}
pub(in crate::depot) unsafe fn clear_parked(&mut self) {
unsafe {
mem::ManuallyDrop::drop(&mut self.key);
mem::ManuallyDrop::drop(&mut self.value.parked);
}
}
pub(in crate::depot) fn write_parked(&mut self, value: Parked) {
self.value.parked = mem::ManuallyDrop::new(value);
}
pub(in crate::depot) fn write_queued(&mut self, value: Queued) {
self.value.queued = mem::ManuallyDrop::new(value);
}
}
pub unsafe trait LinkedNode: Sized {
type Input: Copy;
fn new(input: Self::Input) -> Self;
fn reset(&mut self, input: Self::Input);
fn next(&self) -> Option<NonZero<u32>>;
unsafe fn set_next(&mut self, next: Option<NonZero<u32>>);
}