@@ -3179,6 +3179,7 @@ macro_rules! is_empty {
3179
3179
$self. ptr. as_ptr( ) as * const T == $self. end
3180
3180
} ;
3181
3181
}
3182
+
3182
3183
// To get rid of some bounds checks (see `position`), we compute the length in a somewhat
3183
3184
// unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
3184
3185
macro_rules! len {
@@ -3347,40 +3348,127 @@ macro_rules! iterator {
3347
3348
self . next_back( )
3348
3349
}
3349
3350
3351
+ // We override the default implementation, which uses `try_fold`,
3352
+ // because this simple implementation generates less LLVM IR and is
3353
+ // faster to compile.
3354
+ #[ inline]
3355
+ fn for_each<F >( mut self , mut f: F )
3356
+ where
3357
+ Self : Sized ,
3358
+ F : FnMut ( Self :: Item ) ,
3359
+ {
3360
+ while let Some ( x) = self . next( ) {
3361
+ f( x) ;
3362
+ }
3363
+ }
3364
+
3365
+ // We override the default implementation, which uses `try_fold`,
3366
+ // because this simple implementation generates less LLVM IR and is
3367
+ // faster to compile.
3368
+ #[ inline]
3369
+ fn all<F >( & mut self , mut f: F ) -> bool
3370
+ where
3371
+ Self : Sized ,
3372
+ F : FnMut ( Self :: Item ) -> bool ,
3373
+ {
3374
+ while let Some ( x) = self . next( ) {
3375
+ if !f( x) {
3376
+ return false ;
3377
+ }
3378
+ }
3379
+ true
3380
+ }
3381
+
3382
+ // We override the default implementation, which uses `try_fold`,
3383
+ // because this simple implementation generates less LLVM IR and is
3384
+ // faster to compile.
3385
+ #[ inline]
3386
+ fn any<F >( & mut self , mut f: F ) -> bool
3387
+ where
3388
+ Self : Sized ,
3389
+ F : FnMut ( Self :: Item ) -> bool ,
3390
+ {
3391
+ while let Some ( x) = self . next( ) {
3392
+ if f( x) {
3393
+ return true ;
3394
+ }
3395
+ }
3396
+ false
3397
+ }
3398
+
3399
+ // We override the default implementation, which uses `try_fold`,
3400
+ // because this simple implementation generates less LLVM IR and is
3401
+ // faster to compile.
3402
+ #[ inline]
3403
+ fn find<P >( & mut self , mut predicate: P ) -> Option <Self :: Item >
3404
+ where
3405
+ Self : Sized ,
3406
+ P : FnMut ( & Self :: Item ) -> bool ,
3407
+ {
3408
+ while let Some ( x) = self . next( ) {
3409
+ if predicate( & x) {
3410
+ return Some ( x) ;
3411
+ }
3412
+ }
3413
+ None
3414
+ }
3415
+
3416
+ // We override the default implementation, which uses `try_fold`,
3417
+ // because this simple implementation generates less LLVM IR and is
3418
+ // faster to compile.
3419
+ #[ inline]
3420
+ fn find_map<B , F >( & mut self , mut f: F ) -> Option <B >
3421
+ where
3422
+ Self : Sized ,
3423
+ F : FnMut ( Self :: Item ) -> Option <B >,
3424
+ {
3425
+ while let Some ( x) = self . next( ) {
3426
+ if let Some ( y) = f( x) {
3427
+ return Some ( y) ;
3428
+ }
3429
+ }
3430
+ None
3431
+ }
3432
+
3433
+ // We override the default implementation, which uses `try_fold`,
3434
+ // because this simple implementation generates less LLVM IR and is
3435
+ // faster to compile. Also, the `assume` avoids a bounds check.
3350
3436
#[ inline]
3351
3437
#[ rustc_inherit_overflow_checks]
3352
3438
fn position<P >( & mut self , mut predicate: P ) -> Option <usize > where
3353
3439
Self : Sized ,
3354
3440
P : FnMut ( Self :: Item ) -> bool ,
3355
3441
{
3356
- // The addition might panic on overflow.
3357
3442
let n = len!( self ) ;
3358
- self . try_fold( 0 , move |i, x| {
3359
- if predicate( x) { Err ( i) }
3360
- else { Ok ( i + 1 ) }
3361
- } ) . err( )
3362
- . map( |i| {
3443
+ let mut i = 0 ;
3444
+ while let Some ( x) = self . next( ) {
3445
+ if predicate( x) {
3363
3446
unsafe { assume( i < n) } ;
3364
- i
3365
- } )
3447
+ return Some ( i) ;
3448
+ }
3449
+ i += 1 ;
3450
+ }
3451
+ None
3366
3452
}
3367
3453
3454
+ // We override the default implementation, which uses `try_fold`,
3455
+ // because this simple implementation generates less LLVM IR and is
3456
+ // faster to compile. Also, the `assume` avoids a bounds check.
3368
3457
#[ inline]
3369
3458
fn rposition<P >( & mut self , mut predicate: P ) -> Option <usize > where
3370
3459
P : FnMut ( Self :: Item ) -> bool ,
3371
3460
Self : Sized + ExactSizeIterator + DoubleEndedIterator
3372
3461
{
3373
- // No need for an overflow check here, because `ExactSizeIterator`
3374
3462
let n = len!( self ) ;
3375
- self . try_rfold( n, move |i, x| {
3376
- let i = i - 1 ;
3377
- if predicate( x) { Err ( i) }
3378
- else { Ok ( i) }
3379
- } ) . err( )
3380
- . map( |i| {
3463
+ let mut i = n;
3464
+ while let Some ( x) = self . next_back( ) {
3465
+ i -= 1 ;
3466
+ if predicate( x) {
3381
3467
unsafe { assume( i < n) } ;
3382
- i
3383
- } )
3468
+ return Some ( i) ;
3469
+ }
3470
+ }
3471
+ None
3384
3472
}
3385
3473
3386
3474
$( $extra) *
0 commit comments