generic_arraydeque/
iter.rs

1use core::{fmt, iter::FusedIterator, mem, slice};
2
3/// An iterator over the elements of a [`GenericArrayDeque`](crate::GenericArrayDeque).
4///
5/// This `struct` is created by the [`iter`] method on [`super::GenericArrayDeque`]. See its
6/// documentation for more.
7///
8/// [`iter`]: super::GenericArrayDeque::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::{GenericArrayDeque, typenum::U4};
32  ///
33  /// let mut deque = GenericArrayDeque::<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
58#[rustversion::since(1.70)]
59impl<T> Default for Iter<'_, T> {
60  /// Creates an empty iterator.
61  ///
62  /// ```
63  /// use generic_arraydeque::Iter;
64  ///
65  /// let iter: Iter<'_, u8> = Default::default();
66  /// assert_eq!(iter.len(), 0);
67  /// ```
68  fn default() -> Self {
69    Iter {
70      i1: Default::default(),
71      i2: Default::default(),
72    }
73  }
74}
75
76impl<'a, T> Iterator for Iter<'a, T> {
77  type Item = &'a T;
78
79  #[inline]
80  fn next(&mut self) -> Option<&'a T> {
81    match self.i1.next() {
82      Some(val) => Some(val),
83      None => {
84        // most of the time, the iterator will either always
85        // call next(), or always call next_back(). By swapping
86        // the iterators once the first one is empty, we ensure
87        // that the first branch is taken as often as possible,
88        // without sacrificing correctness, as i1 is empty anyways
89        mem::swap(&mut self.i1, &mut self.i2);
90        self.i1.next()
91      }
92    }
93  }
94
95  #[inline]
96  fn size_hint(&self) -> (usize, Option<usize>) {
97    let len = self.len();
98    (len, Some(len))
99  }
100
101  fn fold<Acc, F>(self, accum: Acc, mut f: F) -> Acc
102  where
103    F: FnMut(Acc, Self::Item) -> Acc,
104  {
105    let accum = self.i1.fold(accum, &mut f);
106    self.i2.fold(accum, &mut f)
107  }
108
109  #[inline]
110  fn last(mut self) -> Option<&'a T> {
111    self.next_back()
112  }
113}
114
115impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
116  #[inline]
117  fn next_back(&mut self) -> Option<&'a T> {
118    match self.i2.next_back() {
119      Some(val) => Some(val),
120      None => {
121        // most of the time, the iterator will either always
122        // call next(), or always call next_back(). By swapping
123        // the iterators once the second one is empty, we ensure
124        // that the first branch is taken as often as possible,
125        // without sacrificing correctness, as i2 is empty anyways
126        mem::swap(&mut self.i1, &mut self.i2);
127        self.i2.next_back()
128      }
129    }
130  }
131
132  fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc
133  where
134    F: FnMut(Acc, Self::Item) -> Acc,
135  {
136    let accum = self.i2.rfold(accum, &mut f);
137    self.i1.rfold(accum, &mut f)
138  }
139}
140
141impl<T> ExactSizeIterator for Iter<'_, T> {
142  fn len(&self) -> usize {
143    self.i1.len() + self.i2.len()
144  }
145}
146
147impl<T> FusedIterator for Iter<'_, T> {}
148
149#[cfg(test)]
150mod tests {
151  use crate::{typenum::U4, GenericArrayDeque};
152
153  #[test]
154  fn as_slices_reflect_wrapping_layout() {
155    let mut deque = GenericArrayDeque::<_, U4>::new();
156    for value in 0..4 {
157      assert!(deque.push_back(value).is_none());
158    }
159    assert_eq!(deque.pop_front(), Some(0));
160    assert!(deque.push_back(4).is_none());
161
162    let mut iter = deque.iter();
163    assert_eq!(iter.next(), Some(&1));
164    let (front, back) = iter.as_slices();
165    assert_eq!(front, &[2, 3]);
166    assert_eq!(back, &[4]);
167  }
168
169  #[test]
170  fn next_and_next_back_cover_all_elements() {
171    let mut deque = GenericArrayDeque::<_, U4>::new();
172    for value in 0..4 {
173      assert!(deque.push_back(value).is_none());
174    }
175
176    let mut iter = deque.iter();
177    assert_eq!(iter.next(), Some(&0));
178    assert_eq!(iter.next_back(), Some(&3));
179    assert_eq!(iter.len(), 2);
180    assert_eq!(iter.next(), Some(&1));
181    assert_eq!(iter.next_back(), Some(&2));
182    assert_eq!(iter.next(), None);
183    assert_eq!(iter.next_back(), None);
184  }
185
186  #[allow(clippy::unnecessary_fold)]
187  #[test]
188  fn fold_and_rfold_process_all_items() {
189    let mut deque = GenericArrayDeque::<_, U4>::new();
190    for value in 0..4 {
191      assert!(deque.push_back(value).is_none());
192    }
193    let iter = deque.iter();
194    let sum = iter.clone().fold(0, |acc, &value| acc + value);
195    assert_eq!(sum, 6);
196    let rsum = iter.rfold(0, |acc, &value| acc + value);
197    assert_eq!(rsum, 6);
198  }
199
200  #[test]
201  fn size_hint_tracks_remaining_items() {
202    let mut deque = GenericArrayDeque::<_, U4>::new();
203    for value in 0..4 {
204      assert!(deque.push_back(value).is_none());
205    }
206    let mut iter = deque.iter();
207    assert_eq!(iter.size_hint(), (4, Some(4)));
208    iter.next();
209    assert_eq!(iter.size_hint(), (3, Some(3)));
210    iter.next_back();
211    assert_eq!(iter.size_hint(), (2, Some(2)));
212  }
213
214  #[test]
215  fn last_returns_final_element() {
216    let mut deque = GenericArrayDeque::<_, U4>::new();
217    for value in 0..4 {
218      assert!(deque.push_back(value).is_none());
219    }
220    assert_eq!(deque.iter().last(), Some(&3));
221  }
222
223  #[rustversion::since(1.70)]
224  #[test]
225  fn default_is_empty() {
226    use super::Iter;
227
228    let iter: Iter<'static, u8> = Default::default();
229    assert_eq!(iter.len(), 0);
230    assert_eq!(iter.size_hint(), (0, Some(0)));
231  }
232}