@@ -11,6 +11,7 @@ pub struct Intersperse<I: Iterator>
1111where
1212 I::Item: Clone,
1313{
14+ started: bool,
1415 separator: I::Item,
1516 next_item: Option<I::Item>,
1617 iter: Fuse<I>,
2930 I::Item: Clone,
3031{
3132 pub(in crate::iter) fn new(iter: I, separator: I::Item) -> Self {
32- let mut iter = iter.fuse();
33- Self { separator, next_item: iter.next(), iter }
33+ Self { started: false, separator, next_item: None, iter: iter.fuse() }
3434 }
3535}
3636
@@ -44,21 +44,26 @@ where
4444
4545 #[inline]
4646 fn next(&mut self) -> Option<Self::Item> {
47- if let Some(v) = self.next_item.take() {
48- Some(v)
49- } else {
50- let next_item = self.iter.next();
51- if next_item.is_some() {
52- self.next_item = next_item;
53- Some(self.separator.clone())
47+ if self.started {
48+ if let Some(v) = self.next_item.take() {
49+ Some(v)
5450 } else {
55- None
51+ let next_item = self.iter.next();
52+ if next_item.is_some() {
53+ self.next_item = next_item;
54+ Some(self.separator.clone())
55+ } else {
56+ None
57+ }
5658 }
59+ } else {
60+ self.started = true;
61+ self.iter.next()
5762 }
5863 }
5964
6065 fn size_hint(&self) -> (usize, Option<usize>) {
61- intersperse_size_hint(&self.iter, self.next_item.is_some())
66+ intersperse_size_hint(&self.iter, self.started, self. next_item.is_some())
6267 }
6368
6469 fn fold<B, F>(self, init: B, f: F) -> B
6772 F: FnMut(B, Self::Item) -> B,
6873 {
6974 let separator = self.separator;
70- intersperse_fold(self.iter, init, f, move || separator.clone(), self.next_item)
75+ intersperse_fold(self.iter, init, f, move || separator.clone(), self.started,self. next_item)
7176 }
7277}
7378
@@ -80,6 +85,7 @@ pub struct IntersperseWith<I, G>
8085where
8186 I: Iterator,
8287{
88+ started: bool,
8389 separator: G,
8490 next_item: Option<I::Item>,
8591 iter: Fuse<I>,
@@ -102,6 +108,7 @@ where
102108{
103109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104110 f.debug_struct("IntersperseWith")
111+ .field("started", &self.started)
105112 .field("separator", &self.separator)
106113 .field("iter", &self.iter)
107114 .field("next_item", &self.next_item)
@@ -118,6 +125,7 @@ where
118125{
119126 fn clone(&self) -> Self {
120127 Self {
128+ started: self.started,
121129 separator: self.separator.clone(),
122130 iter: self.iter.clone(),
123131 next_item: self.next_item.clone(),
@@ -131,8 +139,7 @@ where
131139 G: FnMut() -> I::Item,
132140{
133141 pub(in crate::iter) fn new(iter: I, separator: G) -> Self {
134- let mut iter = iter.fuse();
135- Self { separator, next_item: iter.next(), iter }
142+ Self { started: false, separator, next_item: None, iter: iter.fuse() }
136143 }
137144}
138145
@@ -146,48 +153,60 @@ where
146153
147154 #[inline]
148155 fn next(&mut self) -> Option<Self::Item> {
149- if let Some(v) = self.next_item.take() {
150- Some(v)
151- } else {
152- let next_item = self.iter.next();
153- if next_item.is_some() {
154- self.next_item = next_item;
155- Some((self.separator)())
156+ if self.started {
157+ if let Some(v) = self.next_item.take() {
158+ Some(v)
156159 } else {
157- None
160+ let next_item = self.iter.next();
161+ if next_item.is_some() {
162+ self.next_item = next_item;
163+ Some((self.separator)())
164+ } else {
165+ None
166+ }
158167 }
168+ } else {
169+ self.started = true;
170+ self.iter.next()
159171 }
160172 }
161173
162174 fn size_hint(&self) -> (usize, Option<usize>) {
163- intersperse_size_hint(&self.iter, self.next_item.is_some())
175+ intersperse_size_hint(&self.iter, self.started, self. next_item.is_some())
164176 }
165177
166178 fn fold<B, F>(self, init: B, f: F) -> B
167179 where
168180 Self: Sized,
169181 F: FnMut(B, Self::Item) -> B,
170182 {
171- intersperse_fold(self.iter, init, f, self.separator, self.next_item)
183+ intersperse_fold(self.iter, init, f, self.separator, self.started, self. next_item)
172184 }
173185}
174186
175- fn intersperse_size_hint<I>(iter: &I, next_is_elem : bool) -> (usize, Option<usize>)
187+ fn intersperse_size_hint<I>(iter: &I, started: bool, next_is_some : bool) -> (usize, Option<usize>)
176188where
177189 I: Iterator,
178190{
179191 let (lo, hi) = iter.size_hint();
180192 (
181- lo.saturating_add(next_is_elem as usize).saturating_add(lo),
182- hi.map(|hi| hi.saturating_add(next_is_elem as usize).saturating_add(hi)),
193+ lo.saturating_sub(!started as usize)
194+ .saturating_add(next_is_some as usize)
195+ .saturating_add(lo),
196+ hi.map(|hi| {
197+ hi.saturating_sub(!started as usize)
198+ .saturating_add(next_is_some as usize)
199+ .saturating_add(hi)
200+ }),
183201 )
184202}
185203
186204fn intersperse_fold<I, B, F, G>(
187- iter: I,
205+ mut iter: I,
188206 init: B,
189207 mut f: F,
190208 mut separator: G,
209+ started: bool,
191210 mut next_item: Option<I::Item>,
192211) -> B
193212where
@@ -197,7 +216,8 @@ where
197216{
198217 let mut accum = init;
199218
200- if let Some(x) = next_item.take() {
219+ let first = if started { next_item.take() } else { iter.next() };
220+ if let Some(x) = first {
201221 accum = f(accum, x);
202222 }
203223
0 commit comments