use core::ptr::NonNull;
use crate::iter::{IntoIter, Iter, IterMut};
use crate::node::Node;
pub struct CircularDoublyLinkedList<T> {
head: Option<NonNull<Node<T>>>,
tail: Option<NonNull<Node<T>>>,
length: usize,
}
impl<T> CircularDoublyLinkedList<T> {
pub fn new() -> Self {
Self {
head: None,
tail: None,
length: 0,
}
}
pub fn len(&self) -> usize {
self.length
}
pub fn is_empty(&self) -> bool {
self.length <= 0
}
pub fn front(&self) -> Option<&T> {
self.head.map(|head| unsafe { Node::data_ref(head) })
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.head.map(|head| unsafe { Node::data_mut(head) })
}
pub fn back(&self) -> Option<&T> {
self.tail.map(|tail| unsafe { Node::data_ref(tail) })
}
pub fn back_mut(&mut self) -> Option<&mut T> {
self.tail.map(|tail| unsafe { Node::data_mut(tail) })
}
pub fn push_front(&mut self, value: T) {
let new_node = Node::new(value);
unsafe {
match (self.head, self.tail) {
(None, None) => {
self.head = Some(new_node);
self.tail = Some(new_node);
}
(Some(head), Some(tail)) => {
Node::set_next(new_node, head);
Node::set_prev(new_node, tail);
Node::set_prev(head, new_node);
Node::set_next(tail, new_node);
self.head = Some(new_node);
}
_ => unreachable!("head and tail must both be None or both be Some"),
}
}
self.length += 1;
}
pub fn push_back(&mut self, value: T) {
let new_node = Node::new(value);
unsafe {
match (self.head, self.tail) {
(None, None) => {
self.head = Some(new_node);
self.tail = Some(new_node);
}
(Some(head), Some(tail)) => {
Node::set_next(new_node, head);
Node::set_prev(new_node, tail);
Node::set_next(tail, new_node);
Node::set_prev(head, new_node);
self.tail = Some(new_node);
}
_ => unreachable!("head and tail must both be None or both be Some"),
}
}
self.length += 1;
}
pub fn pop_front(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
unsafe {
let head = self.head?;
let tail = self.tail?;
let next = Node::get_next(head);
let result = if self.length == 1 {
self.head = None;
self.tail = None;
Some(Node::dealloc(head))
} else {
Node::set_next(tail, next);
Node::set_prev(next, tail);
self.head = Some(next);
Some(Node::dealloc(head))
};
self.length -= 1;
result
}
}
pub fn pop_back(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
unsafe {
let head = self.head?;
let tail = self.tail?;
let prev = Node::get_prev(tail);
let result = if self.length == 1 {
self.head = None;
self.tail = None;
Some(Node::dealloc(tail))
} else {
Node::set_next(prev, head);
Node::set_prev(head, prev);
self.tail = Some(prev);
Some(Node::dealloc(tail))
};
self.length -= 1;
result
}
}
pub fn insert_after(&mut self, position: usize, value: T) -> bool {
if position >= self.length {
return false;
}
let target_node = unsafe { self.get_node_at(position).unwrap() };
unsafe {
let new_node = Node::new(value);
let next = Node::get_next(target_node);
Node::set_next(new_node, next);
Node::set_prev(new_node, target_node);
Node::set_next(target_node, new_node);
Node::set_prev(next, new_node);
if Some(target_node) == self.tail {
self.tail = Some(new_node);
}
}
self.length += 1;
true
}
pub fn remove_at(&mut self, position: usize) -> Option<T> {
if self.is_empty() || position >= self.length {
return None;
}
let target_node = unsafe { self.get_node_at(position)? };
unsafe {
let next = Node::get_next(target_node);
let prev = Node::get_prev(target_node);
if Some(target_node) == self.head {
self.head = Some(next);
}
if Some(target_node) == self.tail {
self.tail = Some(prev)
}
if self.length == 1 {
self.head = None;
self.tail = None;
} else {
Node::set_next(prev, next);
Node::set_prev(next, prev);
}
self.length -= 1;
Some(Node::dealloc(target_node))
}
}
pub fn clear(&mut self) {
while self.pop_front().is_some() {}
}
pub fn iter(&self) -> Iter<'_, T> {
Iter::new(self.head, self.length)
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut::new(self.head, self.length)
}
pub fn rotate_left(&mut self) {
if self.length > 1 {
unsafe {
let head = self.head.unwrap();
let new_head = Node::get_next(head);
let new_tail = head;
self.head = Some(new_head);
self.tail = Some(new_tail);
}
}
}
pub fn rotate_right(&mut self) {
if self.length > 1 {
unsafe {
let tail = self.tail.unwrap();
let new_head = tail;
let new_tail = Node::get_prev(tail);
self.head = Some(new_head);
self.tail = Some(new_tail);
}
}
}
unsafe fn get_node_at(&self, position: usize) -> Option<NonNull<Node<T>>> {
if self.is_empty() || position >= self.length {
return None;
}
if position < self.length / 2 {
let mut current = self.head?;
for _ in 0..position {
current = unsafe { Node::get_next(current) }
}
Some(current)
} else {
let mut current = self.tail?;
for _ in position + 1..self.length {
current = unsafe { Node::get_prev(current) }
}
Some(current)
}
}
}
impl<T> Default for CircularDoublyLinkedList<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Drop for CircularDoublyLinkedList<T> {
fn drop(&mut self) {
self.clear();
}
}
impl<T> Clone for CircularDoublyLinkedList<T>
where
T: Clone,
{
fn clone(&self) -> Self {
let mut new_list = CircularDoublyLinkedList::<T>::new();
for item in self.iter() {
new_list.push_back(item.clone());
}
new_list
}
}
impl<T> Extend<T> for CircularDoublyLinkedList<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for item in iter {
self.push_back(item);
}
}
}
impl<T: core::fmt::Debug> core::fmt::Debug for CircularDoublyLinkedList<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<T> FromIterator<T> for CircularDoublyLinkedList<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut list = CircularDoublyLinkedList::<T>::new();
list.extend(iter);
list
}
}
impl<T> IntoIterator for CircularDoublyLinkedList<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
let iter = IntoIter::new(self.head, self.length);
core::mem::forget(self);
iter
}
}
impl<'a, T> IntoIterator for &'a CircularDoublyLinkedList<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut CircularDoublyLinkedList<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}