@@ -2337,18 +2337,25 @@ impl<'a, T> IntoIterator for &'a mut [T] {
2337
2337
}
2338
2338
}
2339
2339
2340
+ // Macro helper functions
2341
+ #[ inline( always) ]
2342
+ fn size_from_ptr < T > ( _: * const T ) -> usize {
2343
+ mem:: size_of :: < T > ( )
2344
+ }
2345
+
2340
2346
// Inlining is_empty and len makes a huge performance difference
2341
2347
macro_rules! is_empty {
2342
2348
// The way we encode the length of a ZST iterator, this works both for ZST
2343
2349
// and non-ZST.
2344
- ( $self: expr ) => { $self. ptr == $self. end}
2350
+ ( $self: ident ) => { $self. ptr == $self. end}
2345
2351
}
2346
2352
macro_rules! len {
2347
- ( $T: ty, $self: expr) => { {
2348
- if mem:: size_of:: <$T>( ) == 0 {
2349
- ( $self. end as usize ) . wrapping_sub( $self. ptr as usize )
2353
+ ( $self: ident) => { {
2354
+ let start = $self. ptr;
2355
+ if size_from_ptr( start) == 0 {
2356
+ ( $self. end as usize ) . wrapping_sub( start as usize )
2350
2357
} else {
2351
- $self. end. offset_from( $self . ptr ) as usize
2358
+ $self. end. offset_from( start ) as usize
2352
2359
}
2353
2360
} }
2354
2361
}
@@ -2360,7 +2367,7 @@ macro_rules! iterator {
2360
2367
// Helper function for creating a slice from the iterator.
2361
2368
#[ inline( always) ]
2362
2369
fn make_slice( & self ) -> & ' a [ T ] {
2363
- unsafe { from_raw_parts( self . ptr, len!( T , self ) ) }
2370
+ unsafe { from_raw_parts( self . ptr, len!( self ) ) }
2364
2371
}
2365
2372
2366
2373
// Helper function for moving the start of the iterator forwards by `offset` elements,
@@ -2398,7 +2405,7 @@ macro_rules! iterator {
2398
2405
impl <' a, T > ExactSizeIterator for $name<' a, T > {
2399
2406
#[ inline( always) ]
2400
2407
fn len( & self ) -> usize {
2401
- unsafe { len!( T , self ) }
2408
+ unsafe { len!( self ) }
2402
2409
}
2403
2410
2404
2411
#[ inline( always) ]
@@ -2429,7 +2436,7 @@ macro_rules! iterator {
2429
2436
2430
2437
#[ inline]
2431
2438
fn size_hint( & self ) -> ( usize , Option <usize >) {
2432
- let exact = unsafe { len!( T , self ) } ;
2439
+ let exact = unsafe { len!( self ) } ;
2433
2440
( exact, Some ( exact) )
2434
2441
}
2435
2442
@@ -2440,7 +2447,7 @@ macro_rules! iterator {
2440
2447
2441
2448
#[ inline]
2442
2449
fn nth( & mut self , n: usize ) -> Option <$elem> {
2443
- if n >= unsafe { len!( T , self ) } {
2450
+ if n >= unsafe { len!( self ) } {
2444
2451
// This iterator is now empty.
2445
2452
if mem:: size_of:: <T >( ) == 0 {
2446
2453
// We have to do it this way as `ptr` may never be 0, but `end`
@@ -2471,7 +2478,7 @@ macro_rules! iterator {
2471
2478
// manual unrolling is needed when there are conditional exits from the loop
2472
2479
let mut accum = init;
2473
2480
unsafe {
2474
- while len!( T , self ) >= 4 {
2481
+ while len!( self ) >= 4 {
2475
2482
accum = f( accum, & $( $mut_ ) * * self . post_inc_start( 1 ) ) ?;
2476
2483
accum = f( accum, & $( $mut_ ) * * self . post_inc_start( 1 ) ) ?;
2477
2484
accum = f( accum, & $( $mut_ ) * * self . post_inc_start( 1 ) ) ?;
@@ -2562,7 +2569,7 @@ macro_rules! iterator {
2562
2569
// manual unrolling is needed when there are conditional exits from the loop
2563
2570
let mut accum = init;
2564
2571
unsafe {
2565
- while len!( T , self ) >= 4 {
2572
+ while len!( self ) >= 4 {
2566
2573
accum = f( accum, & $( $mut_ ) * * self . pre_dec_end( 1 ) ) ?;
2567
2574
accum = f( accum, & $( $mut_ ) * * self . pre_dec_end( 1 ) ) ?;
2568
2575
accum = f( accum, & $( $mut_ ) * * self . pre_dec_end( 1 ) ) ?;
@@ -2769,7 +2776,7 @@ impl<'a, T> IterMut<'a, T> {
2769
2776
/// ```
2770
2777
#[ stable( feature = "iter_to_slice" , since = "1.4.0" ) ]
2771
2778
pub fn into_slice ( self ) -> & ' a mut [ T ] {
2772
- unsafe { from_raw_parts_mut ( self . ptr , len ! ( T , self ) ) }
2779
+ unsafe { from_raw_parts_mut ( self . ptr , len ! ( self ) ) }
2773
2780
}
2774
2781
}
2775
2782
0 commit comments