Skip to content

Commit b0a82d9

Browse files
committed
simplify len macro: No longer require the type
Also use ident, not expr, to avoid accidental side-effects
1 parent 3e3ff4b commit b0a82d9

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

src/libcore/slice/mod.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,18 +2337,25 @@ impl<'a, T> IntoIterator for &'a mut [T] {
23372337
}
23382338
}
23392339

2340+
// Macro helper functions
2341+
#[inline(always)]
2342+
fn size_from_ptr<T>(_: *const T) -> usize {
2343+
mem::size_of::<T>()
2344+
}
2345+
23402346
// Inlining is_empty and len makes a huge performance difference
23412347
macro_rules! is_empty {
23422348
// The way we encode the length of a ZST iterator, this works both for ZST
23432349
// and non-ZST.
2344-
($self: expr) => {$self.ptr == $self.end}
2350+
($self: ident) => {$self.ptr == $self.end}
23452351
}
23462352
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)
23502357
} else {
2351-
$self.end.offset_from($self.ptr) as usize
2358+
$self.end.offset_from(start) as usize
23522359
}
23532360
}}
23542361
}
@@ -2360,7 +2367,7 @@ macro_rules! iterator {
23602367
// Helper function for creating a slice from the iterator.
23612368
#[inline(always)]
23622369
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)) }
23642371
}
23652372

23662373
// Helper function for moving the start of the iterator forwards by `offset` elements,
@@ -2398,7 +2405,7 @@ macro_rules! iterator {
23982405
impl<'a, T> ExactSizeIterator for $name<'a, T> {
23992406
#[inline(always)]
24002407
fn len(&self) -> usize {
2401-
unsafe { len!(T, self) }
2408+
unsafe { len!(self) }
24022409
}
24032410

24042411
#[inline(always)]
@@ -2429,7 +2436,7 @@ macro_rules! iterator {
24292436

24302437
#[inline]
24312438
fn size_hint(&self) -> (usize, Option<usize>) {
2432-
let exact = unsafe { len!(T, self) };
2439+
let exact = unsafe { len!(self) };
24332440
(exact, Some(exact))
24342441
}
24352442

@@ -2440,7 +2447,7 @@ macro_rules! iterator {
24402447

24412448
#[inline]
24422449
fn nth(&mut self, n: usize) -> Option<$elem> {
2443-
if n >= unsafe { len!(T, self) } {
2450+
if n >= unsafe { len!(self) } {
24442451
// This iterator is now empty.
24452452
if mem::size_of::<T>() == 0 {
24462453
// We have to do it this way as `ptr` may never be 0, but `end`
@@ -2471,7 +2478,7 @@ macro_rules! iterator {
24712478
// manual unrolling is needed when there are conditional exits from the loop
24722479
let mut accum = init;
24732480
unsafe {
2474-
while len!(T, self) >= 4 {
2481+
while len!(self) >= 4 {
24752482
accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
24762483
accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
24772484
accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
@@ -2562,7 +2569,7 @@ macro_rules! iterator {
25622569
// manual unrolling is needed when there are conditional exits from the loop
25632570
let mut accum = init;
25642571
unsafe {
2565-
while len!(T, self) >= 4 {
2572+
while len!(self) >= 4 {
25662573
accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
25672574
accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
25682575
accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
@@ -2769,7 +2776,7 @@ impl<'a, T> IterMut<'a, T> {
27692776
/// ```
27702777
#[stable(feature = "iter_to_slice", since = "1.4.0")]
27712778
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)) }
27732780
}
27742781
}
27752782

0 commit comments

Comments
 (0)