improve the TryFrom implementations
This removes the need for a 128 bit storage by making use of the fact that there can be either no over/underflow, either one or both, and each time the target type suffices to hold the limit for comparison. The downside is that the code looks a bit more complex. This test code included in this commit is from @oyvindln 's PR. They also greatly helped fixing a number of errors I made along the way. Thanks a lot!
This commit is contained in:
parent
b4502f7c0b
commit
72ef15e0df
2 changed files with 398 additions and 45 deletions
|
@ -2504,16 +2504,50 @@ impl fmt::Display for TryFromIntError {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! same_sign_try_from_int_impl {
|
||||
($storage:ty, $target:ty, $($source:ty),*) => {$(
|
||||
// no possible bounds violation
|
||||
macro_rules! try_from_unbounded {
|
||||
($source:ty, $($target:ty),*) => {$(
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<$source> for $target {
|
||||
type Error = TryFromIntError;
|
||||
|
||||
#[inline]
|
||||
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
|
||||
let min = <$target as FromStrRadixHelper>::min_value() as $storage;
|
||||
let max = <$target as FromStrRadixHelper>::max_value() as $storage;
|
||||
if u as $storage < min || u as $storage > max {
|
||||
Ok(u as $target)
|
||||
}
|
||||
}
|
||||
)*}
|
||||
}
|
||||
|
||||
// only negative bounds
|
||||
macro_rules! try_from_lower_bounded {
|
||||
($source:ty, $($target:ty),*) => {$(
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<$source> for $target {
|
||||
type Error = TryFromIntError;
|
||||
|
||||
#[inline]
|
||||
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
|
||||
if u >= 0 {
|
||||
Ok(u as $target)
|
||||
} else {
|
||||
Err(TryFromIntError(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
)*}
|
||||
}
|
||||
|
||||
// unsigned to signed (only positive bound)
|
||||
macro_rules! try_from_upper_bounded {
|
||||
($source:ty, $($target:ty),*) => {$(
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<$source> for $target {
|
||||
type Error = TryFromIntError;
|
||||
|
||||
#[inline]
|
||||
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
|
||||
if u > (<$target>::max_value() as $source) {
|
||||
Err(TryFromIntError(()))
|
||||
} else {
|
||||
Ok(u as $target)
|
||||
|
@ -2523,57 +2557,156 @@ macro_rules! same_sign_try_from_int_impl {
|
|||
)*}
|
||||
}
|
||||
|
||||
same_sign_try_from_int_impl!(u128, u8, u8, u16, u32, u64, u128, usize);
|
||||
same_sign_try_from_int_impl!(i128, i8, i8, i16, i32, i64, i128, isize);
|
||||
same_sign_try_from_int_impl!(u128, u16, u8, u16, u32, u64, u128, usize);
|
||||
same_sign_try_from_int_impl!(i128, i16, i8, i16, i32, i64, i128, isize);
|
||||
same_sign_try_from_int_impl!(u128, u32, u8, u16, u32, u64, u128, usize);
|
||||
same_sign_try_from_int_impl!(i128, i32, i8, i16, i32, i64, i128, isize);
|
||||
same_sign_try_from_int_impl!(u128, u64, u8, u16, u32, u64, u128, usize);
|
||||
same_sign_try_from_int_impl!(i128, i64, i8, i16, i32, i64, i128, isize);
|
||||
same_sign_try_from_int_impl!(u128, u128, u8, u16, u32, u64, u128, usize);
|
||||
same_sign_try_from_int_impl!(i128, i128, i8, i16, i32, i64, i128, isize);
|
||||
same_sign_try_from_int_impl!(u128, usize, u8, u16, u32, u64, u128, usize);
|
||||
same_sign_try_from_int_impl!(i128, isize, i8, i16, i32, i64, i128, isize);
|
||||
|
||||
macro_rules! cross_sign_from_int_impl {
|
||||
($unsigned:ty, $($signed:ty),*) => {$(
|
||||
// all other cases
|
||||
macro_rules! try_from_both_bounded {
|
||||
($source:ty, $($target:ty),*) => {$(
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<$unsigned> for $signed {
|
||||
impl TryFrom<$source> for $target {
|
||||
type Error = TryFromIntError;
|
||||
|
||||
fn try_from(u: $unsigned) -> Result<$signed, TryFromIntError> {
|
||||
let max = <$signed as FromStrRadixHelper>::max_value() as u128;
|
||||
if u as u128 > max {
|
||||
#[inline]
|
||||
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
|
||||
let min = <$target>::min_value() as $source;
|
||||
let max = <$target>::max_value() as $source;
|
||||
if u < min || u > max {
|
||||
Err(TryFromIntError(()))
|
||||
} else {
|
||||
Ok(u as $signed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<$signed> for $unsigned {
|
||||
type Error = TryFromIntError;
|
||||
|
||||
fn try_from(u: $signed) -> Result<$unsigned, TryFromIntError> {
|
||||
let max = <$unsigned as FromStrRadixHelper>::max_value() as u128;
|
||||
if u < 0 || u as u128 > max {
|
||||
Err(TryFromIntError(()))
|
||||
} else {
|
||||
Ok(u as $unsigned)
|
||||
Ok(u as $target)
|
||||
}
|
||||
}
|
||||
}
|
||||
)*}
|
||||
}
|
||||
|
||||
cross_sign_from_int_impl!(u8, i8, i16, i32, i64, i128, isize);
|
||||
cross_sign_from_int_impl!(u16, i8, i16, i32, i64, i128, isize);
|
||||
cross_sign_from_int_impl!(u32, i8, i16, i32, i64, i128, isize);
|
||||
cross_sign_from_int_impl!(u64, i8, i16, i32, i64, i128, isize);
|
||||
cross_sign_from_int_impl!(u128, i8, i16, i32, i64, i128, isize);
|
||||
cross_sign_from_int_impl!(usize, i8, i16, i32, i64, i128, isize);
|
||||
macro_rules! rev {
|
||||
($mac:ident, $source:ty, $($target:ty),*) => {$(
|
||||
$mac!($target, $source);
|
||||
)*}
|
||||
}
|
||||
|
||||
/// intra-sign conversions
|
||||
try_from_unbounded!(u8, u8, u16, u32, u64, u128);
|
||||
try_from_unbounded!(u16, u16, u32, u64, u128);
|
||||
try_from_unbounded!(u32, u32, u64, u128);
|
||||
try_from_unbounded!(u64, u64, u128);
|
||||
try_from_unbounded!(u128, u128);
|
||||
try_from_upper_bounded!(u16, u8);
|
||||
try_from_upper_bounded!(u32, u16, u8);
|
||||
try_from_upper_bounded!(u64, u32, u16, u8);
|
||||
try_from_upper_bounded!(u128, u64, u32, u16, u8);
|
||||
|
||||
try_from_unbounded!(i8, i8, i16, i32, i64, i128);
|
||||
try_from_unbounded!(i16, i16, i32, i64, i128);
|
||||
try_from_unbounded!(i32, i32, i64, i128);
|
||||
try_from_unbounded!(i64, i64, i128);
|
||||
try_from_unbounded!(i128, i128);
|
||||
try_from_both_bounded!(i16, i8);
|
||||
try_from_both_bounded!(i32, i16, i8);
|
||||
try_from_both_bounded!(i64, i32, i16, i8);
|
||||
try_from_both_bounded!(i128, i64, i32, i16, i8);
|
||||
|
||||
// unsigned-to-signed
|
||||
try_from_unbounded!(u8, i16, i32, i64, i128);
|
||||
try_from_unbounded!(u16, i32, i64, i128);
|
||||
try_from_unbounded!(u32, i64, i128);
|
||||
try_from_unbounded!(u64, i128);
|
||||
try_from_upper_bounded!(u8, i8);
|
||||
try_from_upper_bounded!(u16, i8, i16);
|
||||
try_from_upper_bounded!(u32, i8, i16, i32);
|
||||
try_from_upper_bounded!(u64, i8, i16, i32, i64);
|
||||
try_from_upper_bounded!(u128, i8, i16, i32, i64, i128);
|
||||
|
||||
// signed-to-unsigned
|
||||
try_from_lower_bounded!(i8, u8, u16, u32, u64, u128);
|
||||
try_from_lower_bounded!(i16, u16, u32, u64, u128);
|
||||
try_from_lower_bounded!(i32, u32, u64, u128);
|
||||
try_from_lower_bounded!(i64, u64, u128);
|
||||
try_from_lower_bounded!(i128, u128);
|
||||
try_from_both_bounded!(i16, u8);
|
||||
try_from_both_bounded!(i32, u16, u8);
|
||||
try_from_both_bounded!(i64, u32, u16, u8);
|
||||
try_from_both_bounded!(i128, u64, u32, u16, u8);
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
pub use self::ptr_try_from_impls::*;
|
||||
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
mod ptr_try_from_impls {
|
||||
use super::TryFromIntError;
|
||||
use convert::TryFrom;
|
||||
|
||||
try_from_upper_bounded!(usize, u8);
|
||||
try_from_unbounded!(usize, usize, u16, u32, u64, u128);
|
||||
try_from_upper_bounded!(usize, i8, i16, isize);
|
||||
try_from_unbounded!(usize, i32, i64, i128);
|
||||
|
||||
try_from_both_bounded!(isize, u8);
|
||||
try_from_lower_bounded!(isize, usize, u16, u32, u64, u128);
|
||||
try_from_both_bounded!(isize, i8);
|
||||
try_from_unbounded!(isize, i16, i32, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, usize, u8, u16);
|
||||
rev!(try_from_upper_bounded, usize, u32, u64, u128);
|
||||
rev!(try_from_lower_bounded, usize, i8, i16);
|
||||
rev!(try_from_both_bounded, usize, i32, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, isize, u8);
|
||||
rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
|
||||
rev!(try_from_unbounded, isize, i8, i16);
|
||||
rev!(try_from_both_bounded, isize, i32, i64, i128);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
mod ptr_try_from_impls {
|
||||
use super::TryFromIntError;
|
||||
use convert::TryFrom;
|
||||
|
||||
try_from_upper_bounded!(usize, u8, u16);
|
||||
try_from_unbounded!(usize, usize, u32, u64, u128);
|
||||
try_from_upper_bounded!(usize, i8, i16, i32, isize);
|
||||
try_from_unbounded!(usize, i64, i128);
|
||||
|
||||
try_from_both_bounded!(isize, u8, u16);
|
||||
try_from_lower_bounded!(isize, usize, u32, u64, u128);
|
||||
try_from_both_bounded!(isize, i8, i16);
|
||||
try_from_unbounded!(isize, i32, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, usize, u8, u16, u32);
|
||||
rev!(try_from_upper_bounded, usize, u64, u128);
|
||||
rev!(try_from_lower_bounded, usize, i8, i16, i32);
|
||||
rev!(try_from_both_bounded, usize, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, isize, u8, u16);
|
||||
rev!(try_from_upper_bounded, isize, u32, u64, u128);
|
||||
rev!(try_from_unbounded, isize, i8, i16, i32);
|
||||
rev!(try_from_both_bounded, isize, i64, i128);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod ptr_try_from_impls {
|
||||
use super::TryFromIntError;
|
||||
use convert::TryFrom;
|
||||
|
||||
try_from_upper_bounded!(usize, u8, u16, u32);
|
||||
try_from_unbounded!(usize, usize, u64, u128);
|
||||
try_from_upper_bounded!(usize, i8, i16, i32, i64, isize);
|
||||
try_from_unbounded!(usize, i128);
|
||||
|
||||
try_from_both_bounded!(isize, u8, u16, u32);
|
||||
try_from_lower_bounded!(isize, usize, u64, u128);
|
||||
try_from_both_bounded!(isize, i8, i16, i32);
|
||||
try_from_unbounded!(isize, i64, i128);
|
||||
|
||||
rev!(try_from_unbounded, usize, u8, u16, u32, u64);
|
||||
rev!(try_from_upper_bounded, usize, u128);
|
||||
rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
|
||||
rev!(try_from_both_bounded, usize, i128);
|
||||
|
||||
rev!(try_from_unbounded, isize, u8, u16, u32);
|
||||
rev!(try_from_upper_bounded, isize, u64, u128);
|
||||
rev!(try_from_unbounded, isize, i8, i16, i32, i64);
|
||||
rev!(try_from_both_bounded, isize, i128);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
trait FromStrRadixHelper: PartialOrd + Copy {
|
||||
|
@ -2587,15 +2720,21 @@ trait FromStrRadixHelper: PartialOrd + Copy {
|
|||
|
||||
macro_rules! doit {
|
||||
($($t:ty)*) => ($(impl FromStrRadixHelper for $t {
|
||||
#[inline]
|
||||
fn min_value() -> Self { Self::min_value() }
|
||||
#[inline]
|
||||
fn max_value() -> Self { Self::max_value() }
|
||||
#[inline]
|
||||
fn from_u32(u: u32) -> Self { u as Self }
|
||||
#[inline]
|
||||
fn checked_mul(&self, other: u32) -> Option<Self> {
|
||||
Self::checked_mul(*self, other as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn checked_sub(&self, other: u32) -> Option<Self> {
|
||||
Self::checked_sub(*self, other as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn checked_add(&self, other: u32) -> Option<Self> {
|
||||
Self::checked_add(*self, other as Self)
|
||||
}
|
||||
|
|
|
@ -36,6 +36,26 @@ mod flt2dec;
|
|||
mod dec2flt;
|
||||
mod bignum;
|
||||
|
||||
|
||||
/// Adds the attribute to all items in the block.
|
||||
macro_rules! cfg_block {
|
||||
($(#[$attr:meta]{$($it:item)*})*) => {$($(
|
||||
#[$attr]
|
||||
$it
|
||||
)*)*}
|
||||
}
|
||||
|
||||
/// Groups items that assume the pointer width is either 16/32/64, and has to be altered if
|
||||
/// support for larger/smaller pointer widths are added in the future.
|
||||
macro_rules! assume_usize_width {
|
||||
{$($it:item)*} => {#[cfg(not(any(
|
||||
target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64")))]
|
||||
compile_error!("The current tests of try_from on usize/isize assume that \
|
||||
the pointer width is either 16, 32, or 64");
|
||||
$($it)*
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function for testing numeric operations
|
||||
pub fn test_num<T>(ten: T, two: T) where
|
||||
T: PartialEq
|
||||
|
@ -212,6 +232,8 @@ fn test_f32f64() {
|
|||
assert!(nan.is_nan());
|
||||
}
|
||||
|
||||
|
||||
/// Conversions where the full width of $source can be represented as $target
|
||||
macro_rules! test_impl_try_from_always_ok {
|
||||
($fn_name:ident, $source:ty, $target: ty) => {
|
||||
#[test]
|
||||
|
@ -233,36 +255,89 @@ test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
|
|||
test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
|
||||
test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
|
||||
test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
|
||||
test_impl_try_from_always_ok! { test_try_u8u128, u8, u128 }
|
||||
test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
|
||||
test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
|
||||
test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_u8i128, u8, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
|
||||
test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
|
||||
test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
|
||||
test_impl_try_from_always_ok! { test_try_u16u128, u16, u128 }
|
||||
test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
|
||||
test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_u16i128, u16, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
|
||||
test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
|
||||
test_impl_try_from_always_ok! { test_try_u32u128, u32, u128 }
|
||||
test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_u32i128, u32, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
|
||||
test_impl_try_from_always_ok! { test_try_u64u128, u64, u128 }
|
||||
test_impl_try_from_always_ok! { test_try_u64i128, u64, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_u128, u128, u128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
|
||||
test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
|
||||
test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
|
||||
test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_i8i128, i8, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
|
||||
test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
|
||||
test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_i16i128, i16, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
|
||||
test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_i32i128, i32, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_i64i128, i64, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_i128i128, i128, i128 }
|
||||
|
||||
assume_usize_width! {
|
||||
test_impl_try_from_always_ok! { test_try_u8usize, u8, usize }
|
||||
test_impl_try_from_always_ok! { test_try_i8isize, i8, isize }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
|
||||
test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 }
|
||||
test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 }
|
||||
test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 }
|
||||
|
||||
test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 }
|
||||
test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 }
|
||||
|
||||
cfg_block!(
|
||||
#[cfg(target_pointer_width = "16")] {
|
||||
test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
|
||||
test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")] {
|
||||
test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
|
||||
test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
|
||||
test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
|
||||
test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")] {
|
||||
test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
|
||||
test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
|
||||
test_impl_try_from_always_ok! { test_try_u64usize, u64, usize }
|
||||
test_impl_try_from_always_ok! { test_try_i64isize, i64, isize }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Conversions where max of $source can be represented as $target,
|
||||
macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
|
||||
($fn_name:ident, $source:ty, $target:ty) => {
|
||||
#[test]
|
||||
|
@ -285,16 +360,51 @@ test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
|
|||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u128, i8, u128 }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u128, i16, u128 }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u128, i32, u128 }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u128, i64, u128 }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i128u128, i128, u128 }
|
||||
|
||||
assume_usize_width! {
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8usize, i8, usize }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16usize, i16, usize }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize }
|
||||
|
||||
cfg_block!(
|
||||
#[cfg(target_pointer_width = "16")] {
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")] {
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")] {
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
|
||||
test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Conversions where max of $source can not be represented as $target,
|
||||
/// but min can.
|
||||
macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
|
||||
($fn_name:ident, $source:ty, $target:ty) => {
|
||||
#[test]
|
||||
|
@ -325,6 +435,39 @@ test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
|
|||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
|
||||
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i8, u128, i8 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i16, u128, i16 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i32, u128, i32 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i64, u128, i64 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 }
|
||||
|
||||
assume_usize_width! {
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize }
|
||||
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize }
|
||||
|
||||
cfg_block!(
|
||||
#[cfg(target_pointer_width = "16")] {
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u64, isize }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")] {
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")] {
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
|
||||
test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Conversions where min/max of $source can not be represented as $target.
|
||||
macro_rules! test_impl_try_from_same_sign_err {
|
||||
($fn_name:ident, $source:ty, $target:ty) => {
|
||||
#[test]
|
||||
|
@ -359,7 +502,13 @@ test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
|
|||
test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
|
||||
test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_u128u8, u128, u8 }
|
||||
test_impl_try_from_same_sign_err! { test_try_u128u16, u128, u16 }
|
||||
test_impl_try_from_same_sign_err! { test_try_u128u32, u128, u32 }
|
||||
test_impl_try_from_same_sign_err! { test_try_u128u64, u128, u64 }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
|
||||
test_impl_try_from_same_sign_err! { test_try_isizei8, isize, i8 }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
|
||||
test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
|
||||
|
@ -368,6 +517,45 @@ test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
|
|||
test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
|
||||
test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_i128i8, i128, i8 }
|
||||
test_impl_try_from_same_sign_err! { test_try_i128i16, i128, i16 }
|
||||
test_impl_try_from_same_sign_err! { test_try_i128i32, i128, i32 }
|
||||
test_impl_try_from_same_sign_err! { test_try_i128i64, i128, i64 }
|
||||
|
||||
assume_usize_width! {
|
||||
test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 }
|
||||
test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize }
|
||||
test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize }
|
||||
|
||||
cfg_block!(
|
||||
#[cfg(target_pointer_width = "16")] {
|
||||
test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize }
|
||||
test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize }
|
||||
test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")] {
|
||||
test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
|
||||
test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
|
||||
test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")] {
|
||||
test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
|
||||
test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 }
|
||||
|
||||
test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
|
||||
test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Conversinos where neither the min nor the max of $source can be represented by
|
||||
/// $target, but max/min of the target can be represented by the source.
|
||||
macro_rules! test_impl_try_from_signed_to_unsigned_err {
|
||||
($fn_name:ident, $source:ty, $target:ty) => {
|
||||
#[test]
|
||||
|
@ -400,6 +588,32 @@ test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
|
|||
test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u8, i128, u8 }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u16, i128, u16 }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u32, i128, u32 }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 }
|
||||
|
||||
assume_usize_width! {
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
|
||||
|
||||
cfg_block! {
|
||||
#[cfg(target_pointer_width = "16")] {
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
|
||||
}
|
||||
#[cfg(target_pointer_width = "32")] {
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
|
||||
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
|
||||
}
|
||||
#[cfg(target_pointer_width = "64")] {
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
|
||||
test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! test_float {
|
||||
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => { mod $modname {
|
||||
use core::num::Float;
|
||||
|
|
Loading…
Add table
Reference in a new issue