diff options
| author | Irfan Hudda <irfanhudda@gmail.com> | 2017-05-31 22:25:15 +0530 |
|---|---|---|
| committer | Irfan Hudda <irfanhudda@gmail.com> | 2017-05-31 22:25:15 +0530 |
| commit | 18fadb61c4aab3d1b2fc49ac7d7fea85b3914fb3 (patch) | |
| tree | d3acf81304994c00200002d60d685c2bfc8a16e0 /src/libcore | |
| parent | 93219a262706447c52f3f20819e5caa7b2e2e3a2 (diff) | |
Simplify helper functions
Based on @scottmcm 's suggestion
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/num/mod.rs | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 8fd21d77dc3..e5a8cfdd9a1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,7 +15,6 @@ use convert::TryFrom; use fmt; use intrinsics; -use mem::size_of; use str::FromStr; /// Provides intentionally-wrapped arithmetic on `T`. @@ -2327,26 +2326,25 @@ macro_rules! uint_impl { (self.wrapping_sub(1)) & self == 0 && !(self == 0) } - // Returns one less than next greater power of two. - // (For 8u8 next greater power of two is 16u8 and for 6u8 it is 8u8) - // - // 8u8.round_up_to_one_less_than_a_power_of_two() == 15 - // 6u8.round_up_to_one_less_than_a_power_of_two() == 7 - fn round_up_to_one_less_than_a_power_of_two(self) -> Self { - let bits = size_of::<Self>() as u32 * 8; - let z = self.leading_zeros(); - (if z == bits { 0 as Self } else { !0 }).wrapping_shr(z) - } - // Returns one less than next power of two. // (For 8u8 next power of two is 8u8 and for 6u8 it is 8u8) // // 8u8.one_less_than_next_power_of_two() == 7 // 6u8.one_less_than_next_power_of_two() == 7 + // + // This method cannot overflow, as in the `next_power_of_two` + // overflow cases it instead ends up returning the maximum value + // of the type, and can return 0 for 0. fn one_less_than_next_power_of_two(self) -> Self { - self.wrapping_sub(1) - .round_up_to_one_less_than_a_power_of_two() - .wrapping_add(if self == 0 { 1 } else { 0 }) + if self <= 1 { return 0; } + + // Because `p > 0`, it cannot consist entirely of leading zeros. + // That means the shift is always in-bounds, and some processors + // (such as intel pre-haswell) have more efficient ctlz + // intrinsics when the argument is non-zero. + let p = self - 1; + let z = p.leading_zeros(); + <$SelfT>::max_value() >> z } /// Returns the smallest power of two greater than or equal to `self`. |
