Merge 8dcf2d2287
into aa36cdb206
This commit is contained in:
commit
c5e2025c62
127
src/cast.rs
127
src/cast.rs
|
@ -238,35 +238,81 @@ macro_rules! impl_to_primitive_float_to_float {
|
|||
)
|
||||
}
|
||||
|
||||
macro_rules! impl_to_primitive_float_to_signed_int {
|
||||
($SrcT:ident, $DstT:ident, $slf:expr) => ({
|
||||
let t = $slf.trunc();
|
||||
if t >= $DstT::min_value() as $SrcT && t <= $DstT::max_value() as $SrcT {
|
||||
Some($slf as $DstT)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
macro_rules! impl_to_primitive_float_to_unsigned_int {
|
||||
($SrcT:ident, $DstT:ident, $slf:expr) => ({
|
||||
let t = $slf.trunc();
|
||||
if t >= $DstT::min_value() as $SrcT && t <= $DstT::max_value() as $SrcT {
|
||||
Some($slf as $DstT)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
macro_rules! impl_to_primitive_float {
|
||||
($T:ident) => (
|
||||
impl ToPrimitive for $T {
|
||||
#[inline]
|
||||
fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
|
||||
fn to_isize(&self) -> Option<isize> {
|
||||
impl_to_primitive_float_to_signed_int!($T, isize, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
|
||||
fn to_i8(&self) -> Option<i8> {
|
||||
impl_to_primitive_float_to_signed_int!($T, i8, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
|
||||
fn to_i16(&self) -> Option<i16> {
|
||||
impl_to_primitive_float_to_signed_int!($T, i16, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
|
||||
fn to_i32(&self) -> Option<i32> {
|
||||
impl_to_primitive_float_to_signed_int!($T, i32, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
impl_to_primitive_float_to_signed_int!($T, i64, *self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
|
||||
fn to_usize(&self) -> Option<usize> {
|
||||
impl_to_primitive_float_to_unsigned_int!($T, usize, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
|
||||
fn to_u8(&self) -> Option<u8> {
|
||||
impl_to_primitive_float_to_unsigned_int!($T, u8, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
|
||||
fn to_u16(&self) -> Option<u16> {
|
||||
impl_to_primitive_float_to_unsigned_int!($T, u16, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
|
||||
fn to_u32(&self) -> Option<u32> {
|
||||
impl_to_primitive_float_to_unsigned_int!($T, u32, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
impl_to_primitive_float_to_unsigned_int!($T, u64, *self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
|
||||
fn to_f32(&self) -> Option<f32> {
|
||||
impl_to_primitive_float_to_float!($T, f32, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
|
||||
fn to_f64(&self) -> Option<f64> {
|
||||
impl_to_primitive_float_to_float!($T, f64, *self)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -591,3 +637,60 @@ fn as_primitive() {
|
|||
let x: u8 = (768i16).as_();
|
||||
assert_eq!(x, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn float_to_integer_checks_overflow() {
|
||||
// This will overflow an i32
|
||||
let source: f64 = 1.0e+123f64;
|
||||
|
||||
// Expect the overflow to be caught
|
||||
assert_eq!(cast::<f64, i32>(source), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cast_to_int_checks_overflow() {
|
||||
let big_f: f64 = 1.0e123;
|
||||
let normal_f: f64 = 1.0;
|
||||
let small_f: f64 = -1.0e123;
|
||||
assert_eq!(None, cast::<f64, isize>(big_f));
|
||||
assert_eq!(None, cast::<f64, i8>(big_f));
|
||||
assert_eq!(None, cast::<f64, i16>(big_f));
|
||||
assert_eq!(None, cast::<f64, i32>(big_f));
|
||||
assert_eq!(None, cast::<f64, i64>(big_f));
|
||||
|
||||
assert_eq!(Some(normal_f as isize), cast::<f64, isize>(normal_f));
|
||||
assert_eq!(Some(normal_f as i8), cast::<f64, i8>(normal_f));
|
||||
assert_eq!(Some(normal_f as i16), cast::<f64, i16>(normal_f));
|
||||
assert_eq!(Some(normal_f as i32), cast::<f64, i32>(normal_f));
|
||||
assert_eq!(Some(normal_f as i64), cast::<f64, i64>(normal_f));
|
||||
|
||||
assert_eq!(None, cast::<f64, isize>(small_f));
|
||||
assert_eq!(None, cast::<f64, i8>(small_f));
|
||||
assert_eq!(None, cast::<f64, i16>(small_f));
|
||||
assert_eq!(None, cast::<f64, i32>(small_f));
|
||||
assert_eq!(None, cast::<f64, i64>(small_f));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cast_to_unsigned_int_checks_overflow() {
|
||||
let big_f: f64 = 1.0e123;
|
||||
let normal_f: f64 = 1.0;
|
||||
let small_f: f64 = -1.0e123;
|
||||
assert_eq!(None, cast::<f64, usize>(big_f));
|
||||
assert_eq!(None, cast::<f64, u8>(big_f));
|
||||
assert_eq!(None, cast::<f64, u16>(big_f));
|
||||
assert_eq!(None, cast::<f64, u32>(big_f));
|
||||
assert_eq!(None, cast::<f64, u64>(big_f));
|
||||
|
||||
assert_eq!(Some(normal_f as usize), cast::<f64, usize>(normal_f));
|
||||
assert_eq!(Some(normal_f as u8), cast::<f64, u8>(normal_f));
|
||||
assert_eq!(Some(normal_f as u16), cast::<f64, u16>(normal_f));
|
||||
assert_eq!(Some(normal_f as u32), cast::<f64, u32>(normal_f));
|
||||
assert_eq!(Some(normal_f as u64), cast::<f64, u64>(normal_f));
|
||||
|
||||
assert_eq!(None, cast::<f64, usize>(small_f));
|
||||
assert_eq!(None, cast::<f64, u8>(small_f));
|
||||
assert_eq!(None, cast::<f64, u16>(small_f));
|
||||
assert_eq!(None, cast::<f64, u32>(small_f));
|
||||
assert_eq!(None, cast::<f64, u64>(small_f));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue