1use alloc::vec::Vec;
2
3use 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)]
10pub 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`.
19pub 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
28impl<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]
44 pub fn put_back(&mut self, x: I::Item) {
45 self.top.push(x);
46 }
47}
48
49impl<I: Iterator> Iterator for PutBackN<I> {
50 type Item = I::Item;
51 #[inline]
52 fn next(&mut self) -> Option<Self::Item> {
53 self.top.pop().or_else(|| self.iter.next())
54 }
55
56 #[inline]
57 fn size_hint(&self) -> (usize, Option<usize>) {
58 size_hint::add_scalar(self.iter.size_hint(), self.top.len())
59 }
60}
61
62