@@ -28,6 +28,22 @@ impl<I> Fuse<I> {
28
28
#[ stable( feature = "fused" , since = "1.26.0" ) ]
29
29
impl < I > FusedIterator for Fuse < I > where I : Iterator { }
30
30
31
+ /// Fuse the iterator if the expression is `None`.
32
+ macro_rules! fuse {
33
+ ( $self: ident . iter . $( $call: tt) +) => {
34
+ match $self. iter {
35
+ Some ( ref mut iter) => match iter. $( $call) + {
36
+ None => {
37
+ $self. iter = None ;
38
+ None
39
+ }
40
+ item => item,
41
+ } ,
42
+ None => None ,
43
+ }
44
+ } ;
45
+ }
46
+
31
47
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
32
48
impl < I > Iterator for Fuse < I >
33
49
where
@@ -37,35 +53,36 @@ where
37
53
38
54
#[ inline]
39
55
default fn next ( & mut self ) -> Option < <I as Iterator >:: Item > {
40
- let next = self . iter . as_mut ( ) ?. next ( ) ;
41
- if next. is_none ( ) {
42
- self . iter = None ;
43
- }
44
- next
56
+ fuse ! ( self . iter. next( ) )
45
57
}
46
58
47
59
#[ inline]
48
60
default fn nth ( & mut self , n : usize ) -> Option < I :: Item > {
49
- let nth = self . iter . as_mut ( ) ?. nth ( n) ;
50
- if nth. is_none ( ) {
51
- self . iter = None ;
52
- }
53
- nth
61
+ fuse ! ( self . iter. nth( n) )
54
62
}
55
63
56
64
#[ inline]
57
65
default fn last ( self ) -> Option < I :: Item > {
58
- self . iter ?. last ( )
66
+ match self . iter {
67
+ Some ( iter) => iter. last ( ) ,
68
+ None => None ,
69
+ }
59
70
}
60
71
61
72
#[ inline]
62
73
default fn count ( self ) -> usize {
63
- self . iter . map_or ( 0 , I :: count)
74
+ match self . iter {
75
+ Some ( iter) => iter. count ( ) ,
76
+ None => 0 ,
77
+ }
64
78
}
65
79
66
80
#[ inline]
67
81
default fn size_hint ( & self ) -> ( usize , Option < usize > ) {
68
- self . iter . as_ref ( ) . map_or ( ( 0 , Some ( 0 ) ) , I :: size_hint)
82
+ match self . iter {
83
+ Some ( ref iter) => iter. size_hint ( ) ,
84
+ None => ( 0 , Some ( 0 ) ) ,
85
+ }
69
86
}
70
87
71
88
#[ inline]
@@ -98,11 +115,7 @@ where
98
115
where
99
116
P : FnMut ( & Self :: Item ) -> bool ,
100
117
{
101
- let found = self . iter . as_mut ( ) ?. find ( predicate) ;
102
- if found. is_none ( ) {
103
- self . iter = None ;
104
- }
105
- found
118
+ fuse ! ( self . iter. find( predicate) )
106
119
}
107
120
}
108
121
@@ -113,20 +126,12 @@ where
113
126
{
114
127
#[ inline]
115
128
default fn next_back ( & mut self ) -> Option < <I as Iterator >:: Item > {
116
- let next = self . iter . as_mut ( ) ?. next_back ( ) ;
117
- if next. is_none ( ) {
118
- self . iter = None ;
119
- }
120
- next
129
+ fuse ! ( self . iter. next_back( ) )
121
130
}
122
131
123
132
#[ inline]
124
133
default fn nth_back ( & mut self , n : usize ) -> Option < <I as Iterator >:: Item > {
125
- let nth = self . iter . as_mut ( ) ?. nth_back ( n) ;
126
- if nth. is_none ( ) {
127
- self . iter = None ;
128
- }
129
- nth
134
+ fuse ! ( self . iter. nth_back( n) )
130
135
}
131
136
132
137
#[ inline]
@@ -159,11 +164,7 @@ where
159
164
where
160
165
P : FnMut ( & Self :: Item ) -> bool ,
161
166
{
162
- let found = self . iter . as_mut ( ) ?. rfind ( predicate) ;
163
- if found. is_none ( ) {
164
- self . iter = None ;
165
- }
166
- found
167
+ fuse ! ( self . iter. rfind( predicate) )
167
168
}
168
169
}
169
170
@@ -173,42 +174,30 @@ where
173
174
I : ExactSizeIterator ,
174
175
{
175
176
default fn len ( & self ) -> usize {
176
- self . iter . as_ref ( ) . map_or ( 0 , I :: len)
177
- }
178
-
179
- default fn is_empty ( & self ) -> bool {
180
- self . iter . as_ref ( ) . map_or ( true , I :: is_empty)
181
- }
182
- }
183
-
184
- // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`
185
- impl < I : FusedIterator > Fuse < I > {
186
- #[ inline( always) ]
187
- fn as_inner ( & self ) -> & I {
188
177
match self . iter {
189
- Some ( ref iter) => iter,
190
- // SAFETY: the specialized iterator never sets `None`
191
- None => unsafe { intrinsics:: unreachable ( ) } ,
178
+ Some ( ref iter) => iter. len ( ) ,
179
+ None => 0 ,
192
180
}
193
181
}
194
182
195
- #[ inline( always) ]
196
- fn as_inner_mut ( & mut self ) -> & mut I {
183
+ default fn is_empty ( & self ) -> bool {
197
184
match self . iter {
198
- Some ( ref mut iter) => iter,
199
- // SAFETY: the specialized iterator never sets `None`
200
- None => unsafe { intrinsics:: unreachable ( ) } ,
185
+ Some ( ref iter) => iter. is_empty ( ) ,
186
+ None => true ,
201
187
}
202
188
}
189
+ }
203
190
204
- #[ inline( always) ]
205
- fn into_inner ( self ) -> I {
206
- match self . iter {
207
- Some ( iter) => iter,
191
+ // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
192
+ // Implementing this as a directly-expanded macro helps codegen performance.
193
+ macro_rules! unchecked {
194
+ ( $self: ident) => {
195
+ match $self {
196
+ Fuse { iter: Some ( iter) } => iter,
208
197
// SAFETY: the specialized iterator never sets `None`
209
- None => unsafe { intrinsics:: unreachable ( ) } ,
198
+ Fuse { iter : None } => unsafe { intrinsics:: unreachable( ) } ,
210
199
}
211
- }
200
+ } ;
212
201
}
213
202
214
203
#[ stable( feature = "fused" , since = "1.26.0" ) ]
@@ -218,27 +207,27 @@ where
218
207
{
219
208
#[ inline]
220
209
fn next ( & mut self ) -> Option < <I as Iterator >:: Item > {
221
- self . as_inner_mut ( ) . next ( )
210
+ unchecked ! ( self ) . next ( )
222
211
}
223
212
224
213
#[ inline]
225
214
fn nth ( & mut self , n : usize ) -> Option < I :: Item > {
226
- self . as_inner_mut ( ) . nth ( n)
215
+ unchecked ! ( self ) . nth ( n)
227
216
}
228
217
229
218
#[ inline]
230
219
fn last ( self ) -> Option < I :: Item > {
231
- self . into_inner ( ) . last ( )
220
+ unchecked ! ( self ) . last ( )
232
221
}
233
222
234
223
#[ inline]
235
224
fn count ( self ) -> usize {
236
- self . into_inner ( ) . count ( )
225
+ unchecked ! ( self ) . count ( )
237
226
}
238
227
239
228
#[ inline]
240
229
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
241
- self . as_inner ( ) . size_hint ( )
230
+ unchecked ! ( self ) . size_hint ( )
242
231
}
243
232
244
233
#[ inline]
@@ -248,23 +237,23 @@ where
248
237
Fold : FnMut ( Acc , Self :: Item ) -> R ,
249
238
R : Try < Ok = Acc > ,
250
239
{
251
- self . as_inner_mut ( ) . try_fold ( init, fold)
240
+ unchecked ! ( self ) . try_fold ( init, fold)
252
241
}
253
242
254
243
#[ inline]
255
244
fn fold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
256
245
where
257
246
Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
258
247
{
259
- self . into_inner ( ) . fold ( init, fold)
248
+ unchecked ! ( self ) . fold ( init, fold)
260
249
}
261
250
262
251
#[ inline]
263
252
fn find < P > ( & mut self , predicate : P ) -> Option < Self :: Item >
264
253
where
265
254
P : FnMut ( & Self :: Item ) -> bool ,
266
255
{
267
- self . as_inner_mut ( ) . find ( predicate)
256
+ unchecked ! ( self ) . find ( predicate)
268
257
}
269
258
}
270
259
@@ -275,12 +264,12 @@ where
275
264
{
276
265
#[ inline]
277
266
fn next_back ( & mut self ) -> Option < <I as Iterator >:: Item > {
278
- self . as_inner_mut ( ) . next_back ( )
267
+ unchecked ! ( self ) . next_back ( )
279
268
}
280
269
281
270
#[ inline]
282
271
fn nth_back ( & mut self , n : usize ) -> Option < <I as Iterator >:: Item > {
283
- self . as_inner_mut ( ) . nth_back ( n)
272
+ unchecked ! ( self ) . nth_back ( n)
284
273
}
285
274
286
275
#[ inline]
@@ -290,23 +279,23 @@ where
290
279
Fold : FnMut ( Acc , Self :: Item ) -> R ,
291
280
R : Try < Ok = Acc > ,
292
281
{
293
- self . as_inner_mut ( ) . try_rfold ( init, fold)
282
+ unchecked ! ( self ) . try_rfold ( init, fold)
294
283
}
295
284
296
285
#[ inline]
297
286
fn rfold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
298
287
where
299
288
Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
300
289
{
301
- self . into_inner ( ) . rfold ( init, fold)
290
+ unchecked ! ( self ) . rfold ( init, fold)
302
291
}
303
292
304
293
#[ inline]
305
294
fn rfind < P > ( & mut self , predicate : P ) -> Option < Self :: Item >
306
295
where
307
296
P : FnMut ( & Self :: Item ) -> bool ,
308
297
{
309
- self . as_inner_mut ( ) . rfind ( predicate)
298
+ unchecked ! ( self ) . rfind ( predicate)
310
299
}
311
300
}
312
301
@@ -316,11 +305,11 @@ where
316
305
I : ExactSizeIterator + FusedIterator ,
317
306
{
318
307
fn len ( & self ) -> usize {
319
- self . as_inner ( ) . len ( )
308
+ unchecked ! ( self ) . len ( )
320
309
}
321
310
322
311
fn is_empty ( & self ) -> bool {
323
- self . as_inner ( ) . is_empty ( )
312
+ unchecked ! ( self ) . is_empty ( )
324
313
}
325
314
}
326
315
0 commit comments