]> git.lizzy.rs Git - rust.git/blob - src/libstd/num/mod.rs
auto merge of #13748 : hjr3/rust/guide-container-update, r=alexcrichton
[rust.git] / src / libstd / num / mod.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Numeric traits and functions for generic mathematics
12 //!
13 //! These are implemented for the primitive numeric types in `std::{u8, u16,
14 //! u32, u64, uint, i8, i16, i32, i64, int, f32, f64, float}`.
15
16 #![allow(missing_doc)]
17
18 use clone::Clone;
19 use cmp::{Eq, Ord};
20 use kinds::Copy;
21 use mem::size_of;
22 use ops::{Add, Sub, Mul, Div, Rem, Neg};
23 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
24 use option::{Option, Some, None};
25 use fmt::{Show, Binary, Octal, LowerHex, UpperHex};
26
27 pub mod strconv;
28
29 /// The base trait for numeric types
30 pub trait Num: Eq + Zero + One
31              + Neg<Self>
32              + Add<Self,Self>
33              + Sub<Self,Self>
34              + Mul<Self,Self>
35              + Div<Self,Self>
36              + Rem<Self,Self> {}
37
38 /// Simultaneous division and remainder
39 #[inline]
40 pub fn div_rem<T: Div<T, T> + Rem<T, T>>(x: T, y: T) -> (T, T) {
41     (x / y, x % y)
42 }
43
44 /// Defines an additive identity element for `Self`.
45 ///
46 /// # Deriving
47 ///
48 /// This trait can be automatically be derived using `#[deriving(Zero)]`
49 /// attribute. If you choose to use this, make sure that the laws outlined in
50 /// the documentation for `Zero::zero` still hold.
51 pub trait Zero: Add<Self, Self> {
52     /// Returns the additive identity element of `Self`, `0`.
53     ///
54     /// # Laws
55     ///
56     /// ~~~notrust
57     /// a + 0 = a       ∀ a ∈ Self
58     /// 0 + a = a       ∀ a ∈ Self
59     /// ~~~
60     ///
61     /// # Purity
62     ///
63     /// This function should return the same result at all times regardless of
64     /// external mutable state, for example values stored in TLS or in
65     /// `static mut`s.
66     // FIXME (#5527): This should be an associated constant
67     fn zero() -> Self;
68
69     /// Returns `true` if `self` is equal to the additive identity.
70     fn is_zero(&self) -> bool;
71 }
72
73 /// Returns the additive identity, `0`.
74 #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
75
76 /// Defines a multiplicative identity element for `Self`.
77 pub trait One: Mul<Self, Self> {
78     /// Returns the multiplicative identity element of `Self`, `1`.
79     ///
80     /// # Laws
81     ///
82     /// ~~~notrust
83     /// a * 1 = a       ∀ a ∈ Self
84     /// 1 * a = a       ∀ a ∈ Self
85     /// ~~~
86     ///
87     /// # Purity
88     ///
89     /// This function should return the same result at all times regardless of
90     /// external mutable state, for example values stored in TLS or in
91     /// `static mut`s.
92     // FIXME (#5527): This should be an associated constant
93     fn one() -> Self;
94 }
95
96 /// Returns the multiplicative identity, `1`.
97 #[inline(always)] pub fn one<T: One>() -> T { One::one() }
98
99 /// Useful functions for signed numbers (i.e. numbers that can be negative).
100 pub trait Signed: Num + Neg<Self> {
101     /// Computes the absolute value.
102     ///
103     /// For float, f32, and f64, `NaN` will be returned if the number is `NaN`.
104     fn abs(&self) -> Self;
105
106     /// The positive difference of two numbers.
107     ///
108     /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
109     /// between `self` and `other` is returned.
110     fn abs_sub(&self, other: &Self) -> Self;
111
112     /// Returns the sign of the number.
113     ///
114     /// For `float`, `f32`, `f64`:
115     ///   * `1.0` if the number is positive, `+0.0` or `INFINITY`
116     ///   * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
117     ///   * `NaN` if the number is `NaN`
118     ///
119     /// For `int`:
120     ///   * `0` if the number is zero
121     ///   * `1` if the number is positive
122     ///   * `-1` if the number is negative
123     fn signum(&self) -> Self;
124
125     /// Returns true if the number is positive and false if the number is zero or negative.
126     fn is_positive(&self) -> bool;
127
128     /// Returns true if the number is negative and false if the number is zero or positive.
129     fn is_negative(&self) -> bool;
130 }
131
132 /// Computes the absolute value.
133 ///
134 /// For float, f32, and f64, `NaN` will be returned if the number is `NaN`
135 #[inline(always)]
136 pub fn abs<T: Signed>(value: T) -> T {
137     value.abs()
138 }
139
140 /// The positive difference of two numbers.
141 ///
142 /// Returns `zero` if the number is less than or equal to `other`,
143 /// otherwise the difference between `self` and `other` is returned.
144 #[inline(always)]
145 pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
146     x.abs_sub(&y)
147 }
148
149 /// Returns the sign of the number.
150 ///
151 /// For float, f32, f64:
152 /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
153 /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
154 /// - `NAN` if the number is `NAN`
155 ///
156 /// For int:
157 /// - `0` if the number is zero
158 /// - `1` if the number is positive
159 /// - `-1` if the number is negative
160 #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
161
162 /// A trait for values which cannot be negative
163 pub trait Unsigned: Num {}
164
165 /// Raises a value to the power of exp, using exponentiation by squaring.
166 ///
167 /// # Example
168 ///
169 /// ```rust
170 /// use std::num;
171 ///
172 /// assert_eq!(num::pow(2, 4), 16);
173 /// ```
174 #[inline]
175 pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
176     if exp == 1 { base }
177     else {
178         let mut acc = one::<T>();
179         while exp > 0 {
180             if (exp & 1) == 1 {
181                 acc = acc * base;
182             }
183             base = base * base;
184             exp = exp >> 1;
185         }
186         acc
187     }
188 }
189
190 /// Numbers which have upper and lower bounds
191 pub trait Bounded {
192     // FIXME (#5527): These should be associated constants
193     /// returns the smallest finite number this type can represent
194     fn min_value() -> Self;
195     /// returns the largest finite number this type can represent
196     fn max_value() -> Self;
197 }
198
199 /// Numbers with a fixed binary representation.
200 pub trait Bitwise: Bounded
201                  + Not<Self>
202                  + BitAnd<Self,Self>
203                  + BitOr<Self,Self>
204                  + BitXor<Self,Self>
205                  + Shl<Self,Self>
206                  + Shr<Self,Self> {
207     /// Returns the number of ones in the binary representation of the number.
208     ///
209     /// # Example
210     ///
211     /// ```rust
212     /// use std::num::Bitwise;
213     ///
214     /// let n = 0b01001100u8;
215     /// assert_eq!(n.count_ones(), 3);
216     /// ```
217     fn count_ones(&self) -> Self;
218
219     /// Returns the number of zeros in the binary representation of the number.
220     ///
221     /// # Example
222     ///
223     /// ```rust
224     /// use std::num::Bitwise;
225     ///
226     /// let n = 0b01001100u8;
227     /// assert_eq!(n.count_zeros(), 5);
228     /// ```
229     #[inline]
230     fn count_zeros(&self) -> Self {
231         (!*self).count_ones()
232     }
233
234     /// Returns the number of leading zeros in the in the binary representation
235     /// of the number.
236     ///
237     /// # Example
238     ///
239     /// ```rust
240     /// use std::num::Bitwise;
241     ///
242     /// let n = 0b0101000u16;
243     /// assert_eq!(n.leading_zeros(), 10);
244     /// ```
245     fn leading_zeros(&self) -> Self;
246
247     /// Returns the number of trailing zeros in the in the binary representation
248     /// of the number.
249     ///
250     /// # Example
251     ///
252     /// ```rust
253     /// use std::num::Bitwise;
254     ///
255     /// let n = 0b0101000u16;
256     /// assert_eq!(n.trailing_zeros(), 3);
257     /// ```
258     fn trailing_zeros(&self) -> Self;
259 }
260
261 /// Specifies the available operations common to all of Rust's core numeric primitives.
262 /// These may not always make sense from a purely mathematical point of view, but
263 /// may be useful for systems programming.
264 pub trait Primitive: Copy
265                    + Clone
266                    + Num
267                    + NumCast
268                    + Ord
269                    + Bounded {}
270
271 /// A collection of traits relevant to primitive signed and unsigned integers
272 pub trait Int: Primitive
273              + Bitwise
274              + CheckedAdd
275              + CheckedSub
276              + CheckedMul
277              + CheckedDiv
278              + Show
279              + Binary
280              + Octal
281              + LowerHex
282              + UpperHex {}
283
284 /// Returns the smallest power of 2 greater than or equal to `n`.
285 #[inline]
286 pub fn next_power_of_two<T: Unsigned + Int>(n: T) -> T {
287     let halfbits: T = cast(size_of::<T>() * 4).unwrap();
288     let mut tmp: T = n - one();
289     let mut shift: T = one();
290     while shift <= halfbits {
291         tmp = tmp | (tmp >> shift);
292         shift = shift << one();
293     }
294     tmp + one()
295 }
296
297 // Returns `true` iff `n == 2^k` for some k.
298 #[inline]
299 pub fn is_power_of_two<T: Unsigned + Int>(n: T) -> bool {
300     (n - one()) & n == zero()
301 }
302
303 /// Returns the smallest power of 2 greater than or equal to `n`. If the next
304 /// power of two is greater than the type's maximum value, `None` is returned,
305 /// otherwise the power of 2 is wrapped in `Some`.
306 #[inline]
307 pub fn checked_next_power_of_two<T: Unsigned + Int>(n: T) -> Option<T> {
308     let halfbits: T = cast(size_of::<T>() * 4).unwrap();
309     let mut tmp: T = n - one();
310     let mut shift: T = one();
311     while shift <= halfbits {
312         tmp = tmp | (tmp >> shift);
313         shift = shift << one();
314     }
315     tmp.checked_add(&one())
316 }
317
318 /// Used for representing the classification of floating point numbers
319 #[deriving(Eq, Show)]
320 pub enum FPCategory {
321     /// "Not a Number", often obtained by dividing by zero
322     FPNaN,
323     /// Positive or negative infinity
324     FPInfinite ,
325     /// Positive or negative zero
326     FPZero,
327     /// De-normalized floating point representation (less precise than `FPNormal`)
328     FPSubnormal,
329     /// A regular floating point number
330     FPNormal,
331 }
332
333 /// Operations on primitive floating point numbers.
334 // FIXME(#5527): In a future version of Rust, many of these functions will
335 //               become constants.
336 //
337 // FIXME(#8888): Several of these functions have a parameter named
338 //               `unused_self`. Removing it requires #8888 to be fixed.
339 pub trait Float: Signed + Primitive {
340     /// Returns the NaN value.
341     fn nan() -> Self;
342     /// Returns the infinite value.
343     fn infinity() -> Self;
344     /// Returns the negative infinite value.
345     fn neg_infinity() -> Self;
346     /// Returns -0.0.
347     fn neg_zero() -> Self;
348
349     /// Returns true if this value is NaN and false otherwise.
350     fn is_nan(self) -> bool;
351     /// Returns true if this value is positive infinity or negative infinity and
352     /// false otherwise.
353     fn is_infinite(self) -> bool;
354     /// Returns true if this number is neither infinite nor NaN.
355     fn is_finite(self) -> bool;
356     /// Returns true if this number is neither zero, infinite, denormal, or NaN.
357     fn is_normal(self) -> bool;
358     /// Returns the category that this number falls into.
359     fn classify(self) -> FPCategory;
360
361     // FIXME (#5527): These should be associated constants
362
363     /// Returns the number of binary digits of mantissa that this type supports.
364     fn mantissa_digits(unused_self: Option<Self>) -> uint;
365     /// Returns the number of base-10 digits of precision that this type supports.
366     fn digits(unused_self: Option<Self>) -> uint;
367     /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
368     fn epsilon() -> Self;
369     /// Returns the minimum binary exponent that this type can represent.
370     fn min_exp(unused_self: Option<Self>) -> int;
371     /// Returns the maximum binary exponent that this type can represent.
372     fn max_exp(unused_self: Option<Self>) -> int;
373     /// Returns the minimum base-10 exponent that this type can represent.
374     fn min_10_exp(unused_self: Option<Self>) -> int;
375     /// Returns the maximum base-10 exponent that this type can represent.
376     fn max_10_exp(unused_self: Option<Self>) -> int;
377     /// Returns the smallest normalized positive number that this type can represent.
378     fn min_pos_value(unused_self: Option<Self>) -> Self;
379
380     /// Constructs a floating point number created by multiplying `x` by 2
381     /// raised to the power of `exp`.
382     fn ldexp(x: Self, exp: int) -> Self;
383     /// Breaks the number into a normalized fraction and a base-2 exponent,
384     /// satisfying:
385     ///
386     ///  * `self = x * pow(2, exp)`
387     ///
388     ///  * `0.5 <= abs(x) < 1.0`
389     fn frexp(self) -> (Self, int);
390     /// Returns the mantissa, exponent and sign as integers, respectively.
391     fn integer_decode(self) -> (u64, i16, i8);
392
393     /// Returns the next representable floating-point value in the direction of
394     /// `other`.
395     fn next_after(self, other: Self) -> Self;
396
397     /// Return the largest integer less than or equal to a number.
398     fn floor(self) -> Self;
399     /// Return the smallest integer greater than or equal to a number.
400     fn ceil(self) -> Self;
401     /// Return the nearest integer to a number. Round half-way cases away from
402     /// `0.0`.
403     fn round(self) -> Self;
404     /// Return the integer part of a number.
405     fn trunc(self) -> Self;
406     /// Return the fractional part of a number.
407     fn fract(self) -> Self;
408
409     /// Returns the maximum of the two numbers.
410     fn max(self, other: Self) -> Self;
411     /// Returns the minimum of the two numbers.
412     fn min(self, other: Self) -> Self;
413
414     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
415     /// error. This produces a more accurate result with better performance than
416     /// a separate multiplication operation followed by an add.
417     fn mul_add(self, a: Self, b: Self) -> Self;
418     /// Take the reciprocal (inverse) of a number, `1/x`.
419     fn recip(self) -> Self;
420
421     /// Raise a number to an integer power.
422     ///
423     /// Using this function is generally faster than using `powf`
424     fn powi(self, n: i32) -> Self;
425     /// Raise a number to a floating point power.
426     fn powf(self, n: Self) -> Self;
427
428     /// sqrt(2.0).
429     fn sqrt2() -> Self;
430     /// 1.0 / sqrt(2.0).
431     fn frac_1_sqrt2() -> Self;
432
433     /// Take the square root of a number.
434     fn sqrt(self) -> Self;
435     /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
436     fn rsqrt(self) -> Self;
437     /// Take the cubic root of a number.
438     fn cbrt(self) -> Self;
439     /// Calculate the length of the hypotenuse of a right-angle triangle given
440     /// legs of length `x` and `y`.
441     fn hypot(self, other: Self) -> Self;
442
443     // FIXME (#5527): These should be associated constants
444
445     /// Archimedes' constant.
446     fn pi() -> Self;
447     /// 2.0 * pi.
448     fn two_pi() -> Self;
449     /// pi / 2.0.
450     fn frac_pi_2() -> Self;
451     /// pi / 3.0.
452     fn frac_pi_3() -> Self;
453     /// pi / 4.0.
454     fn frac_pi_4() -> Self;
455     /// pi / 6.0.
456     fn frac_pi_6() -> Self;
457     /// pi / 8.0.
458     fn frac_pi_8() -> Self;
459     /// 1.0 / pi.
460     fn frac_1_pi() -> Self;
461     /// 2.0 / pi.
462     fn frac_2_pi() -> Self;
463     /// 2.0 / sqrt(pi).
464     fn frac_2_sqrtpi() -> Self;
465
466     /// Computes the sine of a number (in radians).
467     fn sin(self) -> Self;
468     /// Computes the cosine of a number (in radians).
469     fn cos(self) -> Self;
470     /// Computes the tangent of a number (in radians).
471     fn tan(self) -> Self;
472
473     /// Computes the arcsine of a number. Return value is in radians in
474     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
475     /// [-1, 1].
476     fn asin(self) -> Self;
477     /// Computes the arccosine of a number. Return value is in radians in
478     /// the range [0, pi] or NaN if the number is outside the range
479     /// [-1, 1].
480     fn acos(self) -> Self;
481     /// Computes the arctangent of a number. Return value is in radians in the
482     /// range [-pi/2, pi/2];
483     fn atan(self) -> Self;
484     /// Computes the four quadrant arctangent of a number, `y`, and another
485     /// number `x`. Return value is in radians in the range [-pi, pi].
486     fn atan2(self, other: Self) -> Self;
487     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
488     /// `(sin(x), cos(x))`.
489     fn sin_cos(self) -> (Self, Self);
490
491     /// Euler's number.
492     fn e() -> Self;
493     /// log2(e).
494     fn log2_e() -> Self;
495     /// log10(e).
496     fn log10_e() -> Self;
497     /// ln(2.0).
498     fn ln_2() -> Self;
499     /// ln(10.0).
500     fn ln_10() -> Self;
501
502     /// Returns `e^(self)`, (the exponential function).
503     fn exp(self) -> Self;
504     /// Returns 2 raised to the power of the number, `2^(self)`.
505     fn exp2(self) -> Self;
506     /// Returns the exponential of the number, minus 1, in a way that is
507     /// accurate even if the number is close to zero.
508     fn exp_m1(self) -> Self;
509     /// Returns the natural logarithm of the number.
510     fn ln(self) -> Self;
511     /// Returns the logarithm of the number with respect to an arbitrary base.
512     fn log(self, base: Self) -> Self;
513     /// Returns the base 2 logarithm of the number.
514     fn log2(self) -> Self;
515     /// Returns the base 10 logarithm of the number.
516     fn log10(self) -> Self;
517     /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
518     /// accurately than if the operations were performed separately.
519     fn ln_1p(self) -> Self;
520
521     /// Hyperbolic sine function.
522     fn sinh(self) -> Self;
523     /// Hyperbolic cosine function.
524     fn cosh(self) -> Self;
525     /// Hyperbolic tangent function.
526     fn tanh(self) -> Self;
527     /// Inverse hyperbolic sine function.
528     fn asinh(self) -> Self;
529     /// Inverse hyperbolic cosine function.
530     fn acosh(self) -> Self;
531     /// Inverse hyperbolic tangent function.
532     fn atanh(self) -> Self;
533
534     /// Convert radians to degrees.
535     fn to_degrees(self) -> Self;
536     /// Convert degrees to radians.
537     fn to_radians(self) -> Self;
538 }
539
540 /// A generic trait for converting a value to a number.
541 pub trait ToPrimitive {
542     /// Converts the value of `self` to an `int`.
543     #[inline]
544     fn to_int(&self) -> Option<int> {
545         self.to_i64().and_then(|x| x.to_int())
546     }
547
548     /// Converts the value of `self` to an `i8`.
549     #[inline]
550     fn to_i8(&self) -> Option<i8> {
551         self.to_i64().and_then(|x| x.to_i8())
552     }
553
554     /// Converts the value of `self` to an `i16`.
555     #[inline]
556     fn to_i16(&self) -> Option<i16> {
557         self.to_i64().and_then(|x| x.to_i16())
558     }
559
560     /// Converts the value of `self` to an `i32`.
561     #[inline]
562     fn to_i32(&self) -> Option<i32> {
563         self.to_i64().and_then(|x| x.to_i32())
564     }
565
566     /// Converts the value of `self` to an `i64`.
567     fn to_i64(&self) -> Option<i64>;
568
569     /// Converts the value of `self` to an `uint`.
570     #[inline]
571     fn to_uint(&self) -> Option<uint> {
572         self.to_u64().and_then(|x| x.to_uint())
573     }
574
575     /// Converts the value of `self` to an `u8`.
576     #[inline]
577     fn to_u8(&self) -> Option<u8> {
578         self.to_u64().and_then(|x| x.to_u8())
579     }
580
581     /// Converts the value of `self` to an `u16`.
582     #[inline]
583     fn to_u16(&self) -> Option<u16> {
584         self.to_u64().and_then(|x| x.to_u16())
585     }
586
587     /// Converts the value of `self` to an `u32`.
588     #[inline]
589     fn to_u32(&self) -> Option<u32> {
590         self.to_u64().and_then(|x| x.to_u32())
591     }
592
593     /// Converts the value of `self` to an `u64`.
594     #[inline]
595     fn to_u64(&self) -> Option<u64>;
596
597     /// Converts the value of `self` to an `f32`.
598     #[inline]
599     fn to_f32(&self) -> Option<f32> {
600         self.to_f64().and_then(|x| x.to_f32())
601     }
602
603     /// Converts the value of `self` to an `f64`.
604     #[inline]
605     fn to_f64(&self) -> Option<f64> {
606         self.to_i64().and_then(|x| x.to_f64())
607     }
608 }
609
610 macro_rules! impl_to_primitive_int_to_int(
611     ($SrcT:ty, $DstT:ty) => (
612         {
613             if size_of::<$SrcT>() <= size_of::<$DstT>() {
614                 Some(*self as $DstT)
615             } else {
616                 let n = *self as i64;
617                 let min_value: $DstT = Bounded::min_value();
618                 let max_value: $DstT = Bounded::max_value();
619                 if min_value as i64 <= n && n <= max_value as i64 {
620                     Some(*self as $DstT)
621                 } else {
622                     None
623                 }
624             }
625         }
626     )
627 )
628
629 macro_rules! impl_to_primitive_int_to_uint(
630     ($SrcT:ty, $DstT:ty) => (
631         {
632             let zero: $SrcT = Zero::zero();
633             let max_value: $DstT = Bounded::max_value();
634             if zero <= *self && *self as u64 <= max_value as u64 {
635                 Some(*self as $DstT)
636             } else {
637                 None
638             }
639         }
640     )
641 )
642
643 macro_rules! impl_to_primitive_int(
644     ($T:ty) => (
645         impl ToPrimitive for $T {
646             #[inline]
647             fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int) }
648             #[inline]
649             fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8) }
650             #[inline]
651             fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16) }
652             #[inline]
653             fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32) }
654             #[inline]
655             fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64) }
656
657             #[inline]
658             fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint) }
659             #[inline]
660             fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8) }
661             #[inline]
662             fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16) }
663             #[inline]
664             fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32) }
665             #[inline]
666             fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64) }
667
668             #[inline]
669             fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
670             #[inline]
671             fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
672         }
673     )
674 )
675
676 impl_to_primitive_int!(int)
677 impl_to_primitive_int!(i8)
678 impl_to_primitive_int!(i16)
679 impl_to_primitive_int!(i32)
680 impl_to_primitive_int!(i64)
681
682 macro_rules! impl_to_primitive_uint_to_int(
683     ($DstT:ty) => (
684         {
685             let max_value: $DstT = Bounded::max_value();
686             if *self as u64 <= max_value as u64 {
687                 Some(*self as $DstT)
688             } else {
689                 None
690             }
691         }
692     )
693 )
694
695 macro_rules! impl_to_primitive_uint_to_uint(
696     ($SrcT:ty, $DstT:ty) => (
697         {
698             if size_of::<$SrcT>() <= size_of::<$DstT>() {
699                 Some(*self as $DstT)
700             } else {
701                 let zero: $SrcT = Zero::zero();
702                 let max_value: $DstT = Bounded::max_value();
703                 if zero <= *self && *self as u64 <= max_value as u64 {
704                     Some(*self as $DstT)
705                 } else {
706                     None
707                 }
708             }
709         }
710     )
711 )
712
713 macro_rules! impl_to_primitive_uint(
714     ($T:ty) => (
715         impl ToPrimitive for $T {
716             #[inline]
717             fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int) }
718             #[inline]
719             fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8) }
720             #[inline]
721             fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16) }
722             #[inline]
723             fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32) }
724             #[inline]
725             fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64) }
726
727             #[inline]
728             fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint) }
729             #[inline]
730             fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8) }
731             #[inline]
732             fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16) }
733             #[inline]
734             fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32) }
735             #[inline]
736             fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64) }
737
738             #[inline]
739             fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
740             #[inline]
741             fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
742         }
743     )
744 )
745
746 impl_to_primitive_uint!(uint)
747 impl_to_primitive_uint!(u8)
748 impl_to_primitive_uint!(u16)
749 impl_to_primitive_uint!(u32)
750 impl_to_primitive_uint!(u64)
751
752 macro_rules! impl_to_primitive_float_to_float(
753     ($SrcT:ty, $DstT:ty) => (
754         if size_of::<$SrcT>() <= size_of::<$DstT>() {
755             Some(*self as $DstT)
756         } else {
757             let n = *self as f64;
758             let max_value: $SrcT = Bounded::max_value();
759             if -max_value as f64 <= n && n <= max_value as f64 {
760                 Some(*self as $DstT)
761             } else {
762                 None
763             }
764         }
765     )
766 )
767
768 macro_rules! impl_to_primitive_float(
769     ($T:ty) => (
770         impl ToPrimitive for $T {
771             #[inline]
772             fn to_int(&self) -> Option<int> { Some(*self as int) }
773             #[inline]
774             fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
775             #[inline]
776             fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
777             #[inline]
778             fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
779             #[inline]
780             fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
781
782             #[inline]
783             fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
784             #[inline]
785             fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
786             #[inline]
787             fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
788             #[inline]
789             fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
790             #[inline]
791             fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
792
793             #[inline]
794             fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32) }
795             #[inline]
796             fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64) }
797         }
798     )
799 )
800
801 impl_to_primitive_float!(f32)
802 impl_to_primitive_float!(f64)
803
804 /// A generic trait for converting a number to a value.
805 pub trait FromPrimitive {
806     /// Convert an `int` to return an optional value of this type. If the
807     /// value cannot be represented by this value, the `None` is returned.
808     #[inline]
809     fn from_int(n: int) -> Option<Self> {
810         FromPrimitive::from_i64(n as i64)
811     }
812
813     /// Convert an `i8` to return an optional value of this type. If the
814     /// type cannot be represented by this value, the `None` is returned.
815     #[inline]
816     fn from_i8(n: i8) -> Option<Self> {
817         FromPrimitive::from_i64(n as i64)
818     }
819
820     /// Convert an `i16` to return an optional value of this type. If the
821     /// type cannot be represented by this value, the `None` is returned.
822     #[inline]
823     fn from_i16(n: i16) -> Option<Self> {
824         FromPrimitive::from_i64(n as i64)
825     }
826
827     /// Convert an `i32` to return an optional value of this type. If the
828     /// type cannot be represented by this value, the `None` is returned.
829     #[inline]
830     fn from_i32(n: i32) -> Option<Self> {
831         FromPrimitive::from_i64(n as i64)
832     }
833
834     /// Convert an `i64` to return an optional value of this type. If the
835     /// type cannot be represented by this value, the `None` is returned.
836     fn from_i64(n: i64) -> Option<Self>;
837
838     /// Convert an `uint` to return an optional value of this type. If the
839     /// type cannot be represented by this value, the `None` is returned.
840     #[inline]
841     fn from_uint(n: uint) -> Option<Self> {
842         FromPrimitive::from_u64(n as u64)
843     }
844
845     /// Convert an `u8` to return an optional value of this type. If the
846     /// type cannot be represented by this value, the `None` is returned.
847     #[inline]
848     fn from_u8(n: u8) -> Option<Self> {
849         FromPrimitive::from_u64(n as u64)
850     }
851
852     /// Convert an `u16` to return an optional value of this type. If the
853     /// type cannot be represented by this value, the `None` is returned.
854     #[inline]
855     fn from_u16(n: u16) -> Option<Self> {
856         FromPrimitive::from_u64(n as u64)
857     }
858
859     /// Convert an `u32` to return an optional value of this type. If the
860     /// type cannot be represented by this value, the `None` is returned.
861     #[inline]
862     fn from_u32(n: u32) -> Option<Self> {
863         FromPrimitive::from_u64(n as u64)
864     }
865
866     /// Convert an `u64` to return an optional value of this type. If the
867     /// type cannot be represented by this value, the `None` is returned.
868     fn from_u64(n: u64) -> Option<Self>;
869
870     /// Convert a `f32` to return an optional value of this type. If the
871     /// type cannot be represented by this value, the `None` is returned.
872     #[inline]
873     fn from_f32(n: f32) -> Option<Self> {
874         FromPrimitive::from_f64(n as f64)
875     }
876
877     /// Convert a `f64` to return an optional value of this type. If the
878     /// type cannot be represented by this value, the `None` is returned.
879     #[inline]
880     fn from_f64(n: f64) -> Option<Self> {
881         FromPrimitive::from_i64(n as i64)
882     }
883 }
884
885 /// A utility function that just calls `FromPrimitive::from_int`.
886 pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
887     FromPrimitive::from_int(n)
888 }
889
890 /// A utility function that just calls `FromPrimitive::from_i8`.
891 pub fn from_i8<A: FromPrimitive>(n: i8) -> Option<A> {
892     FromPrimitive::from_i8(n)
893 }
894
895 /// A utility function that just calls `FromPrimitive::from_i16`.
896 pub fn from_i16<A: FromPrimitive>(n: i16) -> Option<A> {
897     FromPrimitive::from_i16(n)
898 }
899
900 /// A utility function that just calls `FromPrimitive::from_i32`.
901 pub fn from_i32<A: FromPrimitive>(n: i32) -> Option<A> {
902     FromPrimitive::from_i32(n)
903 }
904
905 /// A utility function that just calls `FromPrimitive::from_i64`.
906 pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
907     FromPrimitive::from_i64(n)
908 }
909
910 /// A utility function that just calls `FromPrimitive::from_uint`.
911 pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
912     FromPrimitive::from_uint(n)
913 }
914
915 /// A utility function that just calls `FromPrimitive::from_u8`.
916 pub fn from_u8<A: FromPrimitive>(n: u8) -> Option<A> {
917     FromPrimitive::from_u8(n)
918 }
919
920 /// A utility function that just calls `FromPrimitive::from_u16`.
921 pub fn from_u16<A: FromPrimitive>(n: u16) -> Option<A> {
922     FromPrimitive::from_u16(n)
923 }
924
925 /// A utility function that just calls `FromPrimitive::from_u32`.
926 pub fn from_u32<A: FromPrimitive>(n: u32) -> Option<A> {
927     FromPrimitive::from_u32(n)
928 }
929
930 /// A utility function that just calls `FromPrimitive::from_u64`.
931 pub fn from_u64<A: FromPrimitive>(n: u64) -> Option<A> {
932     FromPrimitive::from_u64(n)
933 }
934
935 /// A utility function that just calls `FromPrimitive::from_f32`.
936 pub fn from_f32<A: FromPrimitive>(n: f32) -> Option<A> {
937     FromPrimitive::from_f32(n)
938 }
939
940 /// A utility function that just calls `FromPrimitive::from_f64`.
941 pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
942     FromPrimitive::from_f64(n)
943 }
944
945 macro_rules! impl_from_primitive(
946     ($T:ty, $to_ty:expr) => (
947         impl FromPrimitive for $T {
948             #[inline] fn from_int(n: int) -> Option<$T> { $to_ty }
949             #[inline] fn from_i8(n: i8) -> Option<$T> { $to_ty }
950             #[inline] fn from_i16(n: i16) -> Option<$T> { $to_ty }
951             #[inline] fn from_i32(n: i32) -> Option<$T> { $to_ty }
952             #[inline] fn from_i64(n: i64) -> Option<$T> { $to_ty }
953
954             #[inline] fn from_uint(n: uint) -> Option<$T> { $to_ty }
955             #[inline] fn from_u8(n: u8) -> Option<$T> { $to_ty }
956             #[inline] fn from_u16(n: u16) -> Option<$T> { $to_ty }
957             #[inline] fn from_u32(n: u32) -> Option<$T> { $to_ty }
958             #[inline] fn from_u64(n: u64) -> Option<$T> { $to_ty }
959
960             #[inline] fn from_f32(n: f32) -> Option<$T> { $to_ty }
961             #[inline] fn from_f64(n: f64) -> Option<$T> { $to_ty }
962         }
963     )
964 )
965
966 impl_from_primitive!(int, n.to_int())
967 impl_from_primitive!(i8, n.to_i8())
968 impl_from_primitive!(i16, n.to_i16())
969 impl_from_primitive!(i32, n.to_i32())
970 impl_from_primitive!(i64, n.to_i64())
971 impl_from_primitive!(uint, n.to_uint())
972 impl_from_primitive!(u8, n.to_u8())
973 impl_from_primitive!(u16, n.to_u16())
974 impl_from_primitive!(u32, n.to_u32())
975 impl_from_primitive!(u64, n.to_u64())
976 impl_from_primitive!(f32, n.to_f32())
977 impl_from_primitive!(f64, n.to_f64())
978
979 /// Cast from one machine scalar to another.
980 ///
981 /// # Example
982 ///
983 /// ```
984 /// use std::num;
985 ///
986 /// let twenty: f32 = num::cast(0x14).unwrap();
987 /// assert_eq!(twenty, 20f32);
988 /// ```
989 ///
990 #[inline]
991 pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> {
992     NumCast::from(n)
993 }
994
995 /// An interface for casting between machine scalars.
996 pub trait NumCast: ToPrimitive {
997     /// Creates a number from another value that can be converted into a primitive via the
998     /// `ToPrimitive` trait.
999     fn from<T: ToPrimitive>(n: T) -> Option<Self>;
1000 }
1001
1002 macro_rules! impl_num_cast(
1003     ($T:ty, $conv:ident) => (
1004         impl NumCast for $T {
1005             #[inline]
1006             fn from<N: ToPrimitive>(n: N) -> Option<$T> {
1007                 // `$conv` could be generated using `concat_idents!`, but that
1008                 // macro seems to be broken at the moment
1009                 n.$conv()
1010             }
1011         }
1012     )
1013 )
1014
1015 impl_num_cast!(u8,    to_u8)
1016 impl_num_cast!(u16,   to_u16)
1017 impl_num_cast!(u32,   to_u32)
1018 impl_num_cast!(u64,   to_u64)
1019 impl_num_cast!(uint,  to_uint)
1020 impl_num_cast!(i8,    to_i8)
1021 impl_num_cast!(i16,   to_i16)
1022 impl_num_cast!(i32,   to_i32)
1023 impl_num_cast!(i64,   to_i64)
1024 impl_num_cast!(int,   to_int)
1025 impl_num_cast!(f32,   to_f32)
1026 impl_num_cast!(f64,   to_f64)
1027
1028 /// A generic trait for converting a value to a string with a radix (base)
1029 pub trait ToStrRadix {
1030     fn to_str_radix(&self, radix: uint) -> ~str;
1031 }
1032
1033 /// A generic trait for converting a string with a radix (base) to a value
1034 pub trait FromStrRadix {
1035     fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
1036 }
1037
1038 /// A utility function that just calls FromStrRadix::from_str_radix.
1039 pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
1040     FromStrRadix::from_str_radix(str, radix)
1041 }
1042
1043 /// Saturating math operations
1044 pub trait Saturating {
1045     /// Saturating addition operator.
1046     /// Returns a+b, saturating at the numeric bounds instead of overflowing.
1047     fn saturating_add(self, v: Self) -> Self;
1048
1049     /// Saturating subtraction operator.
1050     /// Returns a-b, saturating at the numeric bounds instead of overflowing.
1051     fn saturating_sub(self, v: Self) -> Self;
1052 }
1053
1054 impl<T: CheckedAdd + CheckedSub + Zero + Ord + Bounded> Saturating for T {
1055     #[inline]
1056     fn saturating_add(self, v: T) -> T {
1057         match self.checked_add(&v) {
1058             Some(x) => x,
1059             None => if v >= Zero::zero() {
1060                 Bounded::max_value()
1061             } else {
1062                 Bounded::min_value()
1063             }
1064         }
1065     }
1066
1067     #[inline]
1068     fn saturating_sub(self, v: T) -> T {
1069         match self.checked_sub(&v) {
1070             Some(x) => x,
1071             None => if v >= Zero::zero() {
1072                 Bounded::min_value()
1073             } else {
1074                 Bounded::max_value()
1075             }
1076         }
1077     }
1078 }
1079
1080 /// Performs addition that returns `None` instead of wrapping around on overflow.
1081 pub trait CheckedAdd: Add<Self, Self> {
1082     /// Adds two numbers, checking for overflow. If overflow happens, `None` is returned.
1083     fn checked_add(&self, v: &Self) -> Option<Self>;
1084 }
1085
1086 /// Performs subtraction that returns `None` instead of wrapping around on underflow.
1087 pub trait CheckedSub: Sub<Self, Self> {
1088     /// Subtracts two numbers, checking for underflow. If underflow happens, `None` is returned.
1089     fn checked_sub(&self, v: &Self) -> Option<Self>;
1090 }
1091
1092 /// Performs multiplication that returns `None` instead of wrapping around on underflow or
1093 /// overflow.
1094 pub trait CheckedMul: Mul<Self, Self> {
1095     /// Multiplies two numbers, checking for underflow or overflow. If underflow or overflow
1096     /// happens, `None` is returned.
1097     fn checked_mul(&self, v: &Self) -> Option<Self>;
1098 }
1099
1100 /// Performs division that returns `None` instead of wrapping around on underflow or overflow.
1101 pub trait CheckedDiv: Div<Self, Self> {
1102     /// Divides two numbers, checking for underflow or overflow. If underflow or overflow happens,
1103     /// `None` is returned.
1104     fn checked_div(&self, v: &Self) -> Option<Self>;
1105 }
1106
1107 /// Helper function for testing numeric operations
1108 #[cfg(test)]
1109 pub fn test_num<T:Num + NumCast + Show>(ten: T, two: T) {
1110     assert_eq!(ten.add(&two),  cast(12).unwrap());
1111     assert_eq!(ten.sub(&two),  cast(8).unwrap());
1112     assert_eq!(ten.mul(&two),  cast(20).unwrap());
1113     assert_eq!(ten.div(&two),  cast(5).unwrap());
1114     assert_eq!(ten.rem(&two),  cast(0).unwrap());
1115
1116     assert_eq!(ten.add(&two),  ten + two);
1117     assert_eq!(ten.sub(&two),  ten - two);
1118     assert_eq!(ten.mul(&two),  ten * two);
1119     assert_eq!(ten.div(&two),  ten / two);
1120     assert_eq!(ten.rem(&two),  ten % two);
1121 }
1122
1123 #[cfg(test)]
1124 mod tests {
1125     use prelude::*;
1126     use super::*;
1127     use i8;
1128     use i16;
1129     use i32;
1130     use i64;
1131     use int;
1132     use u8;
1133     use u16;
1134     use u32;
1135     use u64;
1136     use uint;
1137
1138     macro_rules! test_cast_20(
1139         ($_20:expr) => ({
1140             let _20 = $_20;
1141
1142             assert_eq!(20u,   _20.to_uint().unwrap());
1143             assert_eq!(20u8,  _20.to_u8().unwrap());
1144             assert_eq!(20u16, _20.to_u16().unwrap());
1145             assert_eq!(20u32, _20.to_u32().unwrap());
1146             assert_eq!(20u64, _20.to_u64().unwrap());
1147             assert_eq!(20i,   _20.to_int().unwrap());
1148             assert_eq!(20i8,  _20.to_i8().unwrap());
1149             assert_eq!(20i16, _20.to_i16().unwrap());
1150             assert_eq!(20i32, _20.to_i32().unwrap());
1151             assert_eq!(20i64, _20.to_i64().unwrap());
1152             assert_eq!(20f32, _20.to_f32().unwrap());
1153             assert_eq!(20f64, _20.to_f64().unwrap());
1154
1155             assert_eq!(_20, NumCast::from(20u).unwrap());
1156             assert_eq!(_20, NumCast::from(20u8).unwrap());
1157             assert_eq!(_20, NumCast::from(20u16).unwrap());
1158             assert_eq!(_20, NumCast::from(20u32).unwrap());
1159             assert_eq!(_20, NumCast::from(20u64).unwrap());
1160             assert_eq!(_20, NumCast::from(20i).unwrap());
1161             assert_eq!(_20, NumCast::from(20i8).unwrap());
1162             assert_eq!(_20, NumCast::from(20i16).unwrap());
1163             assert_eq!(_20, NumCast::from(20i32).unwrap());
1164             assert_eq!(_20, NumCast::from(20i64).unwrap());
1165             assert_eq!(_20, NumCast::from(20f32).unwrap());
1166             assert_eq!(_20, NumCast::from(20f64).unwrap());
1167
1168             assert_eq!(_20, cast(20u).unwrap());
1169             assert_eq!(_20, cast(20u8).unwrap());
1170             assert_eq!(_20, cast(20u16).unwrap());
1171             assert_eq!(_20, cast(20u32).unwrap());
1172             assert_eq!(_20, cast(20u64).unwrap());
1173             assert_eq!(_20, cast(20i).unwrap());
1174             assert_eq!(_20, cast(20i8).unwrap());
1175             assert_eq!(_20, cast(20i16).unwrap());
1176             assert_eq!(_20, cast(20i32).unwrap());
1177             assert_eq!(_20, cast(20i64).unwrap());
1178             assert_eq!(_20, cast(20f32).unwrap());
1179             assert_eq!(_20, cast(20f64).unwrap());
1180         })
1181     )
1182
1183     #[test] fn test_u8_cast()    { test_cast_20!(20u8)  }
1184     #[test] fn test_u16_cast()   { test_cast_20!(20u16) }
1185     #[test] fn test_u32_cast()   { test_cast_20!(20u32) }
1186     #[test] fn test_u64_cast()   { test_cast_20!(20u64) }
1187     #[test] fn test_uint_cast()  { test_cast_20!(20u)   }
1188     #[test] fn test_i8_cast()    { test_cast_20!(20i8)  }
1189     #[test] fn test_i16_cast()   { test_cast_20!(20i16) }
1190     #[test] fn test_i32_cast()   { test_cast_20!(20i32) }
1191     #[test] fn test_i64_cast()   { test_cast_20!(20i64) }
1192     #[test] fn test_int_cast()   { test_cast_20!(20i)   }
1193     #[test] fn test_f32_cast()   { test_cast_20!(20f32) }
1194     #[test] fn test_f64_cast()   { test_cast_20!(20f64) }
1195
1196     #[test]
1197     fn test_cast_range_int_min() {
1198         assert_eq!(int::MIN.to_int(),  Some(int::MIN as int));
1199         assert_eq!(int::MIN.to_i8(),   None);
1200         assert_eq!(int::MIN.to_i16(),  None);
1201         // int::MIN.to_i32() is word-size specific
1202         assert_eq!(int::MIN.to_i64(),  Some(int::MIN as i64));
1203         assert_eq!(int::MIN.to_uint(), None);
1204         assert_eq!(int::MIN.to_u8(),   None);
1205         assert_eq!(int::MIN.to_u16(),  None);
1206         assert_eq!(int::MIN.to_u32(),  None);
1207         assert_eq!(int::MIN.to_u64(),  None);
1208
1209         #[cfg(target_word_size = "32")]
1210         fn check_word_size() {
1211             assert_eq!(int::MIN.to_i32(), Some(int::MIN as i32));
1212         }
1213
1214         #[cfg(target_word_size = "64")]
1215         fn check_word_size() {
1216             assert_eq!(int::MIN.to_i32(), None);
1217         }
1218
1219         check_word_size();
1220     }
1221
1222     #[test]
1223     fn test_cast_range_i8_min() {
1224         assert_eq!(i8::MIN.to_int(),  Some(i8::MIN as int));
1225         assert_eq!(i8::MIN.to_i8(),   Some(i8::MIN as i8));
1226         assert_eq!(i8::MIN.to_i16(),  Some(i8::MIN as i16));
1227         assert_eq!(i8::MIN.to_i32(),  Some(i8::MIN as i32));
1228         assert_eq!(i8::MIN.to_i64(),  Some(i8::MIN as i64));
1229         assert_eq!(i8::MIN.to_uint(), None);
1230         assert_eq!(i8::MIN.to_u8(),   None);
1231         assert_eq!(i8::MIN.to_u16(),  None);
1232         assert_eq!(i8::MIN.to_u32(),  None);
1233         assert_eq!(i8::MIN.to_u64(),  None);
1234     }
1235
1236     #[test]
1237     fn test_cast_range_i16_min() {
1238         assert_eq!(i16::MIN.to_int(),  Some(i16::MIN as int));
1239         assert_eq!(i16::MIN.to_i8(),   None);
1240         assert_eq!(i16::MIN.to_i16(),  Some(i16::MIN as i16));
1241         assert_eq!(i16::MIN.to_i32(),  Some(i16::MIN as i32));
1242         assert_eq!(i16::MIN.to_i64(),  Some(i16::MIN as i64));
1243         assert_eq!(i16::MIN.to_uint(), None);
1244         assert_eq!(i16::MIN.to_u8(),   None);
1245         assert_eq!(i16::MIN.to_u16(),  None);
1246         assert_eq!(i16::MIN.to_u32(),  None);
1247         assert_eq!(i16::MIN.to_u64(),  None);
1248     }
1249
1250     #[test]
1251     fn test_cast_range_i32_min() {
1252         assert_eq!(i32::MIN.to_int(),  Some(i32::MIN as int));
1253         assert_eq!(i32::MIN.to_i8(),   None);
1254         assert_eq!(i32::MIN.to_i16(),  None);
1255         assert_eq!(i32::MIN.to_i32(),  Some(i32::MIN as i32));
1256         assert_eq!(i32::MIN.to_i64(),  Some(i32::MIN as i64));
1257         assert_eq!(i32::MIN.to_uint(), None);
1258         assert_eq!(i32::MIN.to_u8(),   None);
1259         assert_eq!(i32::MIN.to_u16(),  None);
1260         assert_eq!(i32::MIN.to_u32(),  None);
1261         assert_eq!(i32::MIN.to_u64(),  None);
1262     }
1263
1264     #[test]
1265     fn test_cast_range_i64_min() {
1266         // i64::MIN.to_int() is word-size specific
1267         assert_eq!(i64::MIN.to_i8(),   None);
1268         assert_eq!(i64::MIN.to_i16(),  None);
1269         assert_eq!(i64::MIN.to_i32(),  None);
1270         assert_eq!(i64::MIN.to_i64(),  Some(i64::MIN as i64));
1271         assert_eq!(i64::MIN.to_uint(), None);
1272         assert_eq!(i64::MIN.to_u8(),   None);
1273         assert_eq!(i64::MIN.to_u16(),  None);
1274         assert_eq!(i64::MIN.to_u32(),  None);
1275         assert_eq!(i64::MIN.to_u64(),  None);
1276
1277         #[cfg(target_word_size = "32")]
1278         fn check_word_size() {
1279             assert_eq!(i64::MIN.to_int(), None);
1280         }
1281
1282         #[cfg(target_word_size = "64")]
1283         fn check_word_size() {
1284             assert_eq!(i64::MIN.to_int(), Some(i64::MIN as int));
1285         }
1286
1287         check_word_size();
1288     }
1289
1290     #[test]
1291     fn test_cast_range_int_max() {
1292         assert_eq!(int::MAX.to_int(),  Some(int::MAX as int));
1293         assert_eq!(int::MAX.to_i8(),   None);
1294         assert_eq!(int::MAX.to_i16(),  None);
1295         // int::MAX.to_i32() is word-size specific
1296         assert_eq!(int::MAX.to_i64(),  Some(int::MAX as i64));
1297         assert_eq!(int::MAX.to_u8(),   None);
1298         assert_eq!(int::MAX.to_u16(),  None);
1299         // int::MAX.to_u32() is word-size specific
1300         assert_eq!(int::MAX.to_u64(),  Some(int::MAX as u64));
1301
1302         #[cfg(target_word_size = "32")]
1303         fn check_word_size() {
1304             assert_eq!(int::MAX.to_i32(), Some(int::MAX as i32));
1305             assert_eq!(int::MAX.to_u32(), Some(int::MAX as u32));
1306         }
1307
1308         #[cfg(target_word_size = "64")]
1309         fn check_word_size() {
1310             assert_eq!(int::MAX.to_i32(), None);
1311             assert_eq!(int::MAX.to_u32(), None);
1312         }
1313
1314         check_word_size();
1315     }
1316
1317     #[test]
1318     fn test_cast_range_i8_max() {
1319         assert_eq!(i8::MAX.to_int(),  Some(i8::MAX as int));
1320         assert_eq!(i8::MAX.to_i8(),   Some(i8::MAX as i8));
1321         assert_eq!(i8::MAX.to_i16(),  Some(i8::MAX as i16));
1322         assert_eq!(i8::MAX.to_i32(),  Some(i8::MAX as i32));
1323         assert_eq!(i8::MAX.to_i64(),  Some(i8::MAX as i64));
1324         assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as uint));
1325         assert_eq!(i8::MAX.to_u8(),   Some(i8::MAX as u8));
1326         assert_eq!(i8::MAX.to_u16(),  Some(i8::MAX as u16));
1327         assert_eq!(i8::MAX.to_u32(),  Some(i8::MAX as u32));
1328         assert_eq!(i8::MAX.to_u64(),  Some(i8::MAX as u64));
1329     }
1330
1331     #[test]
1332     fn test_cast_range_i16_max() {
1333         assert_eq!(i16::MAX.to_int(),  Some(i16::MAX as int));
1334         assert_eq!(i16::MAX.to_i8(),   None);
1335         assert_eq!(i16::MAX.to_i16(),  Some(i16::MAX as i16));
1336         assert_eq!(i16::MAX.to_i32(),  Some(i16::MAX as i32));
1337         assert_eq!(i16::MAX.to_i64(),  Some(i16::MAX as i64));
1338         assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as uint));
1339         assert_eq!(i16::MAX.to_u8(),   None);
1340         assert_eq!(i16::MAX.to_u16(),  Some(i16::MAX as u16));
1341         assert_eq!(i16::MAX.to_u32(),  Some(i16::MAX as u32));
1342         assert_eq!(i16::MAX.to_u64(),  Some(i16::MAX as u64));
1343     }
1344
1345     #[test]
1346     fn test_cast_range_i32_max() {
1347         assert_eq!(i32::MAX.to_int(),  Some(i32::MAX as int));
1348         assert_eq!(i32::MAX.to_i8(),   None);
1349         assert_eq!(i32::MAX.to_i16(),  None);
1350         assert_eq!(i32::MAX.to_i32(),  Some(i32::MAX as i32));
1351         assert_eq!(i32::MAX.to_i64(),  Some(i32::MAX as i64));
1352         assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as uint));
1353         assert_eq!(i32::MAX.to_u8(),   None);
1354         assert_eq!(i32::MAX.to_u16(),  None);
1355         assert_eq!(i32::MAX.to_u32(),  Some(i32::MAX as u32));
1356         assert_eq!(i32::MAX.to_u64(),  Some(i32::MAX as u64));
1357     }
1358
1359     #[test]
1360     fn test_cast_range_i64_max() {
1361         // i64::MAX.to_int() is word-size specific
1362         assert_eq!(i64::MAX.to_i8(),   None);
1363         assert_eq!(i64::MAX.to_i16(),  None);
1364         assert_eq!(i64::MAX.to_i32(),  None);
1365         assert_eq!(i64::MAX.to_i64(),  Some(i64::MAX as i64));
1366         // i64::MAX.to_uint() is word-size specific
1367         assert_eq!(i64::MAX.to_u8(),   None);
1368         assert_eq!(i64::MAX.to_u16(),  None);
1369         assert_eq!(i64::MAX.to_u32(),  None);
1370         assert_eq!(i64::MAX.to_u64(),  Some(i64::MAX as u64));
1371
1372         #[cfg(target_word_size = "32")]
1373         fn check_word_size() {
1374             assert_eq!(i64::MAX.to_int(),  None);
1375             assert_eq!(i64::MAX.to_uint(), None);
1376         }
1377
1378         #[cfg(target_word_size = "64")]
1379         fn check_word_size() {
1380             assert_eq!(i64::MAX.to_int(),  Some(i64::MAX as int));
1381             assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as uint));
1382         }
1383
1384         check_word_size();
1385     }
1386
1387     #[test]
1388     fn test_cast_range_uint_min() {
1389         assert_eq!(uint::MIN.to_int(),  Some(uint::MIN as int));
1390         assert_eq!(uint::MIN.to_i8(),   Some(uint::MIN as i8));
1391         assert_eq!(uint::MIN.to_i16(),  Some(uint::MIN as i16));
1392         assert_eq!(uint::MIN.to_i32(),  Some(uint::MIN as i32));
1393         assert_eq!(uint::MIN.to_i64(),  Some(uint::MIN as i64));
1394         assert_eq!(uint::MIN.to_uint(), Some(uint::MIN as uint));
1395         assert_eq!(uint::MIN.to_u8(),   Some(uint::MIN as u8));
1396         assert_eq!(uint::MIN.to_u16(),  Some(uint::MIN as u16));
1397         assert_eq!(uint::MIN.to_u32(),  Some(uint::MIN as u32));
1398         assert_eq!(uint::MIN.to_u64(),  Some(uint::MIN as u64));
1399     }
1400
1401     #[test]
1402     fn test_cast_range_u8_min() {
1403         assert_eq!(u8::MIN.to_int(),  Some(u8::MIN as int));
1404         assert_eq!(u8::MIN.to_i8(),   Some(u8::MIN as i8));
1405         assert_eq!(u8::MIN.to_i16(),  Some(u8::MIN as i16));
1406         assert_eq!(u8::MIN.to_i32(),  Some(u8::MIN as i32));
1407         assert_eq!(u8::MIN.to_i64(),  Some(u8::MIN as i64));
1408         assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as uint));
1409         assert_eq!(u8::MIN.to_u8(),   Some(u8::MIN as u8));
1410         assert_eq!(u8::MIN.to_u16(),  Some(u8::MIN as u16));
1411         assert_eq!(u8::MIN.to_u32(),  Some(u8::MIN as u32));
1412         assert_eq!(u8::MIN.to_u64(),  Some(u8::MIN as u64));
1413     }
1414
1415     #[test]
1416     fn test_cast_range_u16_min() {
1417         assert_eq!(u16::MIN.to_int(),  Some(u16::MIN as int));
1418         assert_eq!(u16::MIN.to_i8(),   Some(u16::MIN as i8));
1419         assert_eq!(u16::MIN.to_i16(),  Some(u16::MIN as i16));
1420         assert_eq!(u16::MIN.to_i32(),  Some(u16::MIN as i32));
1421         assert_eq!(u16::MIN.to_i64(),  Some(u16::MIN as i64));
1422         assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as uint));
1423         assert_eq!(u16::MIN.to_u8(),   Some(u16::MIN as u8));
1424         assert_eq!(u16::MIN.to_u16(),  Some(u16::MIN as u16));
1425         assert_eq!(u16::MIN.to_u32(),  Some(u16::MIN as u32));
1426         assert_eq!(u16::MIN.to_u64(),  Some(u16::MIN as u64));
1427     }
1428
1429     #[test]
1430     fn test_cast_range_u32_min() {
1431         assert_eq!(u32::MIN.to_int(),  Some(u32::MIN as int));
1432         assert_eq!(u32::MIN.to_i8(),   Some(u32::MIN as i8));
1433         assert_eq!(u32::MIN.to_i16(),  Some(u32::MIN as i16));
1434         assert_eq!(u32::MIN.to_i32(),  Some(u32::MIN as i32));
1435         assert_eq!(u32::MIN.to_i64(),  Some(u32::MIN as i64));
1436         assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as uint));
1437         assert_eq!(u32::MIN.to_u8(),   Some(u32::MIN as u8));
1438         assert_eq!(u32::MIN.to_u16(),  Some(u32::MIN as u16));
1439         assert_eq!(u32::MIN.to_u32(),  Some(u32::MIN as u32));
1440         assert_eq!(u32::MIN.to_u64(),  Some(u32::MIN as u64));
1441     }
1442
1443     #[test]
1444     fn test_cast_range_u64_min() {
1445         assert_eq!(u64::MIN.to_int(),  Some(u64::MIN as int));
1446         assert_eq!(u64::MIN.to_i8(),   Some(u64::MIN as i8));
1447         assert_eq!(u64::MIN.to_i16(),  Some(u64::MIN as i16));
1448         assert_eq!(u64::MIN.to_i32(),  Some(u64::MIN as i32));
1449         assert_eq!(u64::MIN.to_i64(),  Some(u64::MIN as i64));
1450         assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as uint));
1451         assert_eq!(u64::MIN.to_u8(),   Some(u64::MIN as u8));
1452         assert_eq!(u64::MIN.to_u16(),  Some(u64::MIN as u16));
1453         assert_eq!(u64::MIN.to_u32(),  Some(u64::MIN as u32));
1454         assert_eq!(u64::MIN.to_u64(),  Some(u64::MIN as u64));
1455     }
1456
1457     #[test]
1458     fn test_cast_range_uint_max() {
1459         assert_eq!(uint::MAX.to_int(),  None);
1460         assert_eq!(uint::MAX.to_i8(),   None);
1461         assert_eq!(uint::MAX.to_i16(),  None);
1462         assert_eq!(uint::MAX.to_i32(),  None);
1463         // uint::MAX.to_i64() is word-size specific
1464         assert_eq!(uint::MAX.to_u8(),   None);
1465         assert_eq!(uint::MAX.to_u16(),  None);
1466         // uint::MAX.to_u32() is word-size specific
1467         assert_eq!(uint::MAX.to_u64(),  Some(uint::MAX as u64));
1468
1469         #[cfg(target_word_size = "32")]
1470         fn check_word_size() {
1471             assert_eq!(uint::MAX.to_u32(), Some(uint::MAX as u32));
1472             assert_eq!(uint::MAX.to_i64(), Some(uint::MAX as i64));
1473         }
1474
1475         #[cfg(target_word_size = "64")]
1476         fn check_word_size() {
1477             assert_eq!(uint::MAX.to_u32(), None);
1478             assert_eq!(uint::MAX.to_i64(), None);
1479         }
1480
1481         check_word_size();
1482     }
1483
1484     #[test]
1485     fn test_cast_range_u8_max() {
1486         assert_eq!(u8::MAX.to_int(),  Some(u8::MAX as int));
1487         assert_eq!(u8::MAX.to_i8(),   None);
1488         assert_eq!(u8::MAX.to_i16(),  Some(u8::MAX as i16));
1489         assert_eq!(u8::MAX.to_i32(),  Some(u8::MAX as i32));
1490         assert_eq!(u8::MAX.to_i64(),  Some(u8::MAX as i64));
1491         assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as uint));
1492         assert_eq!(u8::MAX.to_u8(),   Some(u8::MAX as u8));
1493         assert_eq!(u8::MAX.to_u16(),  Some(u8::MAX as u16));
1494         assert_eq!(u8::MAX.to_u32(),  Some(u8::MAX as u32));
1495         assert_eq!(u8::MAX.to_u64(),  Some(u8::MAX as u64));
1496     }
1497
1498     #[test]
1499     fn test_cast_range_u16_max() {
1500         assert_eq!(u16::MAX.to_int(),  Some(u16::MAX as int));
1501         assert_eq!(u16::MAX.to_i8(),   None);
1502         assert_eq!(u16::MAX.to_i16(),  None);
1503         assert_eq!(u16::MAX.to_i32(),  Some(u16::MAX as i32));
1504         assert_eq!(u16::MAX.to_i64(),  Some(u16::MAX as i64));
1505         assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as uint));
1506         assert_eq!(u16::MAX.to_u8(),   None);
1507         assert_eq!(u16::MAX.to_u16(),  Some(u16::MAX as u16));
1508         assert_eq!(u16::MAX.to_u32(),  Some(u16::MAX as u32));
1509         assert_eq!(u16::MAX.to_u64(),  Some(u16::MAX as u64));
1510     }
1511
1512     #[test]
1513     fn test_cast_range_u32_max() {
1514         // u32::MAX.to_int() is word-size specific
1515         assert_eq!(u32::MAX.to_i8(),   None);
1516         assert_eq!(u32::MAX.to_i16(),  None);
1517         assert_eq!(u32::MAX.to_i32(),  None);
1518         assert_eq!(u32::MAX.to_i64(),  Some(u32::MAX as i64));
1519         assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as uint));
1520         assert_eq!(u32::MAX.to_u8(),   None);
1521         assert_eq!(u32::MAX.to_u16(),  None);
1522         assert_eq!(u32::MAX.to_u32(),  Some(u32::MAX as u32));
1523         assert_eq!(u32::MAX.to_u64(),  Some(u32::MAX as u64));
1524
1525         #[cfg(target_word_size = "32")]
1526         fn check_word_size() {
1527             assert_eq!(u32::MAX.to_int(),  None);
1528         }
1529
1530         #[cfg(target_word_size = "64")]
1531         fn check_word_size() {
1532             assert_eq!(u32::MAX.to_int(),  Some(u32::MAX as int));
1533         }
1534
1535         check_word_size();
1536     }
1537
1538     #[test]
1539     fn test_cast_range_u64_max() {
1540         assert_eq!(u64::MAX.to_int(),  None);
1541         assert_eq!(u64::MAX.to_i8(),   None);
1542         assert_eq!(u64::MAX.to_i16(),  None);
1543         assert_eq!(u64::MAX.to_i32(),  None);
1544         assert_eq!(u64::MAX.to_i64(),  None);
1545         // u64::MAX.to_uint() is word-size specific
1546         assert_eq!(u64::MAX.to_u8(),   None);
1547         assert_eq!(u64::MAX.to_u16(),  None);
1548         assert_eq!(u64::MAX.to_u32(),  None);
1549         assert_eq!(u64::MAX.to_u64(),  Some(u64::MAX as u64));
1550
1551         #[cfg(target_word_size = "32")]
1552         fn check_word_size() {
1553             assert_eq!(u64::MAX.to_uint(), None);
1554         }
1555
1556         #[cfg(target_word_size = "64")]
1557         fn check_word_size() {
1558             assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as uint));
1559         }
1560
1561         check_word_size();
1562     }
1563
1564     #[test]
1565     fn test_saturating_add_uint() {
1566         use uint::MAX;
1567         assert_eq!(3u.saturating_add(5u), 8u);
1568         assert_eq!(3u.saturating_add(MAX-1), MAX);
1569         assert_eq!(MAX.saturating_add(MAX), MAX);
1570         assert_eq!((MAX-2).saturating_add(1), MAX-1);
1571     }
1572
1573     #[test]
1574     fn test_saturating_sub_uint() {
1575         use uint::MAX;
1576         assert_eq!(5u.saturating_sub(3u), 2u);
1577         assert_eq!(3u.saturating_sub(5u), 0u);
1578         assert_eq!(0u.saturating_sub(1u), 0u);
1579         assert_eq!((MAX-1).saturating_sub(MAX), 0);
1580     }
1581
1582     #[test]
1583     fn test_saturating_add_int() {
1584         use int::{MIN,MAX};
1585         assert_eq!(3i.saturating_add(5i), 8i);
1586         assert_eq!(3i.saturating_add(MAX-1), MAX);
1587         assert_eq!(MAX.saturating_add(MAX), MAX);
1588         assert_eq!((MAX-2).saturating_add(1), MAX-1);
1589         assert_eq!(3i.saturating_add(-5i), -2i);
1590         assert_eq!(MIN.saturating_add(-1i), MIN);
1591         assert_eq!((-2i).saturating_add(-MAX), MIN);
1592     }
1593
1594     #[test]
1595     fn test_saturating_sub_int() {
1596         use int::{MIN,MAX};
1597         assert_eq!(3i.saturating_sub(5i), -2i);
1598         assert_eq!(MIN.saturating_sub(1i), MIN);
1599         assert_eq!((-2i).saturating_sub(MAX), MIN);
1600         assert_eq!(3i.saturating_sub(-5i), 8i);
1601         assert_eq!(3i.saturating_sub(-(MAX-1)), MAX);
1602         assert_eq!(MAX.saturating_sub(-MAX), MAX);
1603         assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
1604     }
1605
1606     #[test]
1607     fn test_checked_add() {
1608         let five_less = uint::MAX - 5;
1609         assert_eq!(five_less.checked_add(&0), Some(uint::MAX - 5));
1610         assert_eq!(five_less.checked_add(&1), Some(uint::MAX - 4));
1611         assert_eq!(five_less.checked_add(&2), Some(uint::MAX - 3));
1612         assert_eq!(five_less.checked_add(&3), Some(uint::MAX - 2));
1613         assert_eq!(five_less.checked_add(&4), Some(uint::MAX - 1));
1614         assert_eq!(five_less.checked_add(&5), Some(uint::MAX));
1615         assert_eq!(five_less.checked_add(&6), None);
1616         assert_eq!(five_less.checked_add(&7), None);
1617     }
1618
1619     #[test]
1620     fn test_checked_sub() {
1621         assert_eq!(5u.checked_sub(&0), Some(5));
1622         assert_eq!(5u.checked_sub(&1), Some(4));
1623         assert_eq!(5u.checked_sub(&2), Some(3));
1624         assert_eq!(5u.checked_sub(&3), Some(2));
1625         assert_eq!(5u.checked_sub(&4), Some(1));
1626         assert_eq!(5u.checked_sub(&5), Some(0));
1627         assert_eq!(5u.checked_sub(&6), None);
1628         assert_eq!(5u.checked_sub(&7), None);
1629     }
1630
1631     #[test]
1632     fn test_checked_mul() {
1633         let third = uint::MAX / 3;
1634         assert_eq!(third.checked_mul(&0), Some(0));
1635         assert_eq!(third.checked_mul(&1), Some(third));
1636         assert_eq!(third.checked_mul(&2), Some(third * 2));
1637         assert_eq!(third.checked_mul(&3), Some(third * 3));
1638         assert_eq!(third.checked_mul(&4), None);
1639     }
1640
1641     macro_rules! test_next_power_of_two(
1642         ($test_name:ident, $T:ident) => (
1643             fn $test_name() {
1644                 #![test]
1645                 assert_eq!(next_power_of_two::<$T>(0), 0);
1646                 let mut next_power = 1;
1647                 for i in range::<$T>(1, 40) {
1648                      assert_eq!(next_power_of_two(i), next_power);
1649                      if i == next_power { next_power *= 2 }
1650                 }
1651             }
1652         )
1653     )
1654
1655     test_next_power_of_two!(test_next_power_of_two_u8, u8)
1656     test_next_power_of_two!(test_next_power_of_two_u16, u16)
1657     test_next_power_of_two!(test_next_power_of_two_u32, u32)
1658     test_next_power_of_two!(test_next_power_of_two_u64, u64)
1659     test_next_power_of_two!(test_next_power_of_two_uint, uint)
1660
1661     macro_rules! test_checked_next_power_of_two(
1662         ($test_name:ident, $T:ident) => (
1663             fn $test_name() {
1664                 #![test]
1665                 assert_eq!(checked_next_power_of_two::<$T>(0), None);
1666                 let mut next_power = 1;
1667                 for i in range::<$T>(1, 40) {
1668                      assert_eq!(checked_next_power_of_two(i), Some(next_power));
1669                      if i == next_power { next_power *= 2 }
1670                 }
1671                 assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some());
1672                 assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None);
1673                 assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None);
1674             }
1675         )
1676     )
1677
1678     test_checked_next_power_of_two!(test_checked_next_power_of_two_u8, u8)
1679     test_checked_next_power_of_two!(test_checked_next_power_of_two_u16, u16)
1680     test_checked_next_power_of_two!(test_checked_next_power_of_two_u32, u32)
1681     test_checked_next_power_of_two!(test_checked_next_power_of_two_u64, u64)
1682     test_checked_next_power_of_two!(test_checked_next_power_of_two_uint, uint)
1683
1684     #[deriving(Eq, Show)]
1685     struct Value { x: int }
1686
1687     impl ToPrimitive for Value {
1688         fn to_i64(&self) -> Option<i64> { self.x.to_i64() }
1689         fn to_u64(&self) -> Option<u64> { self.x.to_u64() }
1690     }
1691
1692     impl FromPrimitive for Value {
1693         fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as int }) }
1694         fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as int }) }
1695     }
1696
1697     #[test]
1698     fn test_to_primitive() {
1699         let value = Value { x: 5 };
1700         assert_eq!(value.to_int(),  Some(5));
1701         assert_eq!(value.to_i8(),   Some(5));
1702         assert_eq!(value.to_i16(),  Some(5));
1703         assert_eq!(value.to_i32(),  Some(5));
1704         assert_eq!(value.to_i64(),  Some(5));
1705         assert_eq!(value.to_uint(), Some(5));
1706         assert_eq!(value.to_u8(),   Some(5));
1707         assert_eq!(value.to_u16(),  Some(5));
1708         assert_eq!(value.to_u32(),  Some(5));
1709         assert_eq!(value.to_u64(),  Some(5));
1710         assert_eq!(value.to_f32(),  Some(5f32));
1711         assert_eq!(value.to_f64(),  Some(5f64));
1712     }
1713
1714     #[test]
1715     fn test_from_primitive() {
1716         assert_eq!(from_int(5),    Some(Value { x: 5 }));
1717         assert_eq!(from_i8(5),     Some(Value { x: 5 }));
1718         assert_eq!(from_i16(5),    Some(Value { x: 5 }));
1719         assert_eq!(from_i32(5),    Some(Value { x: 5 }));
1720         assert_eq!(from_i64(5),    Some(Value { x: 5 }));
1721         assert_eq!(from_uint(5),   Some(Value { x: 5 }));
1722         assert_eq!(from_u8(5),     Some(Value { x: 5 }));
1723         assert_eq!(from_u16(5),    Some(Value { x: 5 }));
1724         assert_eq!(from_u32(5),    Some(Value { x: 5 }));
1725         assert_eq!(from_u64(5),    Some(Value { x: 5 }));
1726         assert_eq!(from_f32(5f32), Some(Value { x: 5 }));
1727         assert_eq!(from_f64(5f64), Some(Value { x: 5 }));
1728     }
1729
1730     #[test]
1731     fn test_pow() {
1732         fn naive_pow<T: One + Mul<T, T>>(base: T, exp: uint) -> T {
1733             range(0, exp).fold(one::<T>(), |acc, _| acc * base)
1734         }
1735         macro_rules! assert_pow(
1736             (($num:expr, $exp:expr) => $expected:expr) => {{
1737                 let result = pow($num, $exp);
1738                 assert_eq!(result, $expected);
1739                 assert_eq!(result, naive_pow($num, $exp));
1740             }}
1741         )
1742         assert_pow!((3,    0 ) => 1);
1743         assert_pow!((5,    1 ) => 5);
1744         assert_pow!((-4,   2 ) => 16);
1745         assert_pow!((0.5,  5 ) => 0.03125);
1746         assert_pow!((8,    3 ) => 512);
1747         assert_pow!((8.0,  5 ) => 32768.0);
1748         assert_pow!((8.5,  5 ) => 44370.53125);
1749         assert_pow!((2u64, 50) => 1125899906842624);
1750     }
1751 }
1752
1753
1754 #[cfg(test)]
1755 mod bench {
1756     extern crate test;
1757     use self::test::Bencher;
1758     use num;
1759     use prelude::*;
1760
1761     #[bench]
1762     fn bench_pow_function(b: &mut Bencher) {
1763         let v = Vec::from_fn(1024, |n| n);
1764         b.iter(|| {v.iter().fold(0, |old, new| num::pow(old, *new));});
1765     }
1766 }