Skip to content

Commit 9a3583f

Browse files
committed
Make next_power_of_two generic for unsigned integers
Also rename `next_power_of_two_opt` to `checked_next_power_of_two`.
1 parent 535e806 commit 9a3583f

File tree

8 files changed

+87
-78
lines changed

8 files changed

+87
-78
lines changed

src/libarena/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl Arena {
178178
let new_min_chunk_size = num::max(n_bytes, chunk_size);
179179
self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get()));
180180
self.pod_head =
181-
chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
181+
chunk(num::next_power_of_two(new_min_chunk_size + 1u), true);
182182

183183
return self.alloc_pod_inner(n_bytes, align);
184184
}
@@ -220,7 +220,7 @@ impl Arena {
220220
let new_min_chunk_size = num::max(n_bytes, chunk_size);
221221
self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
222222
self.head =
223-
chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
223+
chunk(num::next_power_of_two(new_min_chunk_size + 1u), false);
224224

225225
return self.alloc_nonpod_inner(n_bytes, align);
226226
}

src/libstd/at_vec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,9 @@ pub mod raw {
177177
use cast::{transmute, transmute_copy};
178178
use container::Container;
179179
use option::None;
180-
use ptr;
181180
use mem;
182-
use uint;
181+
use num::next_power_of_two;
182+
use ptr;
183183
use unstable::intrinsics::{move_val_init, TyDesc};
184184
use unstable::intrinsics;
185185
use unstable::raw::{Box, Vec};
@@ -293,7 +293,7 @@ pub mod raw {
293293
*/
294294
#[inline]
295295
pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
296-
reserve(v, uint::next_power_of_two(n));
296+
reserve(v, next_power_of_two(n));
297297
}
298298
}
299299

src/libstd/hashmap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
388388
pub fn reserve_at_least(&mut self, n: uint) {
389389
if n > self.buckets.len() {
390390
let buckets = n * 4 / 3 + 1;
391-
self.resize(uint::next_power_of_two(buckets));
391+
self.resize(num::next_power_of_two(buckets));
392392
}
393393
}
394394

src/libstd/num/mod.rs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,39 @@ pub trait Primitive: Clone
440440
/// A collection of traits relevant to primitive signed and unsigned integers
441441
pub trait Int: Integer
442442
+ Primitive
443-
+ Bitwise {}
443+
+ Bitwise
444+
+ CheckedAdd
445+
+ CheckedSub
446+
// + CheckedMul // FIXME #8849: currently not impled on 32-bit
447+
+ CheckedDiv {}
448+
449+
/// Returns the smallest power of 2 greater than or equal to `n`.
450+
#[inline]
451+
pub fn next_power_of_two<T: Unsigned + Int>(n: T) -> T {
452+
let halfbits: T = cast(size_of::<T>() * 4).unwrap();
453+
let mut tmp: T = n - one();
454+
let mut shift: T = one();
455+
while shift <= halfbits {
456+
tmp = tmp | (tmp >> shift);
457+
shift = shift << one();
458+
}
459+
tmp + one()
460+
}
461+
462+
/// Returns the smallest power of 2 greater than or equal to `n`. If the next
463+
/// power of two is greater than the type's maximum value, `None` is returned,
464+
/// otherwise the power of 2 is wrapped in `Some`.
465+
#[inline]
466+
pub fn checked_next_power_of_two<T: Unsigned + Int>(n: T) -> Option<T> {
467+
let halfbits: T = cast(size_of::<T>() * 4).unwrap();
468+
let mut tmp: T = n - one();
469+
let mut shift: T = one();
470+
while shift <= halfbits {
471+
tmp = tmp | (tmp >> shift);
472+
shift = shift << one();
473+
}
474+
tmp.checked_add(&one())
475+
}
444476

445477
/// Used for representing the classification of floating point numbers
446478
#[deriving(Eq)]
@@ -1589,6 +1621,48 @@ mod tests {
15891621
assert_eq!(third.checked_mul(&4), None);
15901622
}
15911623

