about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-02-01 04:11:21 -0800
committerbors <bors@rust-lang.org>2014-02-01 04:11:21 -0800
commit1d494198bbb9701b6336febcf9d0ceb39e4b7975 (patch)
tree648f27b2e0b1f8d09b3a207b5d0ed2451ef01b4b /src/libstd
parentc80d28c8e322b6da49b7725d2b5e5b5cc86da822 (diff)
parent1f15d24243078903410176a0924bd5d09fe1c2b8 (diff)
downloadrust-1d494198bbb9701b6336febcf9d0ceb39e4b7975.tar.gz
rust-1d494198bbb9701b6336febcf9d0ceb39e4b7975.zip
auto merge of #11930 : bjz/rust/next_power_of_two, r=huonw
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs6
-rw-r--r--src/libstd/hashmap.rs3
-rw-r--r--src/libstd/num/int.rs7
-rw-r--r--src/libstd/num/int_macros.rs7
-rw-r--r--src/libstd/num/mod.rs76
-rw-r--r--src/libstd/num/uint.rs133
-rw-r--r--src/libstd/num/uint_macros.rs7
-rw-r--r--src/libstd/str.rs5
-rw-r--r--src/libstd/sync/mpmc_bounded_queue.rs4
-rw-r--r--src/libstd/vec.rs4
10 files changed, 99 insertions, 153 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 18cb470db4d..55e90248e1c 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -177,9 +177,9 @@ pub mod raw {
     use cast::{transmute, transmute_copy};
     use container::Container;
     use option::None;
-    use ptr;
     use mem;
-    use uint;
+    use num::next_power_of_two;
+    use ptr;
     use unstable::intrinsics::{move_val_init, TyDesc};
     use unstable::intrinsics;
     use unstable::raw::{Box, Vec};
@@ -293,7 +293,7 @@ pub mod raw {
      */
     #[inline]
     pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
-        reserve(v, uint::next_power_of_two(n));
+        reserve(v, next_power_of_two(n));
     }
 }
 
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 13a03d32525..a97feea786d 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -64,7 +64,6 @@ use num;
 use option::{None, Option, Some};
 use rand::Rng;
 use rand;
-use uint;
 use util::replace;
 use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
 use vec_ng;
@@ -388,7 +387,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
     pub fn reserve_at_least(&mut self, n: uint) {
         if n > self.buckets.len() {
             let buckets = n * 4 / 3 + 1;
-            self.resize(uint::next_power_of_two(buckets));
+            self.resize(num::next_power_of_two(buckets));
         }
     }
 
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index 96e182adb82..f336afe12f4 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -120,10 +120,3 @@ impl CheckedMul for int {
         }
     }
 }
-
-#[test]
-fn test_overflows() {
-    assert!((::int::MAX > 0));
-    assert!((::int::MIN <= 0));
-    assert!((::int::MIN + ::int::MAX + 1 == 0));
-}
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index c0f67912cde..c8d5dc12499 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -446,6 +446,13 @@ mod tests {
     use num::Bitwise;
 
     #[test]
+    fn test_overflows() {
+        assert!(MAX > 0);
+        assert!(MIN <= 0);
+        assert_eq!(MIN + MAX + 1, 0);
+    }
+
+    #[test]
     fn test_num() {
         num::test_num(10 as $T, 2 as $T);
     }
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 956c04db09c..976761b5120 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -440,7 +440,39 @@ pub trait Primitive: Clone
 /// A collection of traits relevant to primitive signed and unsigned integers
 pub trait Int: Integer
              + Primitive
-             + Bitwise {}
+             + Bitwise
+             + CheckedAdd
+             + CheckedSub
+             // + CheckedMul // FIXME #8849: currently not impled on 32-bit
+             + CheckedDiv {}
+
+/// Returns the smallest power of 2 greater than or equal to `n`.
+#[inline]
+pub fn next_power_of_two<T: Unsigned + Int>(n: T) -> T {
+    let halfbits: T = cast(size_of::<T>() * 4).unwrap();
+    let mut tmp: T = n - one();
+    let mut shift: T = one();
+    while shift <= halfbits {
+        tmp = tmp | (tmp >> shift);
+        shift = shift << one();
+    }
+    tmp + one()
+}
+
+/// 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<T: Unsigned + Int>(n: T) -> Option<T> {
+    let halfbits: T = cast(size_of::<T>() * 4).unwrap();
+    let mut tmp: T = n - one();
+    let mut shift: T = one();
+    while shift <= halfbits {
+        tmp = tmp | (tmp >> shift);
+        shift = shift << one();
+    }
+    tmp.checked_add(&one())
+}
 
 /// Used for representing the classification of floating point numbers
 #[deriving(Eq)]
@@ -1589,6 +1621,48 @@ mod tests {
         assert_eq!(third.checked_mul(&4), None);
     }
 
