Skip to content

Commit

Permalink
Rename Bitwise::population_count to Bitwise::count_ones and add Bitwi…
Browse files Browse the repository at this point in the history
…se::count_zeros

These are inspired by the [functions in the Julia standard library](http://docs.julialang.org/en/release-0.2/stdlib/base/#Base.count_ones).
  • Loading branch information
brendanzab committed Feb 17, 2014
1 parent 0ba6d48 commit 79f52cf
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/libextra/enum_set.rs
Expand Up @@ -129,7 +129,7 @@ impl<E:CLike> Iterator<E> for Items<E> {
}

fn size_hint(&self) -> (uint, Option<uint>) {
let exact = self.bits.population_count();
let exact = self.bits.count_ones();
(exact, Some(exact))
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/adt.rs
Expand Up @@ -432,7 +432,7 @@ fn generic_type_of(cx: &CrateContext, r: &Repr, name: Option<&str>, sizing: bool
4 => Type::array(&Type::i32(), align_units),
8 if machine::llalign_of_min(cx, Type::i64()) == 8 =>
Type::array(&Type::i64(), align_units),
a if a.population_count() == 1 => Type::array(&Type::vector(&Type::i32(), a / 4),
a if a.count_ones() == 1 => Type::array(&Type::vector(&Type::i32(), a / 4),
align_units),
_ => fail!("unsupported enum alignment: {:?}", align)
};
Expand Down
10 changes: 6 additions & 4 deletions src/libstd/num/i16.rs
Expand Up @@ -25,15 +25,17 @@ use unstable::intrinsics;
int_module!(i16, 16)

impl Bitwise for i16 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } }
fn count_ones(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } }

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self) } }

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self) } }
}
Expand Down
10 changes: 6 additions & 4 deletions src/libstd/num/i32.rs
Expand Up @@ -25,15 +25,17 @@ use unstable::intrinsics;
int_module!(i32, 32)

impl Bitwise for i32 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } }
fn count_ones(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } }

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self) } }

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self) } }
}
Expand Down
9 changes: 5 additions & 4 deletions src/libstd/num/i64.rs
Expand Up @@ -27,15 +27,16 @@ use unstable::intrinsics;
int_module!(i64, 64)

impl Bitwise for i64 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } }
fn count_ones(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } }

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self) } }

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Counts the number of trailing zeros.
#[inline]
fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self) } }
}
Expand Down
10 changes: 6 additions & 4 deletions src/libstd/num/i8.rs
Expand Up @@ -25,15 +25,17 @@ use unstable::intrinsics;
int_module!(i8, 8)

impl Bitwise for i8 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } }
fn count_ones(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } }

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self) } }

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self) } }
}
Expand Down
20 changes: 12 additions & 8 deletions src/libstd/num/int.rs
Expand Up @@ -27,30 +27,34 @@ use unstable::intrinsics;

#[cfg(target_word_size = "32")]
impl Bitwise for int {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> int { (*self as i32).population_count() as int }
fn count_ones(&self) -> int { (*self as i32).count_ones() as int }

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int }

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int }
}

#[cfg(target_word_size = "64")]
impl Bitwise for int {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> int { (*self as i64).population_count() as int }
fn count_ones(&self) -> int { (*self as i64).count_ones() as int }

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int }

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int }
}
Expand Down
13 changes: 11 additions & 2 deletions src/libstd/num/int_macros.rs
Expand Up @@ -614,8 +614,17 @@ mod tests {
}

#[test]
fn test_bitcount() {
assert_eq!((0b010101 as $T).population_count(), 3);
fn test_count_ones() {
assert_eq!((0b0101100 as $T).count_ones(), 3);
assert_eq!((0b0100001 as $T).count_ones(), 2);
assert_eq!((0b1111001 as $T).count_ones(), 5);
}

#[test]
fn test_count_zeros() {
assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
}

#[test]
Expand Down
31 changes: 25 additions & 6 deletions src/libstd/num/mod.rs
Expand Up @@ -375,18 +375,35 @@ pub trait Bitwise: Bounded
+ BitXor<Self,Self>
+ Shl<Self,Self>
+ Shr<Self,Self> {
/// Returns the number of bits set in the number.
/// Returns the number of ones in the binary representation of the number.
///
/// # Example
///
/// ```rust
/// use std::num::Bitwise;
///
/// let n = 0b0101000u16;
/// assert_eq!(n.population_count(), 2);
/// let n = 0b01001100u8;
/// assert_eq!(n.count_ones(), 3);
/// ```
fn population_count(&self) -> Self;
/// Returns the number of leading zeros in the number.
fn count_ones(&self) -> Self;

/// Returns the number of zeros in the binary representation of the number.
///
/// # Example
///
/// ```rust
/// use std::num::Bitwise;
///
/// let n = 0b01001100u8;
/// assert_eq!(n.count_zeros(), 5);
/// ```
#[inline]
fn count_zeros(&self) -> Self {
(!*self).count_ones()
}

/// Returns the number of leading zeros in the in the binary representation
/// of the number.
///
/// # Example
///
Expand All @@ -397,7 +414,9 @@ pub trait Bitwise: Bounded
/// assert_eq!(n.leading_zeros(), 10);
/// ```
fn leading_zeros(&self) -> Self;
/// Returns the number of trailing zeros in the number.

/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
///
/// # Example
///
Expand Down
25 changes: 18 additions & 7 deletions src/libstd/num/uint_macros.rs
Expand Up @@ -266,19 +266,21 @@ impl ToStrRadix for $T {
impl Primitive for $T {}

impl Bitwise for $T {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> $T {
(*self as $T_SIGNED).population_count() as $T
fn count_ones(&self) -> $T {
(*self as $T_SIGNED).count_ones() as $T
}

/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> $T {
(*self as $T_SIGNED).leading_zeros() as $T
}

/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> $T {
(*self as $T_SIGNED).trailing_zeros() as $T
Expand Down Expand Up @@ -375,8 +377,17 @@ mod tests {
}

#[test]
fn test_bitcount() {
assert_eq!((0b010101 as $T).population_count(), 3);
fn test_count_ones() {
assert_eq!((0b0101100 as $T).count_ones(), 3);
assert_eq!((0b0100001 as $T).count_ones(), 2);
assert_eq!((0b1111001 as $T).count_ones(), 5);
}

#[test]
fn test_count_zeros() {
assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
}

#[test]
Expand Down

5 comments on commit 79f52cf

@bors
Copy link
Contributor

@bors bors commented on 79f52cf Feb 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at brendanzab@79f52cf

@bors
Copy link
Contributor

@bors bors commented on 79f52cf Feb 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging bjz/rust/count-ones = 79f52cf into auto

@bors
Copy link
Contributor

@bors bors commented on 79f52cf Feb 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bjz/rust/count-ones = 79f52cf merged ok, testing candidate = 2bba723

@bors
Copy link
Contributor

@bors bors commented on 79f52cf Feb 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 79f52cf Feb 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 2bba723

Please sign in to comment.