use super::NodePtr;
use crate::{MemoryPolicy, MemoryState, Node, SelfRefCol, Variant};
use core::fmt::Debug;
use orx_pinned_vec::PinnedVec;
pub struct NodeIdx<V: Variant> {
ptr: *mut Node<V>,
state: MemoryState,
}
impl<V: Variant> core::hash::Hash for NodeIdx<V> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.ptr.hash(state);
self.state.hash(state);
}
}
impl<V: Variant> Copy for NodeIdx<V> {}
impl<V: Variant> Clone for NodeIdx<V> {
fn clone(&self) -> Self {
*self
}
}
unsafe impl<V: Variant> Send for NodeIdx<V> where V::Item: Send {}
unsafe impl<V: Variant> Sync for NodeIdx<V> where V::Item: Sync {}
impl<V: Variant> Debug for NodeIdx<V> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("NodeIdx")
.field("ptr", &self.ptr)
.field("state", &self.state)
.finish()
}
}
impl<V: Variant> PartialEq for NodeIdx<V> {
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr && self.state == other.state
}
}
impl<V: Variant> Eq for NodeIdx<V> {}
impl<V> NodeIdx<V>
where
V: Variant,
{
#[inline(always)]
pub fn new(state: MemoryState, node_ptr: NodePtr<V>) -> Self {
Self {
ptr: unsafe { node_ptr.ptr_mut() },
state,
}
}
#[inline(always)]
pub fn is_in_state(self, state: MemoryState) -> bool {
self.state == state
}
#[inline(always)]
pub(crate) unsafe fn ptr(self) -> *const Node<V> {
self.ptr
}
#[inline(always)]
pub(crate) unsafe fn ptr_mut(self) -> *mut Node<V> {
self.ptr
}
#[inline(always)]
pub unsafe fn get_ptr(self, collection_state: MemoryState) -> Option<*mut Node<V>> {
self.state.eq(&collection_state).then_some(self.ptr)
}
#[inline(always)]
pub fn node_ptr(self) -> NodePtr<V> {
NodePtr::new(self.ptr)
}
#[inline(always)]
pub fn is_valid_for<M, P>(self, collection: &SelfRefCol<V, M, P>) -> bool
where
M: MemoryPolicy<V>,
P: PinnedVec<Node<V>>,
{
self.state == collection.memory_state()
&& collection.nodes().contains_ptr(self.ptr)
&& unsafe { &*self.ptr }.is_active()
}
#[inline(always)]
pub fn node<M, P>(self, collection: &SelfRefCol<V, M, P>) -> Option<&Node<V>>
where
M: MemoryPolicy<V>,
P: PinnedVec<Node<V>>,
{
collection.node_from_idx(self)
}
}