Skip to content

Commit 9b01a11

Browse files
Philippe-Choletjswrenn
authored andcommitted
Make IntersperseWith lazy
Similar to what is done by `core::iter::Peekable`, a nested option is now used.
1 parent 4f22173 commit 9b01a11

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/intersperse.rs

Lines changed: 25 additions & 16 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
}
@@ -84,38 +83,48 @@ where
8483
peek,
8584
} = self;
8685
match peek {
87-
item @ Some(_) => item.take(),
88-
None => match iter.next() {
86+
Some(item @ Some(_)) => item.take(),
87+
Some(None) => match iter.next() {
8988
new @ Some(_) => {
90-
*peek = new;
89+
*peek = Some(new);
9190
Some(element.generate())
9291
}
9392
None => None,
9493
},
94+
None => {
95+
*peek = Some(None);
96+
iter.next()
97+
}
9598
}
9699
}
97100

98101
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)
102+
let mut sh = self.iter.size_hint();
103+
sh = size_hint::add(sh, sh);
104+
match self.peek {
105+
Some(Some(_)) => size_hint::add_scalar(sh, 1),
106+
Some(None) => sh,
107+
None => size_hint::sub_scalar(sh, 1),
108+
}
103109
}
104110

105-
fn fold<B, F>(mut self, init: B, mut f: F) -> B
111+
fn fold<B, F>(self, init: B, mut f: F) -> B
106112
where
107113
Self: Sized,
108114
F: FnMut(B, Self::Item) -> B,
109115
{
116+
let Self {
117+
mut element,
118+
mut iter,
119+
peek,
120+
} = self;
110121
let mut accum = init;
111122

112-
if let Some(x) = self.peek.take() {
123+
if let Some(x) = peek.unwrap_or_else(|| iter.next()) {
113124
accum = f(accum, x);
114125
}
115126

116-
let element = &mut self.element;
117-
118-
self.iter.fold(accum, |accum, x| {
127+
iter.fold(accum, |accum, x| {
119128
let accum = f(accum, element.generate());
120129
f(accum, x)
121130
})

0 commit comments

Comments
 (0)