1 use alloc::vec::Vec;
2
3 use crate::size_hint;
4
5 /// An iterator adaptor that allows putting multiple
6 /// items in front of the iterator.
7 ///
8 /// Iterator element type is `I::Item`.
9 #[derive(Debug, Clone)]
10 pub struct PutBackN<I: Iterator> {
11 top: Vec<I::Item>,
12 iter: I,
13 }
14
15 /// Create an iterator where you can put back multiple values to the front
16 /// of the iteration.
17 ///
18 /// Iterator element type is `I::Item`.
put_back_n<I>(iterable: I) -> PutBackN<I::IntoIter> where I: IntoIterator19 pub fn put_back_n<I>(iterable: I) -> PutBackN<I::IntoIter>
20 where I: IntoIterator
21 {
22 PutBackN {
23 top: Vec::new(),
24 iter: iterable.into_iter(),
25 }
26 }
27
28 impl<I: Iterator> PutBackN<I> {
29 /// Puts x in front of the iterator.
30 /// The values are yielded in order of the most recently put back
31 /// values first.
32 ///
33 /// ```rust
34 /// use itertools::put_back_n;
35 ///
36 /// let mut it = put_back_n(1..5);
37 /// it.next();
38 /// it.put_back(1);
39 /// it.put_back(0);
40 ///
41 /// assert!(itertools::equal(it, 0..5));
42 /// ```
43 #[inline]
put_back(&mut self, x: I::Item)44 pub fn put_back(&mut self, x: I::Item) {
45 self.top.push(x);
46 }
47 }
48
49 impl<I: Iterator> Iterator for PutBackN<I> {
50 type Item = I::Item;
51 #[inline]
next(&mut self) -> Option<Self::Item>52 fn next(&mut self) -> Option<Self::Item> {
53 self.top.pop().or_else(|| self.iter.next())
54 }
55
56 #[inline]
size_hint(&self) -> (usize, Option<usize>)57 fn size_hint(&self) -> (usize, Option<usize>) {
58 size_hint::add_scalar(self.iter.size_hint(), self.top.len())
59 }
60 }
61
62