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