+    macro_rules! test_next_power_of_two(
+        ($test_name:ident, $T:ident) => (
+            fn $test_name() {
+                #[test];
+                assert_eq!(next_power_of_two::<$T>(0), 0);
+                let mut next_power = 1;
+                for i in range::<$T>(1, 40) {
+                     assert_eq!(next_power_of_two(i), next_power);
+                     if i == next_power { next_power *= 2 }
+                }
+            }
+        )
+    )
+
+    test_next_power_of_two!(test_next_power_of_two_u8, u8)
+    test_next_power_of_two!(test_next_power_of_two_u16, u16)
+    test_next_power_of_two!(test_next_power_of_two_u32, u32)
+    test_next_power_of_two!(test_next_power_of_two_u64, u64)
+    test_next_power_of_two!(test_next_power_of_two_uint, uint)
+
+    macro_rules! test_checked_next_power_of_two(
+        ($test_name:ident, $T:ident) => (
+            fn $test_name() {
+                #[test];
+                assert_eq!(checked_next_power_of_two::<$T>(0), None);
+                let mut next_power = 1;
+                for i in range::<$T>(1, 40) {
+                     assert_eq!(checked_next_power_of_two(i), 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);
+            }
+        )
+    )
+
+    test_checked_next_power_of_two!(test_checked_next_power_of_two_u8, u8)
+    test_checked_next_power_of_two!(test_checked_next_power_of_two_u16, u16)
+    test_checked_next_power_of_two!(test_checked_next_power_of_two_u32, u32)
+    test_checked_next_power_of_two!(test_checked_next_power_of_two_u64, u64)
+    test_checked_next_power_of_two!(test_checked_next_power_of_two_uint, uint)
 
     #[deriving(Eq)]
     struct Value { x: int }
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 89914571ada..1811ebc7acc 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -15,7 +15,6 @@
 use prelude::*;
 
 use default::Default;
-use mem;
 use num::{Bitwise, Bounded};
 use num::{CheckedAdd, CheckedSub, CheckedMul};
 use num::{CheckedDiv, Zero, One, strconv};
@@ -26,79 +25,6 @@ use unstable::intrinsics;
 
 uint_module!(uint, int, ::int::BITS)
 
-///
-/// Divide two numbers, return the result, rounded up.
-///
-/// # Arguments
-///
-/// * x - an integer
-/// * y - an integer distinct from 0u
-///
-/// # Return value
-///
-/// The smallest integer `q` such that `x/y <= q`.
-///
-pub fn div_ceil(x: uint, y: uint) -> uint {
-    let div = x / y;
-    if x % y == 0u { div }
-    else { div + 1u }
-}
-
-///
-/// Divide two numbers, return the result, rounded to the closest integer.
-///
-/// # Arguments
-///
-/// * x - an integer
-/// * y - an integer distinct from 0u
-///
-/// # Return value
-///
-/// The integer `q` closest to `x/y`.
-///
-pub fn div_round(x: uint, y: uint) -> uint {
-    let div = x / y;
-    if x % y * 2u  < y { div }
-    else { div + 1u }
-}
-
-///
-/// Divide two numbers, return the result, rounded down.
-///
-/// Note: This is the same function as `div`.
-///
-/// # Arguments
-///
-/// * x - an integer
-/// * y - an integer distinct from 0u
-///
-/// # Return value
-///
-/// The smallest integer `q` such that `x/y <= q`. This
-/// is either `x/y` or `x/y + 1`.
-///
-pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
-
-/// Returns the smallest power of 2 greater than or equal to `n`
-#[inline]
-pub fn next_power_of_two(n: uint) -> uint {
-    let halfbits: uint = mem::size_of::<uint>() * 4u;
-    let mut tmp: uint = n - 1u;
-    let mut shift: uint = 1u;
-    while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
-    tmp + 1u
-}
-
-/// Returns the smallest power of 2 greater than or equal to `n`
-#[inline]
-pub fn next_power_of_two_opt(n: uint) -> Option<uint> {
-    let halfbits: uint = mem::size_of::<uint>() * 4u;
-    let mut tmp: uint = n - 1u;
-    let mut shift: uint = 1u;
-    while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
-    tmp.checked_add(&1)
-}
-
 #[cfg(target_word_size = "32")]
 impl CheckedAdd for uint {
     #[inline]
@@ -164,62 +90,3 @@ impl CheckedMul for uint {
         }
     }
 }
-
-#[test]
-fn test_next_power_of_two() {
-    assert!((next_power_of_two(0u) == 0u));
-    assert!((next_power_of_two(1u) == 1u));
-    assert!((next_power_of_two(2u) == 2u));
-    assert!((next_power_of_two(3u) == 4u));
-    assert!((next_power_of_two(4u) == 4u));
-    assert!((next_power_of_two(5u) == 8u));
-    assert!((next_power_of_two(6u) == 8u));
-    assert!((next_power_of_two(7u) == 8u));
-    assert!((next_power_of_two(8u) == 8u));
-    assert!((next_power_of_two(9u) == 16u));
-    assert!((next_power_of_two(10u) == 16u));
-    assert!((next_power_of_two(11u) == 16u));
-    assert!((next_power_of_two(12u) == 16u));
-    assert!((next_power_of_two(13u) == 16u));
-    assert!((next_power_of_two(14u) == 16u));
-    assert!((next_power_of_two(15u) == 16u));
-    assert!((next_power_of_two(16u) == 16u));
-    assert!((next_power_of_two(17u) == 32u));
-    assert!((next_power_of_two(18u) == 32u));
-    assert!((next_power_of_two(19u) == 32u));
-    assert!((next_power_of_two(20u) == 32u));
-    assert!((next_power_of_two(21u) == 32u));
-    assert!((next_power_of_two(22u) == 32u));
-    assert!((next_power_of_two(23u) == 32u));
-    assert!((next_power_of_two(24u) == 32u));
-    assert!((next_power_of_two(25u) == 32u));
-    assert!((next_power_of_two(26u) == 32u));
-    assert!((next_power_of_two(27u) == 32u));
-    assert!((next_power_of_two(28u) == 32u));
-    assert!((next_power_of_two(29u) == 32u));
-    assert!((next_power_of_two(30u) == 32u));
-    assert!((next_power_of_two(31u) == 32u));
-    assert!((next_power_of_two(32u) == 32u));
-    assert!((next_power_of_two(33u) == 64u));
-    assert!((next_power_of_two(34u) == 64u));
-    assert!((next_power_of_two(35u) == 64u));
-    assert!((next_power_of_two(36u) == 64u));
-    assert!((next_power_of_two(37u) == 64u));
-    assert!((next_power_of_two(38u) == 64u));
-    assert!((next_power_of_two(39u) == 64u));
-}
-
-#[test]
-fn test_overflows() {
-    use uint;
-    assert!((uint::MAX > 0u));
-    assert!((uint::MIN <= 0u));
-    assert!((uint::MIN + uint::MAX + 1u == 0u));
-}
-
-#[test]
-fn test_div() {
-    assert!((div_floor(3u, 4u) == 0u));
-    assert!((div_ceil(3u, 4u)  == 1u));
-    assert!((div_round(3u, 4u) == 1u));
-}
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 224f16cc663..eb483843b5d 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -318,6 +318,13 @@ mod tests {
     use u16;
 
     #[test]
+    fn test_overflows() {
+        assert!(MAX > 0);
+        assert!(MIN <= 0);
+        assert_eq!(MIN + MAX + 1, 0);
+    }
+
+    #[test]
     fn test_num() {
         num::test_num(10 as $T, 2 as $T);
     }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 16af8367edf..3cc199ce195 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -104,13 +104,12 @@ use iter::{Iterator, FromIterator, Extendable, range};
 use iter::{Filter, AdditiveIterator, Map};
 use iter::{Rev, DoubleEndedIterator, ExactSize};
 use libc;
-use num::{Saturating};
+use num::{Saturating, checked_next_power_of_two};
 use option::{None, Option, Some};
 use ptr;
 use ptr::RawPtr;
 use to_str::ToStr;
 use from_str::FromStr;
-use uint;
 use vec;
 use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
 use default::Default;
@@ -2640,7 +2639,7 @@ impl OwnedStr for ~str {
 
     #[inline]
     fn reserve_at_least(&mut self, n: uint) {
-        self.reserve(uint::next_power_of_two_opt(n).unwrap_or(n))
+        self.reserve(checked_next_power_of_two(n).unwrap_or(n))
     }
 
     #[inline]
diff --git a/src/libstd/sync/mpmc_bounded_queue.rs b/src/libstd/sync/mpmc_bounded_queue.rs
index bb0e96f96de..74f3a6f6918 100644
--- a/src/libstd/sync/mpmc_bounded_queue.rs
+++ b/src/libstd/sync/mpmc_bounded_queue.rs
@@ -31,10 +31,10 @@
 
 use clone::Clone;
 use kinds::Send;
+use num::next_power_of_two;
 use option::{Option, Some, None};
 use sync::arc::UnsafeArc;
 use sync::atomics::{AtomicUint,Relaxed,Release,Acquire};
-use uint;
 use vec;
 
 struct Node<T> {
@@ -64,7 +64,7 @@ impl<T: Send> State<T> {
                 2u
             } else {
                 // use next power of 2 as capacity
-                uint::next_power_of_two(capacity)
+                next_power_of_two(capacity)
             }
         } else {
             capacity
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 8e733686472..15cd5ce3343 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -109,7 +109,7 @@ use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
 use cmp;
 use default::Default;
 use iter::*;
-use num::{Integer, CheckedAdd, Saturating};
+use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two};
 use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
 use ptr;
@@ -1487,7 +1487,7 @@ impl<T> OwnedVector<T> for ~[T] {
 
     #[inline]
     fn reserve_at_least(&mut self, n: uint) {
-        self.reserve(uint::next_power_of_two_opt(n).unwrap_or(n));
+        self.reserve(checked_next_power_of_two(n).unwrap_or(n));
     }
 
     #[inline]