Jakub Kotur | a425e55 | 2020-12-21 17:28:15 +0100 | [diff] [blame] | 1 | use std::iter::Fuse; |
| 2 | use super::size_hint; |
| 3 | |
| 4 | #[derive(Clone)] |
| 5 | /// An iterator adaptor to insert a particular value |
| 6 | /// between each element of the adapted iterator. |
| 7 | /// |
| 8 | /// Iterator element type is `I::Item` |
| 9 | /// |
| 10 | /// This iterator is *fused*. |
| 11 | /// |
| 12 | /// See [`.intersperse()`](../trait.Itertools.html#method.intersperse) for more information. |
| 13 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] |
| 14 | #[derive(Debug)] |
| 15 | pub struct Intersperse<I> |
| 16 | where I: Iterator |
| 17 | { |
| 18 | element: I::Item, |
| 19 | iter: Fuse<I>, |
| 20 | peek: Option<I::Item>, |
| 21 | } |
| 22 | |
| 23 | /// Create a new Intersperse iterator |
| 24 | pub fn intersperse<I>(iter: I, elt: I::Item) -> Intersperse<I> |
| 25 | where I: Iterator |
| 26 | { |
| 27 | let mut iter = iter.fuse(); |
| 28 | Intersperse { |
| 29 | peek: iter.next(), |
| 30 | iter, |
| 31 | element: elt, |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | impl<I> Iterator for Intersperse<I> |
| 36 | where I: Iterator, |
| 37 | I::Item: Clone |
| 38 | { |
| 39 | type Item = I::Item; |
| 40 | #[inline] |
| 41 | fn next(&mut self) -> Option<I::Item> { |
| 42 | if self.peek.is_some() { |
| 43 | self.peek.take() |
| 44 | } else { |
| 45 | self.peek = self.iter.next(); |
| 46 | if self.peek.is_some() { |
| 47 | Some(self.element.clone()) |
| 48 | } else { |
| 49 | None |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | fn size_hint(&self) -> (usize, Option<usize>) { |
| 55 | // 2 * SH + { 1 or 0 } |
| 56 | let has_peek = self.peek.is_some() as usize; |
| 57 | let sh = self.iter.size_hint(); |
| 58 | size_hint::add_scalar(size_hint::add(sh, sh), has_peek) |
| 59 | } |
| 60 | |
| 61 | fn fold<B, F>(mut self, init: B, mut f: F) -> B where |
| 62 | Self: Sized, F: FnMut(B, Self::Item) -> B, |
| 63 | { |
| 64 | let mut accum = init; |
| 65 | |
| 66 | if let Some(x) = self.peek.take() { |
| 67 | accum = f(accum, x); |
| 68 | } |
| 69 | |
| 70 | let element = &self.element; |
| 71 | |
| 72 | self.iter.fold(accum, |
| 73 | |accum, x| { |
| 74 | let accum = f(accum, element.clone()); |
| 75 | let accum = f(accum, x); |
| 76 | accum |
| 77 | }) |
| 78 | } |
| 79 | } |