Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6727c6f

Browse files
committedFeb 13, 2013
auto merge of #4881 : bjz/rust/incoming, r=catamorphism
2 parents 91c59f5 + 48b2141 commit 6727c6f

24 files changed

+1044
-91
lines changed
 

‎src/libcore/core.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ pub use vec::{OwnedVector, OwnedCopyableVector};
199199
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
200200
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
201201

202-
pub use num::Num;
202+
pub use num::{Num, NumCast};
203203
pub use ptr::Ptr;
204204
pub use to_str::ToStr;
205205
pub use clone::Clone;

‎src/libcore/num/f32.rs

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use cmath;
1414
use cmp;
1515
use libc::{c_float, c_int};
1616
use num;
17+
use num::NumCast;
1718
use option::Option;
1819
use from_str;
1920
use to_str;
@@ -283,11 +284,6 @@ impl f32: num::Num {
283284
pure fn modulo(&self, other: &f32) -> f32 { return *self % *other; }
284285
#[inline(always)]
285286
pure fn neg(&self) -> f32 { return -*self; }
286-
287-
#[inline(always)]
288-
pure fn to_int(&self) -> int { return *self as int; }
289-
#[inline(always)]
290-
static pure fn from_int(n: int) -> f32 { return n as f32; }
291287
}
292288

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

299+
pub impl f32: NumCast {
300+
/**
301+
* Cast `n` to an `f32`
302+
*/
303+
#[inline(always)]
304+
static pure fn from<N:NumCast>(n: N) -> f32 { n.to_f32() }
305+
306+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
307+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
308+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
309+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
310+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
311+
312+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
313+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
314+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
315+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
316+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
317+
318+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self }
319+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
320+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
321+
}
322+
303323
#[abi="rust-intrinsic"]
304324
pub extern {
305325
fn floorf32(val: f32) -> f32;
@@ -545,6 +565,63 @@ impl f32: num::FromStrRadix {
545565
}
546566
}
547567

568+
#[test]
569+
pub fn test_num() {
570+
let ten: f32 = num::cast(10);
571+
let two: f32 = num::cast(2);
572+
573+
assert (ten.add(&two) == num::cast(12));
574+
assert (ten.sub(&two) == num::cast(8));
575+
assert (ten.mul(&two) == num::cast(20));
576+
assert (ten.div(&two) == num::cast(5));
577+
assert (ten.modulo(&two) == num::cast(0));
578+
}
579+
580+
#[test]
581+
fn test_numcast() {
582+
assert (20u == 20f32.to_uint());
583+
assert (20u8 == 20f32.to_u8());
584+
assert (20u16 == 20f32.to_u16());
585+
assert (20u32 == 20f32.to_u32());
586+
assert (20u64 == 20f32.to_u64());
587+
assert (20i == 20f32.to_int());
588+
assert (20i8 == 20f32.to_i8());
589+
assert (20i16 == 20f32.to_i16());
590+
assert (20i32 == 20f32.to_i32());
591+
assert (20i64 == 20f32.to_i64());
592+
assert (20f == 20f32.to_float());
593+
assert (20f32 == 20f32.to_f32());
594+
assert (20f64 == 20f32.to_f64());
595+
596+
assert (20f32 == NumCast::from(20u));
597+
assert (20f32 == NumCast::from(20u8));
598+
assert (20f32 == NumCast::from(20u16));
599+
assert (20f32 == NumCast::from(20u32));
600+
assert (20f32 == NumCast::from(20u64));
601+
assert (20f32 == NumCast::from(20i));
602+
assert (20f32 == NumCast::from(20i8));
603+
assert (20f32 == NumCast::from(20i16));
604+
assert (20f32 == NumCast::from(20i32));
605+
assert (20f32 == NumCast::from(20i64));
606+
assert (20f32 == NumCast::from(20f));
607+
assert (20f32 == NumCast::from(20f32));
608+
assert (20f32 == NumCast::from(20f64));
609+
610+
assert (20f32 == num::cast(20u));
611+
assert (20f32 == num::cast(20u8));
612+
assert (20f32 == num::cast(20u16));
613+
assert (20f32 == num::cast(20u32));
614+
assert (20f32 == num::cast(20u64));
615+
assert (20f32 == num::cast(20i));
616+
assert (20f32 == num::cast(20i8));
617+
assert (20f32 == num::cast(20i16));
618+
assert (20f32 == num::cast(20i32));
619+
assert (20f32 == num::cast(20i64));
620+
assert (20f32 == num::cast(20f));
621+
assert (20f32 == num::cast(20f32));
622+
assert (20f32 == num::cast(20f64));
623+
}
624+
548625
//
549626
// Local Variables:
550627
// mode: rust

‎src/libcore/num/f64.rs

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use cmp;
1515
use libc::{c_double, c_int};
1616
use libc;
1717
use num;
18+
use num::NumCast;
1819
use option::Option;
1920
use to_str;
2021
use from_str;
@@ -307,11 +308,30 @@ impl f64: num::Num {
307308
pure fn modulo(&self, other: &f64) -> f64 { return *self % *other; }
308309
#[inline(always)]
309310
pure fn neg(&self) -> f64 { return -*self; }
311+
}
310312

313+
pub impl f64: NumCast {
314+
/**
315+
* Cast `n` to an `f64`
316+
*/
311317
#[inline(always)]
312-
pure fn to_int(&self) -> int { return *self as int; }
313-
#[inline(always)]
314-
static pure fn from_int(n: int) -> f64 { return n as f64; }
318+
static pure fn from<N:NumCast>(n: N) -> f64 { n.to_f64() }
319+
320+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
321+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
322+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
323+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
324+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
325+
326+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
327+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
328+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
329+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
330+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
331+
332+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
333+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self }
334+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
315335
}
316336

317337
impl f64: num::Zero {
@@ -569,6 +589,63 @@ impl f64: num::FromStrRadix {
569589
}
570590
}
571591

