use alloc::boxed::Box;
pub(crate) mod node;
use crate::cursor::{Cursor, CursorMut};
use {
crate::iter::{IntoIter, Iter, IterMut, Rev},
core::{marker::PhantomData, ptr::NonNull},
node::Node,
};
pub struct CircularList<T> {
pub(crate) head: Option<NonNull<Node<T>>>,
len: usize,
_marker: PhantomData<Box<Node<T>>>,
}
impl<T> Default for CircularList<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Clone> Clone for CircularList<T> {
fn clone(&self) -> Self {
let mut clone: Self = Default::default();
for x in self.iter() {
clone.push_back(x.clone());
}
clone
}
}
impl<T: core::fmt::Debug> core::fmt::Debug for CircularList<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<T: PartialEq> PartialEq for CircularList<T> {
fn eq(&self, other: &Self) -> bool {
let mut self_iter = self.iter();
let mut other_iter = other.iter();
loop {
match (self_iter.next(), other_iter.next()) {
(Some(self_elem), Some(other_elem)) if self_elem == other_elem => {}
(None, None) => break true,
_ => break false,
}
}
}
}
impl<T: Eq> Eq for CircularList<T> {}
impl<T> FromIterator<T> for CircularList<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut new: Self = Default::default();
for x in iter {
new.push_back(x);
}
new
}
}
impl<T> CircularList<T> {
pub fn new() -> Self {
Self {
head: None,
len: 0,
_marker: PhantomData,
}
}
pub fn clear(&mut self) {
while self.pop_front().is_some() {}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.head.is_none()
}
pub fn front(&self) -> Option<&T> {
let head = self.head?;
Some(unsafe { Node::value(head) })
}
pub fn front_mut(&mut self) -> Option<&mut T> {
let head = self.head?;
Some(unsafe { Node::value_mut(head) })
}
pub fn back(&self) -> Option<&T> {
let head = self.head?;
Some(unsafe {
let tail = Node::prev(head);
Node::value(tail)
})
}
pub fn back_mut(&mut self) -> Option<&mut T> {
let head = self.head?;
Some(unsafe {
let tail = Node::prev(head);
Node::value_mut(tail)
})
}
pub fn push_back(&mut self, val: T) {
if let Some(head) = self.head {
unsafe {
Node::insert_prev(head, val);
}
} else {
self.head = Some(Node::new(val));
}
self.len += 1;
}
pub fn push_front(&mut self, val: T) {
self.push_back(val);
self.rotate(-1);
}
pub fn pop_front(&mut self) -> Option<T> {
let head = self.head?;
let next = unsafe { Node::next_distinct(head) };
let val = unsafe { Node::remove(head) };
self.head = next;
self.len -= 1;
Some(val)
}
pub fn pop_back(&mut self) -> Option<T> {
self.rotate(-1);
self.pop_front()
}
pub fn iter(&self) -> Iter<'_, T> {
Iter::from_list(self)
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut::from_list(self)
}
pub fn rev_iter(&self) -> Rev<'_, T> {
Rev::from_list(self)
}
pub fn cursor(&self) -> Option<Cursor<'_, T>> {
Cursor::from_list(self)
}
pub fn cursor_mut(&mut self) -> Option<CursorMut<'_, T>> {
CursorMut::from_list(self)
}
pub fn split_half(&mut self) -> Option<Self> {
let head = self.head?;
let len = self.len;
let (mid, idx) = unsafe { Node::half(self) }?;
if head == mid {
return Some(core::mem::take(self));
}
unsafe {
Node::split(head, mid);
}
self.len = idx;
Some(Self {
head: Some(mid),
len: len - idx,
..Default::default()
})
}
pub fn rotate(&mut self, mid: isize) {
let len = self.len() as isize;
if let Some(head) = self.head.as_mut() {
let n = mid.rem_euclid(len);
if n < 0 {
for _ in 0..-n {
unsafe {
*head = Node::prev(*head);
}
}
} else {
for _ in 0..n {
unsafe {
*head = Node::next(*head);
}
}
}
}
}
pub fn append(&mut self, other: &mut Self) {
match (self.head, other.head) {
(None, None) => {}
(Some(head), None) | (None, Some(head)) => {
self.head = Some(head);
}
(Some(head_a), Some(head_b)) => unsafe {
let tail_a = Node::prev(head_a);
let tail_b = Node::prev(head_b);
Node::connect(tail_a, head_b);
Node::connect(tail_b, head_a);
},
}
self.len += other.len;
other.head = None;
other.len = 0;
}
}
impl<T: PartialEq> CircularList<T> {
pub fn contains(&self, elem: &T) -> bool {
self.iter().any(|x| x == elem)
}
pub fn dedup(&mut self) {
let Some(head) = self.head else {
return;
};
let mut len = self.len;
unsafe {
let mut prev_value = Node::value(head);
let mut current = Node::next(head);
let mut value = Node::value(current);
loop {
if current == head {
break;
}
let next = Node::next(current);
if value == prev_value {
let _ = Node::remove(current);
len -= 1;
} else {
prev_value = value;
}
current = next;
value = Node::value(current);
}
}
self.len = len;
}
}
impl<T: PartialOrd> CircularList<T> {
pub fn merge(&mut self, other: &mut Self) {
match (self.head, other.head) {
(None, None) => {}
(Some(head), None) | (None, Some(head)) => {
self.head = Some(head);
}
(Some(head_a), Some(head_b)) => unsafe {
self.head = Some(Node::merge(head_a, head_b));
},
}
self.len += other.len;
other.len = 0;
other.head = None;
}
}
impl<T> Extend<T> for CircularList<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for val in iter {
self.push_back(val);
}
}
}
impl<T> IntoIterator for CircularList<T> {
type IntoIter = IntoIter<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
IntoIter::from_list(self)
}
}
impl<T> Drop for CircularList<T> {
fn drop(&mut self) {
while self.pop_front().is_some() {}
}
}