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