about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarvin Löbel <loebel.marvin@gmail.com>2013-02-15 05:20:36 +0100
committerMarvin Löbel <loebel.marvin@gmail.com>2013-02-15 05:20:36 +0100
commitbd93a36d73a005de23b9f9137f16ee90b3daecf4 (patch)
treec16a12d521da770794a23c04a9cb32e3d2429f29
parent26e0aafb889fab89c1dee5d74131455826cfa6ed (diff)
downloadrust-bd93a36d73a005de23b9f9137f16ee90b3daecf4.tar.gz
rust-bd93a36d73a005de23b9f9137f16ee90b3daecf4.zip
Made num <-> str conversion functions use NumStrConv trait
Removed hacky dependency on Round trait and generic infinity functions
Removed generic-runtime-failure-depending-on-type behavior
-rw-r--r--src/libcore/num/f32.rs12
-rw-r--r--src/libcore/num/f64.rs12
-rw-r--r--src/libcore/num/float.rs12
-rw-r--r--src/libcore/num/int-template.rs6
-rw-r--r--src/libcore/num/strconv.rs182
-rw-r--r--src/libcore/num/uint-template.rs6
6 files changed, 111 insertions, 119 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 3c5de1b703b..79623402c4d 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -378,7 +378,7 @@ impl num::Round for f32 {
 #[inline(always)]
 pub pure fn to_str(num: f32) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, 10u, true, strconv::SignNeg, strconv::DigAll);
     r
 }
 
@@ -392,7 +392,7 @@ pub pure fn to_str(num: f32) -> ~str {
 #[inline(always)]
 pub pure fn to_str_hex(num: f32) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 16u, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, 16u, true, strconv::SignNeg, strconv::DigAll);
     r
 }
 
@@ -413,7 +413,7 @@ pub pure fn to_str_hex(num: f32) -> ~str {
 #[inline(always)]
 pub pure fn to_str_radix(num: f32, rdx: uint) -> ~str {
     let (r, special) = strconv::to_str_common(
-        &num, rdx, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, rdx, true, strconv::SignNeg, strconv::DigAll);
     if special { fail!(~"number has a special value, \
                       try to_str_radix_special() if those are expected") }
     r
@@ -430,7 +430,7 @@ pub pure fn to_str_radix(num: f32, rdx: uint) -> ~str {
  */
 #[inline(always)]
 pub pure fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
-    strconv::to_str_common(&num, rdx, true, true,
+    strconv::to_str_common(&num, rdx, true,
                            strconv::SignNeg, strconv::DigAll)
 }
 
@@ -446,7 +446,7 @@ pub pure fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
 #[inline(always)]
 pub pure fn to_str_exact(num: f32, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigExact(dig));
+        &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
     r
 }
 
@@ -462,7 +462,7 @@ pub pure fn to_str_exact(num: f32, dig: uint) -> ~str {
 #[inline(always)]
 pub pure fn to_str_digits(num: f32, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigMax(dig));
+        &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
     r
 }
 
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 0bd6e0e9d77..51ee8eeba91 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -403,7 +403,7 @@ impl num::Round for f64 {
 #[inline(always)]
 pub pure fn to_str(num: f64) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, 10u, true, strconv::SignNeg, strconv::DigAll);
     r
 }
 
@@ -417,7 +417,7 @@ pub pure fn to_str(num: f64) -> ~str {
 #[inline(always)]
 pub pure fn to_str_hex(num: f64) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 16u, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, 16u, true, strconv::SignNeg, strconv::DigAll);
     r
 }
 
@@ -438,7 +438,7 @@ pub pure fn to_str_hex(num: f64) -> ~str {
 #[inline(always)]
 pub pure fn to_str_radix(num: f64, rdx: uint) -> ~str {
     let (r, special) = strconv::to_str_common(
-        &num, rdx, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, rdx, true, strconv::SignNeg, strconv::DigAll);
     if special { fail!(~"number has a special value, \
                       try to_str_radix_special() if those are expected") }
     r
@@ -455,7 +455,7 @@ pub pure fn to_str_radix(num: f64, rdx: uint) -> ~str {
  */
 #[inline(always)]
 pub pure fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
-    strconv::to_str_common(&num, rdx, true, true,
+    strconv::to_str_common(&num, rdx, true,
                            strconv::SignNeg, strconv::DigAll)
 }
 
@@ -471,7 +471,7 @@ pub pure fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
 #[inline(always)]
 pub pure fn to_str_exact(num: f64, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigExact(dig));
+        &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
     r
 }
 
@@ -487,7 +487,7 @@ pub pure fn to_str_exact(num: f64, dig: uint) -> ~str {
 #[inline(always)]
 pub pure fn to_str_digits(num: f64, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigMax(dig));
+        &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
     r
 }
 
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index 87879f6d7ad..31bd08b1241 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -109,7 +109,7 @@ pub mod consts {
 #[inline(always)]
 pub pure fn to_str(num: float) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, 10u, true, strconv::SignNeg, strconv::DigAll);
     r
 }
 
@@ -123,7 +123,7 @@ pub pure fn to_str(num: float) -> ~str {
 #[inline(always)]
 pub pure fn to_str_hex(num: float) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 16u, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, 16u, true, strconv::SignNeg, strconv::DigAll);
     r
 }
 
