orx_linked_list/iter/
doubly_iter_mut.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 mutable references to elements of the doubly linked list.
7///
8/// Can be created by calling the `iter_mut` method.
9pub struct DoublyIterMut<'a, T, P>
10where
11    P: PinnedVec<Node<Doubly<T>>>,
12{
13    col: &'a mut CoreCol<Doubly<T>, P>,
14    current: Option<NodePtr<Doubly<T>>>,
15    current_back: Option<NodePtr<Doubly<T>>>,
16}
17
18impl<'a, T, P> DoublyIterMut<'a, T, P>
19where
20    P: PinnedVec<Node<Doubly<T>>>,
21{
22    pub(crate) fn new(
23        col: &'a mut 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 restart_for(
35        &mut self,
36        current: Option<NodePtr<Doubly<T>>>,
37        current_back: Option<NodePtr<Doubly<T>>>,
38    ) {
39        self.current = current;
40        self.current_back = current_back;
41    }
42
43    fn end(&mut self) {
44        self.current = None;
45        self.current_back = None;
46    }
47}
48
49impl<'a, T, P> Iterator for DoublyIterMut<'a, T, P>
50where
51    P: PinnedVec<Node<Doubly<T>>>,
52{
53    type Item = &'a mut T;
54
55    fn next(&mut self) -> Option<Self::Item> {
56        match self.current {
57            Some(p) => {
58                let ptr = unsafe { p.ptr_mut() };
59                match self.current == self.current_back {
60                    false => self.current = self.col.node(p).next().get(),
61                    true => self.end(),
62                }
63
64                unsafe { &mut *ptr }.data_mut()
65            }
66            None => None,
67        }
68    }
69}
70
71impl<T, P> DoubleEndedIterator for DoublyIterMut<'_, T, P>
72where
73    P: PinnedVec<Node<Doubly<T>>>,
74{
75    fn next_back(&mut self) -> Option<Self::Item> {
76        match self.current_back {
77            Some(p) => {
78                // SAFETY: collection as alive as guaranteed by the `col` field.
79                let ptr = unsafe { p.ptr_mut() };
80                match self.current == self.current_back {
81                    false => self.current_back = self.col.node(p).prev().get(),
82                    true => self.end(),
83                }
84                unsafe { &mut *ptr }.data_mut()
85            }
86            None => None,
87        }
88    }
89}
90
91impl<T, P> FusedIterator for DoublyIterMut<'_, T, P> where P: PinnedVec<Node<Doubly<T>>> {}