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