From 9de7ad2d8c1729b7b11c6d234fc8ef8ce96809bb Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Tue, 17 Sep 2013 19:28:35 -0700 Subject: [PATCH] std: Swap {To,From}Primitive to use the 64bit as the unimplemented version One downside with this current implementation is that since BigInt's default is now 64 bit, we can convert larger BigInt's to a primitive, however the current implementation on 32 bit architectures does not take advantage of this fact. --- src/libextra/num/bigint.rs | 48 ++++++++--------- src/libstd/num/num.rs | 70 +++++++++++++------------ src/libsyntax/ext/deriving/primitive.rs | 12 ++--- 3 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 493bbfa14b9..dd2acdb2e14 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -20,13 +20,13 @@ A `BigInt` is a combination of `BigUint` and `Sign`. #[allow(non_uppercase_statics)]; use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; -use std::int; use std::num; use std::num::{Zero, One, ToStrRadix, FromStrRadix, Orderable}; use std::num::{ToPrimitive, FromPrimitive}; use std::rand::Rng; use std::str; use std::uint; +use std::{i64, u64}; use std::vec; /** @@ -503,24 +503,24 @@ impl Integer for BigUint { impl ToPrimitive for BigUint { #[inline] - fn to_int(&self) -> Option { + fn to_i64(&self) -> Option { do self.to_uint().and_then |n| { - // If top bit of uint is set, it's too large to convert to + // If top bit of u64 is set, it's too large to convert to // int. if (n >> (2*BigDigit::bits - 1) != 0) { None } else { - Some(n as int) + Some(n as i64) } } } #[inline] - fn to_uint(&self) -> Option { + fn to_u64(&self) -> Option { match self.data.len() { 0 => Some(0), - 1 => Some(self.data[0] as uint), - 2 => Some(BigDigit::to_uint(self.data[1], self.data[0])), + 1 => Some(self.data[0] as u64), + 2 => Some(BigDigit::to_uint(self.data[1], self.data[0]) as u64), _ => None } } @@ -528,17 +528,17 @@ impl ToPrimitive for BigUint { impl FromPrimitive for BigUint { #[inline] - fn from_int(n: int) -> Option { + fn from_i64(n: i64) -> Option { if (n < 0) { Some(Zero::zero()) } else { - FromPrimitive::from_uint(n as uint) + FromPrimitive::from_u64(n as u64) } } #[inline] - fn from_uint(n: uint) -> Option { - let n = match BigDigit::from_uint(n) { + fn from_u64(n: u64) -> Option { + let n = match BigDigit::from_uint(n as uint) { (0, 0) => Zero::zero(), (0, n0) => BigUint::new(~[n0]), (n1, n0) => BigUint::new(~[n0, n1]) @@ -1083,19 +1083,19 @@ impl Integer for BigInt { impl ToPrimitive for BigInt { #[inline] - fn to_int(&self) -> Option { + fn to_i64(&self) -> Option { match self.sign { - Plus => self.data.to_int(), + Plus => self.data.to_i64(), Zero => Some(0), Minus => { - do self.data.to_uint().and_then |n| { - let m: uint = 1 << (2*BigDigit::bits-1); + do self.data.to_u64().and_then |n| { + let m: u64 = 1 << (2*BigDigit::bits-1); if (n > m) { None } else if (n == m) { - Some(int::min_value) + Some(i64::min_value) } else { - Some(-(n as int)) + Some(-(n as i64)) } } } @@ -1103,9 +1103,9 @@ impl ToPrimitive for BigInt { } #[inline] - fn to_uint(&self) -> Option { + fn to_u64(&self) -> Option { match self.sign { - Plus => self.data.to_uint(), + Plus => self.data.to_u64(), Zero => Some(0), Minus => None } @@ -1114,13 +1114,13 @@ impl ToPrimitive for BigInt { impl FromPrimitive for BigInt { #[inline] - fn from_int(n: int) -> Option { + fn from_i64(n: i64) -> Option { if n > 0 { - do FromPrimitive::from_uint(n as uint).and_then |n| { + do FromPrimitive::from_u64(n as u64).and_then |n| { Some(BigInt::from_biguint(Plus, n)) } } else if n < 0 { - do FromPrimitive::from_uint(uint::max_value - (n as uint) + 1).and_then |n| { + do FromPrimitive::from_u64(u64::max_value - (n as u64) + 1).and_then |n| { Some(BigInt::from_biguint(Minus, n)) } } else { @@ -1129,11 +1129,11 @@ impl FromPrimitive for BigInt { } #[inline] - fn from_uint(n: uint) -> Option { + fn from_u64(n: u64) -> Option { if n == 0 { Some(Zero::zero()) } else { - do FromPrimitive::from_uint(n).and_then |n| { + do FromPrimitive::from_u64(n).and_then |n| { Some(BigInt::from_biguint(Plus, n)) } } diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index a8c85184664..fffa9b49699 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -351,65 +351,69 @@ pub trait Float: Real /// A generic trait for converting a value to a number. pub trait ToPrimitive { /// Converts the value of `self` to an `int`. - fn to_int(&self) -> Option; + #[inline] + fn to_int(&self) -> Option { + // XXX: Check for range. + self.to_i64().and_then(|x| Some(x as int)) + } /// Converts the value of `self` to an `i8`. #[inline] fn to_i8(&self) -> Option { // XXX: Check for range. - self.to_int().and_then(|x| Some(x as i8)) + self.to_i64().and_then(|x| Some(x as i8)) } /// Converts the value of `self` to an `i16`. #[inline] fn to_i16(&self) -> Option { // XXX: Check for range. - self.to_int().and_then(|x| Some(x as i16)) + self.to_i64().and_then(|x| Some(x as i16)) } /// Converts the value of `self` to an `i32`. #[inline] fn to_i32(&self) -> Option { // XXX: Check for range. - self.to_int().and_then(|x| Some(x as i32)) + self.to_i64().and_then(|x| Some(x as i32)) } /// Converts the value of `self` to an `i64`. - #[inline] - fn to_i64(&self) -> Option { - // XXX: Check for range. - self.to_int().and_then(|x| Some(x as i64)) - } + fn to_i64(&self) -> Option; /// Converts the value of `self` to an `uint`. - fn to_uint(&self) -> Option; + #[inline] + fn to_uint(&self) -> Option { + // XXX: Check for range. + self.to_u64().and_then(|x| Some(x as uint)) + } /// Converts the value of `self` to an `u8`. #[inline] fn to_u8(&self) -> Option { // XXX: Check for range. - self.to_uint().and_then(|x| Some(x as u8)) + self.to_u64().and_then(|x| Some(x as u8)) } /// Converts the value of `self` to an `u16`. #[inline] fn to_u16(&self) -> Option { // XXX: Check for range. - self.to_uint().and_then(|x| Some(x as u16)) + self.to_u64().and_then(|x| Some(x as u16)) } /// Converts the value of `self` to an `u32`. #[inline] fn to_u32(&self) -> Option { // XXX: Check for range. - self.to_uint().and_then(|x| Some(x as u32)) + self.to_u64().and_then(|x| Some(x as u32)) } /// Converts the value of `self` to an `u64`. #[inline] fn to_u64(&self) -> Option { // XXX: Check for range. - self.to_uint().and_then(|x| Some(x as u64)) + self.to_u64().and_then(|x| Some(x as u64)) } /// Converts the value of `self` to an `f32`. @@ -423,7 +427,7 @@ pub trait ToPrimitive { #[inline] fn to_f64(&self) -> Option { // XXX: Check for range. - self.to_float().and_then(|x| Some(x as f64)) + self.to_i64().and_then(|x| Some(x as f64)) } } @@ -467,80 +471,80 @@ impl_to_primitive!(float) pub trait FromPrimitive { /// Convert an `int` to return an optional value of this type. If the /// value cannot be represented by this value, the `None` is returned. - fn from_int(n: int) -> Option; + #[inline] + fn from_int(n: int) -> Option { + FromPrimitive::from_i64(n as i64) + } /// Convert an `i8` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_i8(n: i8) -> Option { - FromPrimitive::from_int(n as int) + FromPrimitive::from_i64(n as i64) } /// Convert an `i16` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_i16(n: i16) -> Option { - FromPrimitive::from_int(n as int) + FromPrimitive::from_i64(n as i64) } /// Convert an `i32` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_i32(n: i32) -> Option { - FromPrimitive::from_int(n as int) + FromPrimitive::from_i64(n as i64) } /// Convert an `i64` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. - #[inline] - fn from_i64(n: i64) -> Option { - FromPrimitive::from_int(n as int) - } + fn from_i64(n: i64) -> Option; /// Convert an `uint` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. - fn from_uint(n: uint) -> Option; + #[inline] + fn from_uint(n: uint) -> Option { + FromPrimitive::from_u64(n as u64) + } /// Convert an `u8` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_u8(n: u8) -> Option { - FromPrimitive::from_uint(n as uint) + FromPrimitive::from_u64(n as u64) } /// Convert an `u16` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_u16(n: u16) -> Option { - FromPrimitive::from_uint(n as uint) + FromPrimitive::from_u64(n as u64) } /// Convert an `u32` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_u32(n: u32) -> Option { - FromPrimitive::from_uint(n as uint) + FromPrimitive::from_u64(n as u64) } /// Convert an `u64` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. - #[inline] - fn from_u64(n: u64) -> Option { - FromPrimitive::from_uint(n as uint) - } + fn from_u64(n: u64) -> Option; /// Convert a `f32` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_f32(n: f32) -> Option { - FromPrimitive::from_float(n as float) + FromPrimitive::from_f64(n as f64) } /// Convert a `f64` to return an optional value of this type. If the /// type cannot be represented by this value, the `None` is returned. #[inline] fn from_f64(n: f64) -> Option { - FromPrimitive::from_float(n as float) + FromPrimitive::from_i64(n as i64) } } diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index ddf8fc404d4..38c30def1d1 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -25,32 +25,32 @@ pub fn expand_deriving_from_primitive(cx: @ExtCtxt, generics: LifetimeBounds::empty(), methods: ~[ MethodDef { - name: "from_int", + name: "from_i64", generics: LifetimeBounds::empty(), explicit_self: None, args: ~[ - Literal(Path::new(~["int"])), + Literal(Path::new(~["i64"])), ], ret_ty: Literal(Path::new_(~["std", "option", "Option"], None, ~[~Self], true)), const_nonmatching: false, - combine_substructure: |c, s, sub| cs_from("int", c, s, sub), + combine_substructure: |c, s, sub| cs_from("i64", c, s, sub), }, MethodDef { - name: "from_uint", + name: "from_u64", generics: LifetimeBounds::empty(), explicit_self: None, args: ~[ - Literal(Path::new(~["uint"])), + Literal(Path::new(~["u64"])), ], ret_ty: Literal(Path::new_(~["std", "option", "Option"], None, ~[~Self], true)), const_nonmatching: false, - combine_substructure: |c, s, sub| cs_from("uint", c, s, sub), + combine_substructure: |c, s, sub| cs_from("u64", c, s, sub), }, ] };