1624+
macro_rules! test_next_power_of_two(
1625+
($test_name:ident, $T:ident) => (
1626+
fn $test_name() {
1627+
#[test];
1628+
assert_eq!(next_power_of_two::<$T>(0), 0);
1629+
let mut next_power = 1;
1630+
for i in range::<$T>(1, 40) {
1631+
assert_eq!(next_power_of_two(i), next_power);
1632+
if i == next_power { next_power *= 2 }
1633+
}
1634+
}
1635+
)
1636+
)
1637+
1638+
test_next_power_of_two!(test_next_power_of_two_u8, u8)
1639+
test_next_power_of_two!(test_next_power_of_two_u16, u16)
1640+
test_next_power_of_two!(test_next_power_of_two_u32, u32)
1641+
test_next_power_of_two!(test_next_power_of_two_u64, u64)
1642+
test_next_power_of_two!(test_next_power_of_two_uint, uint)
1643+
1644+
macro_rules! test_checked_next_power_of_two(
1645+
($test_name:ident, $T:ident) => (
1646+
fn $test_name() {
1647+
#[test];
1648+
assert_eq!(checked_next_power_of_two::<$T>(0), None);
1649+
let mut next_power = 1;
1650+
for i in range::<$T>(1, 40) {
1651+
assert_eq!(checked_next_power_of_two(i), Some(next_power));
1652+
if i == next_power { next_power *= 2 }
1653+
}
1654+
assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some());
1655+
assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None);
1656+
assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None);
1657+
}
1658+
)
1659+
)
1660+
1661+
test_checked_next_power_of_two!(test_checked_next_power_of_two_u8, u8)
1662+
test_checked_next_power_of_two!(test_checked_next_power_of_two_u16, u16)
1663+
test_checked_next_power_of_two!(test_checked_next_power_of_two_u32, u32)
1664+
test_checked_next_power_of_two!(test_checked_next_power_of_two_u64, u64)
1665+
test_checked_next_power_of_two!(test_checked_next_power_of_two_uint, uint)
15921666

15931667
#[deriving(Eq)]
15941668
struct Value { x: int }

src/libstd/num/uint.rs

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use prelude::*;
1616

