1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
macro_rules! clone_fields {
    ($name:ident, $($field:ident),+) => (
        fn clone(&self) -> Self
        {
            $name {
                $(
                    $field : self . $field .clone()
                ),*
            }
        }
    );
}

/// An iterator adaptor to insert a particular value
/// between each element of the adapted iterator.
///
/// Iterator element type is **I::Item**
pub struct Intersperse<I> where
    I: Iterator,
{
    element: I::Item,
    iter: I,
    peek: Option<I::Item>,
}

impl<I> Clone for Intersperse<I> where
    I: Iterator + Clone,
    I::Item: Clone,
{
    clone_fields!(Intersperse, element, iter, peek);
}

impl<I> Intersperse<I> where
    I: Iterator,
{
    /// Create a new Intersperse iterator
    pub fn new(mut iter: I, elt: I::Item) -> Self
    {
        Intersperse{peek: iter.next(), iter: iter, element: elt}
    }
}

impl<I> Iterator for Intersperse<I> where
    I: Iterator,
    I::Item: Clone,
{
    type Item = I::Item;
    #[inline]
    fn next(&mut self) -> Option<I::Item>
    {
        if self.peek.is_some() {
            self.peek.take()
        } else {
            self.peek = self.iter.next();
            if self.peek.is_some() {
                Some(self.element.clone())
            } else {
                None
            }
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        let (mut low, mut hi) = self.iter.size_hint();
        if low > 0 {
            low = low.saturating_add((low - 1));
        }
        hi = hi.and_then(|x| if x > 0 {
            x.checked_add(x - 1)
        } else { Some (x) });
        (low, hi)
    }
}