@@ -144,7 +144,7 @@ pub pure fn to_str_hex(num: float) -> ~str {
 #[inline(always)]
 pub pure fn to_str_radix(num: float, radix: uint) -> ~str {
     let (r, special) = strconv::to_str_common(
-        &num, radix, true, true, strconv::SignNeg, strconv::DigAll);
+        &num, radix, true, strconv::SignNeg, strconv::DigAll);
     if special { fail!(~"number has a special value, \
                       try to_str_radix_special() if those are expected") }
     r
@@ -161,7 +161,7 @@ pub pure fn to_str_radix(num: float, radix: uint) -> ~str {
  */
 #[inline(always)]
 pub pure fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
-    strconv::to_str_common(&num, radix, true, true,
+    strconv::to_str_common(&num, radix, true,
                            strconv::SignNeg, strconv::DigAll)
 }
 
@@ -177,7 +177,7 @@ pub pure fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
 #[inline(always)]
 pub pure fn to_str_exact(num: float, digits: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigExact(digits));
+        &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
     r
 }
 
@@ -199,7 +199,7 @@ pub fn test_to_str_exact_do_decimal() {
 #[inline(always)]
 pub pure fn to_str_digits(num: float, digits: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
-        &num, 10u, true, true, strconv::SignNeg, strconv::DigMax(digits));
+        &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
     r
 }
 
diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs
index df9756423ef..c0624608a15 100644
--- a/src/libcore/num/int-template.rs
+++ b/src/libcore/num/int-template.rs
@@ -256,7 +256,7 @@ impl FromStrRadix for T {
 /// Convert to a string as a byte slice in a given base.
 #[inline(always)]
 pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
-    let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, false,
+    let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
                             strconv::SignNeg, strconv::DigAll);
     f(buf)
 }
