@@ -294,13 +294,39 @@ pub trait Iterator {
294
294
#[ inline]
295
295
#[ unstable( feature = "iter_advance_by" , reason = "recently added" , issue = "77404" ) ]
296
296
fn advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
297
- for i in 0 ..n {
298
- if self . next ( ) . is_none ( ) {
299
- // SAFETY: `i` is always less than `n`.
300
- return Err ( unsafe { NonZero :: new_unchecked ( n - i) } ) ;
297
+ /// Helper trait to specialize `advance_by` via `try_fold` for `Sized` iterators.
298
+ trait SpecAdvanceBy {
299
+ fn spec_advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > ;
300
+ }
301
+
302
+ impl < I : Iterator + ?Sized > SpecAdvanceBy for I {
303
+ default fn spec_advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
304
+ for i in 0 ..n {
305
+ if self . next ( ) . is_none ( ) {
306
+ // SAFETY: `i` is always less than `n`.
307
+ return Err ( unsafe { NonZero :: new_unchecked ( n - i) } ) ;
308
+ }
309
+ }
310
+ Ok ( ( ) )
311
+ }
312
+ }
313
+
314
+ impl < I : Iterator > SpecAdvanceBy for I {
315
+ fn spec_advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
316
+ let Some ( n) = NonZero :: new ( n) else {
317
+ return Ok ( ( ) ) ;
318
+ } ;
319
+
320
+ let res = self . try_fold ( n, |n, _| NonZero :: new ( n. get ( ) - 1 ) ) ;
321
+
322
+ match res {
323
+ None => Ok ( ( ) ) ,
324
+ Some ( n) => Err ( n) ,
325
+ }
301
326
}
302
327
}
303
- Ok ( ( ) )
328
+
329
+ self . spec_advance_by ( n)
304
330
}
305
331
306
332
/// Returns the `n`th element of the iterator.
0 commit comments