592+
#[test]
593+
pub fn test_num() {
594+
let ten: f64 = num::cast(10);
595+
let two: f64 = num::cast(2);
596+
597+
assert (ten.add(&two) == num::cast(12));
598+
assert (ten.sub(&two) == num::cast(8));
599+
assert (ten.mul(&two) == num::cast(20));
600+
assert (ten.div(&two) == num::cast(5));
601+
assert (ten.modulo(&two) == num::cast(0));
602+
}
603+
604+
#[test]
605+
fn test_numcast() {
606+
assert (20u == 20f64.to_uint());
607+
assert (20u8 == 20f64.to_u8());
608+
assert (20u16 == 20f64.to_u16());
609+
assert (20u32 == 20f64.to_u32());
610+
assert (20u64 == 20f64.to_u64());
611+
assert (20i == 20f64.to_int());
612+
assert (20i8 == 20f64.to_i8());
613+
assert (20i16 == 20f64.to_i16());
614+
assert (20i32 == 20f64.to_i32());
615+
assert (20i64 == 20f64.to_i64());
616+
assert (20f == 20f64.to_float());
617+
assert (20f32 == 20f64.to_f32());
618+
assert (20f64 == 20f64.to_f64());
619+
620+
assert (20f64 == NumCast::from(20u));
621+
assert (20f64 == NumCast::from(20u8));
622+
assert (20f64 == NumCast::from(20u16));
623+
assert (20f64 == NumCast::from(20u32));
624+
assert (20f64 == NumCast::from(20u64));
625+
assert (20f64 == NumCast::from(20i));
626+
assert (20f64 == NumCast::from(20i8));
627+
assert (20f64 == NumCast::from(20i16));
628+
assert (20f64 == NumCast::from(20i32));
629+
assert (20f64 == NumCast::from(20i64));
630+
assert (20f64 == NumCast::from(20f));
631+
assert (20f64 == NumCast::from(20f32));
632+
assert (20f64 == NumCast::from(20f64));
633+
634+
assert (20f64 == num::cast(20u));
635+
assert (20f64 == num::cast(20u8));
636+
assert (20f64 == num::cast(20u16));
637+
assert (20f64 == num::cast(20u32));
638+
assert (20f64 == num::cast(20u64));
639+
assert (20f64 == num::cast(20i));
640+
assert (20f64 == num::cast(20i8));
641+
assert (20f64 == num::cast(20i16));
642+
assert (20f64 == num::cast(20i32));
643+
assert (20f64 == num::cast(20i64));
644+
assert (20f64 == num::cast(20f));
645+
assert (20f64 == num::cast(20f32));
646+
assert (20f64 == num::cast(20f64));
647+
}
648+
572649
//
573650
// Local Variables:
574651
// mode: rust

