diff options
| author | bors <bors@rust-lang.org> | 2013-10-05 14:26:44 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-10-05 14:26:44 -0700 |
| commit | 2733b189ac60cea541fbf80e5839e5027ffc9fbf (patch) | |
| tree | b9fcc58a2f736f292eb32de9553843c99f91f32d /src/libstd | |
| parent | 0c388be8d1988a966ef62c545b996b9da0f71e93 (diff) | |
| parent | 0e8ad4d8a2f23206c723137d765027a7acd97837 (diff) | |
| download | rust-2733b189ac60cea541fbf80e5839e5027ffc9fbf.tar.gz rust-2733b189ac60cea541fbf80e5839e5027ffc9fbf.zip | |
auto merge of #9250 : erickt/rust/num, r=erickt
This PR solves one of the pain points with c-style enums. Simplifies writing a fn to convert from an int/uint to an enum. It does this through a `#[deriving(FromPrimitive)]` syntax extension. Before this is committed though, we need to discuss if `ToPrimitive`/`FromPrimitive` has the right design (cc #4819). I've changed all the `.to_int()` and `from_int()` style functions to return `Option<int>` so we can handle partial functions. For this PR though only enums and `extra::num::bigint::*` take advantage of returning None for unrepresentable values. In the long run it'd be better if `i64.to_i8()` returned `None` if the value was too large, but I'll save this for a future PR. Closes #3868.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/num/f32.rs | 3 | ||||
| -rw-r--r-- | src/libstd/num/f64.rs | 3 | ||||
| -rw-r--r-- | src/libstd/num/int_macros.rs | 3 | ||||
| -rw-r--r-- | src/libstd/num/num.rs | 953 | ||||
| -rw-r--r-- | src/libstd/num/strconv.rs | 26 | ||||
| -rw-r--r-- | src/libstd/num/uint_macros.rs | 3 | ||||
| -rw-r--r-- | src/libstd/prelude.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rand/mod.rs | 4 |
8 files changed, 897 insertions, 100 deletions
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 41a3d193379..2b4a636e1ad 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -590,6 +590,9 @@ impl Primitive for f32 { #[inline] fn bytes(_: Option<f32>) -> uint { Primitive::bits(Some(0f32)) / 8 } + + #[inline] + fn is_signed(_: Option<f32>) -> bool { true } } impl Float for f32 { diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 772596d15fb..d4442e5b34f 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -638,6 +638,9 @@ impl Primitive for f64 { #[inline] fn bytes(_: Option<f64>) -> uint { Primitive::bits(Some(0f64)) / 8 } + + #[inline] + fn is_signed(_: Option<f64>) -> bool { true } } impl Float for f64 { diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 1070e8e592f..7fae567809b 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -380,6 +380,9 @@ impl Primitive for $T { #[inline] fn bytes(_: Option<$T>) -> uint { bits / 8 } + + #[inline] + fn is_signed(_: Option<$T>) -> bool { true } } // String conversion functions and impl str -> num diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index 95b1057dfd0..fde1928f4a3 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -32,11 +32,6 @@ pub trait Num: Eq + Zero + One + Div<Self,Self> + Rem<Self,Self> {} -pub trait IntConvertible { - fn to_int(&self) -> int; - fn from_int(n: int) -> Self; -} - pub trait Orderable: Ord { // These should be methods on `Ord`, with overridable default implementations. We don't want // to encumber all implementors of Ord by requiring them to implement these functions, but at @@ -291,6 +286,7 @@ pub trait Primitive: Clone // FIXME (#8888): Removing `unused_self` requires #8888 to be fixed. fn bits(unused_self: Option<Self>) -> uint; fn bytes(unused_self: Option<Self>) -> uint; + fn is_signed(unused_self: Option<Self>) -> bool; } /// A collection of traits relevant to primitive signed and unsigned integers @@ -353,6 +349,448 @@ pub trait Float: Real #[inline(always)] pub fn ln_1p<T: Float>(value: T) -> T { value.ln_1p() } #[inline(always)] pub fn mul_add<T: Float>(a: T, b: T, c: T) -> T { a.mul_add(b, c) } +/// A generic trait for converting a value to a number. +pub trait ToPrimitive { + /// Converts the value of `self` to an `int`. + #[inline] + fn to_int(&self) -> Option<int> { + self.to_i64().and_then(|x| x.to_int()) + } + + /// Converts the value of `self` to an `i8`. + #[inline] + fn to_i8(&self) -> Option<i8> { + self.to_i64().and_then(|x| x.to_i8()) + } + + /// Converts the value of `self` to an `i16`. + #[inline] + fn to_i16(&self) -> Option<i16> { + self.to_i64().and_then(|x| x.to_i16()) + } + + /// Converts the value of `self` to an `i32`. + #[inline] + fn to_i32(&self) -> Option<i32> { + self.to_i64().and_then(|x| x.to_i32()) + } + + /// Converts the value of `self` to an `i64`. + fn to_i64(&self) -> Option<i64>; + + /// Converts the value of `self` to an `uint`. + #[inline] + fn to_uint(&self) -> Option<uint> { + self.to_u64().and_then(|x| x.to_uint()) + } + + /// Converts the value of `self` to an `u8`. + #[inline] + fn to_u8(&self) -> Option<u8> { + self.to_u64().and_then(|x| x.to_u8()) + } + + /// Converts the value of `self` to an `u16`. + #[inline] + fn to_u16(&self) -> Option<u16> { + self.to_u64().and_then(|x| x.to_u16()) + } + + /// Converts the value of `self` to an `u32`. + #[inline] + fn to_u32(&self) -> Option<u32> { + self.to_u64().and_then(|x| x.to_u32()) + } + + /// Converts the value of `self` to an `u64`. + #[inline] + fn to_u64(&self) -> Option<u64> { + self.to_u64().and_then(|x| x.to_u64()) + } + + /// Converts the value of `self` to an `f32`. + #[inline] + fn to_f32(&self) -> Option<f32> { + self.to_f64().and_then(|x| x.to_f32()) + } + + /// Converts the value of `self` to an `f64`. + #[inline] + fn to_f64(&self) -> Option<f64> { + self.to_i64().and_then(|x| x.to_f64()) + } +} + +macro_rules! impl_to_primitive_int_to_int( + ($SrcT:ty, $DstT:ty) => ( + { + if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) { + Some(*self as $DstT) + } else { + let n = *self as i64; + let min_value: $DstT = Bounded::min_value(); + let max_value: $DstT = Bounded::max_value(); + if min_value as i64 <= n && n <= max_value as i64 { + Some(*self as $DstT) + } else { + None + } + } + } + ) +) + +macro_rules! impl_to_primitive_int_to_uint( + ($SrcT:ty, $DstT:ty) => ( + { + let zero: $SrcT = Zero::zero(); + let max_value: $DstT = Bounded::max_value(); + if zero <= *self && *self as u64 <= max_value as u64 { + Some(*self as $DstT) + } else { + None + } + } + ) +) + +macro_rules! impl_to_primitive_int( + ($T:ty) => ( + impl ToPrimitive for $T { + #[inline] + fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int) } + #[inline] + fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8) } + #[inline] + fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16) } + #[inline] + fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32) } + #[inline] + fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64) } + + #[inline] + fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint) } + #[inline] + fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8) } + #[inline] + fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16) } + #[inline] + fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32) } + #[inline] + fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64) } + + #[inline] + fn to_f32(&self) -> Option<f32> { Some(*self as f32) } + #[inline] + fn to_f64(&self) -> Option<f64> { Some(*self as f64) } + } + ) +) + +impl_to_primitive_int!(int) +impl_to_primitive_int!(i8) +impl_to_primitive_int!(i16) +impl_to_primitive_int!(i32) +impl_to_primitive_int!(i64) + +macro_rules! impl_to_primitive_uint_to_int( + ($DstT:ty) => ( + { + let max_value: $DstT = Bounded::max_value(); + if *self as u64 <= max_value as u64 { + Some(*self as $DstT) + } else { + None + } + } + ) +) + +macro_rules! impl_to_primitive_uint_to_uint( + ($SrcT:ty, $DstT:ty) => ( + { + if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) { + Some(*self as $DstT) + } else { + let zero: $SrcT = Zero::zero(); + let max_value: $DstT = Bounded::max_value(); + if zero <= *self && *self as u64 <= max_value as u64 { + Some(*self as $DstT) + } else { + None + } + } + } + ) +) + +macro_rules! impl_to_primitive_uint( + ($T:ty) => ( + impl ToPrimitive for $T { + #[inline] + fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int) } + #[inline] + fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8) } + #[inline] + fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16) } + #[inline] + fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32) } + #[inline] + fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64) } + + #[inline] + fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint) } + #[inline] + fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8) } + #[inline] + fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16) } + #[inline] + fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32) } + #[inline] + fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64) } + + #[inline] + fn to_f32(&self) -> Option<f32> { Some(*self as f32) } + #[inline] + fn to_f64(&self) -> Option<f64> { Some(*self as f64) } + } + ) +) + +impl_to_primitive_uint!(uint) +impl_to_primitive_uint!(u8) +impl_to_primitive_uint!(u16) +impl_to_primitive_uint!(u32) +impl_to_primitive_uint!(u64) + +macro_rules! impl_to_primitive_float_to_float( + ($SrcT:ty, $DstT:ty) => ( + if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) { + Some(*self as $DstT) + } else { + let n = *self as f64; + let min_value: $SrcT = Bounded::min_value(); + let max_value: $SrcT = Bounded::max_value(); + if min_value as f64 <= n && n <= max_value as f64 { + Some(*self as $DstT) + } else { + None + } + } + ) +) + +macro_rules! impl_to_primitive_float( + ($T:ty) => ( + impl ToPrimitive for $T { + #[inline] + fn to_int(&self) -> Option<int> { Some(*self as int) } + #[inline] + fn to_i8(&self) -> Option<i8> { Some(*self as i8) } + #[inline] + fn to_i16(&self) -> Option<i16> { Some(*self as i16) } + #[inline] + fn to_i32(&self) -> Option<i32> { Some(*self as i32) } + #[inline] + fn to_i64(&self) -> Option<i64> { Some(*self as i64) } + + #[inline] + fn to_uint(&self) -> Option<uint> { Some(*self as uint) } + #[inline] + fn to_u8(&self) -> Option<u8> { Some(*self as u8) } + #[inline] + fn to_u16(&self) -> Option<u16> { Some(*self as u16) } + #[inline] + fn to_u32(&self) -> Option<u32> { Some(*self as u32) } + #[inline] + fn to_u64(&self) -> Option<u64> { Some(*self as u64) } + + #[inline] + fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32) } + #[inline] + fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64) } + } + ) +) + +impl_to_primitive_float!(f32) +impl_to_primitive_float!(f64) + +/// A generic trait for converting a number to a value. +pub trait FromPrimitive { + /// Convert an `int` to return an optional value of this type. If the + /// value cannot be represented by this value, the `None` is returned. + #[inline] + fn from_int(n: int) -> Option<Self> { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i8` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_i8(n: i8) -> Option<Self> { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i16` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_i16(n: i16) -> Option<Self> { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i32` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_i32(n: i32) -> Option<Self> { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i64` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + fn from_i64(n: i64) -> Option<Self>; + + /// Convert an `uint` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_uint(n: uint) -> Option<Self> { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u8` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_u8(n: u8) -> Option<Self> { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u16` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_u16(n: u16) -> Option<Self> { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u32` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_u32(n: u32) -> Option<Self> { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u64` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + fn from_u64(n: u64) -> Option<Self>; + + /// Convert a `f32` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_f32(n: f32) -> Option<Self> { + FromPrimitive::from_f64(n as f64) + } + + /// Convert a `f64` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_f64(n: f64) -> Option<Self> { + FromPrimitive::from_i64(n as i64) + } +} + +/// A utility function that just calls `FromPrimitive::from_int`. +pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> { + FromPrimitive::from_int(n) +} + +/// A utility function that just calls `FromPrimitive::from_i8`. +pub fn from_i8<A: FromPrimitive>(n: i8) -> Option<A> { + FromPrimitive::from_i8(n) +} + +/// A utility function that just calls `FromPrimitive::from_i16`. +pub fn from_i16<A: FromPrimitive>(n: i16) -> Option<A> { + FromPrimitive::from_i16(n) +} + +/// A utility function that just calls `FromPrimitive::from_i32`. +pub fn from_i32<A: FromPrimitive>(n: i32) -> Option<A> { + FromPrimitive::from_i32(n) +} + +/// A utility function that just calls `FromPrimitive::from_i64`. +pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> { + FromPrimitive::from_i64(n) +} + +/// A utility function that just calls `FromPrimitive::from_uint`. +pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> { + FromPrimitive::from_uint(n) +} + +/// A utility function that just calls `FromPrimitive::from_u8`. +pub fn from_u8<A: FromPrimitive>(n: u8) -> Option<A> { + FromPrimitive::from_u8(n) +} + +/// A utility function that just calls `FromPrimitive::from_u16`. +pub fn from_u16<A: FromPrimitive>(n: u16) -> Option<A> { + FromPrimitive::from_u16(n) +} + +/// A utility function that just calls `FromPrimitive::from_u32`. +pub fn from_u32<A: FromPrimitive>(n: u32) -> Option<A> { + FromPrimitive::from_u32(n) +} + +/// A utility function that just calls `FromPrimitive::from_u64`. +pub fn from_u64<A: FromPrimitive>(n: u64) -> Option<A> { + FromPrimitive::from_u64(n) +} + +/// A utility function that just calls `FromPrimitive::from_f32`. +pub fn from_f32<A: FromPrimitive>(n: f32) -> Option<A> { + FromPrimitive::from_f32(n) +} + +/// A utility function that just calls `FromPrimitive::from_f64`. +pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> { + FromPrimitive::from_f64(n) +} + +macro_rules! impl_from_primitive( + ($T:ty, $to_ty:expr) => ( + impl FromPrimitive for $T { + #[inline] fn from_int(n: int) -> Option<$T> { $to_ty } + #[inline] fn from_i8(n: i8) -> Option<$T> { $to_ty } + #[inline] fn from_i16(n: i16) -> Option<$T> { $to_ty } + #[inline] fn from_i32(n: i32) -> Option<$T> { $to_ty } + #[inline] fn from_i64(n: i64) -> Option<$T> { $to_ty } + + #[inline] fn from_uint(n: uint) -> Option<$T> { $to_ty } + #[inline] fn from_u8(n: u8) -> Option<$T> { $to_ty } + #[inline] fn from_u16(n: u16) -> Option<$T> { $to_ty } + #[inline] fn from_u32(n: u32) -> Option<$T> { $to_ty } + #[inline] fn from_u64(n: u64) -> Option<$T> { $to_ty } + + #[inline] fn from_f32(n: f32) -> Option<$T> { $to_ty } + #[inline] fn from_f64(n: f64) -> Option<$T> { $to_ty } + } + ) +) + +impl_from_primitive!(int, n.to_int()) +impl_from_primitive!(i8, n.to_i8()) +impl_from_primitive!(i16, n.to_i16()) +impl_from_primitive!(i32, n.to_i32()) +impl_from_primitive!(i64, n.to_i64()) +impl_from_primitive!(uint, n.to_uint()) +impl_from_primitive!(u8, n.to_u8()) +impl_from_primitive!(u16, n.to_u16()) +impl_from_primitive!(u32, n.to_u32()) +impl_from_primitive!(u64, n.to_u64()) +impl_from_primitive!(f32, n.to_f32()) +impl_from_primitive!(f64, n.to_f64()) + /// Cast from one machine scalar to another /// /// # Example @@ -363,54 +801,24 @@ pub trait Float: Real /// ``` /// #[inline] -pub fn cast<T:NumCast,U:NumCast>(n: T) -> U { +pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> { NumCast::from(n) } /// An interface for casting between machine scalars -pub trait NumCast { - fn from<T:NumCast>(n: T) -> Self; - - fn to_u8(&self) -> u8; - fn to_u16(&self) -> u16; - fn to_u32(&self) -> u32; - fn to_u64(&self) -> u64; - fn to_uint(&self) -> uint; - - fn to_i8(&self) -> i8; - fn to_i16(&self) -> i16; - fn to_i32(&self) -> i32; - fn to_i64(&self) -> i64; - fn to_int(&self) -> int; - - fn to_f32(&self) -> f32; - fn to_f64(&self) -> f64; +pub trait NumCast: ToPrimitive { + fn from<T: ToPrimitive>(n: T) -> Option<Self>; } macro_rules! impl_num_cast( ($T:ty, $conv:ident) => ( impl NumCast for $T { #[inline] - fn from<N:NumCast>(n: N) -> $T { + fn from<N: ToPrimitive>(n: N) -> Option<$T> { // `$conv` could be generated using `concat_idents!`, but that // macro seems to be broken at the moment n.$conv() } - - #[inline] fn to_u8(&self) -> u8 { *self as u8 } - #[inline] fn to_u16(&self) -> u16 { *self as u16 } - #[inline] fn to_u32(&self) -> u32 { *self as u32 } - #[inline] fn to_u64(&self) -> u64 { *self as u64 } - #[inline] fn to_uint(&self) -> uint { *self as uint } - - #[inline] fn to_i8(&self) -> i8 { *self as i8 } - #[inline] fn to_i16(&self) -> i16 { *self as i16 } - #[inline] fn to_i32(&self) -> i32 { *self as i32 } - #[inline] fn to_i64(&self) -> i64 { *self as i64 } - #[inline] fn to_int(&self) -> int { *self as int } - - #[inline] fn to_f32(&self) -> f32 { *self as f32 } - #[inline] fn to_f64(&self) -> f64 { *self as f64 } } ) ) @@ -461,7 +869,7 @@ pub fn pow_with_uint<T:NumCast+One+Zero+Div<T,T>+Mul<T,T>>(radix: uint, pow: uin if radix == 0u { return _0; } let mut my_pow = pow; let mut total = _1; - let mut multiplier = cast(radix); + let mut multiplier = cast(radix).unwrap(); while (my_pow > 0u) { if my_pow % 2u == 1u { total = total * multiplier; @@ -543,11 +951,11 @@ pub trait CheckedDiv: Div<Self, Self> { /// Helper function for testing numeric operations #[cfg(test)] pub fn test_num<T:Num + NumCast>(ten: T, two: T) { - assert_eq!(ten.add(&two), cast(12)); - assert_eq!(ten.sub(&two), cast(8)); - assert_eq!(ten.mul(&two), cast(20)); - assert_eq!(ten.div(&two), cast(5)); - assert_eq!(ten.rem(&two), cast(0)); + assert_eq!(ten.add(&two), cast(12).unwrap()); + assert_eq!(ten.sub(&two), cast(8).unwrap()); + assert_eq!(ten.mul(&two), cast(20).unwrap()); + assert_eq!(ten.div(&two), cast(5).unwrap()); + assert_eq!(ten.rem(&two), cast(0).unwrap()); assert_eq!(ten.add(&two), ten + two); assert_eq!(ten.sub(&two), ten - two); @@ -559,51 +967,60 @@ pub fn test_num<T:Num + NumCast>(ten: T, two: T) { #[cfg(test)] mod tests { use prelude::*; - use uint; use super::*; + use i8; + use i16; + use i32; + use i64; + use int; + use u8; + use u16; + use u32; + use u64; + use uint; macro_rules! test_cast_20( ($_20:expr) => ({ let _20 = $_20; - assert_eq!(20u, _20.to_uint()); - assert_eq!(20u8, _20.to_u8()); - assert_eq!(20u16, _20.to_u16()); - assert_eq!(20u32, _20.to_u32()); - assert_eq!(20u64, _20.to_u64()); - assert_eq!(20i, _20.to_int()); - assert_eq!(20i8, _20.to_i8()); - assert_eq!(20i16, _20.to_i16()); - assert_eq!(20i32, _20.to_i32()); - assert_eq!(20i64, _20.to_i64()); - assert_eq!(20f32, _20.to_f32()); - assert_eq!(20f64, _20.to_f64()); - - assert_eq!(_20, NumCast::from(20u)); - assert_eq!(_20, NumCast::from(20u8)); - assert_eq!(_20, NumCast::from(20u16)); - assert_eq!(_20, NumCast::from(20u32)); - assert_eq!(_20, NumCast::from(20u64)); - assert_eq!(_20, NumCast::from(20i)); - assert_eq!(_20, NumCast::from(20i8)); - assert_eq!(_20, NumCast::from(20i16)); - assert_eq!(_20, NumCast::from(20i32)); - assert_eq!(_20, NumCast::from(20i64)); - assert_eq!(_20, NumCast::from(20f32)); - assert_eq!(_20, NumCast::from(20f64)); - - assert_eq!(_20, cast(20u)); - assert_eq!(_20, cast(20u8)); - assert_eq!(_20, cast(20u16)); - assert_eq!(_20, cast(20u32)); - assert_eq!(_20, cast(20u64)); - assert_eq!(_20, cast(20i)); - assert_eq!(_20, cast(20i8)); - assert_eq!(_20, cast(20i16)); - assert_eq!(_20, cast(20i32)); - assert_eq!(_20, cast(20i64)); - assert_eq!(_20, cast(20f32)); - assert_eq!(_20, cast(20f64)); + assert_eq!(20u, _20.to_uint().unwrap()); + assert_eq!(20u8, _20.to_u8().unwrap()); + assert_eq!(20u16, _20.to_u16().unwrap()); + assert_eq!(20u32, _20.to_u32().unwrap()); + assert_eq!(20u64, _20.to_u64().unwrap()); + assert_eq!(20i, _20.to_int().unwrap()); + assert_eq!(20i8, _20.to_i8().unwrap()); + assert_eq!(20i16, _20.to_i16().unwrap()); + assert_eq!(20i32, _20.to_i32().unwrap()); + assert_eq!(20i64, _20.to_i64().unwrap()); + assert_eq!(20f32, _20.to_f32().unwrap()); + assert_eq!(20f64, _20.to_f64().unwrap()); + + assert_eq!(_20, NumCast::from(20u).unwrap()); + assert_eq!(_20, NumCast::from(20u8).unwrap()); + assert_eq!(_20, NumCast::from(20u16).unwrap()); + assert_eq!(_20, NumCast::from(20u32).unwrap()); + assert_eq!(_20, NumCast::from(20u64).unwrap()); + assert_eq!(_20, NumCast::from(20i).unwrap()); + assert_eq!(_20, NumCast::from(20i8).unwrap()); + assert_eq!(_20, NumCast::from(20i16).unwrap()); + assert_eq!(_20, NumCast::from(20i32).unwrap()); + assert_eq!(_20, NumCast::from(20i64).unwrap()); + assert_eq!(_20, NumCast::from(20f32).unwrap()); + assert_eq!(_20, NumCast::from(20f64).unwrap()); + + assert_eq!(_20, cast(20u).unwrap()); + assert_eq!(_20, cast(20u8).unwrap()); + assert_eq!(_20, cast(20u16).unwrap()); + assert_eq!(_20, cast(20u32).unwrap()); + assert_eq!(_20, cast(20u64).unwrap()); + assert_eq!(_20, cast(20i).unwrap()); + assert_eq!(_20, cast(20i8).unwrap()); + assert_eq!(_20, cast(20i16).unwrap()); + assert_eq!(_20, cast(20i32).unwrap()); + assert_eq!(_20, cast(20i64).unwrap()); + assert_eq!(_20, cast(20f32).unwrap()); + assert_eq!(_20, cast(20f64).unwrap()); }) ) @@ -621,6 +1038,374 @@ mod tests { #[test] fn test_f64_cast() { test_cast_20!(20f64) } #[test] + fn test_cast_range_int_min() { + assert_eq!(int::min_value.to_int(), Some(int::min_value as int)); + assert_eq!(int::min_value.to_i8(), None); + assert_eq!(int::min_value.to_i16(), None); + // int::min_value.to_i32() is word-size specific + assert_eq!(int::min_value.to_i64(), Some(int::min_value as i64)); + assert_eq!(int::min_value.to_uint(), None); + assert_eq!(int::min_value.to_u8(), None); + assert_eq!(int::min_value.to_u16(), None); + assert_eq!(int::min_value.to_u32(), None); + assert_eq!(int::min_value.to_u64(), None); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(int::min_value.to_i32(), Some(int::min_value as i32)); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(int::min_value.to_i32(), None); + } + + check_word_size(); + } + + #[test] + fn test_cast_range_i8_min() { + assert_eq!(i8::min_value.to_int(), Some(i8::min_value as int)); + assert_eq!(i8::min_value.to_i8(), Some(i8::min_value as i8)); + assert_eq!(i8::min_value.to_i16(), Some(i8::min_value as i16)); + assert_eq!(i8::min_value.to_i32(), Some(i8::min_value as i32)); + assert_eq!(i8::min_value.to_i64(), Some(i8::min_value as i64)); + assert_eq!(i8::min_value.to_uint(), None); + assert_eq!(i8::min_value.to_u8(), None); + assert_eq!(i8::min_value.to_u16(), None); + assert_eq!(i8::min_value.to_u32(), None); + assert_eq!(i8::min_value.to_u64(), None); + } + + #[test] + fn test_cast_range_i16_min() { + assert_eq!(i16::min_value.to_int(), Some(i16::min_value as int)); + assert_eq!(i16::min_value.to_i8(), None); + assert_eq!(i16::min_value.to_i16(), Some(i16::min_value as i16)); + assert_eq!(i16::min_value.to_i32(), Some(i16::min_value as i32)); + assert_eq!(i16::min_value.to_i64(), Some(i16::min_value as i64)); + assert_eq!(i16::min_value.to_uint(), None); + assert_eq!(i16::min_value.to_u8(), None); + assert_eq!(i16::min_value.to_u16(), None); + assert_eq!(i16::min_value.to_u32(), None); + assert_eq!(i16::min_value.to_u64(), None); + } + + #[test] + fn test_cast_range_i32_min() { + assert_eq!(i32::min_value.to_int(), Some(i32::min_value as int)); + assert_eq!(i32::min_value.to_i8(), None); + assert_eq!(i32::min_value.to_i16(), None); + assert_eq!(i32::min_value.to_i32(), Some(i32::min_value as i32)); + assert_eq!(i32::min_value.to_i64(), Some(i32::min_value as i64)); + assert_eq!(i32::min_value.to_uint(), None); + assert_eq!(i32::min_value.to_u8(), None); + assert_eq!(i32::min_value.to_u16(), None); + assert_eq!(i32::min_value.to_u32(), None); + assert_eq!(i32::min_value.to_u64(), None); + } + + #[test] + fn test_cast_range_i64_min() { + // i64::min_value.to_int() is word-size specific + assert_eq!(i64::min_value.to_i8(), None); + assert_eq!(i64::min_value.to_i16(), None); + assert_eq!(i64::min_value.to_i32(), None); + assert_eq!(i64::min_value.to_i64(), Some(i64::min_value as i64)); + assert_eq!(i64::min_value.to_uint(), None); + assert_eq!(i64::min_value.to_u8(), None); + assert_eq!(i64::min_value.to_u16(), None); + assert_eq!(i64::min_value.to_u32(), None); + assert_eq!(i64::min_value.to_u64(), None); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(i64::min_value.to_int(), None); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(i64::min_value.to_int(), Some(i64::min_value as int)); + } + + check_word_size(); + } + + #[test] + fn test_cast_range_int_max() { + assert_eq!(int::max_value.to_int(), Some(int::max_value as int)); + assert_eq!(int::max_value.to_i8(), None); + assert_eq!(int::max_value.to_i16(), None); + // int::max_value.to_i32() is word-size specific + assert_eq!(int::max_value.to_i64(), Some(int::max_value as i64)); + assert_eq!(int::max_value.to_u8(), None); + assert_eq!(int::max_value.to_u16(), None); + // int::max_value.to_u32() is word-size specific + assert_eq!(int::max_value.to_u64(), Some(int::max_value as u64)); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(int::max_value.to_i32(), Some(int::max_value as i32)); + assert_eq!(int::max_value.to_u32(), Some(int::max_value as u32)); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(int::max_value.to_i32(), None); + assert_eq!(int::max_value.to_u32(), None); + } + + check_word_size(); + } + + #[test] + fn test_cast_range_i8_max() { + assert_eq!(i8::max_value.to_int(), Some(i8::max_value as int)); + assert_eq!(i8::max_value.to_i8(), Some(i8::max_value as i8)); + assert_eq!(i8::max_value.to_i16(), Some(i8::max_value as i16)); + assert_eq!(i8::max_value.to_i32(), Some(i8::max_value as i32)); + assert_eq!(i8::max_value.to_i64(), Some(i8::max_value as i64)); + assert_eq!(i8::max_value.to_uint(), Some(i8::max_value as uint)); + assert_eq!(i8::max_value.to_u8(), Some(i8::max_value as u8)); + assert_eq!(i8::max_value.to_u16(), Some(i8::max_value as u16)); + assert_eq!(i8::max_value.to_u32(), Some(i8::max_value as u32)); + assert_eq!(i8::max_value.to_u64(), Some(i8::max_value as u64)); + } + + #[test] + fn test_cast_range_i16_max() { + assert_eq!(i16::max_value.to_int(), Some(i16::max_value as int)); + assert_eq!(i16::max_value.to_i8(), None); + assert_eq!(i16::max_value.to_i16(), Some(i16::max_value as i16)); + assert_eq!(i16::max_value.to_i32(), Some(i16::max_value as i32)); + assert_eq!(i16::max_value.to_i64(), Some(i16::max_value as i64)); + assert_eq!(i16::max_value.to_uint(), Some(i16::max_value as uint)); + assert_eq!(i16::max_value.to_u8(), None); + assert_eq!(i16::max_value.to_u16(), Some(i16::max_value as u16)); + assert_eq!(i16::max_value.to_u32(), Some(i16::max_value as u32)); + assert_eq!(i16::max_value.to_u64(), Some(i16::max_value as u64)); + } + + #[test] + fn test_cast_range_i32_max() { + assert_eq!(i32::max_value.to_int(), Some(i32::max_value as int)); + assert_eq!(i32::max_value.to_i8(), None); + assert_eq!(i32::max_value.to_i16(), None); + assert_eq!(i32::max_value.to_i32(), Some(i32::max_value as i32)); + assert_eq!(i32::max_value.to_i64(), Some(i32::max_value as i64)); + assert_eq!(i32::max_value.to_uint(), Some(i32::max_value as uint)); + assert_eq!(i32::max_value.to_u8(), None); + assert_eq!(i32::max_value.to_u16(), None); + assert_eq!(i32::max_value.to_u32(), Some(i32::max_value as u32)); + assert_eq!(i32::max_value.to_u64(), Some(i32::max_value as u64)); + } + + #[test] + fn test_cast_range_i64_max() { + // i64::max_value.to_int() is word-size specific + assert_eq!(i64::max_value.to_i8(), None); + assert_eq!(i64::max_value.to_i16(), None); + assert_eq!(i64::max_value.to_i32(), None); + assert_eq!(i64::max_value.to_i64(), Some(i64::max_value as i64)); + // i64::max_value.to_uint() is word-size specific + assert_eq!(i64::max_value.to_u8(), None); + assert_eq!(i64::max_value.to_u16(), None); + assert_eq!(i64::max_value.to_u32(), None); + assert_eq!(i64::max_value.to_u64(), Some(i64::max_value as u64)); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(i64::max_value.to_int(), None); + assert_eq!(i64::max_value.to_uint(), None); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(i64::max_value.to_int(), Some(i64::max_value as int)); + assert_eq!(i64::max_value.to_uint(), Some(i64::max_value as uint)); + } + + check_word_size(); + } + + #[test] + fn test_cast_range_uint_min() { + assert_eq!(uint::min_value.to_int(), Some(uint::min_value as int)); + assert_eq!(uint::min_value.to_i8(), Some(uint::min_value as i8)); + assert_eq!(uint::min_value.to_i16(), Some(uint::min_value as i16)); + assert_eq!(uint::min_value.to_i32(), Some(uint::min_value as i32)); + assert_eq!(uint::min_value.to_i64(), Some(uint::min_value as i64)); + assert_eq!(uint::min_value.to_uint(), Some(uint::min_value as uint)); + assert_eq!(uint::min_value.to_u8(), Some(uint::min_value as u8)); + assert_eq!(uint::min_value.to_u16(), Some(uint::min_value as u16)); + assert_eq!(uint::min_value.to_u32(), Some(uint::min_value as u32)); + assert_eq!(uint::min_value.to_u64(), Some(uint::min_value as u64)); + } + + #[test] + fn test_cast_range_u8_min() { + assert_eq!(u8::min_value.to_int(), Some(u8::min_value as int)); + assert_eq!(u8::min_value.to_i8(), Some(u8::min_value as i8)); + assert_eq!(u8::min_value.to_i16(), Some(u8::min_value as i16)); + assert_eq!(u8::min_value.to_i32(), Some(u8::min_value as i32)); + assert_eq!(u8::min_value.to_i64(), Some(u8::min_value as i64)); + assert_eq!(u8::min_value.to_uint(), Some(u8::min_value as uint)); + assert_eq!(u8::min_value.to_u8(), Some(u8::min_value as u8)); + assert_eq!(u8::min_value.to_u16(), Some(u8::min_value as u16)); + assert_eq!(u8::min_value.to_u32(), Some(u8::min_value as u32)); + assert_eq!(u8::min_value.to_u64(), Some(u8::min_value as u64)); + } + + #[test] + fn test_cast_range_u16_min() { + assert_eq!(u16::min_value.to_int(), Some(u16::min_value as int)); + assert_eq!(u16::min_value.to_i8(), Some(u16::min_value as i8)); + assert_eq!(u16::min_value.to_i16(), Some(u16::min_value as i16)); + assert_eq!(u16::min_value.to_i32(), Some(u16::min_value as i32)); + assert_eq!(u16::min_value.to_i64(), Some(u16::min_value as i64)); + assert_eq!(u16::min_value.to_uint(), Some(u16::min_value as uint)); + assert_eq!(u16::min_value.to_u8(), Some(u16::min_value as u8)); + assert_eq!(u16::min_value.to_u16(), Some(u16::min_value as u16)); + assert_eq!(u16::min_value.to_u32(), Some(u16::min_value as u32)); + assert_eq!(u16::min_value.to_u64(), Some(u16::min_value as u64)); + } + + #[test] + fn test_cast_range_u32_min() { + assert_eq!(u32::min_value.to_int(), Some(u32::min_value as int)); + assert_eq!(u32::min_value.to_i8(), Some(u32::min_value as i8)); + assert_eq!(u32::min_value.to_i16(), Some(u32::min_value as i16)); + assert_eq!(u32::min_value.to_i32(), Some(u32::min_value as i32)); + assert_eq!(u32::min_value.to_i64(), Some(u32::min_value as i64)); + assert_eq!(u32::min_value.to_uint(), Some(u32::min_value as uint)); + assert_eq!(u32::min_value.to_u8(), Some(u32::min_value as u8)); + assert_eq!(u32::min_value.to_u16(), Some(u32::min_value as u16)); + assert_eq!(u32::min_value.to_u32(), Some(u32::min_value as u32)); + assert_eq!(u32::min_value.to_u64(), Some(u32::min_value as u64)); + } + + #[test] + fn test_cast_range_u64_min() { + assert_eq!(u64::min_value.to_int(), Some(u64::min_value as int)); + assert_eq!(u64::min_value.to_i8(), Some(u64::min_value as i8)); + assert_eq!(u64::min_value.to_i16(), Some(u64::min_value as i16)); + assert_eq!(u64::min_value.to_i32(), Some(u64::min_value as i32)); + assert_eq!(u64::min_value.to_i64(), Some(u64::min_value as i64)); + assert_eq!(u64::min_value.to_uint(), Some(u64::min_value as uint)); + assert_eq!(u64::min_value.to_u8(), Some(u64::min_value as u8)); + assert_eq!(u64::min_value.to_u16(), Some(u64::min_value as u16)); + assert_eq!(u64::min_value.to_u32(), Some(u64::min_value as u32)); + assert_eq!(u64::min_value.to_u64(), Some(u64::min_value as u64)); + } + + #[test] + fn test_cast_range_uint_max() { + assert_eq!(uint::max_value.to_int(), None); + assert_eq!(uint::max_value.to_i8(), None); + assert_eq!(uint::max_value.to_i16(), None); + assert_eq!(uint::max_value.to_i32(), None); + // uint::max_value.to_i64() is word-size specific + assert_eq!(uint::max_value.to_u8(), None); + assert_eq!(uint::max_value.to_u16(), None); + // uint::max_value.to_u32() is word-size specific + assert_eq!(uint::max_value.to_u64(), Some(uint::max_value as u64)); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(uint::max_value.to_u32(), Some(uint::max_value as u32)); + assert_eq!(uint::max_value.to_i64(), Some(uint::max_value as i64)); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(uint::max_value.to_u32(), None); + assert_eq!(uint::max_value.to_i64(), None); + } + + check_word_size(); + } + + #[test] + fn test_cast_range_u8_max() { + assert_eq!(u8::max_value.to_int(), Some(u8::max_value as int)); + assert_eq!(u8::max_value.to_i8(), None); + assert_eq!(u8::max_value.to_i16(), Some(u8::max_value as i16)); + assert_eq!(u8::max_value.to_i32(), Some(u8::max_value as i32)); + assert_eq!(u8::max_value.to_i64(), Some(u8::max_value as i64)); + assert_eq!(u8::max_value.to_uint(), Some(u8::max_value as uint)); + assert_eq!(u8::max_value.to_u8(), Some(u8::max_value as u8)); + assert_eq!(u8::max_value.to_u16(), Some(u8::max_value as u16)); + assert_eq!(u8::max_value.to_u32(), Some(u8::max_value as u32)); + assert_eq!(u8::max_value.to_u64(), Some(u8::max_value as u64)); + } + + #[test] + fn test_cast_range_u16_max() { + assert_eq!(u16::max_value.to_int(), Some(u16::max_value as int)); + assert_eq!(u16::max_value.to_i8(), None); + assert_eq!(u16::max_value.to_i16(), None); + assert_eq!(u16::max_value.to_i32(), Some(u16::max_value as i32)); + assert_eq!(u16::max_value.to_i64(), Some(u16::max_value as i64)); + assert_eq!(u16::max_value.to_uint(), Some(u16::max_value as uint)); + assert_eq!(u16::max_value.to_u8(), None); + assert_eq!(u16::max_value.to_u16(), Some(u16::max_value as u16)); + assert_eq!(u16::max_value.to_u32(), Some(u16::max_value as u32)); + assert_eq!(u16::max_value.to_u64(), Some(u16::max_value as u64)); + } + + #[test] + fn test_cast_range_u32_max() { + // u32::max_value.to_int() is word-size specific + assert_eq!(u32::max_value.to_i8(), None); + assert_eq!(u32::max_value.to_i16(), None); + assert_eq!(u32::max_value.to_i32(), None); + assert_eq!(u32::max_value.to_i64(), Some(u32::max_value as i64)); + assert_eq!(u32::max_value.to_uint(), Some(u32::max_value as uint)); + assert_eq!(u32::max_value.to_u8(), None); + assert_eq!(u32::max_value.to_u16(), None); + assert_eq!(u32::max_value.to_u32(), Some(u32::max_value as u32)); + assert_eq!(u32::max_value.to_u64(), Some(u32::max_value as u64)); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(u32::max_value.to_int(), None); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(u32::max_value.to_int(), Some(u32::max_value as int)); + } + + check_word_size(); + } + + #[test] + fn test_cast_range_u64_max() { + assert_eq!(u64::max_value.to_int(), None); + assert_eq!(u64::max_value.to_i8(), None); + assert_eq!(u64::max_value.to_i16(), None); + assert_eq!(u64::max_value.to_i32(), None); + assert_eq!(u64::max_value.to_i64(), None); + // u64::max_value.to_uint() is word-size specific + assert_eq!(u64::max_value.to_u8(), None); + assert_eq!(u64::max_value.to_u16(), None); + assert_eq!(u64::max_value.to_u32(), None); + assert_eq!(u64::max_value.to_u64(), Some(u64::max_value as u64)); + + #[cfg(target_word_size = "32")] + fn check_word_size() { + assert_eq!(u64::max_value.to_uint(), None); + } + + #[cfg(target_word_size = "64")] + fn check_word_size() { + assert_eq!(u64::max_value.to_uint(), Some(u64::max_value as uint)); + } + + check_word_size(); + } + + #[test] fn test_saturating_add_uint() { use uint::max_value; assert_eq!(3u.saturating_add(5u), 8u); diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 1863369fdf7..0f253a26ccf 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -140,7 +140,7 @@ pub fn int_to_str_bytes_common<T:NumCast+Zero+Eq+Ord+Integer+ let _0: T = Zero::zero(); let neg = num < _0; - let radix_gen: T = cast(radix); + let radix_gen: T = cast(radix).unwrap(); let mut deccum = num; // This is just for integral types, the largest of which is a u64. The @@ -163,7 +163,7 @@ pub fn int_to_str_bytes_common<T:NumCast+Zero+Eq+Ord+Integer+ } else { current_digit_signed }; - buf[cur] = match current_digit.to_u8() { + buf[cur] = match current_digit.to_u8().unwrap() { i @ 0..9 => '0' as u8 + i, i => 'a' as u8 + (i - 10), }; @@ -247,7 +247,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+ let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity()); let mut buf: ~[u8] = ~[]; - let radix_gen: T = cast(radix as int); + let radix_gen: T = cast(radix as int).unwrap(); // First emit the non-fractional part, looping at least once to make // sure at least a `0` gets emitted. @@ -265,7 +265,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+ deccum = deccum / radix_gen; deccum = deccum.trunc(); - buf.push(char::from_digit(current_digit.to_int() as uint, radix) + buf.push(char::from_digit(current_digit.to_int().unwrap() as uint, radix) .unwrap() as u8); // No more digits to calculate for the non-fractional part -> break @@ -322,7 +322,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+ let current_digit = deccum.trunc().abs(); buf.push(char::from_digit( - current_digit.to_int() as uint, radix).unwrap() as u8); + current_digit.to_int().unwrap() as uint, radix).unwrap() as u8); // Decrease the deccumulator one fractional digit at a time deccum = deccum.fract(); @@ -492,7 +492,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ let _0: T = Zero::zero(); let _1: T = One::one(); - let radix_gen: T = cast(radix as int); + let radix_gen: T = cast(radix as int).unwrap(); let len = buf.len(); @@ -543,9 +543,9 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ // add/subtract current digit depending on sign if accum_positive { - accum = accum + cast(digit as int); + accum = accum + cast(digit as int).unwrap(); } else { - accum = accum - cast(digit as int); + accum = accum - cast(digit as int).unwrap(); } // Detect overflow by comparing to last value, except @@ -556,11 +556,11 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ // Detect overflow by reversing the shift-and-add proccess if accum_positive && - (last_accum != ((accum - cast(digit as int))/radix_gen.clone())) { + (last_accum != ((accum - cast(digit as int).unwrap())/radix_gen.clone())) { return NumStrConv::inf(); } if !accum_positive && - (last_accum != ((accum + cast(digit as int))/radix_gen.clone())) { + (last_accum != ((accum + cast(digit as int).unwrap())/radix_gen.clone())) { return NumStrConv::neg_inf(); } } @@ -596,7 +596,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ // Decrease power one order of magnitude power = power / radix_gen; - let digit_t: T = cast(digit); + let digit_t: T = cast(digit).unwrap(); // add/subtract current digit depending on sign if accum_positive { @@ -654,9 +654,9 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ match exp { Some(exp_pow) => { multiplier = if exp_pow < 0 { - _1 / pow_with_uint::<T>(base, (-exp_pow.to_int()) as uint) + _1 / pow_with_uint::<T>(base, (-exp_pow.to_int().unwrap()) as uint) } else { - pow_with_uint::<T>(base, exp_pow.to_int() as uint) + pow_with_uint::<T>(base, exp_pow.to_int().unwrap() as uint) } } None => return None // invalid exponent -> invalid number diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 45280482b87..f52feced67c 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -306,6 +306,9 @@ impl Primitive for $T { #[inline] fn bytes(_: Option<$T>) -> uint { bits / 8 } + + #[inline] + fn is_signed(_: Option<$T>) -> bool { false } } impl BitCount for $T { diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 96ade70f007..273a01c1811 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -59,7 +59,7 @@ pub use num::{Orderable, Signed, Unsigned, Round}; pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; pub use num::{Integer, Fractional, Real, RealExt}; pub use num::{Bitwise, BitCount, Bounded}; -pub use num::{Primitive, Int, Float, ToStrRadix}; +pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive}; pub use path::GenericPath; pub use path::Path; pub use path::PosixPath; diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index 50a8f184092..70bcb0f7170 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -317,12 +317,12 @@ pub trait Rng { /// ``` fn gen_integer_range<T: Rand + Int>(&mut self, low: T, high: T) -> T { assert!(low < high, "RNG.gen_integer_range called with low >= high"); - let range = (high - low).to_u64(); + let range = (high - low).to_u64().unwrap(); let accept_zone = u64::max_value - u64::max_value % range; loop { let rand = self.gen::<u64>(); if rand < accept_zone { - return low + NumCast::from(rand % range); + return low + NumCast::from(rand % range).unwrap(); } } } |
