@@ -2141,11 +2141,15 @@ macro_rules! iterator {
2141
2141
None
2142
2142
} else {
2143
2143
let old = self . ptr;
2144
- // purposefully don't use 'ptr.offset' because for
2145
- // vectors with 0-size elements this would return the
2146
- // same pointer.
2147
- self . ptr = cast:: transmute( self . ptr as uint +
2148
- sys:: nonzero_size_of:: <T >( ) ) ;
2144
+ self . ptr = if sys:: size_of:: <T >( ) == 0 {
2145
+ // purposefully don't use 'ptr.offset' because for
2146
+ // vectors with 0-size elements this would return the
2147
+ // same pointer.
2148
+ cast:: transmute( self . ptr as uint + 1 )
2149
+ } else {
2150
+ self . ptr. offset( 1 )
2151
+ } ;
2152
+
2149
2153
Some ( cast:: transmute( old) )
2150
2154
}
2151
2155
}
@@ -2171,9 +2175,12 @@ macro_rules! double_ended_iterator {
2171
2175
if self . end == self . ptr {
2172
2176
None
2173
2177
} else {
2174
- // See above for why 'ptr.offset' isn't used
2175
- self . end = cast:: transmute( self . end as uint -
2176
- sys:: nonzero_size_of:: <T >( ) ) ;
2178
+ self . end = if sys:: size_of:: <T >( ) == 0 {
2179
+ // See above for why 'ptr.offset' isn't used
2180
+ cast:: transmute( self . end as uint - 1 )
2181
+ } else {
2182
+ self . end. offset( -1 )
2183
+ } ;
2177
2184
Some ( cast:: transmute( self . end) )
2178
2185
}
2179
2186
}
@@ -3566,3 +3573,26 @@ mod tests {
3566
3573
assert!( cnt == 3 ) ;
3567
3574
}
3568
3575
}
3576
+
3577
+ #[ cfg( test) ]
3578
+ mod bench {
3579
+ use extra:: test:: BenchHarness ;
3580
+ use vec;
3581
+ use option:: * ;
3582
+
3583
+ #[ bench]
3584
+ fn iterator ( bh : & mut BenchHarness ) {
3585
+ // peculiar numbers to stop LLVM from optimising the summation
3586
+ // out.
3587
+ let v = vec:: from_fn ( 100 , |i| i ^ ( i << 1 ) ^ ( i >> 1 ) ) ;
3588
+
3589
+ do bh. iter {
3590
+ let mut sum = 0 ;
3591
+ foreach x in v. iter ( ) {
3592
+ sum += * x;
3593
+ }
3594
+ // sum == 11806, to stop dead code elimination.
3595
+ if sum == 0 { fail ! ( ) }
3596
+ }
3597
+ }
3598
+ }
0 commit comments