diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 3e93430eb69..fb091ec7f84 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -38,7 +38,7 @@ use std::cmp; use std::intrinsics::{TyDesc, get_tydesc}; use std::intrinsics; use std::mem; -use std::num; +use std::num::UnsignedInt; use std::ptr; use std::rc::Rc; use std::rt::heap::{allocate, deallocate}; @@ -187,7 +187,7 @@ impl Arena { self.chunks.borrow_mut().push(self.copy_head.borrow().clone()); *self.copy_head.borrow_mut() = - chunk(num::next_power_of_two(new_min_chunk_size + 1u), true); + chunk((new_min_chunk_size + 1u).next_power_of_two(), true); return self.alloc_copy_inner(n_bytes, align); } @@ -228,7 +228,7 @@ impl Arena { self.chunks.borrow_mut().push(self.head.borrow().clone()); *self.head.borrow_mut() = - chunk(num::next_power_of_two(new_min_chunk_size + 1u), false); + chunk((new_min_chunk_size + 1u).next_power_of_two(), false); return self.alloc_noncopy_inner(n_bytes, align); } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 0e3799ed9ac..3ef7667dd8f 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -21,7 +21,7 @@ use core::default::Default; use core::fmt; use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::mem; -use core::num; +use core::num::UnsignedInt; use core::ops; use core::ptr; use core::raw::Slice as RawSlice; @@ -605,7 +605,7 @@ impl Vec { None => panic!("Vec::reserve: `uint` overflow"), // if the checked_add Some(new_cap) => { - let amort_cap = num::next_power_of_two(new_cap); + let amort_cap = new_cap.next_power_of_two(); // next_power_of_two will overflow to exactly 0 for really big capacities if amort_cap == 0 { self.grow_capacity(new_cap); diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 3763fb14b41..8bab90c57e2 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -621,39 +621,46 @@ int_cast_impl!(i64, u64) #[cfg(target_word_size = "32")] int_cast_impl!(int, u32) #[cfg(target_word_size = "64")] int_cast_impl!(int, u64) -/// Returns the smallest power of 2 greater than or equal to `n`. -#[inline] -pub fn next_power_of_two(n: T) -> T { - let halfbits = size_of::() * 4; - let mut tmp: T = n - one(); - let mut shift = 1u; - while shift <= halfbits { - tmp = tmp | (tmp >> shift); - shift = shift << 1u; +/// Unsigned integers +pub trait UnsignedInt: Int { + /// Returns `true` iff `self == 2^k` for some `k`. + fn is_power_of_two(self) -> bool { + (self - one()) & self == zero() + } + + /// Returns the smallest power of two greater than or equal to `self`. + #[inline] + fn next_power_of_two(self) -> Self { + let halfbits = size_of::() * 4; + let mut tmp = self - one(); + let mut shift = 1u; + while shift <= halfbits { + tmp = tmp | (tmp >> shift); + shift = shift << 1u; + } + tmp + one() + } + + /// 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 { + let halfbits = size_of::() * 4; + let mut tmp = self - one(); + let mut shift = 1u; + while shift <= halfbits { + tmp = tmp | (tmp >> shift); + shift = shift << 1u; + } + tmp.checked_add(&one()) } - tmp + one() } -// Returns `true` iff `n == 2^k` for some k. -#[inline] -pub fn is_power_of_two(n: T) -> bool { - (n - one()) & n == zero() -} - -/// Returns the smallest power of 2 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 2 is wrapped in `Some`. -#[inline] -pub fn checked_next_power_of_two(n: T) -> Option { - let halfbits = size_of::() * 4; - let mut tmp: T = n - one(); - let mut shift = 1u; - while shift <= halfbits { - tmp = tmp | (tmp >> shift); - shift = shift << 1u; - } - tmp.checked_add(&one()) -} +impl UnsignedInt for uint {} +impl UnsignedInt for u8 {} +impl UnsignedInt for u16 {} +impl UnsignedInt for u32 {} +impl UnsignedInt for u64 {} /// A generic trait for converting a value to a number. pub trait ToPrimitive { @@ -1525,4 +1532,18 @@ pub trait Float: Signed + Primitive { // DEPRECATED #[deprecated = "Use `Signed::abs`"] -pub fn abs(value: T) -> T { value.abs() } +pub fn abs(value: T) -> T { + value.abs() +} +#[deprecated = "Use `UnsignedInt::next_power_of_two`"] +pub fn next_power_of_two(n: T) -> T { + n.next_power_of_two() +} +#[deprecated = "Use `UnsignedInt::is_power_of_two`"] +pub fn is_power_of_two(n: T) -> bool { + n.is_power_of_two() +} +#[deprecated = "Use `UnsignedInt::checked_next_power_of_two`"] +pub fn checked_next_power_of_two(n: T) -> Option { + n.checked_next_power_of_two() +} diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f55ce9ba462..68c428f456d 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -18,7 +18,7 @@ use hash::{Hash, Hasher, RandomSipHasher}; use iter::{mod, Iterator, FromIterator, Extend}; use kinds::Sized; use mem::{mod, replace}; -use num; +use num::UnsignedInt; use ops::{Deref, Index, IndexMut}; use option::{Some, None, Option}; use result::{Result, Ok, Err}; @@ -549,7 +549,7 @@ impl, V, S, H: Hasher> HashMap { /// ``` #[inline] pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap { - let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity)); + let cap = max(INITIAL_CAPACITY, capacity).next_power_of_two(); HashMap { hasher: hasher, resize_policy: DefaultResizePolicy::new(cap), @@ -572,8 +572,7 @@ impl, V, S, H: Hasher> HashMap { /// map.reserve(10); /// ``` pub fn reserve(&mut self, new_minimum_capacity: uint) { - let cap = num::next_power_of_two( - max(INITIAL_CAPACITY, new_minimum_capacity)); + let cap = max(INITIAL_CAPACITY, new_minimum_capacity).next_power_of_two(); self.resize_policy.reserve(cap); @@ -588,7 +587,7 @@ impl, V, S, H: Hasher> HashMap { /// 2) Ensure new_capacity is a power of two. fn resize(&mut self, new_capacity: uint) { assert!(self.table.size() <= new_capacity); - assert!(num::is_power_of_two(new_capacity)); + assert!(new_capacity.is_power_of_two()); let mut old_table = replace(&mut self.table, RawTable::new(new_capacity)); let old_size = old_table.size(); diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index fd964cdf02c..b39b15b3eb9 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -17,7 +17,7 @@ use iter::{Iterator, count}; use kinds::{Sized, marker}; use mem::{min_align_of, size_of}; use mem; -use num::{CheckedAdd, CheckedMul, is_power_of_two}; +use num::{CheckedAdd, CheckedMul, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::{Some, None, Option}; use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory}; @@ -516,7 +516,7 @@ impl>> GapThenFull { /// /// Fails if `target_alignment` is not a power of two. fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint { - assert!(is_power_of_two(target_alignment)); + assert!(target_alignment.is_power_of_two()); (unrounded + target_alignment - 1) & !(target_alignment - 1) } diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 3f8504f4553..509de4787d7 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -23,7 +23,7 @@ use option::Option; pub use core::num::{Num, div_rem, Zero, zero, One, one}; pub use core::num::{Signed, abs, signum}; pub use core::num::{Unsigned, pow, Bounded}; -pub use core::num::{Primitive, Int, Saturating}; +pub use core::num::{Primitive, Int, UnsignedInt, Saturating}; pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive}; pub use core::num::{next_power_of_two, is_power_of_two}; @@ -672,10 +672,10 @@ mod tests { ($test_name:ident, $T:ident) => ( fn $test_name() { #![test] - assert_eq!(next_power_of_two::<$T>(0), 0); + assert_eq!((0 as $T).next_power_of_two(), 0); let mut next_power = 1; for i in range::<$T>(1, 40) { - assert_eq!(next_power_of_two(i), next_power); + assert_eq!(i.next_power_of_two(), next_power); if i == next_power { next_power *= 2 } } } @@ -692,15 +692,15 @@ mod tests { ($test_name:ident, $T:ident) => ( fn $test_name() { #![test] - assert_eq!(checked_next_power_of_two::<$T>(0), None); + assert_eq!((0 as $T).checked_next_power_of_two(), None); let mut next_power = 1; for i in range::<$T>(1, 40) { - assert_eq!(checked_next_power_of_two(i), Some(next_power)); + assert_eq!(i.checked_next_power_of_two(), Some(next_power)); if i == next_power { next_power *= 2 } } - assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some()); - assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None); - assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None); + assert!(($T::MAX / 2).checked_next_power_of_two().is_some()); + assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None); + assert_eq!($T::MAX.checked_next_power_of_two(), None); } ) ) diff --git a/src/libsync/mpmc_bounded_queue.rs b/src/libsync/mpmc_bounded_queue.rs index f75511ecbc2..4414f710b15 100644 --- a/src/libsync/mpmc_bounded_queue.rs +++ b/src/libsync/mpmc_bounded_queue.rs @@ -34,7 +34,7 @@ use core::prelude::*; use alloc::arc::Arc; use collections::Vec; -use core::num::next_power_of_two; +use core::num::UnsignedInt; use core::cell::UnsafeCell; use atomic::{AtomicUint,Relaxed,Release,Acquire}; @@ -66,7 +66,7 @@ impl State { 2u } else { // use next power of 2 as capacity - next_power_of_two(capacity) + capacity.next_power_of_two() } } else { capacity