orx_linked_list/iter/
doubly_iter_ptr.rs

1use crate::Doubly;
2use core::iter::FusedIterator;
3use orx_pinned_vec::PinnedVec;
4use orx_selfref_col::{CoreCol, Node, NodePtr};
5
6/// An ordered iterator over pointers to the elements of the doubly linked list.
7///
8/// Can be created by calling the `iter_ptr` method.
9pub struct DoublyIterPtr<'a, T, P>
10where
11    P: PinnedVec<Node<Doubly<T>>>,
12{
13    pub(crate) col: &'a CoreCol<Doubly<T>, P>,
14    current: Option<NodePtr<Doubly<T>>>,
15    current_back: Option<NodePtr<Doubly<T>>>,
16}
17
18impl<'a, T, P> DoublyIterPtr<'a, T, P>
19where
20    P: PinnedVec<Node<Doubly<T>>>,
21{
22    pub(crate) fn new(
23        col: &'a CoreCol<Doubly<T>, P>,
24        current: Option<NodePtr<Doubly<T>>>,
25        current_back: Option<NodePtr<Doubly<T>>>,
26    ) -> Self {
27        Self {
28            col,
29            current,
30            current_back,
31        }
32    }
33
34    pub(crate) fn end(&mut self) {
35        self.current = None;
36        self.current_back = None;
37    }
38}
39
40impl<T, P> Iterator for DoublyIterPtr<'_, T, P>
41where
42    P: PinnedVec<Node<Doubly<T>>>,
43{
44    type Item = NodePtr<Doubly<T>>;
45
46    fn next(&mut self) -> Option<Self::Item> {
47        match &self.current {
48            Some(p) => {
49                let ptr = Some(p.clone());
50                match self.current == self.current_back {
51                    false => self.current = self.col.node(p).next().get().cloned(),
52                    true => self.end(),
53                }
54
55                ptr
56            }
57            None => None,
58        }
59    }
60}
61
62impl<T, P> DoubleEndedIterator for DoublyIterPtr<'_, T, P>
63where
64    P: PinnedVec<Node<Doubly<T>>>,
65{
66    fn next_back(&mut self) -> Option<Self::Item> {
67        match &self.current_back {
68            Some(p) => {
69                let ptr = Some(p.clone());
70
71                match self.current == self.current_back {
72                    false => self.current_back = self.col.node(p).prev().get().cloned(),
73                    true => self.end(),
74                }
75
76                ptr
77            }
78            None => None,
79        }
80    }
81}
82
83impl<T, P> FusedIterator for DoublyIterPtr<'_, T, P> where P: PinnedVec<Node<Doubly<T>>> {}
84
85impl<T, P> Clone for DoublyIterPtr<'_, T, P>
86where
87    P: PinnedVec<Node<Doubly<T>>>,
88{
89    fn clone(&self) -> Self {
90        Self {
91            col: self.col,
92            current: self.current.clone(),
93            current_back: self.current_back.clone(),
94        }
95    }
96}