use {
crate::{CircularList, list::node::Node},
core::ptr::NonNull,
};
pub struct Cursor<'c, T> {
list: &'c CircularList<T>,
current: NonNull<Node<T>>,
index: usize,
}
impl<'c, T> Cursor<'c, T> {
pub(super) fn from_list(list: &'c CircularList<T>) -> Option<Self> {
list.head.map(|h| Self {
list,
current: h,
index: 0,
})
}
}
impl<'c, T> Cursor<'c, T> {
pub fn index(&self) -> usize {
self.index
}
pub fn move_next(&mut self) {
unsafe {
self.current = Node::next(self.current);
}
self.index = (self.index + 1) % self.list.len();
}
pub fn move_prev(&mut self) {
unsafe {
self.current = Node::prev(self.current);
}
let len = self.list.len();
self.index = (len + self.index - 1) % len;
}
pub fn current(&self) -> &'c T {
unsafe { Node::value(self.current) }
}
pub fn peek_next(&self) -> &'c T {
unsafe {
let next = Node::next(self.current);
Node::value(next)
}
}
pub fn peek_prev(&self) -> &'c T {
unsafe {
let prev = Node::prev(self.current);
Node::value(prev)
}
}
}
pub struct CursorMut<'c, T> {
list: &'c mut CircularList<T>,
current: NonNull<Node<T>>,
index: usize,
}
impl<'c, T> CursorMut<'c, T> {
pub(super) fn from_list(list: &'c mut CircularList<T>) -> Option<Self> {
list.head.map(|h| Self {
list,
current: h,
index: 0,
})
}
}
impl<'c, T> CursorMut<'c, T> {
pub fn index(&self) -> usize {
self.index
}
pub fn move_next(&mut self) {
unsafe {
self.current = Node::next(self.current);
}
self.index = (self.index + 1) % self.list.len();
}
pub fn move_prev(&mut self) {
unsafe {
self.current = Node::prev(self.current);
}
let len = self.list.len();
self.index = (len + self.index - 1) % len;
}
pub fn move_node_next(&mut self) {
if self.list.len() < 3 {
return;
}
let current = self.current;
unsafe {
let prev = Node::prev(current);
let next = Node::next(current);
let next_next = Node::next(next);
Node::connect(current, next_next);
Node::connect(next, current);
Node::connect(prev, next);
}
}
pub fn move_node_prev(&mut self) {
if self.list.len() < 3 {
return;
}
let current = self.current;
unsafe {
let prev = Node::prev(current);
let prev_prev = Node::prev(prev);
let next = Node::next(current);
Node::connect(current, prev);
Node::connect(prev, next);
Node::connect(prev_prev, current);
}
}
pub fn current(&mut self) -> &'c mut T {
unsafe { Node::value_mut(self.current) }
}
pub fn peek_next(&self) -> &'c T {
unsafe {
let next = Node::next(self.current);
Node::value(next)
}
}
pub fn peek_prev(&self) -> &'c T {
unsafe {
let prev = Node::prev(self.current);
Node::value(prev)
}
}
}