@@ -11,6 +11,7 @@ pub struct Intersperse<I: Iterator>
11
11
where
12
12
I :: Item : Clone ,
13
13
{
14
+ started : bool ,
14
15
separator : I :: Item ,
15
16
next_item : Option < I :: Item > ,
16
17
iter : Fuse < I > ,
29
30
I :: Item : Clone ,
30
31
{
31
32
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 ( ) }
34
34
}
35
35
}
36
36
@@ -44,21 +44,26 @@ where
44
44
45
45
#[ inline]
46
46
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)
54
50
} 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
+ }
56
58
}
59
+ } else {
60
+ self . started = true ;
61
+ self . iter . next ( )
57
62
}
58
63
}
59
64
60
65
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 ( ) )
62
67
}
63
68
64
69
fn fold < B , F > ( self , init : B , f : F ) -> B
67
72
F : FnMut ( B , Self :: Item ) -> B ,
68
73
{
69
74
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 )
71
76
}
72
77
}
73
78
@@ -80,6 +85,7 @@ pub struct IntersperseWith<I, G>
80
85
where
81
86
I : Iterator ,
82
87
{
88
+ started : bool ,
83
89
separator : G ,
84
90
next_item : Option < I :: Item > ,
85
91
iter : Fuse < I > ,
@@ -102,6 +108,7 @@ where
102
108
{
103
109
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
104
110
f. debug_struct ( "IntersperseWith" )
111
+ . field ( "started" , & self . started )
105
112
. field ( "separator" , & self . separator )
106
113
. field ( "iter" , & self . iter )
107
114
. field ( "next_item" , & self . next_item )
@@ -118,6 +125,7 @@ where
118
125
{
119
126
fn clone ( & self ) -> Self {
120
127
Self {
128
+ started : self . started ,
121
129
separator : self . separator . clone ( ) ,
122
130
iter : self . iter . clone ( ) ,
123
131
next_item : self . next_item . clone ( ) ,
@@ -131,8 +139,7 @@ where
131
139
G : FnMut ( ) -> I :: Item ,
132
140
{
133
141
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 ( ) }
136
143
}
137
144
}
138
145
@@ -146,48 +153,60 @@ where
146
153
147
154
#[ inline]
148
155
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)
156
159
} 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
+ }
158
167
}
168
+ } else {
169
+ self . started = true ;
170
+ self . iter . next ( )
159
171
}
160
172
}
161
173
162
174
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 ( ) )
164
176
}
165
177
166
178
fn fold < B , F > ( self , init : B , f : F ) -> B
167
179
where
168
180
Self : Sized ,
169
181
F : FnMut ( B , Self :: Item ) -> B ,
170
182
{
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 )
172
184
}
173
185
}
174
186
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 > )
176
188
where
177
189
I : Iterator ,
178
190
{
179
191
let ( lo, hi) = iter. size_hint ( ) ;
180
192
(
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
+ } ) ,
183
201
)
184
202
}
185
203
186
204
fn intersperse_fold < I , B , F , G > (
187
- iter : I ,
205
+ mut iter : I ,
188
206
init : B ,
189
207
mut f : F ,
190
208
mut separator : G ,
209
+ started : bool ,
191
210
mut next_item : Option < I :: Item > ,
192
211
) -> B
193
212
where
@@ -197,7 +216,8 @@ where
197
216
{
198
217
let mut accum = init;
199
218
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 {
201
221
accum = f ( accum, x) ;
202
222
}
203
223
0 commit comments