|
@@ -1,10 +1,10 @@
|
|
|
-use core::{i8, i16, i32, i64, isize};
|
|
|
-use core::{u8, u16, u32, u64, usize};
|
|
|
-use core::{f32, f64};
|
|
|
use core::mem::size_of;
|
|
|
use core::num::Wrapping;
|
|
|
+use core::{f32, f64};
|
|
|
#[cfg(has_i128)]
|
|
|
use core::{i128, u128};
|
|
|
+use core::{i16, i32, i64, i8, isize};
|
|
|
+use core::{u16, u32, u64, u8, usize};
|
|
|
|
|
|
use float::FloatCore;
|
|
|
|
|
@@ -137,7 +137,7 @@ macro_rules! impl_to_primitive_int_to_uint {
|
|
|
}
|
|
|
|
|
|
macro_rules! impl_to_primitive_int {
|
|
|
- ($T:ident) => (
|
|
|
+ ($T:ident) => {
|
|
|
impl ToPrimitive for $T {
|
|
|
impl_to_primitive_int_to_int! { $T:
|
|
|
fn to_isize -> isize;
|
|
@@ -160,11 +160,15 @@ macro_rules! impl_to_primitive_int {
|
|
|
}
|
|
|
|
|
|
#[inline]
|
|
|
- fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
|
|
|
+ fn to_f32(&self) -> Option<f32> {
|
|
|
+ Some(*self as f32)
|
|
|
+ }
|
|
|
#[inline]
|
|
|
- fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
|
|
+ fn to_f64(&self) -> Option<f64> {
|
|
|
+ Some(*self as f64)
|
|
|
+ }
|
|
|
}
|
|
|
- )
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
impl_to_primitive_int!(isize);
|
|
@@ -206,7 +210,7 @@ macro_rules! impl_to_primitive_uint_to_uint {
|
|
|
}
|
|
|
|
|
|
macro_rules! impl_to_primitive_uint {
|
|
|
- ($T:ident) => (
|
|
|
+ ($T:ident) => {
|
|
|
impl ToPrimitive for $T {
|
|
|
impl_to_primitive_uint_to_int! { $T:
|
|
|
fn to_isize -> isize;
|
|
@@ -229,11 +233,15 @@ macro_rules! impl_to_primitive_uint {
|
|
|
}
|
|
|
|
|
|
#[inline]
|
|
|
- fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
|
|
|
+ fn to_f32(&self) -> Option<f32> {
|
|
|
+ Some(*self as f32)
|
|
|
+ }
|
|
|
#[inline]
|
|
|
- fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
|
|
+ fn to_f64(&self) -> Option<f64> {
|
|
|
+ Some(*self as f64)
|
|
|
+ }
|
|
|
}
|
|
|
- )
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
impl_to_primitive_uint!(usize);
|
|
@@ -319,7 +327,7 @@ macro_rules! impl_to_primitive_float_to_unsigned_int {
|
|
|
}
|
|
|
|
|
|
macro_rules! impl_to_primitive_float {
|
|
|
- ($T:ident) => (
|
|
|
+ ($T:ident) => {
|
|
|
impl ToPrimitive for $T {
|
|
|
impl_to_primitive_float_to_signed_int! { $T:
|
|
|
fn to_isize -> isize;
|
|
@@ -346,7 +354,7 @@ macro_rules! impl_to_primitive_float {
|
|
|
fn to_f64 -> f64;
|
|
|
}
|
|
|
}
|
|
|
- )
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
impl_to_primitive_float!(f32);
|
|
@@ -463,48 +471,89 @@ pub trait FromPrimitive: Sized {
|
|
|
}
|
|
|
|
|
|
macro_rules! impl_from_primitive {
|
|
|
- ($T:ty, $to_ty:ident) => (
|
|
|
+ ($T:ty, $to_ty:ident) => {
|
|
|
#[allow(deprecated)]
|
|
|
impl FromPrimitive for $T {
|
|
|
- #[inline] fn from_isize(n: isize) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
|
|
|
+ #[inline]
|
|
|
+ fn from_isize(n: isize) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_i8(n: i8) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_i16(n: i16) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_i32(n: i32) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_i64(n: i64) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
#[cfg(has_i128)]
|
|
|
- #[inline] fn from_i128(n: i128) -> Option<$T> { n.$to_ty() }
|
|
|
+ #[inline]
|
|
|
+ fn from_i128(n: i128) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
|
|
|
- #[inline] fn from_usize(n: usize) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
|
|
|
+ #[inline]
|
|
|
+ fn from_usize(n: usize) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_u8(n: u8) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_u16(n: u16) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_u32(n: u32) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_u64(n: u64) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
#[cfg(has_i128)]
|
|
|
- #[inline] fn from_u128(n: u128) -> Option<$T> { n.$to_ty() }
|
|
|
+ #[inline]
|
|
|
+ fn from_u128(n: u128) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
|
|
|
- #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
|
|
|
- #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
|
|
|
+ #[inline]
|
|
|
+ fn from_f32(n: f32) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
+ #[inline]
|
|
|
+ fn from_f64(n: f64) -> Option<$T> {
|
|
|
+ n.$to_ty()
|
|
|
+ }
|
|
|
}
|
|
|
- )
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
impl_from_primitive!(isize, to_isize);
|
|
|
-impl_from_primitive!(i8, to_i8);
|
|
|
-impl_from_primitive!(i16, to_i16);
|
|
|
-impl_from_primitive!(i32, to_i32);
|
|
|
-impl_from_primitive!(i64, to_i64);
|
|
|
+impl_from_primitive!(i8, to_i8);
|
|
|
+impl_from_primitive!(i16, to_i16);
|
|
|
+impl_from_primitive!(i32, to_i32);
|
|
|
+impl_from_primitive!(i64, to_i64);
|
|
|
#[cfg(has_i128)]
|
|
|
-impl_from_primitive!(i128, to_i128);
|
|
|
+impl_from_primitive!(i128, to_i128);
|
|
|
impl_from_primitive!(usize, to_usize);
|
|
|
-impl_from_primitive!(u8, to_u8);
|
|
|
-impl_from_primitive!(u16, to_u16);
|
|
|
-impl_from_primitive!(u32, to_u32);
|
|
|
-impl_from_primitive!(u64, to_u64);
|
|
|
+impl_from_primitive!(u8, to_u8);
|
|
|
+impl_from_primitive!(u16, to_u16);
|
|
|
+impl_from_primitive!(u32, to_u32);
|
|
|
+impl_from_primitive!(u64, to_u64);
|
|
|
#[cfg(has_i128)]
|
|
|
-impl_from_primitive!(u128, to_u128);
|
|
|
-impl_from_primitive!(f32, to_f32);
|
|
|
-impl_from_primitive!(f64, to_f64);
|
|
|
-
|
|
|
+impl_from_primitive!(u128, to_u128);
|
|
|
+impl_from_primitive!(f32, to_f32);
|
|
|
+impl_from_primitive!(f64, to_f64);
|
|
|
|
|
|
macro_rules! impl_to_primitive_wrapping {
|
|
|
($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
|
|
@@ -572,7 +621,6 @@ impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// Cast from one machine scalar to another.
|
|
|
///
|
|
|
/// # Examples
|
|
@@ -596,7 +644,7 @@ pub trait NumCast: Sized + ToPrimitive {
|
|
|
}
|
|
|
|
|
|
macro_rules! impl_num_cast {
|
|
|
- ($T:ty, $conv:ident) => (
|
|
|
+ ($T:ty, $conv:ident) => {
|
|
|
impl NumCast for $T {
|
|
|
#[inline]
|
|
|
#[allow(deprecated)]
|
|
@@ -606,25 +654,25 @@ macro_rules! impl_num_cast {
|
|
|
n.$conv()
|
|
|
}
|
|
|
}
|
|
|
- )
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
-impl_num_cast!(u8, to_u8);
|
|
|
-impl_num_cast!(u16, to_u16);
|
|
|
-impl_num_cast!(u32, to_u32);
|
|
|
-impl_num_cast!(u64, to_u64);
|
|
|
+impl_num_cast!(u8, to_u8);
|
|
|
+impl_num_cast!(u16, to_u16);
|
|
|
+impl_num_cast!(u32, to_u32);
|
|
|
+impl_num_cast!(u64, to_u64);
|
|
|
#[cfg(has_i128)]
|
|
|
-impl_num_cast!(u128, to_u128);
|
|
|
+impl_num_cast!(u128, to_u128);
|
|
|
impl_num_cast!(usize, to_usize);
|
|
|
-impl_num_cast!(i8, to_i8);
|
|
|
-impl_num_cast!(i16, to_i16);
|
|
|
-impl_num_cast!(i32, to_i32);
|
|
|
-impl_num_cast!(i64, to_i64);
|
|
|
+impl_num_cast!(i8, to_i8);
|
|
|
+impl_num_cast!(i16, to_i16);
|
|
|
+impl_num_cast!(i32, to_i32);
|
|
|
+impl_num_cast!(i64, to_i64);
|
|
|
#[cfg(has_i128)]
|
|
|
-impl_num_cast!(i128, to_i128);
|
|
|
+impl_num_cast!(i128, to_i128);
|
|
|
impl_num_cast!(isize, to_isize);
|
|
|
-impl_num_cast!(f32, to_f32);
|
|
|
-impl_num_cast!(f64, to_f64);
|
|
|
+impl_num_cast!(f32, to_f32);
|
|
|
+impl_num_cast!(f64, to_f64);
|
|
|
|
|
|
impl<T: NumCast> NumCast for Wrapping<T> {
|
|
|
fn from<U: ToPrimitive>(n: U) -> Option<Self> {
|
|
@@ -645,20 +693,20 @@ impl<T: NumCast> NumCast for Wrapping<T> {
|
|
|
/// let three: i32 = (3.14159265f32).as_();
|
|
|
/// assert_eq!(three, 3);
|
|
|
/// ```
|
|
|
-///
|
|
|
+///
|
|
|
/// # Safety
|
|
|
-///
|
|
|
+///
|
|
|
/// Currently, some uses of the `as` operator are not entirely safe.
|
|
|
/// In particular, it is undefined behavior if:
|
|
|
-///
|
|
|
+///
|
|
|
/// - A truncated floating point value cannot fit in the target integer
|
|
|
/// type ([#10184](https://github.com/rust-lang/rust/issues/10184));
|
|
|
-///
|
|
|
+///
|
|
|
/// ```ignore
|
|
|
/// # use num_traits::AsPrimitive;
|
|
|
/// let x: u8 = (1.04E+17).as_(); // UB
|
|
|
/// ```
|
|
|
-///
|
|
|
+///
|
|
|
/// - Or a floating point value does not fit in another floating
|
|
|
/// point type ([#15536](https://github.com/rust-lang/rust/issues/15536)).
|
|
|
///
|
|
@@ -666,10 +714,10 @@ impl<T: NumCast> NumCast for Wrapping<T> {
|
|
|
/// # use num_traits::AsPrimitive;
|
|
|
/// let x: f32 = (1e300f64).as_(); // UB
|
|
|
/// ```
|
|
|
-///
|
|
|
+///
|
|
|
pub trait AsPrimitive<T>: 'static + Copy
|
|
|
where
|
|
|
- T: 'static + Copy
|
|
|
+ T: 'static + Copy,
|
|
|
{
|
|
|
/// Convert a value to another, using the `as` operator.
|
|
|
fn as_(self) -> T;
|
|
@@ -712,4 +760,3 @@ impl_as_primitive!(f32 => { f32, f64 });
|
|
|
impl_as_primitive!(f64 => { f32, f64 });
|
|
|
impl_as_primitive!(char => { char });
|
|
|
impl_as_primitive!(bool => {});
|
|
|
-
|