orx_linked_list/iter/
doubly_iter_owned.rs

1use crate::Doubly;
2use core::iter::FusedIterator;
3use orx_pinned_vec::PinnedVec;
4use orx_selfref_col::{CoreCol, Node, NodePtr};
5
6/// An ordered consuming iterator of the doubly linked list.
7///
8/// Can be created by calling the `into_iter` method.
9pub struct DoublyIterOwned<T, P>
10where
11    P: PinnedVec<Node<Doubly<T>>>,
12{
13    col: CoreCol<Doubly<T>, P>,
14    current: Option<NodePtr<Doubly<T>>>,
15    current_back: Option<NodePtr<Doubly<T>>>,
16}
17
18impl<T, P> DoublyIterOwned<T, P>
19where
20    P: PinnedVec<Node<Doubly<T>>>,
21{
22    pub(crate) fn new(col: CoreCol<Doubly<T>, P>) -> Self {
23        let current = col.ends().get(0);
24        let current_back = col.ends().get(1);
25        Self {
26            col,
27            current,
28            current_back,
29        }
30    }
31
32    fn end(&mut self) {
33        self.current = None;
34        self.current_back = None;
35    }
36}
37
38impl<T, P> Iterator for DoublyIterOwned<T, P>
39where
40    P: PinnedVec<Node<Doubly<T>>>,
41{
42    type Item = T;
43
44    fn next(&mut self) -> Option<Self::Item> {
45        match self.current {
46            Some(p) => {
47                let ptr = unsafe { p.ptr_mut() };
48                match self.current == self.current_back {
49                    false => self.current = self.col.node(p).next().get(),
50                    true => self.end(),
51                }
52
53                unsafe { &mut *ptr }.take_data()
54            }
55            None => None,
56        }
57    }
58}
59
60impl<T, P> DoubleEndedIterator for DoublyIterOwned<T, P>
61where
62    P: PinnedVec<Node<Doubly<T>>>,
63{
64    fn next_back(&mut self) -> Option<Self::Item> {
65        match self.current_back {
66            Some(p) => {
67                // SAFETY: collection as alive as guaranteed by the `col` field.
68                let ptr = unsafe { p.ptr_mut() };
69                match self.current == self.current_back {
70                    false => self.current_back = self.col.node(p).prev().get(),
71                    true => self.end(),
72                }
73
74                unsafe { &mut *ptr }.take_data()
75            }
76            None => None,
77        }
78    }
79}
80
81impl<T, P> FusedIterator for DoublyIterOwned<T, P> where P: PinnedVec<Node<Doubly<T>>> {}