diff options
| author | Aaron Liblong <liblonga@physics.utoronto.ca> | 2014-12-08 01:03:35 -0500 |
|---|---|---|
| committer | Aaron Liblong <liblonga@physics.utoronto.ca> | 2014-12-19 18:21:24 -0500 |
| commit | f6328b60da4c506f0f15dc0194f9b9a89aa61a79 (patch) | |
| tree | fa079f83c6ba1a4d2651230958c078e7c6ef1a27 /src/libcore | |
| parent | 99d6956c3bdb290b9fd539c5dc15a2b502da5e7a (diff) | |
| download | rust-f6328b60da4c506f0f15dc0194f9b9a89aa61a79.tar.gz rust-f6328b60da4c506f0f15dc0194f9b9a89aa61a79.zip | |
Reform power_of_two methods for perf increase & semantic change to consider 0 not a power of 2.
Vec panics when attempting to reserve capacity > int::MAX (uint::MAX / 2).
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/num/mod.rs | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index fcb2ca93054..39d8ac279a0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -673,35 +673,30 @@ signed_int_impl! { int } #[unstable = "recently settled as part of numerics reform"] pub trait UnsignedInt: Int { /// Returns `true` iff `self == 2^k` for some `k`. + #[inline] fn is_power_of_two(self) -> bool { - (self - Int::one()) & self == Int::zero() + (self - Int::one()) & self == Int::zero() && !(self == Int::zero()) } /// Returns the smallest power of two greater than or equal to `self`. + /// Unspecified behavior on overflow. #[inline] fn next_power_of_two(self) -> Self { - let halfbits = size_of::<Self>() * 4; - let mut tmp = self - Int::one(); - let mut shift = 1u; - while shift <= halfbits { - tmp = tmp | (tmp >> shift); - shift = shift << 1u; - } - tmp + Int::one() + let bits = size_of::<Self>() * 8; + let one: Self = Int::one(); + one << ((bits - (self - one).leading_zeros()) % bits) } /// Returns the smallest power of two greater than or equal to `n`. If the /// next power of two is greater than the type's maximum value, `None` is /// returned, otherwise the power of two is wrapped in `Some`. fn checked_next_power_of_two(self) -> Option<Self> { - let halfbits = size_of::<Self>() * 4; - let mut tmp = self - Int::one(); - let mut shift = 1u; - while shift <= halfbits { - tmp = tmp | (tmp >> shift); - shift = shift << 1u; + let npot = self.next_power_of_two(); + if npot >= self { + Some(npot) + } else { + None } - tmp.checked_add(Int::one()) } } |
