unrolled_linked_list/
iters.rs

1use std::ptr::NonNull;
2use std::marker::PhantomData;
3use crate::{UnrolledLinkedList, Node};
4use std::fmt;
5
6impl<'a, T> UnrolledLinkedList<T> {
7    /// Provides a forward iterator.
8    ///
9    /// # Examples
10    ///
11    /// ```
12    ///
13    /// use unrolled_linked_list::UnrolledLinkedList;
14    ///
15    /// let mut list: UnrolledLinkedList<u32> = UnrolledLinkedList::new();
16    ///
17    /// list.push(0);
18    /// list.push(1);
19    /// list.push(2);
20    ///
21    /// let mut iter = list.iter();
22    /// assert_eq!(iter.next(), Some(&0));
23    /// assert_eq!(iter.next(), Some(&1));
24    /// assert_eq!(iter.next(), Some(&2));
25    /// assert_eq!(iter.next(), None);
26    /// ```
27    pub fn iter(&self) -> Iter<'a, T> {
28        Iter {
29            len: self.len,
30            index: 0,
31            head: self.head,
32            tail: self.tail,
33            marker: Default::default(),
34        }
35    }
36
37    /// Provides a forward mut iterator.
38   ///
39   /// # Examples
40   ///
41   /// ```
42   ///
43   /// use unrolled_linked_list::UnrolledLinkedList;
44   ///
45   /// let mut list: UnrolledLinkedList<u32> = UnrolledLinkedList::new();
46   ///
47   /// list.push(0);
48   /// list.push(1);
49   /// list.push(2);
50   ///
51   /// for element in list.iter_mut() {
52   ///     *element += 10;
53   /// }
54   ///
55   /// let mut iter = list.iter();
56   /// assert_eq!(iter.next(), Some(&10));
57   /// assert_eq!(iter.next(), Some(&11));
58   /// assert_eq!(iter.next(), Some(&12));
59   /// assert_eq!(iter.next(), None);
60   /// ```
61    pub fn iter_mut(&'a mut self) -> IterMut<'a, T> {
62        IterMut {
63            len: self.len,
64            index: 0,
65            head: self.head,
66            delegate: self
67        }
68    }
69
70}
71/// An iterator over the elements of a `UnrolledLinkedList`.
72///
73/// This `struct` is created by [`UnrolledLinkedList::iter()`]. See its
74/// documentation for more.
75pub struct Iter<'a, T> {
76    len: usize,
77    index: usize,
78    head: Option<NonNull<Node<T>>>,
79    tail: Option<NonNull<Node<T>>>,
80    marker: PhantomData<&'a Node<T>>,
81}
82
83impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        f.debug_tuple("Iter").field(&self.len).finish()
86    }
87}
88impl<T> Clone for Iter<'_, T> {
89    fn clone(&self) -> Self {
90        Iter { ..*self }
91    }
92}
93
94impl<'a, T> Iterator for Iter<'a, T> {
95    type Item = &'a T;
96
97    fn next(&mut self) -> Option<&'a T> {
98        if let Some(n) = self.head {
99            unsafe {
100                let node = &*n.as_ptr();
101                let elem = node.data.get(self.index);
102                if self.index + 1 >= node.data.len() {
103                    self.index = 0;
104                    self.head = node.next;
105                } else {
106                    self.index += 1;
107                }
108                self.len -= 1;
109                elem
110            }
111        } else { None }
112    }
113    #[inline]
114    fn size_hint(&self) -> (usize, Option<usize>) {
115        (self.len, Some(self.len))
116    }
117
118    #[inline]
119    fn last( self) -> Option<&'a T> {
120        unsafe {
121            match (self.head, self.tail) {
122                (Some(n), None) | (_, Some(n)) => (*n.as_ptr()).data.last(),
123                _ => None
124            }
125        }
126    }
127}
128
129/// An owning iterator over the elements of a `UnrolledLinkedList`.
130///
131/// This `struct` is created by the [`into_iter`] method on [`UnrolledLinkedList`]
132/// (provided by the `IntoIterator` trait). See its documentation for more.
133///
134/// [`into_iter`]: UnrolledLinkedList::into_iter
135pub struct IntoIter<T> {
136    delegate: UnrolledLinkedList<T>,
137}
138
139impl<T> Iterator for IntoIter<T> {
140    type Item = T;
141
142    #[inline]
143    fn next(&mut self) -> Option<T> {
144        if self.delegate.is_empty() { None } else { Some(self.delegate.remove(0)) }
145    }
146
147    #[inline]
148    fn size_hint(&self) -> (usize, Option<usize>) {
149        (self.delegate.len, Some(self.delegate.len))
150    }
151}
152
153impl<T> IntoIterator for UnrolledLinkedList<T> {
154    type Item = T;
155    type IntoIter = IntoIter<T>;
156
157    fn into_iter(self) -> Self::IntoIter {
158        IntoIter { delegate: self }
159    }
160}
161impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163        f.debug_tuple("IntoIter").field(&self.delegate).finish()
164    }
165}
166impl<'a, T> IntoIterator for &'a UnrolledLinkedList<T> {
167    type Item = &'a T;
168    type IntoIter = Iter<'a, T>;
169
170    fn into_iter(self) -> Self::IntoIter {
171        self.iter()
172    }
173}
174
175/// A mutable iterator over the elements of a `UnrolledLinkedList`.
176///
177/// This `struct` is created by [`UnrolledLinkedList::iter_mut()`].
178/// See its documentation for more.
179pub struct IterMut<'a,T>{
180    len: usize,
181    index: usize,
182    head: Option<NonNull<Node<T>>>,
183    delegate: &'a mut UnrolledLinkedList<T>,
184}
185impl<'a,T> Iterator for IterMut<'a,T>{
186    type Item = &'a mut T;
187
188    fn next(&mut self) -> Option<Self::Item> {
189        if let Some(n) = self.head {
190            unsafe {
191                let node = &mut *n.as_ptr();
192                let elem = node.data.get_mut(self.index);
193                if self.index + 1 >= n.as_ref().data.len() {
194                    self.index = 0;
195                    self.head = node.next;
196                } else {
197                    self.index += 1;
198                }
199                self.len -= 1;
200                elem
201            }
202        } else { None }
203    }
204}
205impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
206    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207        f.debug_tuple("IterMut").field(&self.delegate).field(&self.len).finish()
208    }
209}
210
211#[cfg(test)]
212mod tests {
213    use crate::UnrolledLinkedList;
214
215
216    #[test]
217    fn iter_test() {
218        let mut list = UnrolledLinkedList::with_capacity(4);
219        for i in (1..20).into_iter() {
220            list.push(i)
221        }
222        let mut idx = 1;
223        for el in list.iter() {
224            assert_eq!(el, &idx);
225            idx += 1;
226        }
227    }
228
229    #[test]
230    fn into_iter_test() {
231        let mut list = UnrolledLinkedList::with_capacity(4);
232        for i in (1..20).into_iter() {
233            list.push(i)
234        }
235        let mut idx = 1;
236        for el in list.into_iter() {
237            assert_eq!(el, idx);
238            idx += 1;
239        }
240    }
241    #[test]
242    fn mut_iter_test() {
243        let mut list = UnrolledLinkedList::with_capacity(4);
244        for _ in (1..20).into_iter() {
245            list.push(1)
246        }
247        for el in list.iter_mut() {
248            assert_eq!(el, &mut 1);
249        }
250    }
251}