‎src/libcore/num/float.rs

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use cmp::{Eq, Ord};
2626
use cmp;
2727
use f64;
2828
use num;
29-
use num::Num::from_int;
29+
use num::NumCast;
3030
use option::{None, Option, Some};
3131
use str;
3232
use uint;
@@ -417,11 +417,6 @@ impl float: num::Num {
417417
pure fn modulo(&self, other: &float) -> float { return *self % *other; }
418418
#[inline(always)]
419419
pure fn neg(&self) -> float { return -*self; }
420-
421-
#[inline(always)]
422-
pure fn to_int(&self) -> int { return *self as int; }
423-
#[inline(always)]
424-
static pure fn from_int(&self, n: int) -> float { return n as float; }
425420
}
426421
427422
impl float: num::Zero {
@@ -434,6 +429,30 @@ impl float: num::One {
434429
static pure fn one() -> float { 1.0 }
435430
}
436431
432+
pub impl float: NumCast {
433+
/**
434+
* Cast `n` to a `float`
435+
*/
436+
#[inline(always)]
437+
static pure fn from<N:NumCast>(n: N) -> float { n.to_float() }
438+
439+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
440+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
441+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
442+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
443+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
444+
445+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
446+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
447+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
448+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
449+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
450+
451+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
452+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
453+
#[inline(always)] pure fn to_float(&self) -> float { *self }
454+
}
455+
437456
impl float: num::Round {
438457
#[inline(always)]
439458
pure fn round(&self, mode: num::RoundMode) -> float {
@@ -657,21 +676,60 @@ pub fn test_round() {
657676
}
658677

659678
#[test]
660-
pub fn test_traits() {
661-
fn test<U:num::Num cmp::Eq>(ten: &U) {
662-
assert (ten.to_int() == 10);
663-
664-
let two: U = from_int(2);
665-
assert (two.to_int() == 2);
666-
667-
assert (ten.add(&two) == from_int(12));
668-
assert (ten.sub(&two) == from_int(8));
669-
assert (ten.mul(&two) == from_int(20));
670-
assert (ten.div(&two) == from_int(5));
671-
assert (ten.modulo(&two) == from_int(0));
672-
}
679+
pub fn test_num() {
680+
let ten: float = num::cast(10);
681+
let two: float = num::cast(2);
673682

674-
test(&10.0);
683+
assert (ten.add(&two) == num::cast(12));
684+
assert (ten.sub(&two) == num::cast(8));
685+
assert (ten.mul(&two) == num::cast(20));
686+
assert (ten.div(&two) == num::cast(5));
687+
assert (ten.modulo(&two) == num::cast(0));
688+
}
689+
690+
#[test]
691+
fn test_numcast() {
692+
assert (20u == 20f.to_uint());
693+
assert (20u8 == 20f.to_u8());
694+
assert (20u16 == 20f.to_u16());
695+
assert (20u32 == 20f.to_u32());
696+
assert (20u64 == 20f.to_u64());
697+
assert (20i == 20f.to_int());
698+
assert (20i8 == 20f.to_i8());
699+
assert (20i16 == 20f.to_i16());
700+
assert (20i32 == 20f.to_i32());
701+
assert (20i64 == 20f.to_i64());
702+
assert (20f == 20f.to_float());
703+
assert (20f32 == 20f.to_f32());
704+
assert (20f64 == 20f.to_f64());
705+
706+
assert (20f == NumCast::from(20u));
707+
assert (20f == NumCast::from(20u8));
708+
assert (20f == NumCast::from(20u16));
709+
assert (20f == NumCast::from(20u32));
710+
assert (20f == NumCast::from(20u64));
711+
assert (20f == NumCast::from(20i));
712+
assert (20f == NumCast::from(20i8));
713+
assert (20f == NumCast::from(20i16));
714+
assert (20f == NumCast::from(20i32));
715+
assert (20f == NumCast::from(20i64));
716+
assert (20f == NumCast::from(20f));
717+
assert (20f == NumCast::from(20f32));
718+
assert (20f == NumCast::from(20f64));
719+
720+
assert (20f == num::cast(20u));
721+
assert (20f == num::cast(20u8));
722+
assert (20f == num::cast(20u16));
723+
assert (20f == num::cast(20u32));
724+
assert (20f == num::cast(20u64));
725+
assert (20f == num::cast(20i));
726+
assert (20f == num::cast(20i8));
727+
assert (20f == num::cast(20i16));
728+
assert (20f == num::cast(20i32));
729+
assert (20f == num::cast(20i64));
730+
assert (20f == num::cast(20f));
731+
assert (20f == num::cast(20f32));
732+
assert (20f == num::cast(20f64));
675733
}
676734

677735

‎src/libcore/num/int-template.rs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use to_str::ToStr;
1717
use from_str::FromStr;
1818
use num::{ToStrRadix, FromStrRadix};
1919
use num;
20-
use num::Num::from_int;
2120
use prelude::*;
2221
use str;
2322
use uint;
@@ -184,11 +183,6 @@ impl T: num::Num {
184183
pure fn modulo(&self, other: &T) -> T { return *self % *other; }
185184
#[inline(always)]
186185
pure fn neg(&self) -> T { return -*self; }
187-
188-
#[inline(always)]
189-
pure fn to_int(&self) -> int { return *self as int; }
190-
#[inline(always)]
191-
static pure fn from_int(n: int) -> T { return n as T; }
192186
}
193187
194188
impl T: num::Zero {
@@ -411,22 +405,15 @@ fn test_int_from_str_overflow() {
411405
}
412406
413407
#[test]
414-
fn test_interfaces() {
415-
fn test<U:num::Num cmp::Eq>(ten: U) {
416-
assert (ten.to_int() == 10);
417-
418-
let two: U = from_int(2);
419-
assert (two.to_int() == 2);
420-
421-
assert (ten.add(&two) == from_int(12));
422-
assert (ten.sub(&two) == from_int(8));
423-
assert (ten.mul(&two) == from_int(20));
424-
assert (ten.div(&two) == from_int(5));
425-
assert (ten.modulo(&two) == from_int(0));
426-
assert (ten.neg() == from_int(-10));
427-
}
428-
429-
test(10 as T);
408+
pub fn test_num() {
409+
let ten: T = num::cast(10);
410+
let two: T = num::cast(2);
411+
412+
assert (ten.add(&two) == num::cast(12));
413+
assert (ten.sub(&two) == num::cast(8));
414+
assert (ten.mul(&two) == num::cast(20));
415+
assert (ten.div(&two) == num::cast(5));
416+
assert (ten.modulo(&two) == num::cast(0));
430417
}
431418
432419
#[test]

‎src/libcore/num/int-template/i16.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,78 @@
1010

1111
//! Operations and constants for `i16`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = i16;
1517
pub const bits: uint = ::u16::bits;
1618
}
19+
20+
pub impl i16: NumCast {
21+
/**
22+
* Cast `n` to a `i16`
23+
*/
24+
#[inline(always)]
25+
static pure fn from<N:NumCast>(n: N) -> i16 { n.to_i16() }
26+
27+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
28+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
29+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
30+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
31+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
32+
33+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
34+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self }
35+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
36+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
37+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
38+
39+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
40+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
41+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
42+
}
43+
44+
#[test]
45+
fn test_numcast() {
46+
assert (20u == 20i16.to_uint());
47+
assert (20u8 == 20i16.to_u8());
48+
assert (20u16 == 20i16.to_u16());
49+
assert (20u32 == 20i16.to_u32());
50+
assert (20u64 == 20i16.to_u64());
51+
assert (20i == 20i16.to_int());
52+
assert (20i8 == 20i16.to_i8());
53+
assert (20i16 == 20i16.to_i16());
54+
assert (20i32 == 20i16.to_i32());
55+
assert (20i64 == 20i16.to_i64());
56+
assert (20f == 20i16.to_float());
57+
assert (20f32 == 20i16.to_f32());
58+
assert (20f64 == 20i16.to_f64());
59+
60+
assert (20i16 == NumCast::from(20u));
61+
assert (20i16 == NumCast::from(20u8));
62+
assert (20i16 == NumCast::from(20u16));
63+
assert (20i16 == NumCast::from(20u32));
64+
assert (20i16 == NumCast::from(20u64));
65+
assert (20i16 == NumCast::from(20i));
66+
assert (20i16 == NumCast::from(20i8));
67+
assert (20i16 == NumCast::from(20i16));
68+
assert (20i16 == NumCast::from(20i32));
69+
assert (20i16 == NumCast::from(20i64));
70+
assert (20i16 == NumCast::from(20f));
71+
assert (20i16 == NumCast::from(20f32));
72+
assert (20i16 == NumCast::from(20f64));
73+
74+
assert (20i16 == num::cast(20u));
75+
assert (20i16 == num::cast(20u8));
76+
assert (20i16 == num::cast(20u16));
77+
assert (20i16 == num::cast(20u32));
78+
assert (20i16 == num::cast(20u64));
79+
assert (20i16 == num::cast(20i));
80+
assert (20i16 == num::cast(20i8));
81+
assert (20i16 == num::cast(20i16));
82+
assert (20i16 == num::cast(20i32));
83+
assert (20i16 == num::cast(20i64));
84+
assert (20i16 == num::cast(20f));
85+
assert (20i16 == num::cast(20f32));
86+
assert (20i16 == num::cast(20f64));
87+
}

‎src/libcore/num/int-template/i32.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,78 @@
1010

1111
//! Operations and constants for `i32`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = i32;
1517
pub const bits: uint = ::u32::bits;
1618
}
19+
20+
pub impl i32: NumCast {
21+
/**
22+
* Cast `n` to a `i32`
23+
*/
24+
#[inline(always)]
25+
static pure fn from<N:NumCast>(n: N) -> i32 { n.to_i32() }
26+
27+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
28+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
29+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
30+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
31+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
32+
33+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
34+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
35+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self }
36+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
37+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
38+
39+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
40+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
41+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
42+
}
43+
44+
#[test]
45+
fn test_numcast() {
46+
assert (20u == 20i32.to_uint());
47+
assert (20u8 == 20i32.to_u8());
48+
assert (20u16 == 20i32.to_u16());
49+
assert (20u32 == 20i32.to_u32());
50+
assert (20u64 == 20i32.to_u64());
51+
assert (20i == 20i32.to_int());
52+
assert (20i8 == 20i32.to_i8());
53+
assert (20i16 == 20i32.to_i16());
54+
assert (20i32 == 20i32.to_i32());
55+
assert (20i64 == 20i32.to_i64());
56+
assert (20f == 20i32.to_float());
57+
assert (20f32 == 20i32.to_f32());
58+
assert (20f64 == 20i32.to_f64());
59+
60+
assert (20i32 == NumCast::from(20u));
61+
assert (20i32 == NumCast::from(20u8));
62+
assert (20i32 == NumCast::from(20u16));
63+
assert (20i32 == NumCast::from(20u32));
64+
assert (20i32 == NumCast::from(20u64));
65+
assert (20i32 == NumCast::from(20i));
66+
assert (20i32 == NumCast::from(20i8));
67+
assert (20i32 == NumCast::from(20i16));
68+
assert (20i32 == NumCast::from(20i32));
69+
assert (20i32 == NumCast::from(20i64));
70+
assert (20i32 == NumCast::from(20f));
71+
assert (20i32 == NumCast::from(20f32));
72+
assert (20i32 == NumCast::from(20f64));
73+
74+
assert (20i32 == num::cast(20u));
75+
assert (20i32 == num::cast(20u8));
76+
assert (20i32 == num::cast(20u16));
77+
assert (20i32 == num::cast(20u32));
78+
assert (20i32 == num::cast(20u64));
79+
assert (20i32 == num::cast(20i));
80+
assert (20i32 == num::cast(20i8));
81+
assert (20i32 == num::cast(20i16));
82+
assert (20i32 == num::cast(20i32));
83+
assert (20i32 == num::cast(20i64));
84+
assert (20i32 == num::cast(20f));
85+
assert (20i32 == num::cast(20f32));
86+
assert (20i32 == num::cast(20f64));
87+
}

‎src/libcore/num/int-template/i64.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,78 @@
1010

1111
//! Operations and constants for `i64`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = i64;
1517
pub const bits: uint = ::u64::bits;
1618
}
19+
20+
pub impl i64: NumCast {
21+
/**
22+
* Cast `n` to a `i64`
23+
*/
24+
#[inline(always)]
25+
static pure fn from<N:NumCast>(n: N) -> i64 { n.to_i64() }
26+
27+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
28+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
29+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
30+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
31+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
32+
33+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
34+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
35+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
36+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self }
37+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
38+
39+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
40+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
41+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
42+
}
43+
44+
#[test]
45+
fn test_numcast() {
46+
assert (20u == 20i64.to_uint());
47+
assert (20u8 == 20i64.to_u8());
48+
assert (20u16 == 20i64.to_u16());
49+
assert (20u32 == 20i64.to_u32());
50+
assert (20u64 == 20i64.to_u64());
51+
assert (20i == 20i64.to_int());
52+
assert (20i8 == 20i64.to_i8());
53+
assert (20i16 == 20i64.to_i16());
54+
assert (20i32 == 20i64.to_i32());
55+
assert (20i64 == 20i64.to_i64());
56+
assert (20f == 20i64.to_float());
57+
assert (20f32 == 20i64.to_f32());
58+
assert (20f64 == 20i64.to_f64());
59+
60+
assert (20i64 == NumCast::from(20u));
61+
assert (20i64 == NumCast::from(20u8));
62+
assert (20i64 == NumCast::from(20u16));
63+
assert (20i64 == NumCast::from(20u32));
64+
assert (20i64 == NumCast::from(20u64));
65+
assert (20i64 == NumCast::from(20i));
66+
assert (20i64 == NumCast::from(20i8));
67+
assert (20i64 == NumCast::from(20i16));
68+
assert (20i64 == NumCast::from(20i32));
69+
assert (20i64 == NumCast::from(20i64));
70+
assert (20i64 == NumCast::from(20f));
71+
assert (20i64 == NumCast::from(20f32));
72+
assert (20i64 == NumCast::from(20f64));
73+
74+
assert (20i64 == num::cast(20u));
75+
assert (20i64 == num::cast(20u8));
76+
assert (20i64 == num::cast(20u16));
77+
assert (20i64 == num::cast(20u32));
78+
assert (20i64 == num::cast(20u64));
79+
assert (20i64 == num::cast(20i));
80+
assert (20i64 == num::cast(20i8));
81+
assert (20i64 == num::cast(20i16));
82+
assert (20i64 == num::cast(20i32));
83+
assert (20i64 == num::cast(20i64));
84+
assert (20i64 == num::cast(20f));
85+
assert (20i64 == num::cast(20f32));
86+
assert (20i64 == num::cast(20f64));
87+
}

