use std::pin::Pin;
use crate::{
list::{
IntrusiveList,
cursor::{Cursor, CursorMut},
},
mpsc,
selector::{
Removed,
borrowed::{Borrowed, BorrowedMut},
},
task::Task,
};
pub struct Iter<'a, P> {
pub(super) cursor: Cursor<'a, Task<P>>,
pub(super) queue: &'a mpsc::Receiver<Task<P>>,
}
impl<'a, P> Iterator for Iter<'a, P> {
type Item = Borrowed<'a, P>;
fn next(&mut self) -> Option<Self::Item> {
Some(Borrowed {
node: self.cursor.pop_front()?,
queue: self.queue,
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.cursor.len();
(len, Some(len))
}
}
impl<P> ExactSizeIterator for Iter<'_, P> {
fn len(&self) -> usize {
self.cursor.len()
}
}
impl<P> DoubleEndedIterator for Iter<'_, P> {
fn next_back(&mut self) -> Option<Self::Item> {
Some(Borrowed {
node: self.cursor.pop_back()?,
queue: self.queue,
})
}
}
pub struct IterMut<'a, P> {
pub(super) cursor: CursorMut<'a, Task<P>>,
pub(super) queue: &'a mpsc::Receiver<Task<P>>,
}
impl<'a, P> Iterator for IterMut<'a, P> {
type Item = BorrowedMut<'a, P>;
fn next(&mut self) -> Option<Self::Item> {
Some(BorrowedMut {
node: self.cursor.pop_front()?,
queue: self.queue,
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.cursor.len();
(len, Some(len))
}
}
impl<P> ExactSizeIterator for IterMut<'_, P> {
fn len(&self) -> usize {
self.cursor.len()
}
}
impl<P> DoubleEndedIterator for IterMut<'_, P> {
fn next_back(&mut self) -> Option<Self::Item> {
Some(BorrowedMut {
node: self.cursor.pop_back()?,
queue: self.queue,
})
}
}
pub struct IntoIter<P>(pub(super) IntrusiveList<Task<P>>);
impl<P> Iterator for IntoIter<P> {
type Item = Removed<P>;
fn next(&mut self) -> Option<Self::Item> {
CursorMut::new(&mut self.0).remove_front().map(Removed)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.0.len();
(len, Some(len))
}
}
impl<P> ExactSizeIterator for IntoIter<P> {
fn len(&self) -> usize {
self.0.len()
}
}
impl<P> DoubleEndedIterator for IntoIter<P> {
fn next_back(&mut self) -> Option<Self::Item> {
CursorMut::new(&mut self.0).remove_back().map(Removed)
}
}
pub struct ExtractIf<'a, P, F>
where
F: FnMut(Pin<&mut P>) -> bool,
{
pub(super) cursor: CursorMut<'a, Task<P>>,
pub(super) pred: F,
}
impl<'a, P, F> Iterator for ExtractIf<'a, P, F>
where
F: FnMut(Pin<&mut P>) -> bool,
{
type Item = Removed<P>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let mut front = self.cursor.peek_front()?;
if (self.pred)(front.get_protected_mut()) {
return self.cursor.remove_front().map(Removed);
} else {
self.cursor.pop_front();
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.cursor.len();
(0, Some(len))
}
}
impl<'a, P, F> DoubleEndedIterator for ExtractIf<'a, P, F>
where
F: FnMut(Pin<&mut P>) -> bool,
{
fn next_back(&mut self) -> Option<Self::Item> {
loop {
let mut back = self.cursor.peek_back()?;
if (self.pred)(back.get_protected_mut()) {
return self.cursor.remove_back().map(Removed);
} else {
self.cursor.pop_back();
}
}
}
}