Skip to content

Commit

Permalink
Add NumCast trait for generic numeric type casts
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanzab committed Feb 11, 2013
1 parent 0f04df8 commit 48b2141
Show file tree
Hide file tree
Showing 24 changed files with 1,044 additions and 91 deletions.
2 changes: 1 addition & 1 deletion src/libcore/core.rc
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ pub use vec::{OwnedVector, OwnedCopyableVector};
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};

pub use num::Num;
pub use num::{Num, NumCast};
pub use ptr::Ptr;
pub use to_str::ToStr;
pub use clone::Clone;
Expand Down
87 changes: 82 additions & 5 deletions src/libcore/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use cmath;
use cmp;
use libc::{c_float, c_int};
use num;
use num::NumCast;
use option::Option;
use from_str;
use to_str;
Expand Down Expand Up @@ -283,11 +284,6 @@ impl f32: num::Num {
pure fn modulo(&self, other: &f32) -> f32 { return *self % *other; }
#[inline(always)]
pure fn neg(&self) -> f32 { return -*self; }

#[inline(always)]
pure fn to_int(&self) -> int { return *self as int; }
#[inline(always)]
static pure fn from_int(n: int) -> f32 { return n as f32; }
}

impl f32: num::Zero {
Expand All @@ -300,6 +296,30 @@ impl f32: num::One {
static pure fn one() -> f32 { 1.0 }
}

pub impl f32: NumCast {
/**
* Cast `n` to an `f32`
*/
#[inline(always)]
static pure fn from<N:NumCast>(n: N) -> f32 { n.to_f32() }

#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }

#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int(&self) -> int { *self as int }

#[inline(always)] pure fn to_f32(&self) -> f32 { *self }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}

#[abi="rust-intrinsic"]
pub extern {
fn floorf32(val: f32) -> f32;
Expand Down Expand Up @@ -545,6 +565,63 @@ impl f32: num::FromStrRadix {
}
}

#[test]
pub fn test_num() {
let ten: f32 = num::cast(10);
let two: f32 = num::cast(2);

assert (ten.add(&two) == num::cast(12));
assert (ten.sub(&two) == num::cast(8));
assert (ten.mul(&two) == num::cast(20));
assert (ten.div(&two) == num::cast(5));
assert (ten.modulo(&two) == num::cast(0));
}

#[test]
fn test_numcast() {
assert (20u == 20f32.to_uint());
assert (20u8 == 20f32.to_u8());
assert (20u16 == 20f32.to_u16());
assert (20u32 == 20f32.to_u32());
assert (20u64 == 20f32.to_u64());
assert (20i == 20f32.to_int());
assert (20i8 == 20f32.to_i8());
assert (20i16 == 20f32.to_i16());
assert (20i32 == 20f32.to_i32());
assert (20i64 == 20f32.to_i64());
assert (20f == 20f32.to_float());
assert (20f32 == 20f32.to_f32());
assert (20f64 == 20f32.to_f64());

assert (20f32 == NumCast::from(20u));
assert (20f32 == NumCast::from(20u8));
assert (20f32 == NumCast::from(20u16));
assert (20f32 == NumCast::from(20u32));
assert (20f32 == NumCast::from(20u64));
assert (20f32 == NumCast::from(20i));
assert (20f32 == NumCast::from(20i8));
assert (20f32 == NumCast::from(20i16));
assert (20f32 == NumCast::from(20i32));
assert (20f32 == NumCast::from(20i64));
assert (20f32 == NumCast::from(20f));
assert (20f32 == NumCast::from(20f32));
assert (20f32 == NumCast::from(20f64));

assert (20f32 == num::cast(20u));
assert (20f32 == num::cast(20u8));
assert (20f32 == num::cast(20u16));
assert (20f32 == num::cast(20u32));
assert (20f32 == num::cast(20u64));
assert (20f32 == num::cast(20i));
assert (20f32 == num::cast(20i8));
assert (20f32 == num::cast(20i16));
assert (20f32 == num::cast(20i32));
assert (20f32 == num::cast(20i64));
assert (20f32 == num::cast(20f));
assert (20f32 == num::cast(20f32));
assert (20f32 == num::cast(20f64));
}

//
// Local Variables:
// mode: rust
Expand Down
83 changes: 80 additions & 3 deletions src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use cmp;
use libc::{c_double, c_int};
use libc;
use num;
use num::NumCast;
use option::Option;
use to_str;
use from_str;
Expand Down Expand Up @@ -307,11 +308,30 @@ impl f64: num::Num {
pure fn modulo(&self, other: &f64) -> f64 { return *self % *other; }
#[inline(always)]
pure fn neg(&self) -> f64 { return -*self; }
}

pub impl f64: NumCast {
/**
* Cast `n` to an `f64`
*/
#[inline(always)]
pure fn to_int(&self) -> int { return *self as int; }
#[inline(always)]
static pure fn from_int(n: int) -> f64 { return n as f64; }
static pure fn from<N:NumCast>(n: N) -> f64 { n.to_f64() }

#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }

#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int(&self) -> int { *self as int }

#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}

impl f64: num::Zero {
Expand Down Expand Up @@ -569,6 +589,63 @@ impl f64: num::FromStrRadix {
}
}

#[test]
pub fn test_num() {
let ten: f64 = num::cast(10);
let two: f64 = num::cast(2);

assert (ten.add(&two) == num::cast(12));
assert (ten.sub(&two) == num::cast(8));
assert (ten.mul(&two) == num::cast(20));
assert (ten.div(&two) == num::cast(5));
assert (ten.modulo(&two) == num::cast(0));
}

#[test]
fn test_numcast() {
assert (20u == 20f64.to_uint());
assert (20u8 == 20f64.to_u8());
assert (20u16 == 20f64.to_u16());
assert (20u32 == 20f64.to_u32());
assert (20u64 == 20f64.to_u64());
assert (20i == 20f64.to_int());
assert (20i8 == 20f64.to_i8());
assert (20i16 == 20f64.to_i16());
assert (20i32 == 20f64.to_i32());
assert (20i64 == 20f64.to_i64());
assert (20f == 20f64.to_float());
assert (20f32 == 20f64.to_f32());
assert (20f64 == 20f64.to_f64());

assert (20f64 == NumCast::from(20u));
assert (20f64 == NumCast::from(20u8));
assert (20f64 == NumCast::from(20u16));
assert (20f64 == NumCast::from(20u32));
assert (20f64 == NumCast::from(20u64));
assert (20f64 == NumCast::from(20i));
assert (20f64 == NumCast::from(20i8));
assert (20f64 == NumCast::from(20i16));
assert (20f64 == NumCast::from(20i32));
assert (20f64 == NumCast::from(20i64));
assert (20f64 == NumCast::from(20f));
assert (20f64 == NumCast::from(20f32));
assert (20f64 == NumCast::from(20f64));

assert (20f64 == num::cast(20u));
assert (20f64 == num::cast(20u8));
assert (20f64 == num::cast(20u16));
assert (20f64 == num::cast(20u32));
assert (20f64 == num::cast(20u64));
assert (20f64 == num::cast(20i));
assert (20f64 == num::cast(20i8));
assert (20f64 == num::cast(20i16));
assert (20f64 == num::cast(20i32));
assert (20f64 == num::cast(20i64));
assert (20f64 == num::cast(20f));
assert (20f64 == num::cast(20f32));
assert (20f64 == num::cast(20f64));
}

//
// Local Variables:
// mode: rust
Expand Down
98 changes: 78 additions & 20 deletions src/libcore/num/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use cmp::{Eq, Ord};
use cmp;
use f64;
use num;
use num::Num::from_int;
use num::NumCast;
use option::{None, Option, Some};
use str;
use uint;
Expand Down Expand Up @@ -417,11 +417,6 @@ impl float: num::Num {
pure fn modulo(&self, other: &float) -> float { return *self % *other; }
#[inline(always)]
pure fn neg(&self) -> float { return -*self; }

#[inline(always)]
pure fn to_int(&self) -> int { return *self as int; }
#[inline(always)]
static pure fn from_int(&self, n: int) -> float { return n as float; }
}

impl float: num::Zero {
Expand All @@ -434,6 +429,30 @@ impl float: num::One {
static pure fn one() -> float { 1.0 }
}

pub impl float: NumCast {
/**
* Cast `n` to a `float`
*/
#[inline(always)]
static pure fn from<N:NumCast>(n: N) -> float { n.to_float() }

#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }

#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int(&self) -> int { *self as int }

#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self }
}

impl float: num::Round {
#[inline(always)]
pure fn round(&self, mode: num::RoundMode) -> float {
Expand Down Expand Up @@ -657,21 +676,60 @@ pub fn test_round() {
}

#[test]
pub fn test_traits() {
fn test<U:num::Num cmp::Eq>(ten: &U) {
assert (ten.to_int() == 10);

let two: U = from_int(2);
assert (two.to_int() == 2);

assert (ten.add(&two) == from_int(12));
assert (ten.sub(&two) == from_int(8));
assert (ten.mul(&two) == from_int(20));
assert (ten.div(&two) == from_int(5));
assert (ten.modulo(&two) == from_int(0));
}
pub fn test_num() {
let ten: float = num::cast(10);
let two: float = num::cast(2);

test(&10.0);
assert (ten.add(&two) == num::cast(12));
assert (ten.sub(&two) == num::cast(8));
assert (ten.mul(&two) == num::cast(20));
assert (ten.div(&two) == num::cast(5));
assert (ten.modulo(&two) == num::cast(0));
}

#[test]
fn test_numcast() {
assert (20u == 20f.to_uint());
assert (20u8 == 20f.to_u8());
assert (20u16 == 20f.to_u16());
assert (20u32 == 20f.to_u32());
assert (20u64 == 20f.to_u64());
assert (20i == 20f.to_int());
assert (20i8 == 20f.to_i8());
assert (20i16 == 20f.to_i16());
assert (20i32 == 20f.to_i32());
assert (20i64 == 20f.to_i64());
assert (20f == 20f.to_float());
assert (20f32 == 20f.to_f32());
assert (20f64 == 20f.to_f64());

assert (20f == NumCast::from(20u));
assert (20f == NumCast::from(20u8));
assert (20f == NumCast::from(20u16));
assert (20f == NumCast::from(20u32));
assert (20f == NumCast::from(20u64));
assert (20f == NumCast::from(20i));
assert (20f == NumCast::from(20i8));
assert (20f == NumCast::from(20i16));
assert (20f == NumCast::from(20i32));
assert (20f == NumCast::from(20i64));
assert (20f == NumCast::from(20f));
assert (20f == NumCast::from(20f32));
assert (20f == NumCast::from(20f64));

assert (20f == num::cast(20u));
assert (20f == num::cast(20u8));
assert (20f == num::cast(20u16));
assert (20f == num::cast(20u32));
assert (20f == num::cast(20u64));
assert (20f == num::cast(20i));
assert (20f == num::cast(20i8));
assert (20f == num::cast(20i16));
assert (20f == num::cast(20i32));
assert (20f == num::cast(20i64));
assert (20f == num::cast(20f));
assert (20f == num::cast(20f32));
assert (20f == num::cast(20f64));
}


Expand Down
Loading

5 comments on commit 48b2141

@bors
Copy link
Contributor

@bors bors commented on 48b2141 Feb 13, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from catamorphism
at brendanzab@48b2141

@bors
Copy link
Contributor

@bors bors commented on 48b2141 Feb 13, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging bjz/rust/incoming = 48b2141 into auto

@bors
Copy link
Contributor

@bors bors commented on 48b2141 Feb 13, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bjz/rust/incoming = 48b2141 merged ok, testing candidate = 6727c6f

@bors
Copy link
Contributor

@bors bors commented on 48b2141 Feb 13, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 48b2141 Feb 13, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = 6727c6f

Please sign in to comment.