|
15 | 15 | use convert::TryFrom;
|
16 | 16 | use fmt;
|
17 | 17 | use intrinsics;
|
18 |
| -use mem::size_of; |
19 | 18 | use str::FromStr;
|
20 | 19 |
|
21 | 20 | /// Provides intentionally-wrapped arithmetic on `T`.
|
@@ -2327,26 +2326,25 @@ macro_rules! uint_impl {
|
2327 | 2326 | (self.wrapping_sub(1)) & self == 0 && !(self == 0)
|
2328 | 2327 | }
|
2329 | 2328 |
|
2330 |
| - // Returns one less than next greater power of two. |
2331 |
| - // (For 8u8 next greater power of two is 16u8 and for 6u8 it is 8u8) |
2332 |
| - // |
2333 |
| - // 8u8.round_up_to_one_less_than_a_power_of_two() == 15 |
2334 |
| - // 6u8.round_up_to_one_less_than_a_power_of_two() == 7 |
2335 |
| - fn round_up_to_one_less_than_a_power_of_two(self) -> Self { |
2336 |
| - let bits = size_of::<Self>() as u32 * 8; |
2337 |
| - let z = self.leading_zeros(); |
2338 |
| - (if z == bits { 0 as Self } else { !0 }).wrapping_shr(z) |
2339 |
| - } |
2340 |
| - |
2341 | 2329 | // Returns one less than next power of two.
|
2342 | 2330 | // (For 8u8 next power of two is 8u8 and for 6u8 it is 8u8)
|
2343 | 2331 | //
|
2344 | 2332 | // 8u8.one_less_than_next_power_of_two() == 7
|
2345 | 2333 | // 6u8.one_less_than_next_power_of_two() == 7
|
| 2334 | + // |
| 2335 | + // This method cannot overflow, as in the `next_power_of_two` |
| 2336 | + // overflow cases it instead ends up returning the maximum value |
| 2337 | + // of the type, and can return 0 for 0. |
2346 | 2338 | fn one_less_than_next_power_of_two(self) -> Self {
|
2347 |
| - self.wrapping_sub(1) |
2348 |
| - .round_up_to_one_less_than_a_power_of_two() |
2349 |
| - .wrapping_add(if self == 0 { 1 } else { 0 }) |
| 2339 | + if self <= 1 { return 0; } |
| 2340 | + |
| 2341 | + // Because `p > 0`, it cannot consist entirely of leading zeros. |
| 2342 | + // That means the shift is always in-bounds, and some processors |
| 2343 | + // (such as intel pre-haswell) have more efficient ctlz |
| 2344 | + // intrinsics when the argument is non-zero. |
| 2345 | + let p = self - 1; |
| 2346 | + let z = p.leading_zeros(); |
| 2347 | + <$SelfT>::max_value() >> z |
2350 | 2348 | }
|
2351 | 2349 |
|
2352 | 2350 | /// Returns the smallest power of two greater than or equal to `self`.
|
|
0 commit comments