summary refs log tree commit diff
path: root/src/libcore/num
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-08-17 14:16:41 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-08-17 19:35:52 -0700
commita2b932c0b614aa5a68f7d24977fab241998a89ef (patch)
treec1641403f5a09d5bdad31b4389a2d3390f63baf2 /src/libcore/num
parent5990249e48efe285fb37be104697af7e68cb3013 (diff)
downloadrust-a2b932c0b614aa5a68f7d24977fab241998a89ef.tar.gz
rust-a2b932c0b614aa5a68f7d24977fab241998a89ef.zip
core: Shuffle around float parsing
Stop using stability to hide the implementation details of ParseFloatError and
instead move the error type into the `dec2flt` module. Also move the
implementation blocks of `FromStr for f{32,64}` into `dec2flt` directly.
Diffstat (limited to 'src/libcore/num')
-rw-r--r--src/libcore/num/dec2flt/mod.rs100
-rw-r--r--src/libcore/num/float_macros.rs17
-rw-r--r--src/libcore/num/mod.rs79
3 files changed, 96 insertions, 100 deletions
diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs
index 7c3c384ea93..4e6b6f04e9e 100644
--- a/src/libcore/num/dec2flt/mod.rs
+++ b/src/libcore/num/dec2flt/mod.rs
@@ -96,8 +96,9 @@
             issue = "0")]
 
 use prelude::v1::*;
-use num::ParseFloatError as PFE;
-use num::FloatErrorKind;
+use fmt;
+use str::FromStr;
+
 use self::parse::{parse_decimal, Decimal, Sign};
 use self::parse::ParseResult::{self, Valid, ShortcutToInf, ShortcutToZero};
 use self::num::digits_to_big;
@@ -110,14 +111,87 @@ mod num;
 pub mod rawfp;
 pub mod parse;
 
-/// Entry point for decimal-to-f32 conversion.
-pub fn to_f32(s: &str) -> Result<f32, PFE> {
-    dec2flt(s)
+macro_rules! from_str_float_impl {
+    ($t:ty, $func:ident) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl FromStr for $t {
+            type Err = ParseFloatError;
+
+            /// Converts a string in base 10 to a float.
+            /// Accepts an optional decimal exponent.
+            ///
+            /// This function accepts strings such as
+            ///
+            /// * '3.14'
+            /// * '-3.14'
+            /// * '2.5E10', or equivalently, '2.5e10'
+            /// * '2.5E-10'
+            /// * '.' (understood as 0)
+            /// * '5.'
+            /// * '.5', or, equivalently,  '0.5'
+            /// * 'inf', '-inf', 'NaN'
+            ///
+            /// Leading and trailing whitespace represent an error.
+            ///
+            /// # Arguments
+            ///
+            /// * src - A string
+            ///
+            /// # Return value
+            ///
+            /// `Err(ParseFloatError)` if the string did not represent a valid
+            /// number.  Otherwise, `Ok(n)` where `n` is the floating-point
+            /// number represented by `src`.
+            #[inline]
+            fn from_str(src: &str) -> Result<Self, ParseFloatError> {
+                dec2flt(src)
+            }
+        }
+    }
+}
+from_str_float_impl!(f32, to_f32);
+from_str_float_impl!(f64, to_f64);
+
+/// An error which can be returned when parsing a float.
+#[derive(Debug, Clone, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseFloatError {
+    kind: FloatErrorKind
+}
+
+#[derive(Debug, Clone, PartialEq)]
+enum FloatErrorKind {
+    Empty,
+    Invalid,
+}
+
+impl ParseFloatError {
+    #[unstable(feature = "int_error_internals",
+               reason = "available through Error trait and this method should \
+                         not be exposed publicly",
+               issue = "0")]
+    #[doc(hidden)]
+    pub fn __description(&self) -> &str {
+        match self.kind {
+            FloatErrorKind::Empty => "cannot parse float from empty string",
+            FloatErrorKind::Invalid => "invalid float literal",
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseFloatError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.__description().fmt(f)
+    }
+}
+
+pub fn pfe_empty() -> ParseFloatError {
+    ParseFloatError { kind: FloatErrorKind::Empty }
 }
 
