1
- use super :: Peekable ;
1
+ use crate :: fmt;
2
+ use crate :: iter:: { Fuse , FusedIterator } ;
2
3
3
4
/// An iterator adapter that places a separator between all elements.
4
5
///
@@ -10,17 +11,26 @@ pub struct Intersperse<I: Iterator>
10
11
where
11
12
I :: Item : Clone ,
12
13
{
14
+ started : bool ,
13
15
separator : I :: Item ,
14
- iter : Peekable < I > ,
15
- needs_sep : bool ,
16
+ next_item : Option < I :: Item > ,
17
+ iter : Fuse < I > ,
18
+ }
19
+
20
+ #[ unstable( feature = "iter_intersperse" , reason = "recently added" , issue = "79524" ) ]
21
+ impl < I > FusedIterator for Intersperse < I >
22
+ where
23
+ I : FusedIterator ,
24
+ I :: Item : Clone ,
25
+ {
16
26
}
17
27
18
28
impl < I : Iterator > Intersperse < I >
19
29
where
20
30
I :: Item : Clone ,
21
31
{
22
32
pub ( in crate :: iter) fn new ( iter : I , separator : I :: Item ) -> Self {
23
- Self { iter : iter . peekable ( ) , separator, needs_sep : false }
33
+ Self { started : false , separator, next_item : None , iter : iter . fuse ( ) }
24
34
}
25
35
}
26
36
@@ -33,27 +43,43 @@ where
33
43
type Item = I :: Item ;
34
44
35
45
#[ inline]
36
- fn next ( & mut self ) -> Option < I :: Item > {
37
- if self . needs_sep && self . iter . peek ( ) . is_some ( ) {
38
- self . needs_sep = false ;
39
- Some ( self . separator . clone ( ) )
46
+ fn next ( & mut self ) -> Option < Self :: Item > {
47
+ if self . started {
48
+ if let Some ( v) = self . next_item . take ( ) {
49
+ Some ( v)
50
+ } else {
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
+ }
58
+ }
40
59
} else {
41
- self . needs_sep = true ;
60
+ self . started = true ;
42
61
self . iter . next ( )
43
62
}
44
63
}
45
64
65
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
66
+ intersperse_size_hint ( & self . iter , self . started , self . next_item . is_some ( ) )
67
+ }
68
+
46
69
fn fold < B , F > ( self , init : B , f : F ) -> B
47
70
where
48
71
Self : Sized ,
49
72
F : FnMut ( B , Self :: Item ) -> B ,
50
73
{
51
74
let separator = self . separator ;
52
- intersperse_fold ( self . iter , init, f, move || separator. clone ( ) , self . needs_sep )
53
- }
54
-
55
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
56
- intersperse_size_hint ( & self . iter , self . needs_sep )
75
+ intersperse_fold (
76
+ self . iter ,
77
+ init,
78
+ f,
79
+ move || separator. clone ( ) ,
80
+ self . started ,
81
+ self . next_item ,
82
+ )
57
83
}
58
84
}
59
85
@@ -66,39 +92,50 @@ pub struct IntersperseWith<I, G>
66
92
where
67
93
I : Iterator ,
68
94
{
95
+ started : bool ,
69
96
separator : G ,
70
- iter : Peekable < I > ,
71
- needs_sep : bool ,
97
+ next_item : Option < I :: Item > ,
98
+ iter : Fuse < I > ,
99
+ }
100
+
101
+ #[ unstable( feature = "iter_intersperse" , reason = "recently added" , issue = "79524" ) ]
102
+ impl < I , G > FusedIterator for IntersperseWith < I , G >
103
+ where
104
+ I : FusedIterator ,
105
+ G : FnMut ( ) -> I :: Item ,
106
+ {
72
107
}
73
108
74
109
#[ unstable( feature = "iter_intersperse" , reason = "recently added" , issue = "79524" ) ]
75
- impl < I , G > crate :: fmt:: Debug for IntersperseWith < I , G >
110
+ impl < I , G > fmt:: Debug for IntersperseWith < I , G >
76
111
where
77
- I : Iterator + crate :: fmt:: Debug ,
78
- I :: Item : crate :: fmt:: Debug ,
79
- G : crate :: fmt:: Debug ,
112
+ I : Iterator + fmt:: Debug ,
113
+ I :: Item : fmt:: Debug ,
114
+ G : fmt:: Debug ,
80
115
{
81
- fn fmt ( & self , f : & mut crate :: fmt:: Formatter < ' _ > ) -> crate :: fmt:: Result {
116
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
82
117
f. debug_struct ( "IntersperseWith" )
118
+ . field ( "started" , & self . started )
83
119
. field ( "separator" , & self . separator )
84
120
. field ( "iter" , & self . iter )
85
- . field ( "needs_sep " , & self . needs_sep )
121
+ . field ( "next_item " , & self . next_item )
86
122
. finish ( )
87
123
}
88
124
}
89
125
90
126
#[ unstable( feature = "iter_intersperse" , reason = "recently added" , issue = "79524" ) ]
91
- impl < I , G > crate :: clone :: Clone for IntersperseWith < I , G >
127
+ impl < I , G > Clone for IntersperseWith < I , G >
92
128
where
93
- I : Iterator + crate :: clone :: Clone ,
94
- I :: Item : crate :: clone :: Clone ,
129
+ I : Iterator + Clone ,
130
+ I :: Item : Clone ,
95
131
G : Clone ,
96
132
{
97
133
fn clone ( & self ) -> Self {
98
- IntersperseWith {
134
+ Self {
135
+ started : self . started ,
99
136
separator : self . separator . clone ( ) ,
100
137
iter : self . iter . clone ( ) ,
101
- needs_sep : self . needs_sep . clone ( ) ,
138
+ next_item : self . next_item . clone ( ) ,
102
139
}
103
140
}
104
141
}
@@ -109,7 +146,7 @@ where
109
146
G : FnMut ( ) -> I :: Item ,
110
147
{
111
148
pub ( in crate :: iter) fn new ( iter : I , separator : G ) -> Self {
112
- Self { iter : iter . peekable ( ) , separator, needs_sep : false }
149
+ Self { started : false , separator, next_item : None , iter : iter . fuse ( ) }
113
150
}
114
151
}
115
152
@@ -122,38 +159,52 @@ where
122
159
type Item = I :: Item ;
123
160
124
161
#[ inline]
125
- fn next ( & mut self ) -> Option < I :: Item > {
126
- if self . needs_sep && self . iter . peek ( ) . is_some ( ) {
127
- self . needs_sep = false ;
128
- Some ( ( self . separator ) ( ) )
162
+ fn next ( & mut self ) -> Option < Self :: Item > {
163
+ if self . started {
164
+ if let Some ( v) = self . next_item . take ( ) {
165
+ Some ( v)
166
+ } else {
167
+ let next_item = self . iter . next ( ) ;
168
+ if next_item. is_some ( ) {
169
+ self . next_item = next_item;
170
+ Some ( ( self . separator ) ( ) )
171
+ } else {
172
+ None
173
+ }
174
+ }
129
175
} else {
130
- self . needs_sep = true ;
176
+ self . started = true ;
131
177
self . iter . next ( )
132
178
}
133
179
}
134
180
181
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
182
+ intersperse_size_hint ( & self . iter , self . started , self . next_item . is_some ( ) )
183
+ }
184
+
135
185
fn fold < B , F > ( self , init : B , f : F ) -> B
136
186
where
137
187
Self : Sized ,
138
188
F : FnMut ( B , Self :: Item ) -> B ,
139
189
{
140
- intersperse_fold ( self . iter , init, f, self . separator , self . needs_sep )
141
- }
142
-
143
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
144
- intersperse_size_hint ( & self . iter , self . needs_sep )
190
+ intersperse_fold ( self . iter , init, f, self . separator , self . started , self . next_item )
145
191
}
146
192
}
147
193
148
- fn intersperse_size_hint < I > ( iter : & I , needs_sep : bool ) -> ( usize , Option < usize > )
194
+ fn intersperse_size_hint < I > ( iter : & I , started : bool , next_is_some : bool ) -> ( usize , Option < usize > )
149
195
where
150
196
I : Iterator ,
151
197
{
152
198
let ( lo, hi) = iter. size_hint ( ) ;
153
- let next_is_elem = !needs_sep;
154
199
(
155
- lo. saturating_sub ( next_is_elem as usize ) . saturating_add ( lo) ,
156
- hi. and_then ( |hi| hi. saturating_sub ( next_is_elem as usize ) . checked_add ( hi) ) ,
200
+ lo. saturating_sub ( !started as usize )
201
+ . saturating_add ( next_is_some as usize )
202
+ . saturating_add ( lo) ,
203
+ hi. and_then ( |hi| {
204
+ hi. saturating_sub ( !started as usize )
205
+ . saturating_add ( next_is_some as usize )
206
+ . checked_add ( hi)
207
+ } ) ,
157
208
)
158
209
}
159
210
@@ -162,7 +213,8 @@ fn intersperse_fold<I, B, F, G>(
162
213
init : B ,
163
214
mut f : F ,
164
215
mut separator : G ,
165
- needs_sep : bool ,
216
+ started : bool ,
217
+ mut next_item : Option < I :: Item > ,
166
218
) -> B
167
219
where
168
220
I : Iterator ,
@@ -171,12 +223,9 @@ where
171
223
{
172
224
let mut accum = init;
173
225
174
- if !needs_sep {
175
- if let Some ( x) = iter. next ( ) {
176
- accum = f ( accum, x) ;
177
- } else {
178
- return accum;
179
- }
226
+ let first = if started { next_item. take ( ) } else { iter. next ( ) } ;
227
+ if let Some ( x) = first {
228
+ accum = f ( accum, x) ;
180
229
}
181
230
182
231
iter. fold ( accum, |mut accum, x| {
0 commit comments