use core::marker::PhantomData;
use crate::{
NodeGuard, alloc_proxy::proxy::Allocator, layout::AugmentedRBTreeLayout,
node::internal_details::NodeRef, policy::internal_details::TreePolicy,
};
#[derive(Debug, Copy)]
pub struct NavCursor<'a, K, V, S> {
pub(crate) current: Option<NodeRef<K, V, S>>,
_marker: PhantomData<&'a ()>,
}
impl<K, V, S> Clone for NavCursor<'_, K, V, S> {
fn clone(&self) -> Self {
Self {
current: self.current,
_marker: PhantomData,
}
}
}
impl<'a, K, V, S> NavCursor<'a, K, V, S> {
pub(crate) fn new(current: Option<NodeRef<K, V, S>>) -> Self {
Self {
current,
_marker: PhantomData,
}
}
#[must_use]
pub fn get(&self) -> Option<(&'a K, &'a V, &'a S)> {
let node = self.current?;
unsafe { Some((node.key(), node.value(), node.stats())) }
}
#[must_use]
pub fn peek_next(&self) -> Option<(&'a K, &'a V, &'a S)> {
let next = self.current?.next_node()?;
unsafe { Some((next.key(), next.value(), next.stats())) }
}
#[must_use]
pub fn peek_prev(&self) -> Option<(&'a K, &'a V, &'a S)> {
let prev = self.current?.prev_node()?;
unsafe { Some((prev.key(), prev.value(), prev.stats())) }
}
#[must_use]
pub fn peek_parent(&self) -> Option<(&'a K, &'a V, &'a S)> {
let parent = self.current?.parent()?;
unsafe { Some((parent.key(), parent.value(), parent.stats())) }
}
#[must_use]
pub fn peek_left(&self) -> Option<(&'a K, &'a V, &'a S)> {
let left = self.current?.left()?;
unsafe { Some((left.key(), left.value(), left.stats())) }
}
#[must_use]
pub fn peek_right(&self) -> Option<(&'a K, &'a V, &'a S)> {
let right = self.current?.right()?;
unsafe { Some((right.key(), right.value(), right.stats())) }
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<(&'a K, &'a V, &'a S)> {
self.current = self.current?.next_node();
let current = self.current?;
unsafe { Some((current.key(), current.value(), current.stats())) }
}
pub fn prev(&mut self) -> Option<(&'a K, &'a V, &'a S)> {
self.current = self.current?.prev_node();
let current = self.current?;
unsafe { Some((current.key(), current.value(), current.stats())) }
}
pub fn parent(&mut self) -> Option<(&'a K, &'a V, &'a S)> {
self.current = self.current?.parent();
let current = self.current?;
unsafe { Some((current.key(), current.value(), current.stats())) }
}
pub fn left(&mut self) -> Option<(&'a K, &'a V, &'a S)> {
self.current = self.current?.left();
let current = self.current?;
unsafe { Some((current.key(), current.value(), current.stats())) }
}
pub fn right(&mut self) -> Option<(&'a K, &'a V, &'a S)> {
self.current = self.current?.right();
let current = self.current?;
unsafe { Some((current.key(), current.value(), current.stats())) }
}
}
#[derive(Debug)]
pub struct NavCursorMut<'a, K, V, S, A, P>
where
P: TreePolicy<K = K, V = V, S = S>,
A: Allocator,
{
layout: &'a mut AugmentedRBTreeLayout<K, V, S, A, P>,
current: Option<NodeRef<K, V, S>>,
_marker: PhantomData<(&'a mut (K, V, S), P)>,
}
impl<'a, K, V, S, A, P> NavCursorMut<'a, K, V, S, A, P>
where
P: TreePolicy<K = K, V = V, S = S>,
A: Allocator,
{
#[inline]
pub(crate) fn new(
layout: &'a mut AugmentedRBTreeLayout<K, V, S, A, P>,
current: Option<NodeRef<K, V, S>>,
) -> Self {
Self {
layout,
current,
_marker: PhantomData,
}
}
pub fn get(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
let node = self.current?;
let guard = NodeGuard::new(node);
Some(guard)
}
pub fn peek_next(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
let next = self.current?.next_node()?;
let guard = NodeGuard::new(next);
Some(guard)
}
pub fn peek_prev(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
let prev = self.current?.prev_node()?;
let guard = NodeGuard::new(prev);
Some(guard)
}
pub fn peek_parent(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
let parent = self.current?.parent()?;
let guard = NodeGuard::new(parent);
Some(guard)
}
pub fn peek_left(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
let left = self.current?.left()?;
let guard = NodeGuard::new(left);
Some(guard)
}
pub fn peek_right(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
let right = self.current?.right()?;
let guard = NodeGuard::new(right);
Some(guard)
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
self.current = self.current?.next_node();
let current = self.current?;
let guard = NodeGuard::new(current);
Some(guard)
}
pub fn prev(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
self.current = self.current?.prev_node();
let current = self.current?;
let guard = NodeGuard::new(current);
Some(guard)
}
pub fn parent(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
self.current = self.current?.parent();
let current = self.current?;
let guard = NodeGuard::new(current);
Some(guard)
}
pub fn left(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
self.current = self.current?.left();
let current = self.current?;
let guard = NodeGuard::new(current);
Some(guard)
}
pub fn right(&mut self) -> Option<NodeGuard<'_, K, V, S, P>> {
self.current = self.current?.right();
let current = self.current?;
let guard = NodeGuard::new(current);
Some(guard)
}
pub fn remove(&mut self) -> Option<(K, V)> {
let node = self.current?;
let next_node = node.next_node();
self.current = next_node;
Some(self.layout.delete_node(node))
}
}