Simplify the to_primitive_float macros
This commit is contained in:
parent
f6dc4d29a4
commit
d195eafbe2
149
src/cast.rs
149
src/cast.rs
|
@ -223,112 +223,91 @@ impl_to_primitive_uint!(u32);
|
||||||
impl_to_primitive_uint!(u64);
|
impl_to_primitive_uint!(u64);
|
||||||
|
|
||||||
macro_rules! impl_to_primitive_float_to_float {
|
macro_rules! impl_to_primitive_float_to_float {
|
||||||
($SrcT:ident, $DstT:ident, $slf:expr) => ({
|
($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
|
||||||
// Only finite values that are reducing size need to worry about overflow.
|
#[inline]
|
||||||
if size_of::<$SrcT>() > size_of::<$DstT>() && FloatCore::is_finite($slf) {
|
fn $method(&self) -> Option<$DstT> {
|
||||||
let n = $slf as f64;
|
// Only finite values that are reducing size need to worry about overflow.
|
||||||
if n < $DstT::MIN as f64 || n > $DstT::MAX as f64 {
|
if size_of::<$SrcT>() > size_of::<$DstT>() && FloatCore::is_finite(*self) {
|
||||||
return None;
|
let n = *self as f64;
|
||||||
|
if n < $DstT::MIN as f64 || n > $DstT::MAX as f64 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// We can safely cast NaN, +-inf, and finite values in range.
|
||||||
|
Some(*self as $DstT)
|
||||||
}
|
}
|
||||||
// We can safely cast NaN, +-inf, and finite values in range.
|
)*}
|
||||||
Some($slf as $DstT)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_to_primitive_float_to_signed_int {
|
macro_rules! impl_to_primitive_float_to_signed_int {
|
||||||
($SrcT:ident, $DstT:ident, $slf:expr) => ({
|
($f:ident : $( fn $method:ident -> $i:ident ; )*) => {$(
|
||||||
let t = $slf.trunc(); // round toward zero.
|
#[inline]
|
||||||
// MIN is a power of two, which we can cast and compare directly.
|
fn $method(&self) -> Option<$i> {
|
||||||
if t >= $DstT::MIN as $SrcT {
|
let t = self.trunc(); // round toward zero.
|
||||||
// The mantissa might not be able to represent all digits of MAX.
|
// MIN is a power of two, which we can cast and compare directly.
|
||||||
let sig_bits = size_of::<$DstT>() as u32 * 8 - 1;
|
if t >= $i::MIN as $f {
|
||||||
let max = if sig_bits > $SrcT::MANTISSA_DIGITS {
|
// The mantissa might not be able to represent all digits of MAX.
|
||||||
let lost_bits = sig_bits - $SrcT::MANTISSA_DIGITS;
|
let sig_bits = size_of::<$i>() as u32 * 8 - 1;
|
||||||
$DstT::MAX & !((1 << lost_bits) - 1)
|
let max = if sig_bits > $f::MANTISSA_DIGITS {
|
||||||
} else {
|
let lost_bits = sig_bits - $f::MANTISSA_DIGITS;
|
||||||
$DstT::MAX
|
$i::MAX & !((1 << lost_bits) - 1)
|
||||||
};
|
} else {
|
||||||
if t <= max as $SrcT {
|
$i::MAX
|
||||||
return Some($slf as $DstT);
|
};
|
||||||
|
if t <= max as $f {
|
||||||
|
return Some(*self as $i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
None
|
)*}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_to_primitive_float_to_unsigned_int {
|
macro_rules! impl_to_primitive_float_to_unsigned_int {
|
||||||
($SrcT:ident, $DstT:ident, $slf:expr) => ({
|
($f:ident : $( fn $method:ident -> $u:ident ; )*) => {$(
|
||||||
let t = $slf.trunc(); // round toward zero.
|
#[inline]
|
||||||
if t >= 0.0 {
|
fn $method(&self) -> Option<$u> {
|
||||||
// The mantissa might not be able to represent all digits of MAX.
|
let t = self.trunc(); // round toward zero.
|
||||||
let sig_bits = size_of::<$DstT>() as u32 * 8;
|
if t >= 0.0 {
|
||||||
let max = if sig_bits > $SrcT::MANTISSA_DIGITS {
|
// The mantissa might not be able to represent all digits of MAX.
|
||||||
let lost_bits = sig_bits - $SrcT::MANTISSA_DIGITS;
|
let sig_bits = size_of::<$u>() as u32 * 8;
|
||||||
$DstT::MAX & !((1 << lost_bits) - 1)
|
let max = if sig_bits > $f::MANTISSA_DIGITS {
|
||||||
} else {
|
let lost_bits = sig_bits - $f::MANTISSA_DIGITS;
|
||||||
$DstT::MAX
|
$u::MAX & !((1 << lost_bits) - 1)
|
||||||
};
|
} else {
|
||||||
if t <= max as $SrcT {
|
$u::MAX
|
||||||
return Some($slf as $DstT);
|
};
|
||||||
|
if t <= max as $f {
|
||||||
|
return Some(*self as $u);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
None
|
)*}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_to_primitive_float {
|
macro_rules! impl_to_primitive_float {
|
||||||
($T:ident) => (
|
($T:ident) => (
|
||||||
impl ToPrimitive for $T {
|
impl ToPrimitive for $T {
|
||||||
#[inline]
|
impl_to_primitive_float_to_signed_int! { $T:
|
||||||
fn to_isize(&self) -> Option<isize> {
|
fn to_isize -> isize;
|
||||||
impl_to_primitive_float_to_signed_int!($T, isize, *self)
|
fn to_i8 -> i8;
|
||||||
}
|
fn to_i16 -> i16;
|
||||||
#[inline]
|
fn to_i32 -> i32;
|
||||||
fn to_i8(&self) -> Option<i8> {
|
fn to_i64 -> i64;
|
||||||
impl_to_primitive_float_to_signed_int!($T, i8, *self)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_i16(&self) -> Option<i16> {
|
|
||||||
impl_to_primitive_float_to_signed_int!($T, i16, *self)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_i32(&self) -> Option<i32> {
|
|
||||||
impl_to_primitive_float_to_signed_int!($T, i32, *self)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_i64(&self) -> Option<i64> {
|
|
||||||
impl_to_primitive_float_to_signed_int!($T, i64, *self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
impl_to_primitive_float_to_unsigned_int! { $T:
|
||||||
fn to_usize(&self) -> Option<usize> {
|
fn to_usize -> usize;
|
||||||
impl_to_primitive_float_to_unsigned_int!($T, usize, *self)
|
fn to_u8 -> u8;
|
||||||
}
|
fn to_u16 -> u16;
|
||||||
#[inline]
|
fn to_u32 -> u32;
|
||||||
fn to_u8(&self) -> Option<u8> {
|
fn to_u64 -> u64;
|
||||||
impl_to_primitive_float_to_unsigned_int!($T, u8, *self)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_u16(&self) -> Option<u16> {
|
|
||||||
impl_to_primitive_float_to_unsigned_int!($T, u16, *self)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_u32(&self) -> Option<u32> {
|
|
||||||
impl_to_primitive_float_to_unsigned_int!($T, u32, *self)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_u64(&self) -> Option<u64> {
|
|
||||||
impl_to_primitive_float_to_unsigned_int!($T, u64, *self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
impl_to_primitive_float_to_float! { $T:
|
||||||
fn to_f32(&self) -> Option<f32> {
|
fn to_f32 -> f32;
|
||||||
impl_to_primitive_float_to_float!($T, f32, *self)
|
fn to_f64 -> f64;
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn to_f64(&self) -> Option<f64> {
|
|
||||||
impl_to_primitive_float_to_float!($T, f64, *self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue