auto merge of #11930 : bjz/rust/next_power_of_two, r=huonw
This commit is contained in:
@@ -36,7 +36,6 @@ use std::ptr;
|
|||||||
use std::kinds::marker;
|
use std::kinds::marker;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rt::global_heap;
|
use std::rt::global_heap;
|
||||||
use std::uint;
|
|
||||||
use std::unstable::intrinsics::{TyDesc, get_tydesc};
|
use std::unstable::intrinsics::{TyDesc, get_tydesc};
|
||||||
use std::unstable::intrinsics;
|
use std::unstable::intrinsics;
|
||||||
use std::util;
|
use std::util;
|
||||||
@@ -180,7 +179,7 @@ impl Arena {
|
|||||||
let new_min_chunk_size = num::max(n_bytes, chunk_size);
|
let new_min_chunk_size = num::max(n_bytes, chunk_size);
|
||||||
self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get()));
|
self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get()));
|
||||||
self.pod_head =
|
self.pod_head =
|
||||||
chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
|
chunk(num::next_power_of_two(new_min_chunk_size + 1u), true);
|
||||||
|
|
||||||
return self.alloc_pod_inner(n_bytes, align);
|
return self.alloc_pod_inner(n_bytes, align);
|
||||||
}
|
}
|
||||||
@@ -222,7 +221,7 @@ impl Arena {
|
|||||||
let new_min_chunk_size = num::max(n_bytes, chunk_size);
|
let new_min_chunk_size = num::max(n_bytes, chunk_size);
|
||||||
self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
|
self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
|
||||||
self.head =
|
self.head =
|
||||||
chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
|
chunk(num::next_power_of_two(new_min_chunk_size + 1u), false);
|
||||||
|
|
||||||
return self.alloc_nonpod_inner(n_bytes, align);
|
return self.alloc_nonpod_inner(n_bytes, align);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,9 +177,9 @@ pub mod raw {
|
|||||||
use cast::{transmute, transmute_copy};
|
use cast::{transmute, transmute_copy};
|
||||||
use container::Container;
|
use container::Container;
|
||||||
use option::None;
|
use option::None;
|
||||||
use ptr;
|
|
||||||
use mem;
|
use mem;
|
||||||
use uint;
|
use num::next_power_of_two;
|
||||||
|
use ptr;
|
||||||
use unstable::intrinsics::{move_val_init, TyDesc};
|
use unstable::intrinsics::{move_val_init, TyDesc};
|
||||||
use unstable::intrinsics;
|
use unstable::intrinsics;
|
||||||
use unstable::raw::{Box, Vec};
|
use unstable::raw::{Box, Vec};
|
||||||
@@ -293,7 +293,7 @@ pub mod raw {
|
|||||||
*/
|
*/
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ use num;
|
|||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand;
|
use rand;
|
||||||
use uint;
|
|
||||||
use util::replace;
|
use util::replace;
|
||||||
use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
|
use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
|
||||||
use vec_ng;
|
use vec_ng;
|
||||||
@@ -388,7 +387,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
|
|||||||
pub fn reserve_at_least(&mut self, n: uint) {
|
pub fn reserve_at_least(&mut self, n: uint) {
|
||||||
if n > self.buckets.len() {
|
if n > self.buckets.len() {
|
||||||
let buckets = n * 4 / 3 + 1;
|
let buckets = n * 4 / 3 + 1;
|
||||||
self.resize(uint::next_power_of_two(buckets));
|
self.resize(num::next_power_of_two(buckets));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -445,6 +445,13 @@ mod tests {
|
|||||||
use num::CheckedDiv;
|
use num::CheckedDiv;
|
||||||
use num::Bitwise;
|
use num::Bitwise;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_overflows() {
|
||||||
|
assert!(MAX > 0);
|
||||||
|
assert!(MIN <= 0);
|
||||||
|
assert_eq!(MIN + MAX + 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num() {
|
fn test_num() {
|
||||||
num::test_num(10 as $T, 2 as $T);
|
num::test_num(10 as $T, 2 as $T);
|
||||||
|
|||||||
@@ -440,7 +440,39 @@ pub trait Primitive: Clone
|
|||||||
/// A collection of traits relevant to primitive signed and unsigned integers
|
/// A collection of traits relevant to primitive signed and unsigned integers
|
||||||
pub trait Int: Integer
|
pub trait Int: Integer
|
||||||
+ Primitive
|
+ 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
|
/// Used for representing the classification of floating point numbers
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
@@ -1589,6 +1621,48 @@ mod tests {
|
|||||||
assert_eq!(third.checked_mul(&4), None);
|
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)]
|
#[deriving(Eq)]
|
||||||
struct Value { x: int }
|
struct Value { x: int }
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
use default::Default;
|
use default::Default;
|
||||||
use mem;
|
|
||||||
use num::{Bitwise, Bounded};
|
use num::{Bitwise, Bounded};
|
||||||
use num::{CheckedAdd, CheckedSub, CheckedMul};
|
use num::{CheckedAdd, CheckedSub, CheckedMul};
|
||||||
use num::{CheckedDiv, Zero, One, strconv};
|
use num::{CheckedDiv, Zero, One, strconv};
|
||||||
@@ -26,79 +25,6 @@ use unstable::intrinsics;
|
|||||||
|
|
||||||
uint_module!(uint, int, ::int::BITS)
|
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")]
|
#[cfg(target_word_size = "32")]
|
||||||
impl CheckedAdd for uint {
|
impl CheckedAdd for uint {
|
||||||
#[inline]
|
#[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));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -317,6 +317,13 @@ mod tests {
|
|||||||
use num::Bitwise;
|
use num::Bitwise;
|
||||||
use u16;
|
use u16;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_overflows() {
|
||||||
|
assert!(MAX > 0);
|
||||||
|
assert!(MIN <= 0);
|
||||||
|
assert_eq!(MIN + MAX + 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num() {
|
fn test_num() {
|
||||||
num::test_num(10 as $T, 2 as $T);
|
num::test_num(10 as $T, 2 as $T);
|
||||||
|
|||||||
@@ -104,13 +104,12 @@ use iter::{Iterator, FromIterator, Extendable, range};
|
|||||||
use iter::{Filter, AdditiveIterator, Map};
|
use iter::{Filter, AdditiveIterator, Map};
|
||||||
use iter::{Rev, DoubleEndedIterator, ExactSize};
|
use iter::{Rev, DoubleEndedIterator, ExactSize};
|
||||||
use libc;
|
use libc;
|
||||||
use num::{Saturating};
|
use num::{Saturating, checked_next_power_of_two};
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use ptr;
|
use ptr;
|
||||||
use ptr::RawPtr;
|
use ptr::RawPtr;
|
||||||
use to_str::ToStr;
|
use to_str::ToStr;
|
||||||
use from_str::FromStr;
|
use from_str::FromStr;
|
||||||
use uint;
|
|
||||||
use vec;
|
use vec;
|
||||||
use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
|
use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
|
||||||
use default::Default;
|
use default::Default;
|
||||||
@@ -2640,7 +2639,7 @@ impl OwnedStr for ~str {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reserve_at_least(&mut self, n: uint) {
|
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]
|
#[inline]
|
||||||
|
|||||||
@@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use kinds::Send;
|
use kinds::Send;
|
||||||
|
use num::next_power_of_two;
|
||||||
use option::{Option, Some, None};
|
use option::{Option, Some, None};
|
||||||
use sync::arc::UnsafeArc;
|
use sync::arc::UnsafeArc;
|
||||||
use sync::atomics::{AtomicUint,Relaxed,Release,Acquire};
|
use sync::atomics::{AtomicUint,Relaxed,Release,Acquire};
|
||||||
use uint;
|
|
||||||
use vec;
|
use vec;
|
||||||
|
|
||||||
struct Node<T> {
|
struct Node<T> {
|
||||||
@@ -64,7 +64,7 @@ impl<T: Send> State<T> {
|
|||||||
2u
|
2u
|
||||||
} else {
|
} else {
|
||||||
// use next power of 2 as capacity
|
// use next power of 2 as capacity
|
||||||
uint::next_power_of_two(capacity)
|
next_power_of_two(capacity)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
capacity
|
capacity
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
|
|||||||
use cmp;
|
use cmp;
|
||||||
use default::Default;
|
use default::Default;
|
||||||
use iter::*;
|
use iter::*;
|
||||||
use num::{Integer, CheckedAdd, Saturating};
|
use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two};
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use ptr::to_unsafe_ptr;
|
use ptr::to_unsafe_ptr;
|
||||||
use ptr;
|
use ptr;
|
||||||
@@ -1487,7 +1487,7 @@ impl<T> OwnedVector<T> for ~[T] {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reserve_at_least(&mut self, n: uint) {
|
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]
|
#[inline]
|
||||||
|
|||||||
Reference in New Issue
Block a user