use core::marker::PhantomData;
use core::ptr::NonNull;
use crate::node::Node;
pub struct Iter<'a, T> {
current: Option<NonNull<Node<T>>>,
back: Option<NonNull<Node<T>>>,
remaining: usize,
_marker: PhantomData<&'a T>,
}
impl<'a, T> Iter<'a, T> {
pub(crate) fn new(head: Option<NonNull<Node<T>>>, length: usize) -> Self {
let back = if length > 0 {
head.map(|h| unsafe { Node::get_prev(h) })
} else {
None
};
Self {
current: head,
back,
remaining: length,
_marker: PhantomData,
}
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
unsafe {
let current = self.current.unwrap_unchecked();
let data = Node::data_ref(current);
self.current = Some(Node::get_next(current));
self.remaining -= 1;
Some(data)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize {
self.remaining
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
unsafe {
let back = self.back.unwrap_unchecked();
let data = Node::data_ref(back);
self.back = Some(Node::get_prev(back));
self.remaining -= 1;
Some(data)
}
}
}
impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Self {
Self {
current: self.current,
back: self.back,
remaining: self.remaining,
_marker: PhantomData,
}
}
}
pub struct IterMut<'a, T> {
current: Option<NonNull<Node<T>>>,
back: Option<NonNull<Node<T>>>,
remaining: usize,
_marker: PhantomData<&'a mut T>,
}
impl<'a, T> IterMut<'a, T> {
pub(crate) fn new(head: Option<NonNull<Node<T>>>, length: usize) -> Self {
let back = if length > 0 {
head.map(|h| unsafe { Node::get_prev(h) })
} else {
None
};
Self {
current: head,
back,
remaining: length,
_marker: PhantomData,
}
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
unsafe {
let current = self.current.unwrap_unchecked();
let data = Node::data_mut(current);
self.current = Some(Node::get_next(current));
self.remaining -= 1;
Some(data)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
fn len(&self) -> usize {
self.remaining
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
unsafe {
let back = self.back.unwrap_unchecked();
let data = Node::data_mut(back);
self.back = Some(Node::get_prev(back));
self.remaining -= 1;
Some(data)
}
}
}
pub struct IntoIter<T> {
current: Option<NonNull<Node<T>>>,
remaining: usize,
}
impl<T> IntoIter<T> {
pub(crate) fn new(head: Option<NonNull<Node<T>>>, length: usize) -> Self {
Self {
current: head,
remaining: length,
}
}
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
unsafe {
let current = self.current.unwrap_unchecked();
let next = Node::get_next(current);
self.current = if self.remaining == 1 {
None
} else {
Some(next)
};
self.remaining -= 1;
Some(Node::dealloc(current))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize {
self.remaining
}
}
impl<T> Drop for IntoIter<T> {
fn drop(&mut self) {
if self.remaining == 0 {
return;
}
unsafe {
let mut current = self.current.unwrap();
let mut count = 0;
while count < self.remaining {
let next = Node::get_next(current);
Node::dealloc(current);
current = next;
count += 1;
}
}
self.current = None;
self.remaining = 0;
}
}