Skip to content

Commit 89d7c61

Browse files
Make IntersperseWith lazy
Similar to what is done by `core::iter::Peekable`, a nested option is now used.
1 parent 0b0ef1b commit 89d7c61

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

src/intersperse.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,17 @@ where
5454
{
5555
element: ElemF,
5656
iter: Fuse<I>,
57-
peek: Option<I::Item>,
57+
peek: Option<Option<I::Item>>,
5858
}
5959

6060
/// Create a new `IntersperseWith` iterator
6161
pub fn intersperse_with<I, ElemF>(iter: I, elt: ElemF) -> IntersperseWith<I, ElemF>
6262
where
6363
I: Iterator,
6464
{
65-
let mut iter = iter.fuse();
6665
IntersperseWith {
67-
peek: iter.next(),
68-
iter,
66+
peek: None,
67+
iter: iter.fuse(),
6968
element: elt,
7069
}
7170
}
@@ -83,11 +82,11 @@ where
8382
iter,
8483
peek,
8584
} = self;
86-
match peek.take() {
85+
match peek.get_or_insert_with(|| iter.next()).take() {
8786
item @ Some(_) => item,
8887
None => match iter.next() {
8988
new @ Some(_) => {
90-
*peek = new;
89+
*peek = Some(new);
9190
Some(element.generate())
9291
}
9392
None => None,
@@ -96,26 +95,32 @@ where
9695
}
9796

9897
fn size_hint(&self) -> (usize, Option<usize>) {
99-
// 2 * SH + { 1 or 0 }
100-
let has_peek = self.peek.is_some() as usize;
101-
let sh = self.iter.size_hint();
102-
size_hint::add_scalar(size_hint::add(sh, sh), has_peek)
98+
let mut sh = self.iter.size_hint();
99+
sh = size_hint::add(sh, sh);
100+
match self.peek {
101+
Some(Some(_)) => size_hint::add_scalar(sh, 1),
102+
Some(None) => sh,
103+
None => size_hint::sub_scalar(sh, 1),
104+
}
103105
}
104106

105-
fn fold<B, F>(mut self, init: B, mut f: F) -> B
107+
fn fold<B, F>(self, init: B, mut f: F) -> B
106108
where
107109
Self: Sized,
108110
F: FnMut(B, Self::Item) -> B,
109111
{
112+
let Self {
113+
mut element,
114+
mut iter,
115+
peek,
116+
} = self;
110117
let mut accum = init;
111118

112-
if let Some(x) = self.peek.take() {
119+
if let Some(x) = peek.unwrap_or_else(|| iter.next()) {
113120
accum = f(accum, x);
114121
}
115122

116-
let element = &mut self.element;
117-
118-
self.iter.fold(accum, |accum, x| {
123+
iter.fold(accum, |accum, x| {
119124
let accum = f(accum, element.generate());
120125
f(accum, x)
121126
})

0 commit comments

Comments
 (0)