@@ -264,7 +264,7 @@ pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
 /// Convert to a string in base 10.
 #[inline(always)]
 pub pure fn to_str(num: T) -> ~str {
-    let (buf, _) = strconv::to_str_common(&num, 10u, false, false,
+    let (buf, _) = strconv::to_str_common(&num, 10u, false,
                                       strconv::SignNeg, strconv::DigAll);
     buf
 }
@@ -272,7 +272,7 @@ pub pure fn to_str(num: T) -> ~str {
 /// Convert to a string in a given base.
 #[inline(always)]
 pub pure fn to_str_radix(num: T, radix: uint) -> ~str {
-    let (buf, _) = strconv::to_str_common(&num, radix, false, false,
+    let (buf, _) = strconv::to_str_common(&num, radix, false,
                                       strconv::SignNeg, strconv::DigAll);
     buf
 }
diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs
index d5a76ef89d5..7d6b6254262 100644
--- a/src/libcore/num/strconv.rs
+++ b/src/libcore/num/strconv.rs
@@ -16,9 +16,9 @@ use str;
 use kinds::Copy;
 use vec;
 use num::{NumCast, Zero, One, cast, pow_with_uint};
-use num::{Round, RoundToZero,
+/*use num::{Round, RoundToZero,
           is_NaN, is_infinity, is_neg_infinity, is_neg_zero,
-          infinity, neg_infinity, NaN};
+          infinity, neg_infinity, NaN};*/
 use float;
 use f32;
 use f64;
@@ -42,59 +42,61 @@ pub enum SignFormat {
 }
 
 pub trait NumStrConv {
-    static fn has_NaN()      -> bool;
-    static fn has_inf()      -> bool;
-    static fn has_neg_inf()  -> bool;
-    static fn has_neg_zero() -> bool;
+    static pure fn has_NaN()      -> bool;
+    static pure fn has_inf()      -> bool;
+    static pure fn has_neg_inf()  -> bool;
+    static pure fn has_neg_zero() -> bool;
 
-    static fn NaN()      -> Option<Self>;
-    static fn inf()      -> Option<Self>;
-    static fn neg_inf()  -> Option<Self>;
-    static fn neg_zero() -> Option<Self>;
+    static pure fn NaN()      -> Option<Self>;
+    static pure fn inf()      -> Option<Self>;
+    static pure fn neg_inf()  -> Option<Self>;
+    static pure fn neg_zero() -> Option<Self>;
 
-    fn is_NaN(&self)      -> bool;
-    fn is_inf(&self)      -> bool;
-    fn is_neg_inf(&self)  -> bool;
-    fn is_neg_zero(&self) -> bool;
+    pure fn is_NaN(&self)      -> bool;
+    pure fn is_inf(&self)      -> bool;
+    pure fn is_neg_inf(&self)  -> bool;
+    pure fn is_neg_zero(&self) -> bool;
 
-    fn round_to_zero(&self) -> Self;
-    fn split_at_dot(&self) -> (Self, Self);
+    pure fn round_to_zero(&self)   -> Self;
+    pure fn fractional_part(&self) -> Self;
 
 }
 
 macro_rules! impl_NumStrConv_Floating (
     ($t:ty) => (
         impl NumStrConv for $t {
-            static fn has_NaN()      -> bool { true }
-            static fn has_inf()      -> bool { true }
-            static fn has_neg_inf()  -> bool { true }
-            static fn has_neg_zero() -> bool { true }
-
-            static fn NaN()      -> Option<$t> { Some( 0.0 / 0.0) }
-            static fn inf()      -> Option<$t> { Some( 1.0 / 0.0) }
-            static fn neg_inf()  -> Option<$t> { Some(-1.0 / 0.0) }
-            static fn neg_zero() -> Option<$t> { Some(-0.0      ) }
-
-            fn is_NaN(&self)      -> bool { *self != *self }
-            fn is_inf(&self)      -> bool {
+            static pure fn has_NaN()      -> bool { true }
+            static pure fn has_inf()      -> bool { true }
+            static pure fn has_neg_inf()  -> bool { true }
+            static pure fn has_neg_zero() -> bool { true }
+
+            static pure fn NaN()      -> Option<$t> { Some( 0.0 / 0.0) }
+            static pure fn inf()      -> Option<$t> { Some( 1.0 / 0.0) }
+            static pure fn neg_inf()  -> Option<$t> { Some(-1.0 / 0.0) }
+            static pure fn neg_zero() -> Option<$t> { Some(-0.0      ) }
+
+            pure fn is_NaN(&self)      -> bool { *self != *self }
+
+            pure fn is_inf(&self)      -> bool {
                 *self == NumStrConv::inf().unwrap()
             }
-            fn is_neg_inf(&self)  -> bool {
+
+            pure fn is_neg_inf(&self)  -> bool {
                 *self == NumStrConv::neg_inf().unwrap()
             }
-            fn is_neg_zero(&self) -> bool {
+
+            pure fn is_neg_zero(&self) -> bool {
                 *self == 0.0 && (1.0 / *self).is_neg_inf()
             }
 
-            fn round_to_zero(&self) -> $t {
+            pure fn round_to_zero(&self) -> $t {
                 ( if *self < 0.0 { f64::ceil(*self as f64)  }
                   else           { f64::floor(*self as f64) }
                 ) as $t
             }
 
-            fn split_at_dot(&self) -> ($t, $t) {
-                let r = self.round_to_zero();
-                (r, *self - r)
+            pure fn fractional_part(&self) -> $t {
+                *self - self.round_to_zero()
             }
         }
     )
@@ -103,24 +105,23 @@ macro_rules! impl_NumStrConv_Floating (
 macro_rules! impl_NumStrConv_Integer (
     ($t:ty) => (
         impl NumStrConv for $t {
-            static fn has_NaN()      -> bool { false }
-            static fn has_inf()      -> bool { false }
-            static fn has_neg_inf()  -> bool { false }
-            static fn has_neg_zero() -> bool { false }
-
-            static fn NaN()      -> Option<$t> { None }
-            static fn inf()      -> Option<$t> { None }
-            static fn neg_inf()  -> Option<$t> { None }
-            static fn neg_zero() -> Option<$t> { None }
-
-            fn is_NaN(&self)      -> bool { false }
-            fn is_inf(&self)      -> bool { false }
-            fn is_neg_inf(&self)  -> bool { false }
-            fn is_neg_zero(&self) -> bool { false }
-
-            fn round_to_zero(&self) -> $t { *self }
-
-            fn split_at_dot(&self) -> ($t, $t) { (*self, 0) }
+            static pure fn has_NaN()      -> bool { false }
+            static pure fn has_inf()      -> bool { false }
+            static pure fn has_neg_inf()  -> bool { false }
+            static pure fn has_neg_zero() -> bool { false }
+
+            static pure fn NaN()      -> Option<$t> { None }
+            static pure fn inf()      -> Option<$t> { None }
+            static pure fn neg_inf()  -> Option<$t> { None }
+            static pure fn neg_zero() -> Option<$t> { None }
+
+            pure fn is_NaN(&self)      -> bool { false }
+            pure fn is_inf(&self)      -> bool { false }
+            pure fn is_neg_inf(&self)  -> bool { false }
+            pure fn is_neg_zero(&self) -> bool { false }
+
+            pure fn round_to_zero(&self)   -> $t { *self }
+            pure fn fractional_part(&self) -> $t {     0 }
         }
     )
 )
@@ -142,6 +143,8 @@ impl_NumStrConv_Integer!(u16)
 impl_NumStrConv_Integer!(u32)
 impl_NumStrConv_Integer!(u64)
 
+// NOTE: inline the methods
+
 /**
  * Converts a number to its string representation as a byte vector.
  * This is meant to be a common base implementation for all numeric string
@@ -151,10 +154,6 @@ impl_NumStrConv_Integer!(u64)
  * - `num`           - The number to convert. Accepts any number that
  *                     implements the numeric traits.
  * - `radix`         - Base to use. Accepts only the values 2-36.
- * - `special`       - Whether to attempt to compare to special values like
- *                     `inf` or `NaN`. Also needed to detect negative 0.
- *                     Can fail if it doesn't match `num`s type
- *                     (see safety note).
  * - `negative_zero` - Whether to treat the special value `-0` as
  *                     `-0` or as `+0`.
  * - `sign`          - How to emit the sign. Options are:
@@ -176,19 +175,10 @@ impl_NumStrConv_Integer!(u64)
  *
  * # Failure
  * - Fails if `radix` < 2 or `radix` > 36.
- * - Fails on wrong value for `special` (see safety note).
- *
- * # Safety note
- * The function detects the special values `inf`, `-inf` and `NaN` by
- * dynamically comparing `num` to `1 / 0`, `-1 / 0` and `0 / 0`
- * (each of type T) if `special` is `true`. This will fail on integer types
- * with a 'divide by zero'. Likewise, it will fail if `num` **is** one of
- * those special values, and `special` is `false`, because then the
- * algorithm just does normal calculations on them.
  */
-pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
+pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+Div<T,T>+
                                   Neg<T>+Modulo<T,T>+Mul<T,T>>(
-        num: &T, radix: uint, special: bool, negative_zero: bool,
+        num: &T, radix: uint, negative_zero: bool,
         sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) {
     if radix as int <  2 {
         fail!(fmt!("to_str_bytes_common: radix %? to low, \
@@ -201,24 +191,25 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
     let _0: T = Zero::zero();
     let _1: T = One::one();
 
-    if special {
-        if is_NaN(num) {
-            return (str::to_bytes("NaN"), true);
-        } else if is_infinity(num){
-            return match sign {
-                SignAll => (str::to_bytes("+inf"), true),
-                _       => (str::to_bytes("inf"), true)
-            }
-        } else if is_neg_infinity(num) {
-            return match sign {
-                SignNone => (str::to_bytes("inf"), true),
-                _        => (str::to_bytes("-inf"), true),
-            }
+    if NumStrConv::has_NaN::<T>() && num.is_NaN() {
+        return (str::to_bytes("NaN"), true);
+    }
+    if NumStrConv::has_inf::<T>() && num.is_inf(){
+        return match sign {
+            SignAll => (str::to_bytes("+inf"), true),
+            _       => (str::to_bytes("inf"), true)
+        }
+    }
+    if NumStrConv::has_neg_inf::<T>() && num.is_neg_inf() {
+        return match sign {
+            SignNone => (str::to_bytes("inf"), true),
+            _        => (str::to_bytes("-inf"), true),
         }
     }
 
-    let neg = *num < _0 || (negative_zero && *num == _0
-                            && special && is_neg_zero(num));
+    let neg = *num < _0 || (negative_zero
+                            && NumStrConv::has_neg_zero::<T>()
+                            && num.is_neg_zero());
     let mut buf: ~[u8] = ~[];
     let radix_gen: T   = cast(radix as int);
 
@@ -226,7 +217,7 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
 
     // First emit the non-fractional part, looping at least once to make
     // sure at least a `0` gets emitted.
-    deccum = num.round(RoundToZero);
+    deccum = num.round_to_zero();
     loop {
         // Calculate the absolute value of each digit instead of only
         // doing it once for the whole number because a
@@ -243,7 +234,7 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
 
         // Decrease the deccumulator one digit at a time
         deccum /= radix_gen;
-        deccum = deccum.round(RoundToZero);
+        deccum = deccum.round_to_zero();
 
         unsafe { // FIXME: Pureness workaround (#4568)
             buf.push(char::from_digit(current_digit.to_int() as uint, radix)
@@ -286,7 +277,7 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
     let start_fractional_digits = buf.len();
 
     // Now emit the fractional part, if any
-    deccum = num.fract();
+    deccum = num.fractional_part();
     if deccum != _0 || (limit_digits && exact && digit_count > 0) {
         unsafe { // FIXME: Pureness workaround (#4568)
             buf.push('.' as u8);
@@ -309,7 +300,7 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
 
             // Calculate the absolute value of each digit.
             // See note in first loop.
-            let current_digit_signed = deccum.round(RoundToZero);
+            let current_digit_signed = deccum.round_to_zero();
             let current_digit = if current_digit_signed < _0 {
                 -current_digit_signed
             } else {
@@ -322,7 +313,7 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
             }
 
             // Decrease the deccumulator one fractional digit at a time
-            deccum = deccum.fract();
+            deccum = deccum.fractional_part();
             dig += 1u;
         }
 
@@ -409,11 +400,11 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
  * `to_str_bytes_common()`, for details see there.
  */
 #[inline(always)]
-pub pure fn to_str_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+Neg<T>
+pub pure fn to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+Div<T,T>+Neg<T>
                             +Modulo<T,T>+Mul<T,T>>(
-        num: &T, radix: uint, special: bool, negative_zero: bool,
+        num: &T, radix: uint, negative_zero: bool,
         sign: SignFormat, digits: SignificantDigits) -> (~str, bool) {
-    let (bytes, special) = to_str_bytes_common(num, radix, special,
+    let (bytes, special) = to_str_bytes_common(num, radix,
                                negative_zero, sign, digits);
     (str::from_bytes(bytes), special)
 }
@@ -466,7 +457,7 @@ priv const DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
  *   formated like `FF_AE_FF_FF`.
  */
 pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
-                                    Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>>(
+                                    Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv>(
         buf: &[u8], radix: uint, negative: bool, fractional: bool,
         special: bool, exponent: ExponentFormat, empty_zero: bool
         ) -> Option<T> {
@@ -503,17 +494,18 @@ pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
         }
     }
 
+    // XXX: Bytevector constant from str
     if special {
         if buf == str::to_bytes("inf") || buf == str::to_bytes("+inf") {
-            return Some(infinity());
+            return NumStrConv::inf();
         } else if buf == str::to_bytes("-inf") {
             if negative {
-                return Some(neg_infinity());
+                return NumStrConv::neg_inf();
             } else {
                 return None;
             }
         } else if buf == str::to_bytes("NaN") {
-            return Some(NaN());
+            return NumStrConv::NaN();
         }
     }
 
@@ -654,7 +646,7 @@ pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
  */
 #[inline(always)]
 pub pure fn from_str_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+Mul<T,T>+
-                              Sub<T,T>+Neg<T>+Add<T,T>>(
+                              Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv>(
         buf: &str, radix: uint, negative: bool, fractional: bool,
         special: bool, exponent: ExponentFormat, empty_zero: bool
         ) -> Option<T> {
diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs
index 9829bf9d9e0..c5743b40a89 100644
--- a/src/libcore/num/uint-template.rs
+++ b/src/libcore/num/uint-template.rs
@@ -220,7 +220,7 @@ impl FromStrRadix for T {
 /// Convert to a string as a byte slice in a given base.
 #[inline(always)]
 pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
-    let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, false,
+    let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
                             strconv::SignNeg, strconv::DigAll);
     f(buf)
 }
@@ -228,7 +228,7 @@ pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
 /// Convert to a string in base 10.
 #[inline(always)]
 pub pure fn to_str(num: T) -> ~str {
-    let (buf, _) = strconv::to_str_common(&num, 10u, false, false,
+    let (buf, _) = strconv::to_str_common(&num, 10u, false,
                             strconv::SignNeg, strconv::DigAll);
     buf
 }
@@ -236,7 +236,7 @@ pub pure fn to_str(num: T) -> ~str {
 /// Convert to a string in a given base.
 #[inline(always)]
 pub pure fn to_str_radix(num: T, radix: uint) -> ~str {
-    let (buf, _) = strconv::to_str_common(&num, radix, false, false,
+    let (buf, _) = strconv::to_str_common(&num, radix, false,
                             strconv::SignNeg, strconv::DigAll);
     buf
 }