-/// Entry point for decimal-to-f64 conversion.
-pub fn to_f64(s: &str) -> Result<f64, PFE> {
-    dec2flt(s)
+pub fn pfe_invalid() -> ParseFloatError {
+    ParseFloatError { kind: FloatErrorKind::Invalid }
 }
 
 /// Split decimal string into sign and the rest, without inspecting or validating the rest.
@@ -131,9 +205,9 @@ fn extract_sign(s: &str) -> (Sign, &str) {
 }
 
 /// Convert a decimal string into a floating point number.
-fn dec2flt<T: RawFloat>(s: &str) -> Result<T, PFE> {
+fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
     if s.is_empty() {
-        return Err(PFE { __kind: FloatErrorKind::Empty });
+        return Err(pfe_empty())
     }
     let (sign, s) = extract_sign(s);
     let flt = match parse_decimal(s) {
@@ -143,7 +217,7 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, PFE> {
         ParseResult::Invalid => match s {
             "inf" => T::infinity(),
             "NaN" => T::nan(),
-            _ => { return Err(PFE { __kind: FloatErrorKind::Invalid }); }
+            _ => { return Err(pfe_invalid()); }
         }
     };
 
@@ -155,7 +229,7 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, PFE> {
 
 /// The main workhorse for the decimal-to-float conversion: Orchestrate all the preprocessing
 /// and figure out which algorithm should do the actual conversion.
-fn convert<T: RawFloat>(mut decimal: Decimal) -> Result<T, PFE> {
+fn convert<T: RawFloat>(mut decimal: Decimal) -> Result<T, ParseFloatError> {
     simplify(&mut decimal);
     if let Some(x) = trivial_cases(&decimal) {
         return Ok(x);
@@ -172,7 +246,7 @@ fn convert<T: RawFloat>(mut decimal: Decimal) -> Result<T, PFE> {
     // If we exceed this, perhaps while calculating `f * 10^e` in Algorithm R or Algorithm M,
     // we'll crash. So we error out before getting too close, with a generous safety margin.
     if max_digits > 375 {
-        return Err(PFE { __kind: FloatErrorKind::Invalid });
+        return Err(pfe_invalid());
     }
     let f = digits_to_big(decimal.integral, decimal.fractional);
 
diff --git a/src/libcore/num/float_macros.rs b/src/libcore/num/float_macros.rs
index e3fa7047ec8..88c3b756793 100644
--- a/src/libcore/num/float_macros.rs
+++ b/src/libcore/num/float_macros.rs
@@ -23,8 +23,7 @@ macro_rules! from_str_radix_float_impl {
     ($T:ty) => {
         fn from_str_radix(src: &str, radix: u32)
                           -> Result<$T, ParseFloatError> {
-            use num::FloatErrorKind::*;
-            use num::ParseFloatError as PFE;
+            use num::dec2flt::{pfe_empty, pfe_invalid};
 
             // Special values
             match src {
@@ -35,8 +34,8 @@ macro_rules! from_str_radix_float_impl {
             }
 
             let (is_positive, src) =  match src.slice_shift_char() {
-                None             => return Err(PFE { __kind: Empty }),
-                Some(('-', ""))  => return Err(PFE { __kind: Empty }),
+                None             => return Err(pfe_empty()),
+                Some(('-', ""))  => return Err(pfe_empty()),
                 Some(('-', src)) => (false, src),
                 Some((_, _))     => (true,  src),
             };
@@ -88,7 +87,7 @@ macro_rules! from_str_radix_float_impl {
                             break;  // start of fractional part
                         },
                         _ => {
-                            return Err(PFE { __kind: Invalid });
+                            return Err(pfe_invalid())
                         },
                     },
                 }
@@ -122,7 +121,7 @@ macro_rules! from_str_radix_float_impl {
                                 break; // start of exponent
                             },
                             _ => {
-                                return Err(PFE { __kind: Invalid });
+                                return Err(pfe_invalid())
                             },
                         },
                     }
@@ -135,7 +134,7 @@ macro_rules! from_str_radix_float_impl {
                     let base = match c {
                         'E' | 'e' if radix == 10 => 10.0,
                         'P' | 'p' if radix == 16 => 2.0,
-                        _ => return Err(PFE { __kind: Invalid }),
+                        _ => return Err(pfe_invalid()),
                     };
 
                     // Parse the exponent as decimal integer
@@ -144,13 +143,13 @@ macro_rules! from_str_radix_float_impl {
                         Some(('-', src)) => (false, src.parse::<usize>()),
                         Some(('+', src)) => (true,  src.parse::<usize>()),
                         Some((_, _))     => (true,  src.parse::<usize>()),
-                        None             => return Err(PFE { __kind: Invalid }),
+                        None             => return Err(pfe_invalid()),
                     };
 
                     match (is_positive, exp) {
                         (true,  Ok(exp)) => base.powi(exp as i32),
                         (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
-                        (_, Err(_))      => return Err(PFE { __kind: Invalid }),
+                        (_, Err(_))      => return Err(pfe_invalid()),
                     }
                 },
                 None => 1.0, // no exponent
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 086437445de..8770f46bc8e 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1365,47 +1365,6 @@ pub trait Float: Sized {
     fn to_radians(self) -> Self;
 }
 
-macro_rules! from_str_float_impl {
-    ($t:ty, $func:ident) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl FromStr for $t {
-            type Err = ParseFloatError;
-
-            /// Converts a string in base 10 to a float.
-            /// Accepts an optional decimal exponent.
-            ///
-            /// This function accepts strings such as
-            ///
-            /// * '3.14'
-            /// * '-3.14'
-            /// * '2.5E10', or equivalently, '2.5e10'
-            /// * '2.5E-10'
-            /// * '.' (understood as 0)
-            /// * '5.'
-            /// * '.5', or, equivalently,  '0.5'
-            /// * 'inf', '-inf', 'NaN'
-            ///
-            /// Leading and trailing whitespace represent an error.
-            ///
-            /// # Arguments
-            ///
-            /// * src - A string
-            ///
-            /// # Return value
-            ///
-            /// `Err(ParseFloatError)` if the string did not represent a valid
-            /// number.  Otherwise, `Ok(n)` where `n` is the floating-point
-            /// number represented by `src`.
-            #[inline]
-            fn from_str(src: &str) -> Result<Self, ParseFloatError> {
-                dec2flt::$func(src)
-            }
-        }
-    }
-}
-from_str_float_impl!(f32, to_f32);
-from_str_float_impl!(f64, to_f64);
-
 macro_rules! from_str_radix_int_impl {
     ($($t:ty)*) => {$(
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -1548,40 +1507,4 @@ impl fmt::Display for ParseIntError {
     }
 }
 
-/// An error which can be returned when parsing a float.
-#[derive(Debug, Clone, PartialEq)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct ParseFloatError {
-    #[doc(hidden)]
-    #[unstable(feature = "float_error_internals",
-               reason = "should not be exposed publicly",
-               issue = "0")]
-    pub __kind: FloatErrorKind
-}
-
-#[derive(Debug, Clone, PartialEq)]
-#[unstable(feature = "float_error_internals",
-           reason = "should not be exposed publicly",
-           issue = "0")]
-#[doc(hidden)]
-pub enum FloatErrorKind {
-    Empty,
-    Invalid,
-}
-
-impl ParseFloatError {
-    #[doc(hidden)]
-    pub fn __description(&self) -> &str {
-        match self.__kind {
-            FloatErrorKind::Empty => "cannot parse float from empty string",
-            FloatErrorKind::Invalid => "invalid float literal",
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for ParseFloatError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.__description().fmt(f)
-    }
-}
+pub use num::dec2flt::ParseFloatError;