‎src/libcore/num/int-template/i8.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,78 @@
1010

1111
//! Operations and constants for `i8`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = i8;
1517
pub const bits: uint = ::u8::bits;
1618
}
19+
20+
pub impl i8: NumCast {
21+
/**
22+
* Cast `n` to a `i8`
23+
*/
24+
#[inline(always)]
25+
static pure fn from<N:NumCast>(n: N) -> i8 { n.to_i8() }
26+
27+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
28+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
29+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
30+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
31+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
32+
33+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self }
34+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
35+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
36+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
37+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
38+
39+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
40+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
41+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
42+
}
43+
44+
#[test]
45+
fn test_numcast() {
46+
assert (20u == 20i8.to_uint());
47+
assert (20u8 == 20i8.to_u8());
48+
assert (20u16 == 20i8.to_u16());
49+
assert (20u32 == 20i8.to_u32());
50+
assert (20u64 == 20i8.to_u64());
51+
assert (20i == 20i8.to_int());
52+
assert (20i8 == 20i8.to_i8());
53+
assert (20i16 == 20i8.to_i16());
54+
assert (20i32 == 20i8.to_i32());
55+
assert (20i64 == 20i8.to_i64());
56+
assert (20f == 20i8.to_float());
57+
assert (20f32 == 20i8.to_f32());
58+
assert (20f64 == 20i8.to_f64());
59+
60+
assert (20i8 == NumCast::from(20u));
61+
assert (20i8 == NumCast::from(20u8));
62+
assert (20i8 == NumCast::from(20u16));
63+
assert (20i8 == NumCast::from(20u32));
64+
assert (20i8 == NumCast::from(20u64));
65+
assert (20i8 == NumCast::from(20i));
66+
assert (20i8 == NumCast::from(20i8));
67+
assert (20i8 == NumCast::from(20i16));
68+
assert (20i8 == NumCast::from(20i32));
69+
assert (20i8 == NumCast::from(20i64));
70+
assert (20i8 == NumCast::from(20f));
71+
assert (20i8 == NumCast::from(20f32));
72+
assert (20i8 == NumCast::from(20f64));
73+
74+
assert (20i8 == num::cast(20u));
75+
assert (20i8 == num::cast(20u8));
76+
assert (20i8 == num::cast(20u16));
77+
assert (20i8 == num::cast(20u32));
78+
assert (20i8 == num::cast(20u64));
79+
assert (20i8 == num::cast(20i));
80+
assert (20i8 == num::cast(20i8));
81+
assert (20i8 == num::cast(20i16));
82+
assert (20i8 == num::cast(20i32));
83+
assert (20i8 == num::cast(20i64));
84+
assert (20i8 == num::cast(20f));
85+
assert (20i8 == num::cast(20f32));
86+
assert (20i8 == num::cast(20f64));
87+
}

‎src/libcore/num/int-template/int.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! Operations and constants for `int`
1212
13+
use num::NumCast;
14+
1315
pub use self::inst::pow;
1416

1517
mod inst {
@@ -55,3 +57,72 @@ mod inst {
5557
assert (::int::min_value + ::int::max_value + 1 == 0);
5658
}
5759
}
60+
61+
pub impl int: NumCast {
62+
/**
63+
* Cast `n` to a `int`
64+
*/
65+
#[inline(always)]
66+
static pure fn from<N:NumCast>(n: N) -> int { n.to_int() }
67+
68+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
69+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
70+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
71+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
72+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
73+
74+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
75+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
76+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
77+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
78+
#[inline(always)] pure fn to_int(&self) -> int { *self }
79+
80+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
81+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
82+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
83+
}
84+
85+
#[test]
86+
fn test_numcast() {
87+
assert (20u == 20i.to_uint());
88+
assert (20u8 == 20i.to_u8());
89+
assert (20u16 == 20i.to_u16());
90+
assert (20u32 == 20i.to_u32());
91+
assert (20u64 == 20i.to_u64());
92+
assert (20i == 20i.to_int());
93+
assert (20i8 == 20i.to_i8());
94+
assert (20i16 == 20i.to_i16());
95+
assert (20i32 == 20i.to_i32());
96+
assert (20i64 == 20i.to_i64());
97+
assert (20f == 20i.to_float());
98+
assert (20f32 == 20i.to_f32());
99+
assert (20f64 == 20i.to_f64());
100+
101+
assert (20i == NumCast::from(20u));
102+
assert (20i == NumCast::from(20u8));
103+
assert (20i == NumCast::from(20u16));
104+
assert (20i == NumCast::from(20u32));
105+
assert (20i == NumCast::from(20u64));
106+
assert (20i == NumCast::from(20i));
107+
assert (20i == NumCast::from(20i8));
108+
assert (20i == NumCast::from(20i16));
109+
assert (20i == NumCast::from(20i32));
110+
assert (20i == NumCast::from(20i64));
111+
assert (20i == NumCast::from(20f));
112+
assert (20i == NumCast::from(20f32));
113+
assert (20i == NumCast::from(20f64));
114+
115+
assert (20i == num::cast(20u));
116+
assert (20i == num::cast(20u8));
117+
assert (20i == num::cast(20u16));
118+
assert (20i == num::cast(20u32));
119+
assert (20i == num::cast(20u64));
120+
assert (20i == num::cast(20i));
121+
assert (20i == num::cast(20i8));
122+
assert (20i == num::cast(20i16));
123+
assert (20i == num::cast(20i32));
124+
assert (20i == num::cast(20i64));
125+
assert (20i == num::cast(20f));
126+
assert (20i == num::cast(20f32));
127+
assert (20i == num::cast(20f64));
128+
}

