提交 9de7ad2d 编写于 作者: E Erick Tryzelaar

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.
上级 5a64e1a3
......@@ -20,13 +20,13 @@
#[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 @@ fn is_odd(&self) -> bool { !self.is_even() }
impl ToPrimitive for BigUint {
#[inline]
fn to_int(&self) -> Option<int> {
fn to_i64(&self) -> Option<i64> {
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<uint> {
fn to_u64(&self) -> Option<u64> {
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 @@ fn to_uint(&self) -> Option<uint> {
impl FromPrimitive for BigUint {
#[inline]
fn from_int(n: int) -> Option<BigUint> {
fn from_i64(n: i64) -> Option<BigUint> {
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<BigUint> {
let n = match BigDigit::from_uint(n) {
fn from_u64(n: u64) -> Option<BigUint> {
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 @@ fn is_odd(&self) -> bool { self.data.is_odd() }
impl ToPrimitive for BigInt {
#[inline]
fn to_int(&self) -> Option<int> {
fn to_i64(&self) -> Option<i64> {
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 @@ fn to_int(&self) -> Option<int> {
}
#[inline]
fn to_uint(&self) -> Option<uint> {
fn to_u64(&self) -> Option<u64> {
match self.sign {
Plus => self.data.to_uint(),
Plus => self.data.to_u64(),
Zero => Some(0),
Minus => None
}
......@@ -1114,13 +1114,13 @@ fn to_uint(&self) -> Option<uint> {
impl FromPrimitive for BigInt {
#[inline]
fn from_int(n: int) -> Option<BigInt> {
fn from_i64(n: i64) -> Option<BigInt> {
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 @@ fn from_int(n: int) -> Option<BigInt> {
}
#[inline]
fn from_uint(n: uint) -> Option<BigInt> {
fn from_u64(n: u64) -> Option<BigInt> {
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))
}
}
......
......@@ -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<int>;
#[inline]
fn to_int(&self) -> Option<int> {
// 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<i8> {
// 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<i16> {
// 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<i32> {
// 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`.
fn to_i64(&self) -> Option<i64>;
/// Converts the value of `self` to an `uint`.
#[inline]
fn to_i64(&self) -> Option<i64> {
fn to_uint(&self) -> Option<uint> {
// XXX: Check for range.
self.to_int().and_then(|x| Some(x as i64))
self.to_u64().and_then(|x| Some(x as uint))
}
/// Converts the value of `self` to an `uint`.
fn to_uint(&self) -> Option<uint>;
/// Converts the value of `self` to an `u8`.
#[inline]
fn to_u8(&self) -> Option<u8> {
// 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<u16> {
// 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<u32> {
// 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<u64> {
// 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 @@ fn to_f32(&self) -> Option<f32> {
#[inline]
fn to_f64(&self) -> Option<f64> {
// 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 ToPrimitive for $T {
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<Self>;
#[inline]
fn from_int(n: int) -> Option<Self> {
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<Self> {
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<Self> {
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<Self> {
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<Self> {
FromPrimitive::from_int(n as int)
}
fn from_i64(n: i64) -> Option<Self>;
/// 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<Self>;
#[inline]
fn from_uint(n: uint) -> Option<Self> {
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<Self> {
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<Self> {
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<Self> {
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<Self> {
FromPrimitive::from_uint(n as uint)
}
fn from_u64(n: u64) -> Option<Self>;
/// 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<Self> {
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<Self> {
FromPrimitive::from_float(n as float)
FromPrimitive::from_i64(n as i64)
}
}
......
......@@ -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),
},
]
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册