@@ -6,17 +6,16 @@ use core::{i128, u128};
66use core:: { i16, i32, i64, i8, isize} ;
77use core:: { u16, u32, u64, u8, usize} ;
88
9- use float:: FloatCore ;
10-
119/// A generic trait for converting a value to a number.
1210///
1311/// A value can be represented by the target type when it lies within
1412/// the range of scalars supported by the target type.
1513/// For example, a negative integer cannot be represented by an unsigned
16- /// integer type, and an `f64 ` with a very high magnitude might not be
17- /// convertible to an `f32 `.
14+ /// integer type, and an `i64 ` with a very high magnitude might not be
15+ /// convertible to an `i32 `.
1816/// On the other hand, conversions with possible precision loss or truncation
19- /// (e.g. an `f32` with a decimal part to an integer type) are admitted.
17+ /// are admitted, like an `f32` with a decimal part to an integer type, or
18+ /// even a large `f64` saturating to `f32` infinity.
2019pub trait ToPrimitive {
2120 /// Converts the value of `self` to an `isize`. If the value cannot be
2221 /// represented by an `isize`, then `None` is returned.
@@ -102,23 +101,29 @@ pub trait ToPrimitive {
102101 ///
103102 /// This method is only available with feature `i128` enabled on Rust >= 1.26.
104103 ///
105- /// The default implementation converts through `to_u64()`. Types implementing
104+ /// The default implementation converts through `to_u64()`. Types implementing
106105 /// this trait should override this method if they can represent a greater range.
107106 #[ inline]
108107 #[ cfg( has_i128) ]
109108 fn to_u128 ( & self ) -> Option < u128 > {
110109 self . to_u64 ( ) . map ( From :: from)
111110 }
112111
113- /// Converts the value of `self` to an `f32`. If the value cannot be
114- /// represented by an `f32`, then `None` is returned.
112+ /// Converts the value of `self` to an `f32`. Overflows may map to positive
113+ /// or negative inifinity, otherwise `None` is returned if the value cannot
114+ /// be represented by an `f32`.
115115 #[ inline]
116116 fn to_f32 ( & self ) -> Option < f32 > {
117117 self . to_f64 ( ) . as_ref ( ) . and_then ( ToPrimitive :: to_f32)
118118 }
119119
120- /// Converts the value of `self` to an `f64`. If the value cannot be
121- /// represented by an `f64`, then `None` is returned.
120+ /// Converts the value of `self` to an `f64`. Overflows may map to positive
121+ /// or negative inifinity, otherwise `None` is returned if the value cannot
122+ /// be represented by an `f64`.
123+ ///
124+ /// The default implementation tries to convert through `to_i64()`, and
125+ /// failing that through `to_u64()`. Types implementing this trait should
126+ /// override this method if they can represent a greater range.
122127 #[ inline]
123128 fn to_f64 ( & self ) -> Option < f64 > {
124129 match self . to_i64 ( ) {
@@ -279,14 +284,8 @@ macro_rules! impl_to_primitive_float_to_float {
279284 ( $SrcT: ident : $( fn $method: ident -> $DstT: ident ; ) * ) => { $(
280285 #[ inline]
281286 fn $method( & self ) -> Option <$DstT> {
282- // Only finite values that are reducing size need to worry about overflow.
283- if size_of:: <$SrcT>( ) > size_of:: <$DstT>( ) && FloatCore :: is_finite( * self ) {
284- let n = * self as f64 ;
285- if n < $DstT:: MIN as f64 || n > $DstT:: MAX as f64 {
286- return None ;
287- }
288- }
289- // We can safely cast NaN, +-inf, and finite values in range.
287+ // We can safely cast all values, whether NaN, +-inf, or finite.
288+ // Finite values that are reducing size may saturate to +-inf.
290289 Some ( * self as $DstT)
291290 }
292291 ) * }
@@ -404,10 +403,11 @@ impl_to_primitive_float!(f64);
404403/// A value can be represented by the target type when it lies within
405404/// the range of scalars supported by the target type.
406405/// For example, a negative integer cannot be represented by an unsigned
407- /// integer type, and an `f64 ` with a very high magnitude might not be
408- /// convertible to an `f32 `.
406+ /// integer type, and an `i64 ` with a very high magnitude might not be
407+ /// convertible to an `i32 `.
409408/// On the other hand, conversions with possible precision loss or truncation
410- /// (e.g. an `f32` with a decimal part to an integer type) are admitted.
409+ /// are admitted, like an `f32` with a decimal part to an integer type, or
410+ /// even a large `f64` saturating to `f32` infinity.
411411pub trait FromPrimitive : Sized {
412412 /// Converts an `isize` to return an optional value of this type. If the
413413 /// value cannot be represented by this type, then `None` is returned.
@@ -508,6 +508,10 @@ pub trait FromPrimitive: Sized {
508508
509509 /// Converts a `f64` to return an optional value of this type. If the
510510 /// value cannot be represented by this type, then `None` is returned.
511+ ///
512+ /// The default implementation tries to convert through `from_i64()`, and
513+ /// failing that through `from_u64()`. Types implementing this trait should
514+ /// override this method if they can represent a greater range.
511515 #[ inline]
512516 fn from_f64 ( n : f64 ) -> Option < Self > {
513517 match n. to_i64 ( ) {
@@ -692,10 +696,11 @@ pub trait NumCast: Sized + ToPrimitive {
692696 /// A value can be represented by the target type when it lies within
693697 /// the range of scalars supported by the target type.
694698 /// For example, a negative integer cannot be represented by an unsigned
695- /// integer type, and an `f64 ` with a very high magnitude might not be
696- /// convertible to an `f32 `.
699+ /// integer type, and an `i64 ` with a very high magnitude might not be
700+ /// convertible to an `i32 `.
697701 /// On the other hand, conversions with possible precision loss or truncation
698- /// (e.g. an `f32` with a decimal part to an integer type) are admitted.
702+ /// are admitted, like an `f32` with a decimal part to an integer type, or
703+ /// even a large `f64` saturating to `f32` infinity.
699704 fn from < T : ToPrimitive > ( n : T ) -> Option < Self > ;
700705}
701706
0 commit comments