1717
use default::Default;
18-
use mem;
1918
use num::{Bitwise, Bounded};
2019
use num::{CheckedAdd, CheckedSub, CheckedMul};
2120
use num::{CheckedDiv, Zero, One, strconv};
@@ -79,26 +78,6 @@ pub fn div_round(x: uint, y: uint) -> uint {
7978
///
8079
pub fn div_floor(x: uint, y: uint) -> uint { return x / y; }
8180

82-
/// Returns the smallest power of 2 greater than or equal to `n`
83-
#[inline]
84-
pub fn next_power_of_two(n: uint) -> uint {
85-
let halfbits: uint = mem::size_of::<uint>() * 4u;
86-
let mut tmp: uint = n - 1u;
87-
let mut shift: uint = 1u;
88-
while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
89-
tmp + 1u
90-
}
91-
92-
/// Returns the smallest power of 2 greater than or equal to `n`
93-
#[inline]
94-
pub fn next_power_of_two_opt(n: uint) -> Option<uint> {
95-
let halfbits: uint = mem::size_of::<uint>() * 4u;
96-
let mut tmp: uint = n - 1u;
97-
let mut shift: uint = 1u;
98-
while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
99-
tmp.checked_add(&1)
100-
}
101-
10281
#[cfg(target_word_size = "32")]
10382
impl CheckedAdd for uint {
10483
#[inline]
@@ -165,50 +144,6 @@ impl CheckedMul for uint {
165144
}
166145
}
167146

168-
#[test]
169-
fn test_next_power_of_two() {
170-
assert!((next_power_of_two(0u) == 0u));
171-
assert!((next_power_of_two(1u) == 1u));
172-
assert!((next_power_of_two(2u) == 2u));
173-
assert!((next_power_of_two(3u) == 4u));
174-
assert!((next_power_of_two(4u) == 4u));
175-
assert!((next_power_of_two(5u) == 8u));
176-
assert!((next_power_of_two(6u) == 8u));
177-
assert!((next_power_of_two(7u) == 8u));
178-
assert!((next_power_of_two(8u) == 8u));
179-
assert!((next_power_of_two(9u) == 16u));
180-
assert!((next_power_of_two(10u) == 16u));
181-
assert!((next_power_of_two(11u) == 16u));
182-
assert!((next_power_of_two(12u) == 16u));
183-
assert!((next_power_of_two(13u) == 16u));
184-
assert!((next_power_of_two(14u) == 16u));
185-
assert!((next_power_of_two(15u) == 16u));
186-
assert!((next_power_of_two(16u) == 16u));
187-
assert!((next_power_of_two(17u) == 32u));
188-
assert!((next_power_of_two(18u) == 32u));
189-
assert!((next_power_of_two(19u) == 32u));
190-
assert!((next_power_of_two(20u) == 32u));
191-
assert!((next_power_of_two(21u) == 32u));
192-
assert!((next_power_of_two(22u) == 32u));
193-
assert!((next_power_of_two(23u) == 32u));
194-
assert!((next_power_of_two(24u) == 32u));
195-
assert!((next_power_of_two(25u) == 32u));
196-
assert!((next_power_of_two(26u) == 32u));
197-
assert!((next_power_of_two(27u) == 32u));
198-
assert!((next_power_of_two(28u) == 32u));
199-
assert!((next_power_of_two(29u) == 32u));
200-
assert!((next_power_of_two(30u) == 32u));
201-
assert!((next_power_of_two(31u) == 32u));
202-
assert!((next_power_of_two(32u) == 32u));
203-
assert!((next_power_of_two(33u) == 64u));
204-
assert!((next_power_of_two(34u) == 64u));
205-
assert!((next_power_of_two(35u) == 64u));
206-
assert!((next_power_of_two(36u) == 64u));
207-
assert!((next_power_of_two(37u) == 64u));
208-
assert!((next_power_of_two(38u) == 64u));
209-
assert!((next_power_of_two(39u) == 64u));
210-
}
211-
212147
#[test]
213148
fn test_overflows() {
214149
use uint;

src/libstd/str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ use iter::{Iterator, FromIterator, Extendable, range};
104104
use iter::{Filter, AdditiveIterator, Map};
105105
use iter::{Rev, DoubleEndedIterator, ExactSize};
106106
use libc;
107-
use num::{Saturating};
107+
use num::{Saturating, checked_next_power_of_two};
108108
use option::{None, Option, Some};
109109
use ptr;
110110
use ptr::RawPtr;
@@ -2640,7 +2640,7 @@ impl OwnedStr for ~str {
26402640

26412641
#[inline]
26422642
fn reserve_at_least(&mut self, n: uint) {
2643-
self.reserve(uint::next_power_of_two_opt(n).unwrap_or(n))
2643+
self.reserve(checked_next_power_of_two(n).unwrap_or(n))
26442644
}
26452645

26462646
#[inline]

src/libstd/sync/mpmc_bounded_queue.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131

3232
use clone::Clone;
3333
use kinds::Send;
34+
use num::next_power_of_two;
3435
use option::{Option, Some, None};
3536
use sync::arc::UnsafeArc;
3637
use sync::atomics::{AtomicUint,Relaxed,Release,Acquire};
37-
use uint;
3838
use vec;
3939

4040
struct Node<T> {
@@ -64,7 +64,7 @@ impl<T: Send> State<T> {
6464
2u
6565
} else {
6666
// use next power of 2 as capacity
67-
uint::next_power_of_two(capacity)
67+
next_power_of_two(capacity)
6868
}
6969
} else {
7070
capacity

src/libstd/vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
109109
use cmp;
110110
use default::Default;
111111
use iter::*;
112-
use num::{Integer, CheckedAdd, Saturating};
112+
use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two};
113113
use option::{None, Option, Some};
114114
use ptr::to_unsafe_ptr;
115115
use ptr;
@@ -1486,7 +1486,7 @@ impl<T> OwnedVector<T> for ~[T] {
14861486

14871487
#[inline]
14881488
fn reserve_at_least(&mut self, n: uint) {
1489-
self.reserve(uint::next_power_of_two_opt(n).unwrap_or(n));
1489+
self.reserve(checked_next_power_of_two(n).unwrap_or(n));
14901490
}
14911491

14921492
#[inline]

0 commit comments

Comments
 (0)