#![no_std]
extern crate alloc;
mod head;
mod invariants;
mod sort;
pub use head::cursor::{Cursor, CursorMut, DoubleCursor};
use {
crate::head::{Iter, IterMut, ListHead},
alloc::boxed::Box,
core::{iter::FromIterator, ops::Not, ptr},
};
#[macro_export]
macro_rules! list {
[$($elem:expr),* $(,)?] => {{
#[allow(unused_mut)]
let mut l = $crate::CircularList::default();
$(
l.add($elem);
)*
l
}};
[@each $iter:expr] => {{
$iter.collect::<$crate::CircularList<_>>()
}};
}
pub struct CircularList<T> {
head: *const ListHead<T>,
length: usize,
}
impl<T> CircularList<T> {
pub(crate) unsafe fn insert_after(&mut self, val: T, element: *mut ListHead<T>) {
let new = Box::into_raw(ListHead::<T>::new(val));
unsafe {
(*element).add_after(new);
}
self.length += 1;
}
}
impl<T> CircularList<T> {
pub fn len(&self) -> usize {
self.length
}
pub fn is_empty(&self) -> bool {
self.length == 0
}
pub fn add(&mut self, val: T) {
let new = Box::into_raw(ListHead::<T>::new(val));
if self.head.is_null() {
debug_assert_eq!(self.length, 0);
self.head = new;
} else {
let head = self.head as *mut ListHead<T>;
unsafe {
(*head).add(new);
}
}
self.length += 1;
}
pub fn peek(&self) -> &T {
if self.is_empty() {
panic!("Cannot peek when list is empty");
}
unsafe {
(*self.head).value()
}
}
pub fn remove(&mut self) -> Option<T> {
if self.head.is_null() {
debug_assert_eq!(self.length, 0);
None
} else {
let (new_head, old_val) = unsafe {
ListHead::<T>::del_entry(self.head as *mut _)
};
self.head = new_head;
self.length -= 1;
debug_assert_eq!(self.head.is_null(), self.length == 0);
Some(old_val)
}
}
pub fn pop(&mut self) -> Option<T> {
if self.length == 1 {
self.remove()
} else if self.head.is_null() {
debug_assert_eq!(self.length, 0);
None
} else {
let (_, old_val) = unsafe {
ListHead::<T>::del_entry((*self.head).prev() as *mut _)
};
self.length -= 1;
Some(old_val)
}
}
pub fn exchange(&mut self, i: usize, j: usize) {
if self.is_empty() {
return;
}
let i = i % self.length;
let j = j % self.length;
if i == j {
return;
}
let from = i.min(j);
let count = i.max(j) - from;
let mut item1 = self.head as *mut ListHead<T>;
for _ in 0..from {
item1 = unsafe {
(*item1).next()
} as *mut _;
}
let mut item2 = item1;
for _ in 0..count {
item2 = unsafe {
(*item2).next()
} as *mut _;
}
unsafe {
ListHead::<T>::swap(item1, item2);
}
if item1 as *const _ == self.head {
self.head = item2 as *const _;
} else if item2 as *const _ == self.head {
self.head = item1 as *const _;
}
}
pub fn append(&mut self, mut other: Self) {
if self.head.is_null() {
self.head = other.head;
} else if !other.head.is_null() {
let other_head = other.head as *mut ListHead<T>;
let head = self.head as *mut ListHead<T>;
unsafe {
ListHead::<T>::add_list(other_head, head);
}
}
self.length += other.length;
other.head = ptr::null();
other.length = 0;
}
pub fn merge(&mut self, mut other: Self)
where
T: PartialOrd,
{
if self.is_empty() {
self.append(other);
} else if other.is_empty().not() {
let mut s = self.head as *mut ListHead<T>;
let mut s_head = s;
let mut o = other.head as *mut ListHead<T>;
unsafe {
let mut s_next = (*s).next() as *mut ListHead<T>;
let mut o_next = (*o).next() as *mut ListHead<T>;
let o_end = (*o).prev() as *mut ListHead<T>;
if *o < *s {
self.head = o;
s_head = o;
}
let mut reached_end_of_s = false;
loop {
if reached_end_of_s {
ListHead::add_list(o, s_head);
break;
} else if *o < *s {
ListHead::move_entry(o, (*s).prev() as *mut _, s);
if o == o_end {
break;
}
o = o_next;
o_next = (*o).next() as *mut ListHead<T>;
} else {
s = s_next;
s_next = (*s).next() as *mut ListHead<T>;
reached_end_of_s = s == s_head;
}
}
}
self.length += other.length;
other.head = ptr::null();
other.length = 0;
}
}
pub fn sort(&mut self)
where
T: PartialOrd,
{
sort::sort::<T, sort::MergeSort<T>>(self)
}
pub fn left_rot(&mut self, count: usize) {
if self.is_empty() {
return;
}
let count = count % self.length;
for _ in 0..count {
self.head = unsafe {
(*self.head).next()
};
}
}
pub fn rotate(&mut self, count: isize) {
if self.is_empty() {
return;
}
let count = count.rem_euclid(self.length as isize);
for _ in 0..count {
self.head = unsafe {
(*self.head).next()
};
}
}
pub fn rotate_until<F: Fn(&T) -> bool>(&mut self, f: F) {
if self.is_empty() {
return;
}
loop {
if f(self.peek()) {
break;
}
self.left_rot(1);
}
}
pub fn right_rot(&mut self, count: usize) {
if self.is_empty() {
return;
}
let count = count % self.length;
for _ in 0..count {
self.head = unsafe {
(*self.head).prev()
};
}
}
pub fn iter_forever(&self) -> impl Iterator<Item = &T> {
self.is_empty()
.not()
.then(|| Iter::new(self))
.into_iter()
.flatten()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.iter_forever().take(self.len())
}
pub fn iter_mut_forever(&mut self) -> impl Iterator<Item = &mut T> {
self.is_empty()
.not()
.then(|| IterMut::new(self))
.into_iter()
.flatten()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
let len = self.len();
self.iter_mut_forever().take(len)
}
pub fn cursor(&self) -> Option<Cursor<T>> {
self.is_empty().not().then(|| Cursor::from_list(self))
}
pub fn cursor_mut(&mut self) -> Option<CursorMut<T>> {
self.is_empty().not().then(|| CursorMut::from_list(self))
}
pub fn double_cursor(&mut self) -> Option<DoubleCursor<T>> {
self.is_empty().not().then(|| DoubleCursor::from_list(self))
}
}
impl<T> Default for CircularList<T> {
fn default() -> Self {
Self {
head: ptr::null(),
length: 0,
}
}
}
impl<T: Clone> Clone for CircularList<T> {
fn clone(&self) -> Self {
let mut clone: Self = Default::default();
for x in self.iter() {
clone.add(x.clone());
}
clone
}
}
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.add(x);
}
new
}
}
impl<T> Drop for CircularList<T> {
fn drop(&mut self) {
while self.remove().is_some() {}
}
}
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()
}
}
pub struct IntoIter<T>(CircularList<T>);
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.remove()
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.pop()
}
}
impl<T> IntoIterator for CircularList<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter::<T>(self)
}
}
#[cfg(test)]
mod tests {
use {
super::*,
alloc::{vec, vec::Vec},
};
#[test]
fn empty() {
let l = CircularList::default();
assert_eq!(l.iter().copied().collect::<Vec<i32>>(), &[]);
}
#[test]
fn add() {
let l = list![42, 43, 44, 45, 46];
assert_eq!(l.into_iter().collect::<Vec<i32>>(), &[42, 43, 44, 45, 46])
}
#[test]
fn remove() {
let mut l = list![42, 43, 44, 45, 46];
assert_eq!(Some(42), l.remove());
assert_eq!(Some(43), l.remove());
assert_eq!(Some(44), l.remove());
assert_eq!(Some(45), l.remove());
assert_eq!(Some(46), l.remove());
}
#[test]
fn mutating() {
let mut l = list![42, 43, 44, 45, 46];
for x in l.iter_mut() {
*x += 1;
}
assert_eq!(
l.iter().copied().collect::<Vec<i32>>(),
&[43, 44, 45, 46, 47]
);
}
#[test]
fn exchange() {
for (i, j, expected) in [
(1, 3, &[42, 45, 44, 43, 46]),
(0, 1, &[43, 42, 44, 45, 46]),
(1, 2, &[42, 44, 43, 45, 46]),
(3, 4, &[42, 43, 44, 46, 45]),
(2, 2, &[42, 43, 44, 45, 46]),
(0, 4, &[46, 43, 44, 45, 42]),
] {
let mut l = list![42, 43, 44, 45, 46];
l.exchange(i, j);
assert_eq!(l.into_iter().collect::<Vec<i32>>(), expected);
}
let mut l = list![42, 43];
l.exchange(0, 1);
assert_eq!(l.into_iter().collect::<Vec<i32>>(), &[43, 42]);
}
#[test]
fn left_rotate() {
let mut l = list![42, 43, 44, 45, 46];
l.left_rot(3);
assert_eq!(l.into_iter().collect::<Vec<i32>>(), &[45, 46, 42, 43, 44]);
}
#[test]
fn right_rotate() {
let mut l = list![42, 43, 44, 45, 46];
l.right_rot(3);
assert_eq!(l.into_iter().collect::<Vec<i32>>(), &[44, 45, 46, 42, 43]);
}
#[test]
fn into_iter_double_ended_iterator() {
let numbers = list![1, 2, 3, 4, 5, 6];
let mut iter = numbers.into_iter();
assert_eq!(Some(1), iter.next());
assert_eq!(Some(6), iter.next_back());
assert_eq!(Some(5), iter.next_back());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(3), iter.next());
assert_eq!(Some(4), iter.next());
assert_eq!(None, iter.next());
assert_eq!(None, iter.next_back());
}
#[test]
fn iter_forever() {
let numbers = list![1, 2, 3, 4, 5, 6];
let double_sum = numbers
.iter_forever()
.take(2 * numbers.len())
.copied()
.sum();
assert_eq!(42, double_sum);
}
#[test]
fn from_iterator() {
let mut numbers: CircularList<_> = vec![4, 5, 6, 7].into_iter().collect();
assert_eq!(Some(7), numbers.pop());
assert_eq!(Some(6), numbers.pop());
assert_eq!(Some(5), numbers.pop());
assert_eq!(Some(4), numbers.pop());
assert_eq!(None, numbers.pop());
}
#[test]
fn into_iter_rev() {
let numbers = list![1, 2, 3];
let mut iter = numbers.into_iter().rev();
assert_eq!(Some(3), iter.next());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(1), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn append() {
let mut a = list![1, 2, 3];
let b = list![4, 5, 6, 7];
a.append(b);
assert_eq!(a.len(), 7);
assert_eq!(a.into_iter().collect::<Vec<i32>>(), &[1, 2, 3, 4, 5, 6, 7]);
let mut a = list![1, 2, 3];
a.append(list![]);
assert_eq!(a.len(), 3);
assert_eq!(a.into_iter().collect::<Vec<i32>>(), &[1, 2, 3]);
let mut a = list![];
a.append(list![1, 2, 3]);
assert_eq!(a.len(), 3);
assert_eq!(a.into_iter().collect::<Vec<i32>>(), &[1, 2, 3]);
let mut a = list![];
a.append(list![]);
assert_eq!(a.len(), 0);
assert_eq!(a.into_iter().collect::<Vec<i32>>(), &[]);
}
#[test]
fn merge() {
for (mut a, b, c) in [
(list![1, 2, 3], list![], vec![1, 2, 3]),
(list![], list![1, 2, 3], vec![1, 2, 3]),
(list![1], list![0], vec![0, 1]),
(list![1], list![0], vec![0, 1]),
(list![1, 2, 3], list![4, 5, 6], vec![1, 2, 3, 4, 5, 6]),
(list![1, 3, 5], list![2, 4, 6], vec![1, 2, 3, 4, 5, 6]),
(list![1, 3, 5], list![0, 2, 4, 6], vec![0, 1, 2, 3, 4, 5, 6]),
(list![1, 3, 5], list![2, 4], vec![1, 2, 3, 4, 5]),
(list![1, 3, 5], list![2, 2, 4, 4], vec![1, 2, 2, 3, 4, 4, 5]),
(list![1, 3], list![0, 0, 4, 8], vec![0, 0, 1, 3, 4, 8]),
(list![7, 8, 9], list![1, 2, 8], vec![1, 2, 7, 8, 8, 9]),
(list![5, 5, 6], list![5, 8, 9], vec![5, 5, 5, 6, 8, 9]),
(list![1, 2, 3], list![1, 2, 3], vec![1, 1, 2, 2, 3, 3]),
] {
a.merge(b);
assert_eq!(a.into_iter().collect::<Vec<i32>>(), c);
}
}
}