‎src/libcore/num/num.rs

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ pub trait Num {
2424
pure fn div(&self, other: &Self) -> Self;
2525
pure fn modulo(&self, other: &Self) -> Self;
2626
pure fn neg(&self) -> Self;
27-
28-
pure fn to_int(&self) -> int;
29-
static pure fn from_int(n: int) -> Self;
3027
}
3128

3229
pub trait IntConvertible {
@@ -50,6 +47,44 @@ pub trait Round {
5047
pure fn fract(&self) -> Self;
5148
}
5249

50+
/**
51+
* Cast a number the the enclosing type
52+
*
53+
* # Example
54+
*
55+
* ~~~
56+
* let twenty: f32 = num::cast(0x14);
57+
* assert twenty == 20f32;
58+
* ~~~
59+
*/
60+
#[inline(always)]
61+
pub pure fn cast<T:NumCast, U:NumCast>(n: T) -> U {
62+
NumCast::from(n)
63+
}
64+
65+
/**
66+
* An interface for generic numeric type casts
67+
*/
68+
pub trait NumCast {
69+
static pure fn from<T:NumCast>(n: T) -> Self;
70+
71+
pure fn to_u8(&self) -> u8;
72+
pure fn to_u16(&self) -> u16;
73+
pure fn to_u32(&self) -> u32;
74+
pure fn to_u64(&self) -> u64;
75+
pure fn to_uint(&self) -> uint;
76+
77+
pure fn to_i8(&self) -> i8;
78+
pure fn to_i16(&self) -> i16;
79+
pure fn to_i32(&self) -> i32;
80+
pure fn to_i64(&self) -> i64;
81+
pure fn to_int(&self) -> int;
82+
83+
pure fn to_f32(&self) -> f32;
84+
pure fn to_f64(&self) -> f64;
85+
pure fn to_float(&self) -> float;
86+
}
87+
5388
pub enum RoundMode {
5489
RoundDown,
5590
RoundUp,
@@ -135,16 +170,16 @@ pub pure fn is_neg_zero<T: Num One Zero Eq>(num: &T) -> bool {
135170
* - If code written to use this function doesn't care about it, it's
136171
* probably assuming that `x^0` always equals `1`.
137172
*/
138-
pub pure fn pow_with_uint<T: Num One Zero Copy>(radix: uint,
139-
pow: uint) -> T {
173+
pub pure fn pow_with_uint<T: Num NumCast One Zero Copy>(radix: uint,
174+
pow: uint) -> T {
140175
let _0: T = Zero::zero();
141176
let _1: T = One::one();
142177

143178
if pow == 0u { return _1; }
144179
if radix == 0u { return _0; }
145180
let mut my_pow = pow;
146181
let mut total = _1;
147-
let mut multiplier = Num::from_int(radix as int);
182+
let mut multiplier = cast(radix as int);
148183
while (my_pow > 0u) {
149184
if my_pow % 2u == 1u {
150185
total *= multiplier;
@@ -217,7 +252,7 @@ pub enum SignFormat {
217252
* those special values, and `special` is `false`, because then the
218253
* algorithm just does normal calculations on them.
219254
*/
220-
pub pure fn to_str_bytes_common<T: Num Zero One Eq Ord Round Copy>(
255+
pub pure fn to_str_bytes_common<T: Num NumCast Zero One Eq Ord Round Copy>(
221256
num: &T, radix: uint, special: bool, negative_zero: bool,
222257
sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) {
223258
if radix as int < 2 {
@@ -250,7 +285,7 @@ pub pure fn to_str_bytes_common<T: Num Zero One Eq Ord Round Copy>(
250285
let neg = *num < _0 || (negative_zero && *num == _0
251286
&& special && is_neg_zero(num));
252287
let mut buf: ~[u8] = ~[];
253-
let radix_gen = Num::from_int::<T>(radix as int);
288+
let radix_gen: T = cast(radix as int);
254289

255290
let mut deccum;
256291

@@ -439,7 +474,7 @@ pub pure fn to_str_bytes_common<T: Num Zero One Eq Ord Round Copy>(
439474
* `to_str_bytes_common()`, for details see there.
440475
*/
441476
#[inline(always)]
442-
pub pure fn to_str_common<T: Num Zero One Eq Ord Round Copy>(
477+
pub pure fn to_str_common<T: Num NumCast Zero One Eq Ord Round Copy>(
443478
num: &T, radix: uint, special: bool, negative_zero: bool,
444479
sign: SignFormat, digits: SignificantDigits) -> (~str, bool) {
445480
let (bytes, special) = to_str_bytes_common(num, radix, special,
@@ -494,7 +529,7 @@ priv const DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
494529
* - Could accept option to allow ignoring underscores, allowing for numbers
495530
* formated like `FF_AE_FF_FF`.
496531
*/
497-
pub pure fn from_str_bytes_common<T: Num Zero One Ord Copy>(
532+
pub pure fn from_str_bytes_common<T: Num NumCast Zero One Ord Copy>(
498533
buf: &[u8], radix: uint, negative: bool, fractional: bool,
499534
special: bool, exponent: ExponentFormat, empty_zero: bool
500535
) -> Option<T> {
@@ -519,7 +554,7 @@ pub pure fn from_str_bytes_common<T: Num Zero One Ord Copy>(
519554

520555
let _0: T = Zero::zero();
521556
let _1: T = One::one();
522-
let radix_gen: T = Num::from_int(radix as int);
557+
let radix_gen: T = cast(radix as int);
523558

524559
let len = buf.len();
525560

@@ -570,9 +605,9 @@ pub pure fn from_str_bytes_common<T: Num Zero One Ord Copy>(
570605

571606
// add/subtract current digit depending on sign
572607
if accum_positive {
573-
accum += Num::from_int(digit as int);
608+
accum += cast(digit as int);
574609
} else {
575-
accum -= Num::from_int(digit as int);
610+
accum -= cast(digit as int);
576611
}
577612

578613
// Detect overflow by comparing to last value
@@ -609,11 +644,13 @@ pub pure fn from_str_bytes_common<T: Num Zero One Ord Copy>(
609644
// Decrease power one order of magnitude
610645
power /= radix_gen;
611646

647+
let digit_t: T = cast(digit);
648+
612649
// add/subtract current digit depending on sign
613650
if accum_positive {
614-
accum += Num::from_int::<T>(digit as int) * power;
651+
accum += digit_t * power;
615652
} else {
616-
accum -= Num::from_int::<T>(digit as int) * power;
653+
accum -= digit_t * power;
617654
}
618655

619656
// Detect overflow by comparing to last value
@@ -679,7 +716,7 @@ pub pure fn from_str_bytes_common<T: Num Zero One Ord Copy>(
679716
* `from_str_bytes_common()`, for details see there.
680717
*/
681718
#[inline(always)]
682-
pub pure fn from_str_common<T: Num Zero One Ord Copy>(
719+
pub pure fn from_str_common<T: Num NumCast Zero One Ord Copy>(
683720
buf: &str, radix: uint, negative: bool, fractional: bool,
684721
special: bool, exponent: ExponentFormat, empty_zero: bool
685722
) -> Option<T> {

‎src/libcore/num/uint-template.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,6 @@ impl T: num::Num {
146146
pure fn modulo(&self, other: &T) -> T { return *self % *other; }
147147
#[inline(always)]
148148
pure fn neg(&self) -> T { return -*self; }
149-
150-
#[inline(always)]
151-
pure fn to_int(&self) -> int { return *self as int; }
152-
#[inline(always)]
153-
static pure fn from_int(n: int) -> T { return n as T; }
154149
}
155150
156151
impl T: num::Zero {
@@ -409,6 +404,18 @@ pub fn test_ranges() {
409404
}
410405
}
411406

407+
#[test]
408+
pub fn test_num() {
409+
let ten: T = num::cast(10);
410+
let two: T = num::cast(2);
411+
412+
assert (ten.add(&two) == num::cast(12));
413+
assert (ten.sub(&two) == num::cast(8));
414+
assert (ten.mul(&two) == num::cast(20));
415+
assert (ten.div(&two) == num::cast(5));
416+
assert (ten.modulo(&two) == num::cast(0));
417+
}
418+
412419
#[test]
413420
#[should_fail]
414421
#[ignore(cfg(windows))]

‎src/libcore/num/uint-template/u16.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,80 @@
1010

1111
//! Operations and constants for `u16`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = u16;
1517
#[allow(non_camel_case_types)]
1618
pub type T_SIGNED = i16;
1719
pub const bits: uint = 16;
1820
}
21+
22+
pub impl u16: NumCast {
23+
/**
24+
* Cast `n` to a `u16`
25+
*/
26+
#[inline(always)]
27+
static pure fn from<N:NumCast>(n: N) -> u16 { n.to_u16() }
28+
29+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
30+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self }
31+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
32+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
33+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
34+
35+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
36+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
37+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
38+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
39+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
40+
41+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
42+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
43+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
44+
}
45+
46+
#[test]
47+
fn test_numcast() {
48+
assert (20u == 20u16.to_uint());
49+
assert (20u8 == 20u16.to_u8());
50+
assert (20u16 == 20u16.to_u16());
51+
assert (20u32 == 20u16.to_u32());
52+
assert (20u64 == 20u16.to_u64());
53+
assert (20i == 20u16.to_int());
54+
assert (20i8 == 20u16.to_i8());
55+
assert (20i16 == 20u16.to_i16());
56+
assert (20i32 == 20u16.to_i32());
57+
assert (20i64 == 20u16.to_i64());
58+
assert (20f == 20u16.to_float());
59+
assert (20f32 == 20u16.to_f32());
60+
assert (20f64 == 20u16.to_f64());
61+
62+
assert (20u16 == NumCast::from(20u));
63+
assert (20u16 == NumCast::from(20u8));
64+
assert (20u16 == NumCast::from(20u16));
65+
assert (20u16 == NumCast::from(20u32));
66+
assert (20u16 == NumCast::from(20u64));
67+
assert (20u16 == NumCast::from(20i));
68+
assert (20u16 == NumCast::from(20i8));
69+
assert (20u16 == NumCast::from(20i16));
70+
assert (20u16 == NumCast::from(20i32));
71+
assert (20u16 == NumCast::from(20i64));
72+
assert (20u16 == NumCast::from(20f));
73+
assert (20u16 == NumCast::from(20f32));
74+
assert (20u16 == NumCast::from(20f64));
75+
76+
assert (20u16 == num::cast(20u));
77+
assert (20u16 == num::cast(20u8));
78+
assert (20u16 == num::cast(20u16));
79+
assert (20u16 == num::cast(20u32));
80+
assert (20u16 == num::cast(20u64));
81+
assert (20u16 == num::cast(20i));
82+
assert (20u16 == num::cast(20i8));
83+
assert (20u16 == num::cast(20i16));
84+
assert (20u16 == num::cast(20i32));
85+
assert (20u16 == num::cast(20i64));
86+
assert (20u16 == num::cast(20f));
87+
assert (20u16 == num::cast(20f32));
88+
assert (20u16 == num::cast(20f64));
89+
}

‎src/libcore/num/uint-template/u32.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,80 @@
1010

1111
//! Operations and constants for `u32`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = u32;
1517
#[allow(non_camel_case_types)]
1618
pub type T_SIGNED = i32;
1719
pub const bits: uint = 32;
20+
}
21+
22+
pub impl u32: NumCast {
23+
/**
24+
* Cast `n` to a `u32`
25+
*/
26+
#[inline(always)]
27+
static pure fn from<N:NumCast>(n: N) -> u32 { n.to_u32() }
28+
29+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
30+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
31+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self }
32+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
33+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
34+
35+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
36+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
37+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
38+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
39+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
40+
41+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
42+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
43+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
44+
}
45+
46+
#[test]
47+
fn test_numcast() {
48+
assert (20u == 20u64.to_uint());
49+
assert (20u8 == 20u64.to_u8());
50+
assert (20u16 == 20u64.to_u16());
51+
assert (20u32 == 20u64.to_u32());
52+
assert (20u64 == 20u64.to_u64());
53+
assert (20i == 20u64.to_int());
54+
assert (20i8 == 20u64.to_i8());
55+
assert (20i16 == 20u64.to_i16());
56+
assert (20i32 == 20u64.to_i32());
57+
assert (20i64 == 20u64.to_i64());
58+
assert (20f == 20u64.to_float());
59+
assert (20f32 == 20u64.to_f32());
60+
assert (20f64 == 20u64.to_f64());
61+
62+
assert (20u64 == NumCast::from(20u));
63+
assert (20u64 == NumCast::from(20u8));
64+
assert (20u64 == NumCast::from(20u16));
65+
assert (20u64 == NumCast::from(20u32));
66+
assert (20u64 == NumCast::from(20u64));
67+
assert (20u64 == NumCast::from(20i));
68+
assert (20u64 == NumCast::from(20i8));
69+
assert (20u64 == NumCast::from(20i16));
70+
assert (20u64 == NumCast::from(20i32));
71+
assert (20u64 == NumCast::from(20i64));
72+
assert (20u64 == NumCast::from(20f));
73+
assert (20u64 == NumCast::from(20f32));
74+
assert (20u64 == NumCast::from(20f64));
75+
76+
assert (20u64 == num::cast(20u));
77+
assert (20u64 == num::cast(20u8));
78+
assert (20u64 == num::cast(20u16));
79+
assert (20u64 == num::cast(20u32));
80+
assert (20u64 == num::cast(20u64));
81+
assert (20u64 == num::cast(20i));
82+
assert (20u64 == num::cast(20i8));
83+
assert (20u64 == num::cast(20i16));
84+
assert (20u64 == num::cast(20i32));
85+
assert (20u64 == num::cast(20i64));
86+
assert (20u64 == num::cast(20f));
87+
assert (20u64 == num::cast(20f32));
88+
assert (20u64 == num::cast(20f64));
1889
}

‎src/libcore/num/uint-template/u64.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,80 @@
1010

1111
//! Operations and constants for `u64`
1212
13+
use num::NumCast;
14+
1315
mod inst {
1416
pub type T = u64;
1517
#[allow(non_camel_case_types)]
1618
pub type T_SIGNED = i64;
1719
pub const bits: uint = 64;
20+
}
21+
22+
pub impl u64: num::NumCast {
23+
/**
24+
* Cast `n` to a `u64`
25+
*/
26+
#[inline(always)]
27+
static pure fn from<N:NumCast>(n: N) -> u64 { n.to_u64() }
28+
29+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
30+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
31+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
32+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self }
33+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
34+
35+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
36+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
37+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
38+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
39+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
40+
41+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
42+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
43+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
44+
}
45+
46+
#[test]
47+
fn test_numcast() {
48+
assert (20u == 20u64.to_uint());
49+
assert (20u8 == 20u64.to_u8());
50+
assert (20u16 == 20u64.to_u16());
51+
assert (20u32 == 20u64.to_u32());
52+
assert (20u64 == 20u64.to_u64());
53+
assert (20i == 20u64.to_int());
54+
assert (20i8 == 20u64.to_i8());
55+
assert (20i16 == 20u64.to_i16());
56+
assert (20i32 == 20u64.to_i32());
57+
assert (20i64 == 20u64.to_i64());
58+
assert (20f == 20u64.to_float());
59+
assert (20f32 == 20u64.to_f32());
60+
assert (20f64 == 20u64.to_f64());
61+
62+
assert (20u64 == NumCast::from(20u));
63+
assert (20u64 == NumCast::from(20u8));
64+
assert (20u64 == NumCast::from(20u16));
65+
assert (20u64 == NumCast::from(20u32));
66+
assert (20u64 == NumCast::from(20u64));
67+
assert (20u64 == NumCast::from(20i));
68+
assert (20u64 == NumCast::from(20i8));
69+
assert (20u64 == NumCast::from(20i16));
70+
assert (20u64 == NumCast::from(20i32));
71+
assert (20u64 == NumCast::from(20i64));
72+
assert (20u64 == NumCast::from(20f));
73+
assert (20u64 == NumCast::from(20f32));
74+
assert (20u64 == NumCast::from(20f64));
75+
76+
assert (20u64 == num::cast(20u));
77+
assert (20u64 == num::cast(20u8));
78+
assert (20u64 == num::cast(20u16));
79+
assert (20u64 == num::cast(20u32));
80+
assert (20u64 == num::cast(20u64));
81+
assert (20u64 == num::cast(20i));
82+
assert (20u64 == num::cast(20i8));
83+
assert (20u64 == num::cast(20i16));
84+
assert (20u64 == num::cast(20i32));
85+
assert (20u64 == num::cast(20i64));
86+
assert (20u64 == num::cast(20f));
87+
assert (20u64 == num::cast(20f32));
88+
assert (20u64 == num::cast(20f64));
1889
}

‎src/libcore/num/uint-template/u8.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
1313
pub use self::inst::is_ascii;
1414

15+
use num::NumCast;
16+
1517
mod inst {
1618
pub type T = u8;
1719
#[allow(non_camel_case_types)]
@@ -23,3 +25,72 @@ mod inst {
2325

2426
pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; }
2527
}
28+
29+
pub impl u8: NumCast {
30+
/**
31+
* Cast `n` to a `u8`
32+
*/
33+
#[inline(always)]
34+
static pure fn from<N:NumCast>(n: N) -> u8 { n.to_u8() }
35+
36+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self }
37+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
38+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
39+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
40+
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
41+
42+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
43+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
44+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
45+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
46+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
47+
48+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
49+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
50+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
51+
}
52+
53+
#[test]
54+
fn test_numcast() {
55+
assert (20u == 20u8.to_uint());
56+
assert (20u8 == 20u8.to_u8());
57+
assert (20u16 == 20u8.to_u16());
58+
assert (20u32 == 20u8.to_u32());
59+
assert (20u64 == 20u8.to_u64());
60+
assert (20i == 20u8.to_int());
61+
assert (20i8 == 20u8.to_i8());
62+
assert (20i16 == 20u8.to_i16());
63+
assert (20i32 == 20u8.to_i32());
64+
assert (20i64 == 20u8.to_i64());
65+
assert (20f == 20u8.to_float());
66+
assert (20f32 == 20u8.to_f32());
67+
assert (20f64 == 20u8.to_f64());
68+
69+
assert (20u8 == NumCast::from(20u));
70+
assert (20u8 == NumCast::from(20u8));
71+
assert (20u8 == NumCast::from(20u16));
72+
assert (20u8 == NumCast::from(20u32));
73+
assert (20u8 == NumCast::from(20u64));
74+
assert (20u8 == NumCast::from(20i));
75+
assert (20u8 == NumCast::from(20i8));
76+
assert (20u8 == NumCast::from(20i16));
77+
assert (20u8 == NumCast::from(20i32));
78+
assert (20u8 == NumCast::from(20i64));
79+
assert (20u8 == NumCast::from(20f));
80+
assert (20u8 == NumCast::from(20f32));
81+
assert (20u8 == NumCast::from(20f64));
82+
83+
assert (20u8 == num::cast(20u));
84+
assert (20u8 == num::cast(20u8));
85+
assert (20u8 == num::cast(20u16));
86+
assert (20u8 == num::cast(20u32));
87+
assert (20u8 == num::cast(20u64));
88+
assert (20u8 == num::cast(20i));
89+
assert (20u8 == num::cast(20i8));
90+
assert (20u8 == num::cast(20i16));
91+
assert (20u8 == num::cast(20i32));
92+
assert (20u8 == num::cast(20i64));
93+
assert (20u8 == num::cast(20f));
94+
assert (20u8 == num::cast(20f32));
95+
assert (20u8 == num::cast(20f64));
96+
}

‎src/libcore/num/uint-template/uint.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! Operations and constants for `uint`
1212
13+
use num::NumCast;
14+
1315
pub use self::inst::{
1416
div_ceil, div_round, div_floor, iterate,
1517
next_power_of_two
@@ -206,3 +208,72 @@ pub mod inst {
206208
assert (accum == 10);
207209
}
208210
}
211+
212+
pub impl uint: NumCast {
213+
/**
214+
* Cast `n` to a `uint`
215+
*/
216+
#[inline(always)]
217+
static pure fn from<N:NumCast>(n: N) -> uint { n.to_uint() }
218+
219+
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
220+
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
221+
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
222+
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
223+
#[inline(always)] pure fn to_uint(&self) -> uint { *self }
224+
225+
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
226+
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
227+
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
228+
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
229+
#[inline(always)] pure fn to_int(&self) -> int { *self as int }
230+
231+
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
232+
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
233+
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
234+
}
235+
236+
#[test]
237+
fn test_numcast() {
238+
assert (20u == 20u.to_uint());
239+
assert (20u8 == 20u.to_u8());
240+
assert (20u16 == 20u.to_u16());
241+
assert (20u32 == 20u.to_u32());
242+
assert (20u64 == 20u.to_u64());
243+
assert (20i == 20u.to_int());
244+
assert (20i8 == 20u.to_i8());
245+
assert (20i16 == 20u.to_i16());
246+
assert (20i32 == 20u.to_i32());
247+
assert (20i64 == 20u.to_i64());
248+
assert (20f == 20u.to_float());
249+
assert (20f32 == 20u.to_f32());
250+
assert (20f64 == 20u.to_f64());
251+
252+
assert (20u == NumCast::from(20u));
253+
assert (20u == NumCast::from(20u8));
254+
assert (20u == NumCast::from(20u16));
255+
assert (20u == NumCast::from(20u32));
256+
assert (20u == NumCast::from(20u64));
257+
assert (20u == NumCast::from(20i));
258+
assert (20u == NumCast::from(20i8));
259+
assert (20u == NumCast::from(20i16));
260+
assert (20u == NumCast::from(20i32));
261+
assert (20u == NumCast::from(20i64));
262+
assert (20u == NumCast::from(20f));
263+
assert (20u == NumCast::from(20f32));
264+
assert (20u == NumCast::from(20f64));
265+
266+
assert (20u == num::cast(20u));
267+
assert (20u == num::cast(20u8));
268+
assert (20u == num::cast(20u16));
269+
assert (20u == num::cast(20u32));
270+
assert (20u == num::cast(20u64));
271+
assert (20u == num::cast(20i));
272+
assert (20u == num::cast(20i8));
273+
assert (20u == num::cast(20i16));
274+
assert (20u == num::cast(20i32));
275+
assert (20u == num::cast(20i64));
276+
assert (20u == num::cast(20f));
277+
assert (20u == num::cast(20f32));
278+
assert (20u == num::cast(20f64));
279+
}

‎src/libcore/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub use container::{Container, Mutable, Map, Set};
2929
pub use hash::Hash;
3030
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
3131
pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
32-
pub use num::Num;
32+
pub use num::{Num, NumCast};
3333
pub use path::GenericPath;
3434
pub use path::Path;
3535
pub use path::PosixPath;

‎src/test/run-pass/trait-inheritance-num.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
// except according to those terms.
1212

1313
use cmp::{Eq, Ord};
14-
use num::Num::from_int;
14+
use num::NumCast::from;
1515

1616
extern mod std;
1717
use std::cmp::FuzzyEq;
1818

19-
pub trait NumExt: Num Eq Ord {}
19+
pub trait NumExt: Num NumCast Eq Ord {}
2020

2121
pub trait FloatExt: NumExt FuzzyEq<Self> {}
2222

23-
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > from_int(1) }
24-
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > from_int(1) }
23+
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > from(1) }
24+
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > from(1) }
2525

2626
pub fn main() {}

‎src/test/run-pass/trait-inheritance-num0.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212

1313
// Extending Num and using inherited static methods
1414

15-
use Num::from_int;
15+
use num::NumCast::from;
1616

1717
trait Num {
1818
static fn from_int(i: int) -> Self;
1919
fn gt(&self, other: &Self) -> bool;
2020
}
2121

22-
pub trait NumExt: Num { }
22+
pub trait NumExt: Num NumCast { }
2323

2424
fn greater_than_one<T:NumExt>(n: &T) -> bool {
25-
n.gt(&from_int(1))
25+
n.gt(&from(1))
2626
}
2727

2828
pub fn main() {}

‎src/test/run-pass/trait-inheritance-num1.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
// Using the real Num from core
1212

1313
use cmp::Ord;
14-
use num::Num::from_int;
14+
use num::NumCast::from;
1515

16-
pub trait NumExt: Num Ord { }
16+
pub trait NumExt: Num NumCast Ord { }
1717

1818
fn greater_than_one<T:NumExt>(n: &T) -> bool {
19-
*n > from_int(1)
19+
*n > from(1)
2020
}
2121

2222
pub fn main() {}

‎src/test/run-pass/trait-inheritance-num2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// A more complex example of numeric extensions
1414

1515
use cmp::{Eq, Ord};
16-
use num::Num::from_int;
16+
use num::NumCast::from;
1717

1818
extern mod std;
1919
use std::cmp::FuzzyEq;
@@ -38,7 +38,7 @@ pub impl f64: TypeExt {}
3838
pub impl float: TypeExt {}
3939

4040

41-
pub trait NumExt: TypeExt Eq Ord Num {}
41+
pub trait NumExt: TypeExt Eq Ord Num NumCast {}
4242

4343
pub impl u8: NumExt {}
4444
pub impl u16: NumExt {}

‎src/test/run-pass/trait-inheritance-num3.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
// except according to those terms.
1010

1111
use cmp::{Eq, Ord};
12-
use num::Num::from_int;
12+
use num::NumCast::from;
1313

14-
pub trait NumExt: Eq Ord Num {}
14+
pub trait NumExt: Eq Ord Num NumCast {}
1515

1616
pub impl f32: NumExt {}
1717

18-
fn num_eq_one<T:NumExt>(n: T) { io::println(fmt!("%?", n == from_int(1))) }
18+
fn num_eq_one<T:NumExt>(n: T) { io::println(fmt!("%?", n == from(1))) }
1919

2020
pub fn main() {
2121
num_eq_one(1f32); // you need to actually use the function to trigger the ICE

‎src/test/run-pass/trait-inheritance-num5.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
// except according to those terms.
1010

1111
use cmp::{Eq, Ord};
12-
use num::Num::from_int;
12+
use num::NumCast::from;
1313

14-
pub trait NumExt: Eq Num {}
14+
pub trait NumExt: Eq Num NumCast {}
1515

1616
pub impl f32: NumExt {}
1717
pub impl int: NumExt {}
1818

1919
fn num_eq_one<T:NumExt>() -> T {
20-
from_int(1)
20+
from(1)
2121
}
2222

2323
pub fn main() {

0 commit comments

Comments
 (0)
Please sign in to comment.