2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
// FIXME(#4375): this shouldn't have to be a nested module named 'generated'
|
2012-12-13 15:05:22 -06:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
#[macro_escape];
|
2013-09-19 00:18:38 -05:00
|
|
|
#[doc(hidden)];
|
2013-05-12 20:14:40 -05:00
|
|
|
|
|
|
|
macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
|
|
|
|
|
2013-06-30 22:51:13 -05:00
|
|
|
#[allow(non_uppercase_statics)];
|
|
|
|
|
2013-09-11 23:49:25 -05:00
|
|
|
use default::Default;
|
2013-05-12 20:14:40 -05:00
|
|
|
use num::BitCount;
|
2013-01-24 14:47:57 -06:00
|
|
|
use num::{ToStrRadix, FromStrRadix};
|
2013-08-11 17:32:07 -05:00
|
|
|
use num::{CheckedDiv, Zero, One, strconv};
|
2013-01-24 14:47:57 -06:00
|
|
|
use prelude::*;
|
2013-06-28 16:05:10 -05:00
|
|
|
use str;
|
2012-04-15 00:07:45 -05:00
|
|
|
|
2013-01-15 19:30:01 -06:00
|
|
|
pub use cmp::{min, max};
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
pub static bits : uint = $bits;
|
|
|
|
pub static bytes : uint = ($bits / 8);
|
2012-04-15 00:07:45 -05:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
pub static min_value: $T = 0 as $T;
|
|
|
|
pub static max_value: $T = 0 as $T - 1 as $T;
|
2012-04-15 00:07:45 -05:00
|
|
|
|
2013-08-11 17:32:07 -05:00
|
|
|
impl CheckedDiv for $T {
|
|
|
|
#[inline]
|
|
|
|
fn checked_div(&self, v: &$T) -> Option<$T> {
|
|
|
|
if *v == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(self / *v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Num for $T {}
|
2013-04-24 05:08:08 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Ord for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn lt(&self, other: &$T) -> bool { (*self) < (*other) }
|
2012-09-19 20:00:26 -05:00
|
|
|
}
|
2012-06-06 16:19:52 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Eq for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
|
2012-09-19 20:00:26 -05:00
|
|
|
}
|
2012-06-06 16:19:52 -05:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Orderable for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn min(&self, other: &$T) -> $T {
|
2013-04-26 10:01:53 -05:00
|
|
|
if *self < *other { *self } else { *other }
|
|
|
|
}
|
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn max(&self, other: &$T) -> $T {
|
2013-04-26 10:01:53 -05:00
|
|
|
if *self > *other { *self } else { *other }
|
|
|
|
}
|
|
|
|
|
2013-05-18 00:02:58 -05:00
|
|
|
/// Returns the number constrained within the range `mn <= self <= mx`.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn clamp(&self, mn: &$T, mx: &$T) -> $T {
|
2013-09-18 06:21:57 -05:00
|
|
|
match () {
|
|
|
|
_ if (*self > *mx) => *mx,
|
|
|
|
_ if (*self < *mn) => *mn,
|
|
|
|
_ => *self,
|
|
|
|
}
|
2013-05-18 00:02:58 -05:00
|
|
|
}
|
2013-04-26 10:01:53 -05:00
|
|
|
}
|
|
|
|
|
2013-09-11 23:49:25 -05:00
|
|
|
impl Default for $T {
|
|
|
|
#[inline]
|
|
|
|
fn default() -> $T { 0 }
|
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Zero for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn zero() -> $T { 0 }
|
2013-04-25 00:30:56 -05:00
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-25 00:30:56 -05:00
|
|
|
fn is_zero(&self) -> bool { *self == 0 }
|
2012-12-20 09:14:38 -06:00
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl One for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn one() -> $T { 1 }
|
2012-12-20 09:14:38 -06:00
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Add<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn add(&self, other: &$T) -> $T { *self + *other }
|
2013-02-12 19:07:26 -06:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Sub<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn sub(&self, other: &$T) -> $T { *self - *other }
|
2013-02-12 19:07:26 -06:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Mul<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn mul(&self, other: &$T) -> $T { *self * *other }
|
2013-02-12 19:07:26 -06:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Div<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn div(&self, other: &$T) -> $T { *self / *other }
|
2013-02-12 19:07:26 -06:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Rem<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn rem(&self, other: &$T) -> $T { *self % *other }
|
2013-04-21 10:58:53 -05:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Neg<$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn neg(&self) -> $T { -*self }
|
2013-02-12 19:07:26 -06:00
|
|
|
}
|
2013-04-18 08:24:24 -05:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Unsigned for $T {}
|
2013-04-23 02:59:49 -05:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Integer for $T {
|
2013-05-01 00:40:05 -05:00
|
|
|
/// Calculates `div` (`\`) and `rem` (`%`) simultaneously
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn div_rem(&self, other: &$T) -> ($T,$T) {
|
2013-05-01 00:40:05 -05:00
|
|
|
(*self / *other, *self % *other)
|
|
|
|
}
|
2013-04-23 21:54:11 -05:00
|
|
|
|
2013-05-01 00:40:05 -05:00
|
|
|
/// Unsigned integer division. Returns the same result as `div` (`/`).
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn div_floor(&self, other: &$T) -> $T { *self / *other }
|
2013-04-23 21:54:11 -05:00
|
|
|
|
2013-05-01 00:40:05 -05:00
|
|
|
/// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-08-19 01:23:29 -05:00
|
|
|
fn mod_floor(&self, other: &$T) -> $T { *self % *other }
|
2013-04-23 21:54:11 -05:00
|
|
|
|
2013-08-19 01:23:29 -05:00
|
|
|
/// Calculates `div_floor` and `mod_floor` simultaneously
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
|
2013-04-24 07:50:56 -05:00
|
|
|
(*self / *other, *self % *other)
|
2013-04-23 21:54:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Calculates the Greatest Common Divisor (GCD) of the number and `other`
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn gcd(&self, other: &$T) -> $T {
|
2013-04-23 21:54:11 -05:00
|
|
|
// Use Euclid's algorithm
|
2013-06-06 20:54:14 -05:00
|
|
|
let mut m = *self;
|
|
|
|
let mut n = *other;
|
2013-04-23 21:54:11 -05:00
|
|
|
while m != 0 {
|
|
|
|
let temp = m;
|
|
|
|
m = n % temp;
|
|
|
|
n = temp;
|
|
|
|
}
|
|
|
|
n
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn lcm(&self, other: &$T) -> $T {
|
2013-04-24 07:50:56 -05:00
|
|
|
(*self * *other) / self.gcd(other)
|
2013-04-23 21:54:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if the number can be divided by `other` without leaving a remainder
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
|
2013-04-23 21:54:11 -05:00
|
|
|
|
|
|
|
/// Returns `true` if the number is divisible by `2`
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-29 01:02:43 -05:00
|
|
|
fn is_even(&self) -> bool { self.is_multiple_of(&2) }
|
2013-04-23 21:54:11 -05:00
|
|
|
|
|
|
|
/// Returns `true` if the number is not divisible by `2`
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-23 21:54:11 -05:00
|
|
|
fn is_odd(&self) -> bool { !self.is_even() }
|
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Bitwise for $T {}
|
2013-04-25 19:02:00 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl BitOr<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn bitor(&self, other: &$T) -> $T { *self | *other }
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl BitAnd<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn bitand(&self, other: &$T) -> $T { *self & *other }
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl BitXor<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Shl<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn shl(&self, other: &$T) -> $T { *self << *other }
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Shr<$T,$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn shr(&self, other: &$T) -> $T { *self >> *other }
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
2013-04-23 12:56:49 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Not<$T> for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn not(&self) -> $T { !*self }
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
2013-02-12 19:07:26 -06:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Bounded for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn min_value() -> $T { min_value }
|
2013-04-25 19:02:00 -05:00
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn max_value() -> $T { max_value }
|
2013-04-25 19:02:00 -05:00
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Int for $T {}
|
2013-04-25 19:22:08 -05:00
|
|
|
|
2013-01-24 14:47:57 -06:00
|
|
|
// String conversion functions and impl str -> num
|
2012-08-02 19:14:26 -05:00
|
|
|
|
2013-01-24 14:47:57 -06:00
|
|
|
/// Parse a byte slice as a number in the given base.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
|
2013-02-14 20:29:36 -06:00
|
|
|
strconv::from_str_bytes_common(buf, radix, false, false, false,
|
2013-04-07 09:23:42 -05:00
|
|
|
strconv::ExpNone, false, false)
|
2012-05-16 00:50:29 -05:00
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl FromStr for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn from_str(s: &str) -> Option<$T> {
|
2013-09-15 00:27:32 -05:00
|
|
|
strconv::from_str_common(s, 10u, false, false, false,
|
|
|
|
strconv::ExpNone, false, false)
|
2012-06-04 20:05:34 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl FromStrRadix for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
|
2013-09-15 00:27:32 -05:00
|
|
|
strconv::from_str_common(s, radix, false, false, false,
|
|
|
|
strconv::ExpNone, false, false)
|
2012-05-16 00:50:29 -05:00
|
|
|
}
|
2013-01-24 14:47:57 -06:00
|
|
|
}
|
2012-06-04 16:20:57 -05:00
|
|
|
|
2013-01-24 14:47:57 -06:00
|
|
|
// String conversion functions and impl num -> str
|
2012-12-14 19:03:35 -06:00
|
|
|
|
2013-01-24 14:47:57 -06:00
|
|
|
/// Convert to a string as a byte slice in a given base.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
|
2013-06-28 16:05:10 -05:00
|
|
|
// The radix can be as low as 2, so we need at least 64 characters for a
|
|
|
|
// base 2 number.
|
|
|
|
let mut buf = [0u8, ..64];
|
|
|
|
let mut cur = 0;
|
|
|
|
do strconv::int_to_str_bytes_common(n, radix, strconv::SignNone) |i| {
|
|
|
|
buf[cur] = i;
|
|
|
|
cur += 1;
|
|
|
|
}
|
|
|
|
f(buf.slice(0, cur))
|
2013-01-24 14:47:57 -06:00
|
|
|
}
|
2012-12-14 19:03:35 -06:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl ToStr for $T {
|
2013-08-17 21:47:54 -05:00
|
|
|
/// Convert to a string in base 10.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn to_str(&self) -> ~str {
|
2013-08-17 21:47:54 -05:00
|
|
|
self.to_str_radix(10u)
|
2013-01-24 14:47:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl ToStrRadix for $T {
|
2013-08-17 21:47:54 -05:00
|
|
|
/// Convert to a string in a given base.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn to_str_radix(&self, radix: uint) -> ~str {
|
2013-08-17 21:47:54 -05:00
|
|
|
let mut buf = ~[];
|
|
|
|
do strconv::int_to_str_bytes_common(*self, radix, strconv::SignNone) |i| {
|
|
|
|
buf.push(i);
|
|
|
|
}
|
|
|
|
// We know we generated valid utf-8, so we don't need to go through that
|
|
|
|
// check.
|
2013-09-05 07:17:24 -05:00
|
|
|
unsafe { str::raw::from_utf8_owned(buf) }
|
2013-01-24 14:47:57 -06:00
|
|
|
}
|
|
|
|
}
|
2012-05-16 00:50:29 -05:00
|
|
|
|
2013-05-12 20:14:40 -05:00
|
|
|
impl Primitive for $T {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-08-08 13:38:10 -05:00
|
|
|
fn bits(_: Option<$T>) -> uint { bits }
|
2013-05-12 20:14:40 -05:00
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-08-08 13:38:10 -05:00
|
|
|
fn bytes(_: Option<$T>) -> uint { bits / 8 }
|
2013-09-27 22:41:49 -05:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn is_signed(_: Option<$T>) -> bool { false }
|
2013-05-12 20:14:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl BitCount for $T {
|
|
|
|
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn population_count(&self) -> $T {
|
|
|
|
(*self as $T_SIGNED).population_count() as $T
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn leading_zeros(&self) -> $T {
|
|
|
|
(*self as $T_SIGNED).leading_zeros() as $T
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-12 20:14:40 -05:00
|
|
|
fn trailing_zeros(&self) -> $T {
|
|
|
|
(*self as $T_SIGNED).trailing_zeros() as $T
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use prelude::*;
|
2013-09-08 14:00:00 -05:00
|
|
|
use super::*;
|
2013-04-18 05:58:58 -05:00
|
|
|
|
2013-05-24 21:35:29 -05:00
|
|
|
use num;
|
2013-10-16 20:34:01 -05:00
|
|
|
use mem;
|
2013-05-24 21:35:29 -05:00
|
|
|
use u16;
|
|
|
|
|
2013-04-24 05:08:08 -05:00
|
|
|
#[test]
|
|
|
|
fn test_num() {
|
2013-05-12 20:14:40 -05:00
|
|
|
num::test_num(10 as $T, 2 as $T);
|
2013-04-24 05:08:08 -05:00
|
|
|
}
|
|
|
|
|
2013-04-26 10:01:53 -05:00
|
|
|
#[test]
|
|
|
|
fn test_orderable() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!((1 as $T).min(&(2 as $T)), 1 as $T);
|
|
|
|
assert_eq!((2 as $T).min(&(1 as $T)), 1 as $T);
|
|
|
|
assert_eq!((1 as $T).max(&(2 as $T)), 2 as $T);
|
|
|
|
assert_eq!((2 as $T).max(&(1 as $T)), 2 as $T);
|
|
|
|
assert_eq!((1 as $T).clamp(&(2 as $T), &(4 as $T)), 2 as $T);
|
|
|
|
assert_eq!((8 as $T).clamp(&(2 as $T), &(4 as $T)), 4 as $T);
|
|
|
|
assert_eq!((3 as $T).clamp(&(2 as $T), &(4 as $T)), 3 as $T);
|
2013-04-26 10:01:53 -05:00
|
|
|
}
|
|
|
|
|
2013-08-19 01:23:29 -05:00
|
|
|
#[test]
|
|
|
|
fn test_div_mod_floor() {
|
|
|
|
assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
|
|
|
|
assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
|
|
|
|
assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
|
|
|
|
assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
|
|
|
|
assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
|
|
|
|
assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
|
|
|
|
assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
|
|
|
|
assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
|
|
|
|
assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
|
|
|
|
}
|
|
|
|
|
2013-04-23 21:54:11 -05:00
|
|
|
#[test]
|
|
|
|
fn test_gcd() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!((10 as $T).gcd(&2), 2 as $T);
|
|
|
|
assert_eq!((10 as $T).gcd(&3), 1 as $T);
|
|
|
|
assert_eq!((0 as $T).gcd(&3), 3 as $T);
|
|
|
|
assert_eq!((3 as $T).gcd(&3), 3 as $T);
|
|
|
|
assert_eq!((56 as $T).gcd(&42), 14 as $T);
|
2013-04-23 21:54:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_lcm() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!((1 as $T).lcm(&0), 0 as $T);
|
|
|
|
assert_eq!((0 as $T).lcm(&1), 0 as $T);
|
|
|
|
assert_eq!((1 as $T).lcm(&1), 1 as $T);
|
|
|
|
assert_eq!((8 as $T).lcm(&9), 72 as $T);
|
|
|
|
assert_eq!((11 as $T).lcm(&5), 55 as $T);
|
|
|
|
assert_eq!((99 as $T).lcm(&17), 1683 as $T);
|
2013-04-23 21:54:11 -05:00
|
|
|
}
|
|
|
|
|
2013-04-29 01:02:43 -05:00
|
|
|
#[test]
|
|
|
|
fn test_multiple_of() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert!((6 as $T).is_multiple_of(&(6 as $T)));
|
|
|
|
assert!((6 as $T).is_multiple_of(&(3 as $T)));
|
|
|
|
assert!((6 as $T).is_multiple_of(&(1 as $T)));
|
2013-04-29 01:02:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_even() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!((0 as $T).is_even(), true);
|
|
|
|
assert_eq!((1 as $T).is_even(), false);
|
|
|
|
assert_eq!((2 as $T).is_even(), true);
|
|
|
|
assert_eq!((3 as $T).is_even(), false);
|
|
|
|
assert_eq!((4 as $T).is_even(), true);
|
2013-04-29 01:02:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_odd() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!((0 as $T).is_odd(), false);
|
|
|
|
assert_eq!((1 as $T).is_odd(), true);
|
|
|
|
assert_eq!((2 as $T).is_odd(), false);
|
|
|
|
assert_eq!((3 as $T).is_odd(), true);
|
|
|
|
assert_eq!((4 as $T).is_odd(), false);
|
2013-04-29 01:02:43 -05:00
|
|
|
}
|
|
|
|
|
2013-04-18 05:58:58 -05:00
|
|
|
#[test]
|
2013-04-26 01:27:51 -05:00
|
|
|
fn test_bitwise() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
|
|
|
|
assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
|
|
|
|
assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
|
|
|
|
assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
|
|
|
|
assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
|
|
|
|
assert_eq!(max_value - (0b1011 as $T), (0b1011 as $T).not());
|
2013-04-18 05:58:58 -05:00
|
|
|
}
|
|
|
|
|
2013-04-26 01:27:51 -05:00
|
|
|
#[test]
|
|
|
|
fn test_bitcount() {
|
2013-05-12 20:14:40 -05:00
|
|
|
assert_eq!((0b010101 as $T).population_count(), 3);
|
2013-04-26 01:27:51 -05:00
|
|
|
}
|
|
|
|
|
2013-04-25 19:02:00 -05:00
|
|
|
#[test]
|
|
|
|
fn test_primitive() {
|
2013-08-08 13:38:10 -05:00
|
|
|
let none: Option<$T> = None;
|
2013-10-16 20:34:01 -05:00
|
|
|
assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8);
|
|
|
|
assert_eq!(Primitive::bytes(none), mem::size_of::<$T>());
|
2013-04-25 19:02:00 -05:00
|
|
|
}
|
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
pub fn test_to_str() {
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!((0 as $T).to_str_radix(10u), ~"0");
|
|
|
|
assert_eq!((1 as $T).to_str_radix(10u), ~"1");
|
|
|
|
assert_eq!((2 as $T).to_str_radix(10u), ~"2");
|
|
|
|
assert_eq!((11 as $T).to_str_radix(10u), ~"11");
|
|
|
|
assert_eq!((11 as $T).to_str_radix(16u), ~"b");
|
|
|
|
assert_eq!((255 as $T).to_str_radix(16u), ~"ff");
|
|
|
|
assert_eq!((0xff as $T).to_str_radix(10u), ~"255");
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
2012-06-04 20:05:34 -05:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
pub fn test_from_str() {
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<$T>("0"), Some(0u as $T));
|
|
|
|
assert_eq!(from_str::<$T>("3"), Some(3u as $T));
|
|
|
|
assert_eq!(from_str::<$T>("10"), Some(10u as $T));
|
|
|
|
assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
|
|
|
|
assert_eq!(from_str::<$T>("00100"), Some(100u as $T));
|
2013-05-23 11:39:17 -05:00
|
|
|
|
2013-09-15 00:27:32 -05:00
|
|
|
assert!(from_str::<$T>("").is_none());
|
|
|
|
assert!(from_str::<$T>(" ").is_none());
|
|
|
|
assert!(from_str::<$T>("x").is_none());
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
2012-05-16 00:50:29 -05:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
pub fn test_parse_bytes() {
|
2013-06-10 22:10:37 -05:00
|
|
|
use str::StrSlice;
|
|
|
|
assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123u as $T));
|
|
|
|
assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9u as $T));
|
|
|
|
assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83u as $T));
|
|
|
|
assert_eq!(u16::parse_bytes("123".as_bytes(), 16u), Some(291u as u16));
|
|
|
|
assert_eq!(u16::parse_bytes("ffff".as_bytes(), 16u), Some(65535u as u16));
|
|
|
|
assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35u as $T));
|
|
|
|
|
|
|
|
assert!(parse_bytes("Z".as_bytes(), 10u).is_none());
|
|
|
|
assert!(parse_bytes("_".as_bytes(), 2u).is_none());
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
2012-06-04 17:22:40 -05:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
fn test_uint_to_str_overflow() {
|
|
|
|
let mut u8_val: u8 = 255_u8;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u8_val.to_str(), ~"255");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u8_val += 1 as u8;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u8_val.to_str(), ~"0");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
let mut u16_val: u16 = 65_535_u16;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u16_val.to_str(), ~"65535");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u16_val += 1 as u16;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u16_val.to_str(), ~"0");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
let mut u32_val: u32 = 4_294_967_295_u32;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u32_val.to_str(), ~"4294967295");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u32_val += 1 as u32;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u32_val.to_str(), ~"0");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u64_val.to_str(), ~"18446744073709551615");
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u64_val += 1 as u64;
|
2013-08-17 21:47:54 -05:00
|
|
|
assert_eq!(u64_val.to_str(), ~"0");
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
fn test_uint_from_str_overflow() {
|
|
|
|
let mut u8_val: u8 = 255_u8;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u8>("255"), Some(u8_val));
|
|
|
|
assert!(from_str::<u8>("256").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u8_val += 1 as u8;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u8>("0"), Some(u8_val));
|
|
|
|
assert!(from_str::<u8>("-1").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
let mut u16_val: u16 = 65_535_u16;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u16>("65535"), Some(u16_val));
|
|
|
|
assert!(from_str::<u16>("65536").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u16_val += 1 as u16;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u16>("0"), Some(u16_val));
|
|
|
|
assert!(from_str::<u16>("-1").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
let mut u32_val: u32 = 4_294_967_295_u32;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
|
|
|
|
assert!(from_str::<u32>("4294967296").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u32_val += 1 as u32;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u32>("0"), Some(u32_val));
|
|
|
|
assert!(from_str::<u32>("-1").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
|
|
|
|
assert!(from_str::<u64>("18446744073709551616").is_none());
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
u64_val += 1 as u64;
|
2013-09-15 00:27:32 -05:00
|
|
|
assert_eq!(from_str::<u64>("0"), Some(u64_val));
|
|
|
|
assert!(from_str::<u64>("-1").is_none());
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
2013-01-24 14:47:57 -06:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
pub fn to_str_radix1() {
|
2013-08-17 21:47:54 -05:00
|
|
|
100u.to_str_radix(1u);
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
2012-06-04 17:22:40 -05:00
|
|
|
|
2013-04-15 10:08:52 -05:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
pub fn to_str_radix37() {
|
2013-08-17 21:47:54 -05:00
|
|
|
100u.to_str_radix(37u);
|
2013-04-15 10:08:52 -05:00
|
|
|
}
|
A new `times` method on numeric types
This method is intended to elegantly subsume two common iteration functions.
The first is `iter::range`, which is used identically to the method introduced
in this commit, but currently works only on uints. The second is a common case
of `{int, i8, uint, etc.}::range`, in the case where the inductive variable is
ignored. Compare the usage of the three:
```
for iter::range(100u) {
// do whatever
}
for int::range(0, 100) |_i| {
// do whatever
}
for 100.times {
// do whatever
}
```
I feel that the latter reads much more nicely than the first two approaches,
and unlike the first two the new method allows the user to ignore the specific
type of the number (ineed, if we're throwing away the inductive variable, who
cares what type it is?). A minor benefit is that this new method will be
somewhat familiar to users of Ruby, from which we borrow the name "times".
2012-07-05 21:12:26 -05:00
|
|
|
|
2013-08-11 17:32:07 -05:00
|
|
|
#[test]
|
|
|
|
fn test_unsigned_checked_div() {
|
|
|
|
assert_eq!(10u.checked_div(&2), Some(5));
|
|
|
|
assert_eq!(5u.checked_div(&0), None);
|
|
|
|
}
|
2013-04-18 17:53:29 -05:00
|
|
|
}
|
2013-05-12 20:14:40 -05:00
|
|
|
|
|
|
|
}))
|