Skip to main content

generic_arraydeque/
iter.rs

1use core::{fmt, iter::FusedIterator, mem, slice};
2
3/// An iterator over the elements of a [`ArrayDeque`](crate::ArrayDeque).
4///
5/// This `struct` is created by the [`iter`] method on [`super::ArrayDeque`]. See its
6/// documentation for more.
7///
8/// [`iter`]: super::ArrayDeque::iter
9#[derive(Clone)]
10pub struct Iter<'a, T> {
11  i1: slice::Iter<'a, T>,
12  i2: slice::Iter<'a, T>,
13}
14
15impl<'a, T> Iter<'a, T> {
16  pub(super) const fn new(i1: slice::Iter<'a, T>, i2: slice::Iter<'a, T>) -> Self {
17    Self { i1, i2 }
18  }
19
20  /// Views the underlying data as a pair of subslices of the original data.
21  ///
22  /// The slices contain, in order, the contents of the deque not yet yielded
23  /// by the iterator.
24  ///
25  /// This has the same lifetime as the original deque, and so the
26  /// iterator can continue to be used while this exists.
27  ///
28  /// # Examples
29  ///
30  /// ```
31  /// use generic_arraydeque::{ArrayDeque, typenum::U4};
32  ///
33  /// let mut deque = ArrayDeque::<u32, U4>::new();
34  /// for value in 0..3 {
35  ///     assert!(deque.push_back(value).is_none());
36  /// }
37  ///
38  /// let mut iter = deque.iter();
39  /// assert_eq!(iter.next(), Some(&0));
40  /// let (front, back) = iter.as_slices();
41  /// assert_eq!(front, &[1, 2]);
42  /// assert!(back.is_empty());
43  /// ```
44  pub fn as_slices(&self) -> (&'a [T], &'a [T]) {
45    (self.i1.as_slice(), self.i2.as_slice())
46  }
47}
48
49impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
50  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51    f.debug_tuple("Iter")
52      .field(&self.i1.as_slice())
53      .field(&self.i2.as_slice())
54      .finish()
55  }
56}
57
58impl<T> Default for Iter<'_, T> {
59  /// Creates an empty iterator.
60  ///
61  /// ```
62  /// use generic_arraydeque::Iter;
63  ///
64  /// let iter: Iter<'_, u8> = Default::default();
65  /// assert_eq!(iter.len(), 0);
66  /// ```
67  fn default() -> Self {
68    Iter {
69      i1: Default::default(),
70      i2: Default::default(),
71    }
72  }
73}
74
75impl<'a, T> Iterator for Iter<'a, T> {
76  type Item = &'a T;
77
78  #[inline]
79  fn next(&mut self) -> Option<&'a T> {
80    match self.i1.next() {
81      Some(val) => Some(val),
82      None => {
83        // most of the time, the iterator will either always
84        // call next(), or always call next_back(). By swapping
85        // the iterators once the first one is empty, we ensure
86        // that the first branch is taken as often as possible,
87        // without sacrificing correctness, as i1 is empty anyways
88        mem::swap(&mut self.i1, &mut self.i2);
89        self.i1.next()
90      }
91    }
92  }
93
94  #[inline]
95  fn size_hint(&self) -> (usize, Option<usize>) {
96    let len = self.len();
97    (len, Some(len))
98  }
99
100  fn fold<Acc, F>(self, accum: Acc, mut f: F) -> Acc
101  where
102    F: FnMut(Acc, Self::Item) -> Acc,
103  {
104    let accum = self.i1.fold(accum, &mut f);
105    self.i2.fold(accum, &mut f)
106  }
107
108  #[inline]
109  fn last(mut self) -> Option<&'a T> {
110    self.next_back()
111  }
112}
113
114impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
115  #[inline]
116  fn next_back(&mut self) -> Option<&'a T> {
117    match self.i2.next_back() {
118      Some(val) => Some(val),
119      None => {
120        // most of the time, the iterator will either always
121        // call next(), or always call next_back(). By swapping
122        // the iterators once the second one is empty, we ensure
123        // that the first branch is taken as often as possible,
124        // without sacrificing correctness, as i2 is empty anyways
125        mem::swap(&mut self.i1, &mut self.i2);
126        self.i2.next_back()
127      }
128    }
129  }
130
131  fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc
132  where
133    F: FnMut(Acc, Self::Item) -> Acc,
134  {
135    let accum = self.i2.rfold(accum, &mut f);
136    self.i1.rfold(accum, &mut f)
137  }
138}
139
140impl<T> ExactSizeIterator for Iter<'_, T> {
141  fn len(&self) -> usize {
142    self.i1.len() + self.i2.len()
143  }
144}
145
146impl<T> FusedIterator for Iter<'_, T> {}
147
148#[cfg(test)]
149mod tests {
150  use crate::{ArrayDeque, typenum::U4};
151
152  #[test]
153  fn as_slices_reflect_wrapping_layout() {
154    let mut deque = ArrayDeque::<_, U4>::new();
155    for value in 0..4 {
156      assert!(deque.push_back(value).is_none());
157    }
158    assert_eq!(deque.pop_front(), Some(0));
159    assert!(deque.push_back(4).is_none());
160
161    let mut iter = deque.iter();
162    assert_eq!(iter.next(), Some(&1));
163    let (front, back) = iter.as_slices();
164    assert_eq!(front, &[2, 3]);
165    assert_eq!(back, &[4]);
166  }
167
168  #[test]
169  fn next_and_next_back_cover_all_elements() {
170    let mut deque = ArrayDeque::<_, U4>::new();
171    for value in 0..4 {
172      assert!(deque.push_back(value).is_none());
173    }
174
175    let mut iter = deque.iter();
176    assert_eq!(iter.next(), Some(&0));
177    assert_eq!(iter.next_back(), Some(&3));
178    assert_eq!(iter.len(), 2);
179    assert_eq!(iter.next(), Some(&1));
180    assert_eq!(iter.next_back(), Some(&2));
181    assert_eq!(iter.next(), None);
182    assert_eq!(iter.next_back(), None);
183  }
184
185  #[allow(clippy::unnecessary_fold)]
186  #[test]
187  fn fold_and_rfold_process_all_items() {
188    let mut deque = ArrayDeque::<_, U4>::new();
189    for value in 0..4 {
190      assert!(deque.push_back(value).is_none());
191    }
192    let iter = deque.iter();
193    let sum = iter.clone().fold(0, |acc, &value| acc + value);
194    assert_eq!(sum, 6);
195    let rsum = iter.rfold(0, |acc, &value| acc + value);
196    assert_eq!(rsum, 6);
197  }
198
199  #[test]
200  fn size_hint_tracks_remaining_items() {
201    let mut deque = ArrayDeque::<_, U4>::new();
202    for value in 0..4 {
203      assert!(deque.push_back(value).is_none());
204    }
205    let mut iter = deque.iter();
206    assert_eq!(iter.size_hint(), (4, Some(4)));
207    iter.next();
208    assert_eq!(iter.size_hint(), (3, Some(3)));
209    iter.next_back();
210    assert_eq!(iter.size_hint(), (2, Some(2)));
211  }
212
213  #[test]
214  fn last_returns_final_element() {
215    let mut deque = ArrayDeque::<_, U4>::new();
216    for value in 0..4 {
217      assert!(deque.push_back(value).is_none());
218    }
219    assert_eq!(deque.iter().last(), Some(&3));
220  }
221
222  #[test]
223  fn default_is_empty() {
224    use super::Iter;
225
226    let iter: Iter<'static, u8> = Default::default();
227    assert_eq!(iter.len(), 0);
228    assert_eq!(iter.size_hint(), (0, Some(0)));
229  }
230}