Explorar el Código

Auto merge of #164 - rust-num:split-into-crates, r=cuviper

Move segments of library to separate crates

Issue #102

- [x] traits
- [x] bigint
- [x] integer
- [x] complex
- [x] iter
- [x] rational
Homu hace 9 años
padre
commit
095738e7de

+ 1 - 1
.multirust.sh

@@ -7,7 +7,7 @@ set -ex
 for toolchain in 1.0.0 beta nightly; do
     run="multirust run $toolchain"
     $run cargo build --verbose
-    $run cargo test --verbose
+    $run make test
     $run .travis/test_features.sh
     if [ $toolchain = nightly ]; then
         $run .travis/test_nightly.sh

+ 2 - 3
.travis.yml

@@ -6,11 +6,10 @@ rust:
 sudo: false
 script:
   - cargo build --verbose
-  - cargo test --verbose
+  - make test
   - .travis/test_features.sh
   - |
-    [ $TRAVIS_RUST_VERSION != nightly ] ||
-    .travis/test_nightly.sh
+    [ $TRAVIS_RUST_VERSION != nightly ] || .travis/test_nightly.sh
   - cargo doc
 after_success: |
   [ $TRAVIS_BRANCH = master ] &&

+ 0 - 2
.travis/test_features.sh

@@ -4,6 +4,4 @@ set -ex
 
 for feature in '' bigint rational complex; do
   cargo build --verbose --no-default-features --features="$feature"
-  cargo test --verbose --no-default-features --features="$feature"
 done
-

+ 1 - 1
.travis/test_nightly.sh

@@ -4,4 +4,4 @@ set -ex
 
 cargo bench --verbose
 
-cargo test --verbose --manifest-path=num-macros/Cargo.toml
+cargo test --verbose --manifest-path=macros/Cargo.toml

+ 52 - 27
Cargo.toml

@@ -1,38 +1,63 @@
 [package]
-
-name = "num"
-version = "0.1.31"
 authors = ["The Rust Project Developers"]
-license = "MIT/Apache-2.0"
-homepage = "https://github.com/rust-num/num"
-repository = "https://github.com/rust-num/num"
+description = "A collection of numeric types and traits for Rust, including bigint,\ncomplex, rational, range iterators, generic integers, and more!\n"
 documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
 keywords = ["mathematics", "numerics"]
-description = """
-A collection of numeric types and traits for Rust, including bigint,
-complex, rational, range iterators, generic integers, and more!
-"""
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-num/num"
+name = "num"
+version = "0.1.31"
+
+[[bench]]
+name = "bigint"
+
+[[bench]]
+harness = false
+name = "shootout-pidigits"
 
 [dependencies]
-rand = { version = "0.3.8", optional = true }
-rustc-serialize = { version = "0.3.13", optional = true }
-serde = { version = "^0.7.0", optional = true }
 
-[dev-dependencies]
-# Some tests of non-rand functionality still use rand because the tests
-# themselves are randomized.
-rand = { version = "0.3.8" }
+[dependencies.num-bigint]
+optional = true
+path = "bigint"
 
-[features]
+[dependencies.num-complex]
+optional = true
+path = "complex"
 
-complex = []
-rational = []
-bigint = []
-default = ["bigint", "complex", "rand", "rational", "rustc-serialize"]
+[dependencies.num-integer]
+path = "./integer"
 
-[[bench]]
-name = "bigint"
+[dependencies.num-iter]
+optional = false
+path = "iter"
 
-[[bench]]
-name = "shootout-pidigits"
-harness = false
+[dependencies.num-rational]
+optional = true
+path = "rational"
+
+[dependencies.num-traits]
+path = "./traits"
+
+[dev-dependencies]
+
+[dev-dependencies.rand]
+version = "0.3.8"
+
+[features]
+bigint = ["num-bigint"]
+complex = ["num-complex"]
+rational = ["num-rational"]
+default = ["bigint", "complex", "rational", "rustc-serialize"]
+
+serde = [
+  "num-bigint/serde",
+  "num-complex/serde",
+  "num-rational/serde"
+]
+rustc-serialize = [
+  "num-bigint/rustc-serialize",
+  "num-complex/rustc-serialize",
+  "num-rational/rustc-serialize"
+]

+ 14 - 0
Makefile

@@ -0,0 +1,14 @@
+CARGO_CMD ?= cargo
+
+packages = bigint complex integer iter rational traits
+
+test:
+	$(MAKE) run-all TASK="test"
+
+run-all: $(packages)
+	$(CARGO_CMD) $(TASK)
+
+$(packages):
+	$(CARGO_CMD) $(TASK) --manifest-path $@/Cargo.toml
+
+.PHONY: $(packages) test

+ 33 - 0
bigint/Cargo.toml

@@ -0,0 +1,33 @@
+[package]
+authors = ["The Rust Project Developers"]
+description = "Big integer implementation for Rust"
+documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
+keywords = ["mathematics", "numerics"]
+license = "MIT/Apache-2.0"
+name = "num-bigint"
+repository = "https://github.com/rust-num/num"
+version = "0.1.0"
+
+[dependencies]
+
+[dependencies.num-integer]
+path = "../integer"
+
+[dependencies.num-traits]
+path = "../traits"
+
+[dependencies.rand]
+optional = true
+version = "0.3.14"
+
+[dependencies.rustc-serialize]
+optional = true
+version = "0.3.19"
+
+[dependencies.serde]
+optional = true
+version = "0.7.0"
+
+[features]
+default = ["rand", "rustc-serialize"]

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 314 - 223
bigint/src/lib.rs


+ 28 - 0
complex/Cargo.toml

@@ -0,0 +1,28 @@
+[package]
+authors = ["The Rust Project Developers"]
+description = "Complex numbers implementation for Rust"
+documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
+keywords = ["mathematics", "numerics"]
+license = "MIT/Apache-2.0"
+name = "num-complex"
+repository = "https://github.com/rust-num/num"
+version = "0.1.0"
+
+[dependencies]
+
+[dependencies.num-traits]
+optional = false
+path = "../traits"
+
+[dependencies.rustc-serialize]
+optional = true
+version = "0.3.19"
+
+[dependencies.serde]
+optional = true
+version = "^0.7.0"
+
+[features]
+default = ["rustc-serialize"]
+unstable = []

+ 21 - 4
src/complex.rs → complex/src/lib.rs

@@ -8,16 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 //! Complex numbers.
 
+extern crate num_traits as traits;
+
+#[cfg(feature = "rustc-serialize")]
+extern crate rustc_serialize;
+
+#[cfg(feature = "serde")]
+extern crate serde;
+
 use std::fmt;
+#[cfg(test)]
+use std::hash;
 use std::ops::{Add, Div, Mul, Neg, Sub};
 
 #[cfg(feature = "serde")]
 use serde;
 
-use {Zero, One, Num, Float};
+use traits::{Zero, One, Num, Float};
 
 // FIXME #1284: handle complex NaN & infinity etc. This
 // probably doesn't map to C's _Complex correctly.
@@ -593,6 +602,14 @@ impl<T> serde::Deserialize for Complex<T> where
     }
 }
 
+#[cfg(test)]
+fn hash<T: hash::Hash>(x: &T) -> u64 {
+    use std::hash::Hasher;
+    let mut hasher = hash::SipHasher::new();
+    x.hash(&mut hasher);
+    hasher.finish()
+}
+
 #[cfg(test)]
 mod test {
     #![allow(non_upper_case_globals)]
@@ -600,7 +617,7 @@ mod test {
     use super::{Complex64, Complex};
     use std::f64;
 
-    use {Zero, One, Float};
+    use traits::{Zero, One, Float};
 
     pub const _0_0i : Complex64 = Complex { re: 0.0, im: 0.0 };
     pub const _1_0i : Complex64 = Complex { re: 1.0, im: 0.0 };
@@ -993,7 +1010,7 @@ mod test {
 
     mod complex_arithmetic {
         use super::{_0_0i, _1_0i, _1_1i, _0_1i, _neg1_1i, _05_05i, all_consts};
-        use Zero;
+        use traits::Zero;
 
         #[test]
         fn test_add() {

+ 13 - 0
integer/Cargo.toml

@@ -0,0 +1,13 @@
+[package]
+authors = ["The Rust Project Developers"]
+description = "Integer traits and functions"
+documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
+keywords = ["mathematics", "numerics"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-num/num"
+name = "num-integer"
+version = "0.1.0"
+
+[dependencies.num-traits]
+path = "../traits"

+ 82 - 48
src/integer.rs → integer/src/lib.rs

@@ -10,17 +10,17 @@
 
 //! Integer trait and functions.
 
-use {Num, Signed};
+extern crate num_traits as traits;
 
-pub trait Integer
-    : Sized + Num + Ord
-{
+use traits::{Num, Signed};
+
+pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// Floored integer division.
     ///
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert!(( 8).div_floor(& 3) ==  2);
     /// assert!(( 8).div_floor(&-3) == -3);
     /// assert!((-8).div_floor(& 3) == -3);
@@ -36,7 +36,7 @@ pub trait Integer
     /// Floored integer modulo, satisfying:
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// # let n = 1; let d = 1;
     /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
     /// ~~~
@@ -44,7 +44,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert!(( 8).mod_floor(& 3) ==  2);
     /// assert!(( 8).mod_floor(&-3) == -1);
     /// assert!((-8).mod_floor(& 3) ==  1);
@@ -62,7 +62,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(6.gcd(&8), 2);
     /// assert_eq!(7.gcd(&3), 1);
     /// ~~~
@@ -73,7 +73,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(7.lcm(&3), 21);
     /// assert_eq!(2.lcm(&4), 4);
     /// ~~~
@@ -87,7 +87,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(9.is_multiple_of(&3), true);
     /// assert_eq!(3.is_multiple_of(&9), false);
     /// ~~~
@@ -98,7 +98,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(3.is_even(), false);
     /// assert_eq!(4.is_even(), true);
     /// ~~~
@@ -109,7 +109,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(3.is_odd(), true);
     /// assert_eq!(4.is_odd(), false);
     /// ~~~
@@ -121,7 +121,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(( 8).div_rem( &3), ( 2,  2));
     /// assert_eq!(( 8).div_rem(&-3), (-2,  2));
     /// assert_eq!((-8).div_rem( &3), (-2, -2));
@@ -141,7 +141,7 @@ pub trait Integer
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(( 8).div_mod_floor( &3), ( 2,  2));
     /// assert_eq!(( 8).div_mod_floor(&-3), (-3, -1));
     /// assert_eq!((-8).div_mod_floor( &3), (-3,  1));
@@ -158,26 +158,44 @@ pub trait Integer
 }
 
 /// Simultaneous integer division and modulus
-#[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
+#[inline]
+pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) {
+    x.div_rem(&y)
+}
 /// Floored integer division
-#[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
+#[inline]
+pub fn div_floor<T: Integer>(x: T, y: T) -> T {
+    x.div_floor(&y)
+}
 /// Floored integer modulus
-#[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
+#[inline]
+pub fn mod_floor<T: Integer>(x: T, y: T) -> T {
+    x.mod_floor(&y)
+}
 /// Simultaneous floored integer division and modulus
-#[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
+#[inline]
+pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) {
+    x.div_mod_floor(&y)
+}
 
 /// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
 /// result is always positive.
-#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
+#[inline(always)]
+pub fn gcd<T: Integer>(x: T, y: T) -> T {
+    x.gcd(&y)
+}
 /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
-#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
+#[inline(always)]
+pub fn lcm<T: Integer>(x: T, y: T) -> T {
+    x.lcm(&y)
+}
 
 macro_rules! impl_integer_for_isize {
     ($T:ty, $test_mod:ident) => (
         impl Integer for $T {
             /// Floored integer division
             #[inline]
-            fn div_floor(&self, other: &$T) -> $T {
+            fn div_floor(&self, other: &Self) -> Self {
                 // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
                 // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
                 match self.div_rem(other) {
@@ -189,7 +207,7 @@ macro_rules! impl_integer_for_isize {
 
             /// Floored integer modulo
             #[inline]
-            fn mod_floor(&self, other: &$T) -> $T {
+            fn mod_floor(&self, other: &Self) -> Self {
                 // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
                 // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
                 match *self % *other {
@@ -201,7 +219,7 @@ macro_rules! impl_integer_for_isize {
 
             /// Calculates `div_floor` and `mod_floor` simultaneously
             #[inline]
-            fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
+            fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
                 // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
                 // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
                 match self.div_rem(other) {
@@ -214,7 +232,7 @@ macro_rules! impl_integer_for_isize {
             /// Calculates the Greatest Common Divisor (GCD) of the number and
             /// `other`. The result is always positive.
             #[inline]
-            fn gcd(&self, other: &$T) -> $T {
+            fn gcd(&self, other: &Self) -> Self {
                 // Use Stein's algorithm
                 let mut m = *self;
                 let mut n = *other;
@@ -231,7 +249,7 @@ macro_rules! impl_integer_for_isize {
                 // Assuming two's complement, the number created by the shift
                 // is positive for all numbers except gcd = abs(min value)
                 // The call to .abs() causes a panic in debug mode
-                if m == <$T>::min_value() || n == <$T>::min_value() {
+                if m == Self::min_value() || n == Self::min_value() {
                     return (1 << shift).abs()
                 }
 
@@ -255,18 +273,22 @@ macro_rules! impl_integer_for_isize {
             /// Calculates the Lowest Common Multiple (LCM) of the number and
             /// `other`.
             #[inline]
-            fn lcm(&self, other: &$T) -> $T {
+            fn lcm(&self, other: &Self) -> Self {
                 // should not have to recalculate abs
                 (*self * (*other / self.gcd(other))).abs()
             }
 
             /// Deprecated, use `is_multiple_of` instead.
             #[inline]
-            fn divides(&self, other: &$T) -> bool { return self.is_multiple_of(other); }
+            fn divides(&self, other: &Self) -> bool {
+                self.is_multiple_of(other)
+            }
 
             /// Returns `true` if the number is a multiple of `other`.
             #[inline]
-            fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
+            fn is_multiple_of(&self, other: &Self) -> bool {
+                *self % *other == 0
+            }
 
             /// Returns `true` if the number is divisible by `2`
             #[inline]
@@ -278,7 +300,7 @@ macro_rules! impl_integer_for_isize {
 
             /// Simultaneous truncated integer division and modulus.
             #[inline]
-            fn div_rem(&self, other: &$T) -> ($T, $T) {
+            fn div_rem(&self, other: &Self) -> (Self, Self) {
                 (*self / *other, *self % *other)
             }
         }
@@ -293,7 +315,7 @@ macro_rules! impl_integer_for_isize {
             /// - `d`: denominator (divisor)
             /// - `qr`: quotient and remainder
             #[cfg(test)]
-            fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
+            fn test_division_rule((n,d): ($T, $T), (q,r): ($T, $T)) {
                 assert_eq!(d * q + r, n);
             }
 
@@ -462,26 +484,30 @@ macro_rules! impl_integer_for_isize {
     )
 }
 
-impl_integer_for_isize!(i8,   test_integer_i8);
-impl_integer_for_isize!(i16,  test_integer_i16);
-impl_integer_for_isize!(i32,  test_integer_i32);
-impl_integer_for_isize!(i64,  test_integer_i64);
-impl_integer_for_isize!(isize,  test_integer_isize);
+impl_integer_for_isize!(i8, test_integer_i8);
+impl_integer_for_isize!(i16, test_integer_i16);
+impl_integer_for_isize!(i32, test_integer_i32);
+impl_integer_for_isize!(i64, test_integer_i64);
+impl_integer_for_isize!(isize, test_integer_isize);
 
 macro_rules! impl_integer_for_usize {
     ($T:ty, $test_mod:ident) => (
         impl Integer for $T {
             /// Unsigned integer division. Returns the same result as `div` (`/`).
             #[inline]
-            fn div_floor(&self, other: &$T) -> $T { *self / *other }
+            fn div_floor(&self, other: &Self) -> Self {
+                *self / *other
+            }
 
             /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
             #[inline]
-            fn mod_floor(&self, other: &$T) -> $T { *self % *other }
+            fn mod_floor(&self, other: &Self) -> Self {
+                *self % *other
+            }
 
             /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
             #[inline]
-            fn gcd(&self, other: &$T) -> $T {
+            fn gcd(&self, other: &Self) -> Self {
                 // Use Stein's algorithm
                 let mut m = *self;
                 let mut n = *other;
@@ -505,29 +531,37 @@ macro_rules! impl_integer_for_usize {
 
             /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
             #[inline]
-            fn lcm(&self, other: &$T) -> $T {
+            fn lcm(&self, other: &Self) -> Self {
                 *self * (*other / self.gcd(other))
             }
 
             /// Deprecated, use `is_multiple_of` instead.
             #[inline]
-            fn divides(&self, other: &$T) -> bool { return self.is_multiple_of(other); }
+            fn divides(&self, other: &Self) -> bool {
+                self.is_multiple_of(other)
+            }
 
             /// Returns `true` if the number is a multiple of `other`.
             #[inline]
-            fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
+            fn is_multiple_of(&self, other: &Self) -> bool {
+                *self % *other == 0
+            }
 
             /// Returns `true` if the number is divisible by `2`.
             #[inline]
-            fn is_even(&self) -> bool { (*self) & 1 == 0 }
+            fn is_even(&self) -> bool {
+                *self % 2 == 0
+            }
 
             /// Returns `true` if the number is not divisible by `2`.
             #[inline]
-            fn is_odd(&self) -> bool { !(*self).is_even() }
+            fn is_odd(&self) -> bool {
+                !self.is_even()
+            }
 
             /// Simultaneous truncated integer division and modulus.
             #[inline]
-            fn div_rem(&self, other: &$T) -> ($T, $T) {
+            fn div_rem(&self, other: &Self) -> (Self, Self) {
                 (*self / *other, *self % *other)
             }
         }
@@ -621,10 +655,10 @@ macro_rules! impl_integer_for_usize {
     )
 }
 
-impl_integer_for_usize!(u8,   test_integer_u8);
-impl_integer_for_usize!(u16,  test_integer_u16);
-impl_integer_for_usize!(u32,  test_integer_u32);
-impl_integer_for_usize!(u64,  test_integer_u64);
+impl_integer_for_usize!(u8, test_integer_u8);
+impl_integer_for_usize!(u16, test_integer_u16);
+impl_integer_for_usize!(u32, test_integer_u32);
+impl_integer_for_usize!(u64, test_integer_u64);
 impl_integer_for_usize!(usize, test_integer_usize);
 
 #[test]

+ 20 - 0
iter/Cargo.toml

@@ -0,0 +1,20 @@
+[package]
+authors = ["The Rust Project Developers"]
+description = "External iterators for generic mathematics"
+documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
+keywords = ["mathematics", "numerics"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-num/num"
+name = "num-iter"
+version = "0.1.0"
+
+[dependencies]
+
+[dependencies.num-integer]
+optional = false
+path = "../integer"
+
+[dependencies.num-traits]
+optional = false
+path = "../traits"

+ 7 - 5
src/iter.rs → iter/src/lib.rs

@@ -10,7 +10,11 @@
 
 //! External iterators for generic mathematics
 
-use {Integer, Zero, One, CheckedAdd, ToPrimitive};
+extern crate num_traits as traits;
+extern crate num_integer as integer;
+
+use integer::Integer;
+use traits::{Zero, One, CheckedAdd, ToPrimitive};
 use std::ops::{Add, Sub};
 
 /// An iterator over the range [start, stop)
@@ -27,11 +31,9 @@ pub struct Range<A> {
 /// # Example
 ///
 /// ```rust
-/// use num::iter;
-///
 /// let array = [0, 1, 2, 3, 4];
 ///
-/// for i in iter::range(0, 5) {
+/// for i in num_iter::range(0, 5) {
 ///     println!("{}", i);
 ///     assert_eq!(i,  array[i]);
 /// }
@@ -261,7 +263,7 @@ mod tests {
     use std::usize;
     use std::ops::{Add, Mul};
     use std::cmp::Ordering;
-    use {One, ToPrimitive};
+    use traits::{One, ToPrimitive};
 
     #[test]
     fn test_range() {

+ 1 - 3
num-macros/Cargo.toml → macros/Cargo.toml

@@ -7,9 +7,7 @@ homepage = "https://github.com/rust-num/num"
 repository = "https://github.com/rust-num/num"
 documentation = "http://rust-num.github.io/num"
 keywords = ["mathematics", "numerics"]
-description = """
-Numeric syntax extensions.
-"""
+description = "Numeric syntax extensions"
 
 [lib]
 name = "num_macros"

+ 0 - 0
num-macros/src/lib.rs → macros/src/lib.rs


+ 0 - 0
num-macros/tests/test_macro.rs → macros/tests/test_macro.rs


+ 34 - 0
rational/Cargo.toml

@@ -0,0 +1,34 @@
+[package]
+authors = ["The Rust Project Developers"]
+description = "Rational numbers implementation for Rust"
+documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
+keywords = ["mathematics", "numerics"]
+license = "MIT/Apache-2.0"
+name = "num-rational"
+repository = "https://github.com/rust-num/num"
+version = "0.1.0"
+
+[dependencies]
+
+[dependencies.num-bigint]
+optional = true
+path = "../bigint"
+
+[dependencies.num-integer]
+path = "../integer"
+
+[dependencies.num-traits]
+path = "../traits"
+
+[dependencies.rustc-serialize]
+optional = true
+version = "0.3.19"
+
+[dependencies.serde]
+optional = true
+version = "0.7.0"
+
+[features]
+default = ["bigint", "rustc-serialize"]
+bigint = ["num-bigint"]

+ 193 - 112
src/rational.rs → rational/src/lib.rs

@@ -10,21 +10,32 @@
 
 //! Rational numbers
 
-use Integer;
+#[cfg(feature = "rustc-serialize")]
+extern crate rustc_serialize;
+#[cfg(feature = "serde")]
+extern crate serde;
+#[cfg(feature = "num-bigint")]
+extern crate num_bigint as bigint;
+
+extern crate num_traits as traits;
+extern crate num_integer as integer;
 
 use std::cmp;
 use std::error::Error;
 use std::fmt;
+#[cfg(test)]
+use std::hash;
 use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
 use std::str::FromStr;
 
 #[cfg(feature = "serde")]
 use serde;
 
-#[cfg(feature = "bigint")]
+#[cfg(feature = "num-bigint")]
 use bigint::{BigInt, BigUint, Sign};
-use traits::{FromPrimitive, Float, PrimInt};
-use {Num, Signed, Zero, One};
+
+use integer::Integer;
+use traits::{FromPrimitive, Float, PrimInt, Num, Signed, Zero, One};
 
 /// Represents the ratio between 2 numbers.
 #[derive(Copy, Clone, Hash, Debug)]
@@ -32,7 +43,7 @@ use {Num, Signed, Zero, One};
 #[allow(missing_docs)]
 pub struct Ratio<T> {
     numer: T,
-    denom: T
+    denom: T,
 }
 
 /// Alias for a `Ratio` of machine-sized integers.
@@ -40,7 +51,7 @@ pub type Rational = Ratio<isize>;
 pub type Rational32 = Ratio<i32>;
 pub type Rational64 = Ratio<i64>;
 
-#[cfg(feature = "bigint")]
+#[cfg(feature = "num-bigint")]
 /// Alias for arbitrary precision rationals.
 pub type BigRational = Ratio<BigInt>;
 
@@ -54,7 +65,10 @@ impl<T: Clone + Integer> Ratio<T> {
     /// Creates a ratio without checking for `denom == 0` or reducing.
     #[inline]
     pub fn new_raw(numer: T, denom: T) -> Ratio<T> {
-        Ratio { numer: numer, denom: denom }
+        Ratio {
+            numer: numer,
+            denom: denom,
+        }
     }
 
     /// Create a new Ratio. Fails if `denom == 0`.
@@ -94,7 +108,7 @@ impl<T: Clone + Integer> Ratio<T> {
 
     /// Put self into lowest terms, with denom > 0.
     fn reduce(&mut self) {
-        let g : T = self.numer.gcd(&self.denom);
+        let g: T = self.numer.gcd(&self.denom);
 
         // FIXME(#5992): assignment operator overloads
         // self.numer /= g;
@@ -128,7 +142,8 @@ impl<T: Clone + Integer> Ratio<T> {
     pub fn floor(&self) -> Ratio<T> {
         if *self < Zero::zero() {
             let one: T = One::one();
-            Ratio::from_integer((self.numer.clone() - self.denom.clone() + one) / self.denom.clone())
+            Ratio::from_integer((self.numer.clone() - self.denom.clone() + one) /
+                                self.denom.clone())
         } else {
             Ratio::from_integer(self.numer.clone() / self.denom.clone())
         }
@@ -141,7 +156,8 @@ impl<T: Clone + Integer> Ratio<T> {
             Ratio::from_integer(self.numer.clone() / self.denom.clone())
         } else {
             let one: T = One::one();
-            Ratio::from_integer((self.numer.clone() + self.denom.clone() - one) / self.denom.clone())
+            Ratio::from_integer((self.numer.clone() + self.denom.clone() - one) /
+                                self.denom.clone())
         }
     }
 
@@ -154,7 +170,9 @@ impl<T: Clone + Integer> Ratio<T> {
 
         // Find unsigned fractional part of rational number
         let mut fractional = self.fract();
-        if fractional < zero { fractional = zero - fractional };
+        if fractional < zero {
+            fractional = zero - fractional
+        };
 
         // The algorithm compares the unsigned fractional part with 1/2, that
         // is, a/b >= 1/2, or a >= b/2. For odd denominators, we use
@@ -197,13 +215,14 @@ impl<T: Clone + Integer + PrimInt> Ratio<T> {
         match expon.cmp(&0) {
             cmp::Ordering::Equal => One::one(),
             cmp::Ordering::Less => self.recip().pow(-expon),
-            cmp::Ordering::Greater => Ratio::new_raw(self.numer.pow(expon as u32),
-                                                     self.denom.pow(expon as u32)),
+            cmp::Ordering::Greater => {
+                Ratio::new_raw(self.numer.pow(expon as u32), self.denom.pow(expon as u32))
+            }
         }
     }
 }
 
-#[cfg(feature = "bigint")]
+#[cfg(feature = "num-bigint")]
 impl Ratio<BigInt> {
     /// Converts a float into a rational number.
     pub fn from_float<T: Float>(f: T) -> Option<BigRational> {
@@ -211,7 +230,11 @@ impl Ratio<BigInt> {
             return None;
         }
         let (mantissa, exponent, sign) = f.integer_decode();
-        let bigint_sign = if sign == 1 { Sign::Plus } else { Sign::Minus };
+        let bigint_sign = if sign == 1 {
+            Sign::Plus
+        } else {
+            Sign::Minus
+        };
         if exponent < 0 {
             let one: BigInt = One::one();
             let denom: BigInt = one << ((-exponent) as usize);
@@ -225,7 +248,7 @@ impl Ratio<BigInt> {
     }
 }
 
-/* Comparisons */
+// Comparisons
 
 // Mathematically, comparing a/b and c/d is the same as comparing a*d and b*c, but it's very easy
 // for those multiplications to overflow fixed-size integers, so we need to take care.
@@ -236,13 +259,21 @@ impl<T: Clone + Integer> Ord for Ratio<T> {
         // With equal denominators, the numerators can be directly compared
         if self.denom == other.denom {
             let ord = self.numer.cmp(&other.numer);
-            return if self.denom < T::zero() { ord.reverse() } else { ord };
+            return if self.denom < T::zero() {
+                ord.reverse()
+            } else {
+                ord
+            };
         }
 
         // With equal numerators, the denominators can be inversely compared
         if self.numer == other.numer {
             let ord = self.denom.cmp(&other.denom);
-            return if self.numer < T::zero() { ord } else { ord.reverse() };
+            return if self.numer < T::zero() {
+                ord
+            } else {
+                ord.reverse()
+            };
         }
 
         // Unfortunately, we don't have CheckedMul to try.  That could sometimes avoid all the
@@ -267,7 +298,7 @@ impl<T: Clone + Integer> Ord for Ratio<T> {
                         self_recip.cmp(&other_recip).reverse()
                     }
                 }
-            },
+            }
         }
     }
 }
@@ -340,17 +371,17 @@ macro_rules! forward_all_binop {
     };
 }
 
-/* Arithmetic */
+// Arithmetic
 forward_all_binop!(impl Mul, mul);
 // a/b * c/d = (a*c)/(b*d)
 impl<'a, 'b, T> Mul<&'b Ratio<T>> for &'a Ratio<T>
     where T: Clone + Integer
 {
-
-        type Output = Ratio<T>;
+    type Output = Ratio<T>;
     #[inline]
     fn mul(self, rhs: &Ratio<T>) -> Ratio<T> {
-        Ratio::new(self.numer.clone() * rhs.numer.clone(), self.denom.clone() * rhs.denom.clone())
+        Ratio::new(self.numer.clone() * rhs.numer.clone(),
+                   self.denom.clone() * rhs.denom.clone())
     }
 }
 
@@ -363,7 +394,8 @@ impl<'a, 'b, T> Div<&'b Ratio<T>> for &'a Ratio<T>
 
     #[inline]
     fn div(self, rhs: &Ratio<T>) -> Ratio<T> {
-        Ratio::new(self.numer.clone() * rhs.denom.clone(), self.denom.clone() * rhs.numer.clone())
+        Ratio::new(self.numer.clone() * rhs.denom.clone(),
+                   self.denom.clone() * rhs.numer.clone())
     }
 }
 
@@ -414,9 +446,8 @@ impl<'a, T> Neg for &'a Ratio<T>
     }
 }
 
-/* Constants */
-impl<T: Clone + Integer>
-    Zero for Ratio<T> {
+// Constants
+impl<T: Clone + Integer> Zero for Ratio<T> {
     #[inline]
     fn zero() -> Ratio<T> {
         Ratio::new_raw(Zero::zero(), One::one())
@@ -428,8 +459,7 @@ impl<T: Clone + Integer>
     }
 }
 
-impl<T: Clone + Integer>
-    One for Ratio<T> {
+impl<T: Clone + Integer> One for Ratio<T> {
     #[inline]
     fn one() -> Ratio<T> {
         Ratio::new_raw(One::one(), One::one())
@@ -443,19 +473,21 @@ impl<T: Clone + Integer> Num for Ratio<T> {
     fn from_str_radix(s: &str, radix: u32) -> Result<Ratio<T>, ParseRatioError> {
         let split: Vec<&str> = s.splitn(2, '/').collect();
         if split.len() < 2 {
-            Err(ParseRatioError{kind: RatioErrorKind::ParseError})
+            Err(ParseRatioError { kind: RatioErrorKind::ParseError })
         } else {
-            let a_result: Result<T, _> = T::from_str_radix(
-                split[0],
-                radix).map_err(|_| ParseRatioError{kind: RatioErrorKind::ParseError});
+            let a_result: Result<T, _> = T::from_str_radix(split[0], radix).map_err(|_| {
+                ParseRatioError { kind: RatioErrorKind::ParseError }
+            });
             a_result.and_then(|a| {
-                let b_result: Result<T, _>  =
-                    T::from_str_radix(split[1], radix).map_err(
-                        |_| ParseRatioError{kind: RatioErrorKind::ParseError});
-                b_result.and_then(|b| if b.is_zero() {
-                    Err(ParseRatioError{kind: RatioErrorKind::ZeroDenominator})
-                } else {
-                    Ok(Ratio::new(a.clone(), b.clone()))
+                let b_result: Result<T, _> = T::from_str_radix(split[1], radix).map_err(|_| {
+                    ParseRatioError { kind: RatioErrorKind::ParseError }
+                });
+                b_result.and_then(|b| {
+                    if b.is_zero() {
+                        Err(ParseRatioError { kind: RatioErrorKind::ZeroDenominator })
+                    } else {
+                        Ok(Ratio::new(a.clone(), b.clone()))
+                    }
                 })
             })
         }
@@ -465,12 +497,20 @@ impl<T: Clone + Integer> Num for Ratio<T> {
 impl<T: Clone + Integer + Signed> Signed for Ratio<T> {
     #[inline]
     fn abs(&self) -> Ratio<T> {
-        if self.is_negative() { -self.clone() } else { self.clone() }
+        if self.is_negative() {
+            -self.clone()
+        } else {
+            self.clone()
+        }
     }
 
     #[inline]
     fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
-        if *self <= *other { Zero::zero() } else { self - other }
+        if *self <= *other {
+            Zero::zero()
+        } else {
+            self - other
+        }
     }
 
     #[inline]
@@ -480,12 +520,14 @@ impl<T: Clone + Integer + Signed> Signed for Ratio<T> {
         } else if self.is_zero() {
             Self::zero()
         } else {
-            - Self::one()
+            -Self::one()
         }
     }
 
     #[inline]
-    fn is_positive(&self) -> bool { !self.is_negative() }
+    fn is_positive(&self) -> bool {
+        !self.is_negative()
+    }
 
     #[inline]
     fn is_negative(&self) -> bool {
@@ -493,9 +535,9 @@ impl<T: Clone + Integer + Signed> Signed for Ratio<T> {
     }
 }
 
-/* String conversions */
-impl<T> fmt::Display for Ratio<T> where
-    T: fmt::Display + Eq + One
+// String conversions
+impl<T> fmt::Display for Ratio<T>
+    where T: fmt::Display + Eq + One
 {
     /// Renders as `numer/denom`. If denom=1, renders as numer.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -514,17 +556,16 @@ impl<T: FromStr + Clone + Integer> FromStr for Ratio<T> {
     fn from_str(s: &str) -> Result<Ratio<T>, ParseRatioError> {
         let mut split = s.splitn(2, '/');
 
-        let n = try!(split.next().ok_or(
-            ParseRatioError{kind: RatioErrorKind::ParseError}));
-        let num = try!(FromStr::from_str(n).map_err(
-            |_| ParseRatioError{kind: RatioErrorKind::ParseError}));
+        let n = try!(split.next().ok_or(ParseRatioError { kind: RatioErrorKind::ParseError }));
+        let num = try!(FromStr::from_str(n)
+                           .map_err(|_| ParseRatioError { kind: RatioErrorKind::ParseError }));
 
         let d = split.next().unwrap_or("1");
-        let den = try!(FromStr::from_str(d).map_err(
-            |_| ParseRatioError{kind: RatioErrorKind::ParseError}));
+        let den = try!(FromStr::from_str(d)
+                           .map_err(|_| ParseRatioError { kind: RatioErrorKind::ParseError }));
 
         if Zero::is_zero(&den) {
-            Err(ParseRatioError{kind: RatioErrorKind::ZeroDenominator})
+            Err(ParseRatioError { kind: RatioErrorKind::ZeroDenominator })
         } else {
             Ok(Ratio::new(num, den))
         }
@@ -535,8 +576,8 @@ impl<T: FromStr + Clone + Integer> FromStr for Ratio<T> {
 impl<T> serde::Serialize for Ratio<T>
     where T: serde::Serialize + Clone + Integer + PartialOrd
 {
-    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
-        S: serde::Serializer
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
+        where S: serde::Serializer
     {
         (self.numer(), self.denom()).serialize(serializer)
     }
@@ -546,8 +587,8 @@ impl<T> serde::Serialize for Ratio<T>
 impl<T> serde::Deserialize for Ratio<T>
     where T: serde::Deserialize + Clone + Integer + PartialOrd
 {
-    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
-        D: serde::Deserializer,
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
+        where D: serde::Deserializer
     {
         let (numer, denom) = try!(serde::Deserialize::deserialize(deserializer));
         if denom == Zero::zero() {
@@ -560,7 +601,9 @@ impl<T> serde::Deserialize for Ratio<T>
 
 // FIXME: Bubble up specific errors
 #[derive(Copy, Clone, Debug, PartialEq)]
-pub struct ParseRatioError { kind: RatioErrorKind }
+pub struct ParseRatioError {
+    kind: RatioErrorKind,
+}
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 enum RatioErrorKind {
@@ -575,7 +618,9 @@ impl fmt::Display for ParseRatioError {
 }
 
 impl Error for ParseRatioError {
-    fn description(&self) -> &str { self.kind.description() }
+    fn description(&self) -> &str {
+        self.kind.description()
+    }
 }
 
 impl RatioErrorKind {
@@ -588,39 +633,73 @@ impl RatioErrorKind {
 }
 
 #[cfg(test)]
-mod test {
+fn hash<T: hash::Hash>(x: &T) -> u64 {
+    use std::hash::Hasher;
+    let mut hasher = hash::SipHasher::new();
+    x.hash(&mut hasher);
+    hasher.finish()
+}
 
+#[cfg(test)]
+mod test {
     use super::{Ratio, Rational};
-    #[cfg(feature = "bigint")]
+    #[cfg(feature = "num-bigint")]
     use super::BigRational;
+
     use std::str::FromStr;
     use std::i32;
-    use {Zero, One, Signed, FromPrimitive, Float};
-
-    pub const _0 : Rational = Ratio { numer: 0, denom: 1};
-    pub const _1 : Rational = Ratio { numer: 1, denom: 1};
-    pub const _2: Rational = Ratio { numer: 2, denom: 1};
-    pub const _1_2: Rational = Ratio { numer: 1, denom: 2};
-    pub const _3_2: Rational = Ratio { numer: 3, denom: 2};
-    pub const _NEG1_2: Rational = Ratio { numer: -1, denom: 2};
-    pub const _1_3: Rational = Ratio { numer: 1, denom: 3};
-    pub const _NEG1_3: Rational = Ratio { numer: -1, denom: 3};
-    pub const _2_3: Rational = Ratio { numer: 2, denom: 3};
-    pub const _NEG2_3: Rational = Ratio { numer: -2, denom: 3};
-
-    #[cfg(feature = "bigint")]
+    use traits::{Zero, One, Signed, FromPrimitive, Float};
+
+    pub const _0: Rational = Ratio {
+        numer: 0,
+        denom: 1,
+    };
+    pub const _1: Rational = Ratio {
+        numer: 1,
+        denom: 1,
+    };
+    pub const _2: Rational = Ratio {
+        numer: 2,
+        denom: 1,
+    };
+    pub const _1_2: Rational = Ratio {
+        numer: 1,
+        denom: 2,
+    };
+    pub const _3_2: Rational = Ratio {
+        numer: 3,
+        denom: 2,
+    };
+    pub const _NEG1_2: Rational = Ratio {
+        numer: -1,
+        denom: 2,
+    };
+    pub const _1_3: Rational = Ratio {
+        numer: 1,
+        denom: 3,
+    };
+    pub const _NEG1_3: Rational = Ratio {
+        numer: -1,
+        denom: 3,
+    };
+    pub const _2_3: Rational = Ratio {
+        numer: 2,
+        denom: 3,
+    };
+    pub const _NEG2_3: Rational = Ratio {
+        numer: -2,
+        denom: 3,
+    };
+
+    #[cfg(feature = "num-bigint")]
     pub fn to_big(n: Rational) -> BigRational {
-        Ratio::new(
-            FromPrimitive::from_isize(n.numer).unwrap(),
-            FromPrimitive::from_isize(n.denom).unwrap()
-        )
+        Ratio::new(FromPrimitive::from_isize(n.numer).unwrap(),
+                   FromPrimitive::from_isize(n.denom).unwrap())
     }
-    #[cfg(not(feature = "bigint"))]
+    #[cfg(not(feature = "num-bigint"))]
     pub fn to_big(n: Rational) -> Rational {
-        Ratio::new(
-            FromPrimitive::from_isize(n.numer).unwrap(),
-            FromPrimitive::from_isize(n.denom).unwrap()
-        )
+        Ratio::new(FromPrimitive::from_isize(n.numer).unwrap(),
+                   FromPrimitive::from_isize(n.denom).unwrap())
     }
 
     #[test]
@@ -629,21 +708,21 @@ mod test {
         assert_eq!(_0, Zero::zero());
         assert_eq!(_1, One::one());
         assert_eq!(_2, Ratio::from_integer(2));
-        assert_eq!(_1_2, Ratio::new(1,2));
-        assert_eq!(_3_2, Ratio::new(3,2));
-        assert_eq!(_NEG1_2, Ratio::new(-1,2));
+        assert_eq!(_1_2, Ratio::new(1, 2));
+        assert_eq!(_3_2, Ratio::new(3, 2));
+        assert_eq!(_NEG1_2, Ratio::new(-1, 2));
     }
 
     #[test]
     fn test_new_reduce() {
-        let one22 = Ratio::new(2,2);
+        let one22 = Ratio::new(2, 2);
 
         assert_eq!(one22, One::one());
     }
     #[test]
     #[should_panic]
     fn test_new_zero() {
-        let _a = Ratio::new(1,0);
+        let _a = Ratio::new(1, 0);
     }
 
 
@@ -690,7 +769,7 @@ mod test {
         for (i, &a) in ratios.iter().enumerate() {
             check_cmp(a, a, Ordering::Equal);
             check_cmp(-a, a, Ordering::Less);
-            for &b in &ratios[i+1..] {
+            for &b in &ratios[i + 1..] {
                 check_cmp(a, b, Ordering::Less);
                 check_cmp(-a, -b, Ordering::Greater);
                 check_cmp(a.recip(), b.recip(), Ordering::Greater);
@@ -785,7 +864,7 @@ mod test {
             }
 
             test(_1, _1_2, _1_2);
-            test(_1_2, _3_2, Ratio::new(3,4));
+            test(_1_2, _3_2, Ratio::new(3, 4));
             test(_1_2, _NEG1_2, Ratio::new(-1, 4));
         }
 
@@ -810,7 +889,7 @@ mod test {
 
             test(_3_2, _1, _1_2);
             test(_2, _NEG1_2, _0);
-            test(_1_2, _2,  _1_2);
+            test(_1_2, _2, _1_2);
         }
 
         #[test]
@@ -835,7 +914,7 @@ mod test {
         #[test]
         #[should_panic]
         fn test_div_0() {
-            let _a =  _1 / _0;
+            let _a = _1 / _0;
         }
     }
 
@@ -879,13 +958,13 @@ mod test {
         // Overflow checks
 
         let _neg1 = Ratio::from_integer(-1);
-        let _large_rat1 = Ratio::new(i32::MAX, i32::MAX-1);
-        let _large_rat2 = Ratio::new(i32::MAX-1, i32::MAX);
-        let _large_rat3 = Ratio::new(i32::MIN+2, i32::MIN+1);
-        let _large_rat4 = Ratio::new(i32::MIN+1, i32::MIN+2);
-        let _large_rat5 = Ratio::new(i32::MIN+2, i32::MAX);
-        let _large_rat6 = Ratio::new(i32::MAX, i32::MIN+2);
-        let _large_rat7 = Ratio::new(1, i32::MIN+1);
+        let _large_rat1 = Ratio::new(i32::MAX, i32::MAX - 1);
+        let _large_rat2 = Ratio::new(i32::MAX - 1, i32::MAX);
+        let _large_rat3 = Ratio::new(i32::MIN + 2, i32::MIN + 1);
+        let _large_rat4 = Ratio::new(i32::MIN + 1, i32::MIN + 2);
+        let _large_rat5 = Ratio::new(i32::MIN + 2, i32::MAX);
+        let _large_rat6 = Ratio::new(i32::MAX, i32::MIN + 2);
+        let _large_rat7 = Ratio::new(1, i32::MIN + 1);
         let _large_rat8 = Ratio::new(1, i32::MAX);
 
         assert_eq!(_large_rat1.round(), One::one());
@@ -947,27 +1026,28 @@ mod test {
             assert!(rational.is_err());
         }
 
-        let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "1/0"];
+        let xs = ["0 /1", "abc", "", "1/", "--1/2", "3/2/1", "1/0"];
         for &s in xs.iter() {
             test(s);
         }
     }
 
-    #[cfg(feature = "bigint")]
+    #[cfg(feature = "num-bigint")]
     #[test]
     fn test_from_float() {
         fn test<T: Float>(given: T, (numer, denom): (&str, &str)) {
             let ratio: BigRational = Ratio::from_float(given).unwrap();
-            assert_eq!(ratio, Ratio::new(
-                FromStr::from_str(numer).unwrap(),
-                FromStr::from_str(denom).unwrap()));
+            assert_eq!(ratio,
+                       Ratio::new(FromStr::from_str(numer).unwrap(),
+                                  FromStr::from_str(denom).unwrap()));
         }
 
         // f32
         test(3.14159265359f32, ("13176795", "4194304"));
         test(2f32.powf(100.), ("1267650600228229401496703205376", "1"));
         test(-2f32.powf(100.), ("-1267650600228229401496703205376", "1"));
-        test(1.0 / 2f32.powf(100.), ("1", "1267650600228229401496703205376"));
+        test(1.0 / 2f32.powf(100.),
+             ("1", "1267650600228229401496703205376"));
         test(684729.48391f32, ("1369459", "2"));
         test(-8573.5918555f32, ("-4389679", "512"));
 
@@ -977,10 +1057,11 @@ mod test {
         test(-2f64.powf(100.), ("-1267650600228229401496703205376", "1"));
         test(684729.48391f64, ("367611342500051", "536870912"));
         test(-8573.5918555f64, ("-4713381968463931", "549755813888"));
-        test(1.0 / 2f64.powf(100.), ("1", "1267650600228229401496703205376"));
+        test(1.0 / 2f64.powf(100.),
+             ("1", "1267650600228229401496703205376"));
     }
 
-    #[cfg(feature = "bigint")]
+    #[cfg(feature = "num-bigint")]
     #[test]
     fn test_from_float_fail() {
         use std::{f32, f64};
@@ -999,10 +1080,10 @@ mod test {
         assert_eq!(_3_2.abs_sub(&_1_2), _1);
         assert_eq!(_1_2.abs_sub(&_3_2), Zero::zero());
         assert_eq!(_1_2.signum(), One::one());
-        assert_eq!(_NEG1_2.signum(), - ::one::<Ratio<isize>>());
+        assert_eq!(_NEG1_2.signum(), -<Ratio<isize>>::one());
         assert!(_NEG1_2.is_negative());
-        assert!(! _NEG1_2.is_positive());
-        assert!(! _1_2.is_negative());
+        assert!(!_NEG1_2.is_positive());
+        assert!(!_1_2.is_negative());
     }
 
     #[test]

+ 32 - 43
src/lib.rs

@@ -57,44 +57,41 @@
        html_root_url = "http://rust-num.github.io/num/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#[cfg(feature = "rustc-serialize")]
-extern crate rustc_serialize;
-
-// Some of the tests of non-RNG-based functionality are randomized using the
-// RNG-based functionality, so the RNG-based functionality needs to be enabled
-// for tests.
-#[cfg(any(feature = "rand", all(feature = "bigint", test)))]
-extern crate rand;
-
-#[cfg(feature = "serde")]
-extern crate serde;
-
-#[cfg(feature = "bigint")]
-pub use bigint::{BigInt, BigUint};
-#[cfg(feature = "rational")]
-pub use rational::Rational;
-#[cfg(all(feature = "rational", feature="bigint"))]
-pub use rational::BigRational;
-#[cfg(feature = "complex")]
-pub use complex::Complex;
-pub use integer::Integer;
-pub use iter::{range, range_inclusive, range_step, range_step_inclusive};
-pub use traits::{Num, Zero, One, Signed, Unsigned, Bounded,
-                 Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
-                 PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast};
-
-#[cfg(test)] use std::hash;
+pub extern crate num_traits;
+pub extern crate num_integer;
+pub extern crate num_iter;
+#[cfg(feature = "num-complex")]
+pub extern crate num_complex;
+#[cfg(feature = "num-bigint")]
+pub extern crate num_bigint;
+#[cfg(feature = "num-rational")]
+pub extern crate num_rational;
+
+#[cfg(feature = "num-bigint")]
+pub use num_bigint::{BigInt, BigUint};
+#[cfg(feature = "num-rational")]
+pub use num_rational::Rational;
+#[cfg(all(feature = "num-rational", feature="num-bigint"))]
+pub use num_rational::BigRational;
+#[cfg(feature = "num-complex")]
+pub use num_complex::Complex;
+pub use num_integer::Integer;
+pub use num_iter::{range, range_inclusive, range_step, range_step_inclusive};
+pub use num_traits::{Num, Zero, One, Signed, Unsigned, Bounded,
+                     Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
+                     PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast};
 
 use std::ops::{Mul};
 
-#[cfg(feature = "bigint")]
-pub mod bigint;
-pub mod complex;
-pub mod integer;
-pub mod iter;
-pub mod traits;
-#[cfg(feature = "rational")]
-pub mod rational;
+#[cfg(feature = "num-bigint")]
+pub use num_bigint as bigint;
+#[cfg(feature = "num-complex")]
+pub use num_complex as complex;
+pub use num_integer as integer;
+pub use num_iter as iter;
+pub use num_traits as traits;
+#[cfg(feature = "num-rational")]
+pub use num_rational as rational;
 
 /// Returns the additive identity, `0`.
 #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
@@ -206,11 +203,3 @@ pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) ->
     }
     Some(acc)
 }
-
-#[cfg(test)]
-fn hash<T: hash::Hash>(x: &T) -> u64 {
-    use std::hash::Hasher;
-    let mut hasher = hash::SipHasher::new();
-    x.hash(&mut hasher);
-    hasher.finish()
-}

+ 0 - 2552
src/traits.rs

@@ -1,2552 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Numeric traits for generic mathematics
-
-use std::ops::{Add, Sub, Mul, Div, Rem, Neg};
-use std::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
-use std::{usize, u8, u16, u32, u64};
-use std::{isize, i8, i16, i32, i64};
-use std::{f32, f64};
-use std::mem::{self, size_of};
-use std::num::FpCategory;
-
-/// The base trait for numeric types
-pub trait Num: PartialEq + Zero + One
-    + Add<Output = Self> + Sub<Output = Self>
-    + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self>
-{
-    /// Parse error for `from_str_radix`
-    type FromStrRadixErr;
-
-    /// Convert from a string and radix <= 36.
-    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
-}
-
-macro_rules! int_trait_impl {
-    ($name:ident for $($t:ty)*) => ($(
-        impl $name for $t {
-            type FromStrRadixErr = ::std::num::ParseIntError;
-            fn from_str_radix(s: &str, radix: u32)
-                              -> Result<Self, ::std::num::ParseIntError>
-            {
-                <$t>::from_str_radix(s, radix)
-            }
-        }
-    )*)
-}
-
-// FIXME: std::num::ParseFloatError is stable in 1.0, but opaque to us,
-// so there's not really any way for us to reuse it.
-#[derive(Debug)]
-pub struct ParseFloatError { pub kind: FloatErrorKind }
-#[derive(Debug)]
-pub enum FloatErrorKind { Empty, Invalid }
-
-// FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
-// with this implementation ourselves until we want to make a breaking change.
-// (would have to drop it from `Num` though)
-macro_rules! float_trait_impl {
-    ($name:ident for $($t:ty)*) => ($(
-        impl $name for $t {
-            type FromStrRadixErr = ParseFloatError;
-            fn from_str_radix(src: &str, radix: u32)
-                              -> Result<Self, ParseFloatError>
-            {
-                use self::FloatErrorKind::*;
-                use self::ParseFloatError as PFE;
-
-                // Special values
-                match src {
-                    "inf"   => return Ok(Float::infinity()),
-                    "-inf"  => return Ok(Float::neg_infinity()),
-                    "NaN"   => return Ok(Float::nan()),
-                    _       => {},
-                }
-
-                fn slice_shift_char(src: &str) -> Option<(char, &str)> {
-                    src.chars().nth(0).map(|ch| (ch, &src[1..]))
-                }
-
-                let (is_positive, src) =  match slice_shift_char(src) {
-                    None             => return Err(PFE { kind: Empty }),
-                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
-                    Some(('-', src)) => (false, src),
-                    Some((_, _))     => (true,  src),
-                };
-
-                // The significand to accumulate
-                let mut sig = if is_positive { 0.0 } else { -0.0 };
-                // Necessary to detect overflow
-                let mut prev_sig = sig;
-                let mut cs = src.chars().enumerate();
-                // Exponent prefix and exponent index offset
-                let mut exp_info = None::<(char, usize)>;
-
-                // Parse the integer part of the significand
-                for (i, c) in cs.by_ref() {
-                    match c.to_digit(radix) {
-                        Some(digit) => {
-                            // shift significand one digit left
-                            sig = sig * (radix as $t);
-
-                            // add/subtract current digit depending on sign
-                            if is_positive {
-                                sig = sig + ((digit as isize) as $t);
-                            } else {
-                                sig = sig - ((digit as isize) as $t);
-                            }
-
-                            // Detect overflow by comparing to last value, except
-                            // if we've not seen any non-zero digits.
-                            if prev_sig != 0.0 {
-                                if is_positive && sig <= prev_sig
-                                    { return Ok(Float::infinity()); }
-                                if !is_positive && sig >= prev_sig
-                                    { return Ok(Float::neg_infinity()); }
-
-                                // Detect overflow by reversing the shift-and-add process
-                                if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
-                                    { return Ok(Float::infinity()); }
-                                if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
-                                    { return Ok(Float::neg_infinity()); }
-                            }
-                            prev_sig = sig;
-                        },
-                        None => match c {
-                            'e' | 'E' | 'p' | 'P' => {
-                                exp_info = Some((c, i + 1));
-                                break;  // start of exponent
-                            },
-                            '.' => {
-                                break;  // start of fractional part
-                            },
-                            _ => {
-                                return Err(PFE { kind: Invalid });
-                            },
-                        },
-                    }
-                }
-
-                // If we are not yet at the exponent parse the fractional
-                // part of the significand
-                if exp_info.is_none() {
-                    let mut power = 1.0;
-                    for (i, c) in cs.by_ref() {
-                        match c.to_digit(radix) {
-                            Some(digit) => {
-                                // Decrease power one order of magnitude
-                                power = power / (radix as $t);
-                                // add/subtract current digit depending on sign
-                                sig = if is_positive {
-                                    sig + (digit as $t) * power
-                                } else {
-                                    sig - (digit as $t) * power
-                                };
-                                // Detect overflow by comparing to last value
-                                if is_positive && sig < prev_sig
-                                    { return Ok(Float::infinity()); }
-                                if !is_positive && sig > prev_sig
-                                    { return Ok(Float::neg_infinity()); }
-                                prev_sig = sig;
-                            },
-                            None => match c {
-                                'e' | 'E' | 'p' | 'P' => {
-                                    exp_info = Some((c, i + 1));
-                                    break; // start of exponent
-                                },
-                                _ => {
-                                    return Err(PFE { kind: Invalid });
-                                },
-                            },
-                        }
-                    }
-                }
-
-                // Parse and calculate the exponent
-                let exp = match exp_info {
-                    Some((c, offset)) => {
-                        let base = match c {
-                            'E' | 'e' if radix == 10 => 10.0,
-                            'P' | 'p' if radix == 16 => 2.0,
-                            _ => return Err(PFE { kind: Invalid }),
-                        };
-
-                        // Parse the exponent as decimal integer
-                        let src = &src[offset..];
-                        let (is_positive, exp) = match slice_shift_char(src) {
-                            Some(('-', src)) => (false, src.parse::<usize>()),
-                            Some(('+', src)) => (true,  src.parse::<usize>()),
-                            Some((_, _))     => (true,  src.parse::<usize>()),
-                            None             => return Err(PFE { kind: Invalid }),
-                        };
-
-                        match (is_positive, exp) {
-                            (true,  Ok(exp)) => base.powi(exp as i32),
-                            (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
-                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
-                        }
-                    },
-                    None => 1.0, // no exponent
-                };
-
-                Ok(sig * exp)
-
-            }
-        }
-    )*)
-}
-
-int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
-float_trait_impl!(Num for f32 f64);
-
-/// Defines an additive identity element for `Self`.
-pub trait Zero: Sized + Add<Self, Output = Self> {
-    /// Returns the additive identity element of `Self`, `0`.
-    ///
-    /// # Laws
-    ///
-    /// ```{.text}
-    /// a + 0 = a       ∀ a ∈ Self
-    /// 0 + a = a       ∀ a ∈ Self
-    /// ```
-    ///
-    /// # Purity
-    ///
-    /// This function should return the same result at all times regardless of
-    /// external mutable state, for example values stored in TLS or in
-    /// `static mut`s.
-    // FIXME (#5527): This should be an associated constant
-    fn zero() -> Self;
-
-    /// Returns `true` if `self` is equal to the additive identity.
-    #[inline]
-    fn is_zero(&self) -> bool;
-}
-
-macro_rules! zero_impl {
-    ($t:ty, $v:expr) => {
-        impl Zero for $t {
-            #[inline]
-            fn zero() -> $t { $v }
-            #[inline]
-            fn is_zero(&self) -> bool { *self == $v }
-        }
-    }
-}
-
-zero_impl!(usize, 0usize);
-zero_impl!(u8,   0u8);
-zero_impl!(u16,  0u16);
-zero_impl!(u32,  0u32);
-zero_impl!(u64,  0u64);
-
-zero_impl!(isize, 0isize);
-zero_impl!(i8,  0i8);
-zero_impl!(i16, 0i16);
-zero_impl!(i32, 0i32);
-zero_impl!(i64, 0i64);
-
-zero_impl!(f32, 0.0f32);
-zero_impl!(f64, 0.0f64);
-
-/// Defines a multiplicative identity element for `Self`.
-pub trait One: Sized + Mul<Self, Output = Self> {
-    /// Returns the multiplicative identity element of `Self`, `1`.
-    ///
-    /// # Laws
-    ///
-    /// ```{.text}
-    /// a * 1 = a       ∀ a ∈ Self
-    /// 1 * a = a       ∀ a ∈ Self
-    /// ```
-    ///
-    /// # Purity
-    ///
-    /// This function should return the same result at all times regardless of
-    /// external mutable state, for example values stored in TLS or in
-    /// `static mut`s.
-    // FIXME (#5527): This should be an associated constant
-    fn one() -> Self;
-}
-
-macro_rules! one_impl {
-    ($t:ty, $v:expr) => {
-        impl One for $t {
-            #[inline]
-            fn one() -> $t { $v }
-        }
-    }
-}
-
-one_impl!(usize, 1usize);
-one_impl!(u8,  1u8);
-one_impl!(u16, 1u16);
-one_impl!(u32, 1u32);
-one_impl!(u64, 1u64);
-
-one_impl!(isize, 1isize);
-one_impl!(i8,  1i8);
-one_impl!(i16, 1i16);
-one_impl!(i32, 1i32);
-one_impl!(i64, 1i64);
-
-one_impl!(f32, 1.0f32);
-one_impl!(f64, 1.0f64);
-
-/// Useful functions for signed numbers (i.e. numbers that can be negative).
-pub trait Signed: Sized + Num + Neg<Output = Self> {
-    /// Computes the absolute value.
-    ///
-    /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
-    ///
-    /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
-    fn abs(&self) -> Self;
-
-    /// The positive difference of two numbers.
-    ///
-    /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
-    /// between `self` and `other` is returned.
-    fn abs_sub(&self, other: &Self) -> Self;
-
-    /// Returns the sign of the number.
-    ///
-    /// For `f32` and `f64`:
-    ///
-    /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
-    /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-    /// * `NaN` if the number is `NaN`
-    ///
-    /// For signed integers:
-    ///
-    /// * `0` if the number is zero
-    /// * `1` if the number is positive
-    /// * `-1` if the number is negative
-    fn signum(&self) -> Self;
-
-    /// Returns true if the number is positive and false if the number is zero or negative.
-    fn is_positive(&self) -> bool;
-
-    /// Returns true if the number is negative and false if the number is zero or positive.
-    fn is_negative(&self) -> bool;
-}
-
-macro_rules! signed_impl {
-    ($($t:ty)*) => ($(
-        impl Signed for $t {
-            #[inline]
-            fn abs(&self) -> $t {
-                if self.is_negative() { -*self } else { *self }
-            }
-
-            #[inline]
-            fn abs_sub(&self, other: &$t) -> $t {
-                if *self <= *other { 0 } else { *self - *other }
-            }
-
-            #[inline]
-            fn signum(&self) -> $t {
-                match *self {
-                    n if n > 0 => 1,
-                    0 => 0,
-                    _ => -1,
-                }
-            }
-
-            #[inline]
-            fn is_positive(&self) -> bool { *self > 0 }
-
-            #[inline]
-            fn is_negative(&self) -> bool { *self < 0 }
-        }
-    )*)
-}
-
-signed_impl!(isize i8 i16 i32 i64);
-
-macro_rules! signed_float_impl {
-    ($t:ty, $nan:expr, $inf:expr, $neg_inf:expr) => {
-        impl Signed for $t {
-            /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
-            #[inline]
-            fn abs(&self) -> $t {
-                <$t>::abs(*self)
-            }
-
-            /// The positive difference of two numbers. Returns `0.0` if the number is
-            /// less than or equal to `other`, otherwise the difference between`self`
-            /// and `other` is returned.
-            #[inline]
-            fn abs_sub(&self, other: &$t) -> $t {
-                <$t>::abs_sub(*self, *other)
-            }
-
-            /// # Returns
-            ///
-            /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
-            /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-            /// - `NAN` if the number is NaN
-            #[inline]
-            fn signum(&self) -> $t {
-                <$t>::signum(*self)
-            }
-
-            /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
-            #[inline]
-            fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == $inf }
-
-            /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
-            #[inline]
-            fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == $neg_inf }
-        }
-    }
-}
-
-signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY);
-signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY);
-
-/// A trait for values which cannot be negative
-pub trait Unsigned: Num {}
-
-macro_rules! empty_trait_impl {
-    ($name:ident for $($t:ty)*) => ($(
-        impl $name for $t {}
-    )*)
-}
-
-empty_trait_impl!(Unsigned for usize u8 u16 u32 u64);
-
-/// Numbers which have upper and lower bounds
-pub trait Bounded {
-    // FIXME (#5527): These should be associated constants
-    /// returns the smallest finite number this type can represent
-    fn min_value() -> Self;
-    /// returns the largest finite number this type can represent
-    fn max_value() -> Self;
-}
-
-macro_rules! bounded_impl {
-    ($t:ty, $min:expr, $max:expr) => {
-        impl Bounded for $t {
-            #[inline]
-            fn min_value() -> $t { $min }
-
-            #[inline]
-            fn max_value() -> $t { $max }
-        }
-    }
-}
-
-bounded_impl!(usize, usize::MIN, usize::MAX);
-bounded_impl!(u8, u8::MIN, u8::MAX);
-bounded_impl!(u16, u16::MIN, u16::MAX);
-bounded_impl!(u32, u32::MIN, u32::MAX);
-bounded_impl!(u64, u64::MIN, u64::MAX);
-
-bounded_impl!(isize, isize::MIN, isize::MAX);
-bounded_impl!(i8, i8::MIN, i8::MAX);
-bounded_impl!(i16, i16::MIN, i16::MAX);
-bounded_impl!(i32, i32::MIN, i32::MAX);
-bounded_impl!(i64, i64::MIN, i64::MAX);
-
-bounded_impl!(f32, f32::MIN, f32::MAX);
-bounded_impl!(f64, f64::MIN, f64::MAX);
-
-macro_rules! for_each_tuple_ {
-    ( $m:ident !! ) => (
-        $m! { }
-    );
-    ( $m:ident !! $h:ident, $($t:ident,)* ) => (
-        $m! { $h $($t)* }
-        for_each_tuple_! { $m !! $($t,)* }
-    );
-}
-macro_rules! for_each_tuple {
-    ( $m:ident ) => (
-        for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
-    );
-}
-
-macro_rules! bounded_tuple {
-    ( $($name:ident)* ) => (
-        impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
-            fn min_value() -> Self {
-                ($($name::min_value(),)*)
-            }
-            fn max_value() -> Self {
-                ($($name::max_value(),)*)
-            }
-        }
-    );
-}
-
-for_each_tuple!(bounded_tuple);
-
-/// Saturating math operations
-pub trait Saturating {
-    /// Saturating addition operator.
-    /// Returns a+b, saturating at the numeric bounds instead of overflowing.
-    fn saturating_add(self, v: Self) -> Self;
-
-    /// Saturating subtraction operator.
-    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
-    fn saturating_sub(self, v: Self) -> Self;
-}
-
-impl<T: CheckedAdd + CheckedSub + Zero + PartialOrd + Bounded> Saturating for T {
-    #[inline]
-    fn saturating_add(self, v: T) -> T {
-        match self.checked_add(&v) {
-            Some(x) => x,
-            None => if v >= Zero::zero() {
-                Bounded::max_value()
-            } else {
-                Bounded::min_value()
-            }
-        }
-    }
-
-    #[inline]
-    fn saturating_sub(self, v: T) -> T {
-        match self.checked_sub(&v) {
-            Some(x) => x,
-            None => if v >= Zero::zero() {
-                Bounded::min_value()
-            } else {
-                Bounded::max_value()
-            }
-        }
-    }
-}
-
-/// Performs addition that returns `None` instead of wrapping around on
-/// overflow.
-pub trait CheckedAdd: Sized + Add<Self, Output = Self> {
-    /// Adds two numbers, checking for overflow. If overflow happens, `None` is
-    /// returned.
-    fn checked_add(&self, v: &Self) -> Option<Self>;
-}
-
-macro_rules! checked_impl {
-    ($trait_name:ident, $method:ident, $t:ty) => {
-        impl $trait_name for $t {
-            #[inline]
-            fn $method(&self, v: &$t) -> Option<$t> {
-                <$t>::$method(*self, *v)
-            }
-        }
-    }
-}
-
-checked_impl!(CheckedAdd, checked_add, u8);
-checked_impl!(CheckedAdd, checked_add, u16);
-checked_impl!(CheckedAdd, checked_add, u32);
-checked_impl!(CheckedAdd, checked_add, u64);
-checked_impl!(CheckedAdd, checked_add, usize);
-
-checked_impl!(CheckedAdd, checked_add, i8);
-checked_impl!(CheckedAdd, checked_add, i16);
-checked_impl!(CheckedAdd, checked_add, i32);
-checked_impl!(CheckedAdd, checked_add, i64);
-checked_impl!(CheckedAdd, checked_add, isize);
-
-/// Performs subtraction that returns `None` instead of wrapping around on underflow.
-pub trait CheckedSub: Sized + Sub<Self, Output = Self> {
-    /// Subtracts two numbers, checking for underflow. If underflow happens,
-    /// `None` is returned.
-    fn checked_sub(&self, v: &Self) -> Option<Self>;
-}
-
-checked_impl!(CheckedSub, checked_sub, u8);
-checked_impl!(CheckedSub, checked_sub, u16);
-checked_impl!(CheckedSub, checked_sub, u32);
-checked_impl!(CheckedSub, checked_sub, u64);
-checked_impl!(CheckedSub, checked_sub, usize);
-
-checked_impl!(CheckedSub, checked_sub, i8);
-checked_impl!(CheckedSub, checked_sub, i16);
-checked_impl!(CheckedSub, checked_sub, i32);
-checked_impl!(CheckedSub, checked_sub, i64);
-checked_impl!(CheckedSub, checked_sub, isize);
-
-/// Performs multiplication that returns `None` instead of wrapping around on underflow or
-/// overflow.
-pub trait CheckedMul: Sized + Mul<Self, Output = Self> {
-    /// Multiplies two numbers, checking for underflow or overflow. If underflow
-    /// or overflow happens, `None` is returned.
-    fn checked_mul(&self, v: &Self) -> Option<Self>;
-}
-
-checked_impl!(CheckedMul, checked_mul, u8);
-checked_impl!(CheckedMul, checked_mul, u16);
-checked_impl!(CheckedMul, checked_mul, u32);
-checked_impl!(CheckedMul, checked_mul, u64);
-checked_impl!(CheckedMul, checked_mul, usize);
-
-checked_impl!(CheckedMul, checked_mul, i8);
-checked_impl!(CheckedMul, checked_mul, i16);
-checked_impl!(CheckedMul, checked_mul, i32);
-checked_impl!(CheckedMul, checked_mul, i64);
-checked_impl!(CheckedMul, checked_mul, isize);
-
-/// Performs division that returns `None` instead of panicking on division by zero and instead of
-/// wrapping around on underflow and overflow.
-pub trait CheckedDiv: Sized + Div<Self, Output = Self> {
-    /// Divides two numbers, checking for underflow, overflow and division by
-    /// zero. If any of that happens, `None` is returned.
-    fn checked_div(&self, v: &Self) -> Option<Self>;
-}
-
-macro_rules! checkeddiv_int_impl {
-    ($t:ty, $min:expr) => {
-        impl CheckedDiv for $t {
-            #[inline]
-            fn checked_div(&self, v: &$t) -> Option<$t> {
-                if *v == 0 || (*self == $min && *v == -1) {
-                    None
-                } else {
-                    Some(*self / *v)
-                }
-            }
-        }
-    }
-}
-
-checkeddiv_int_impl!(isize, isize::MIN);
-checkeddiv_int_impl!(i8, i8::MIN);
-checkeddiv_int_impl!(i16, i16::MIN);
-checkeddiv_int_impl!(i32, i32::MIN);
-checkeddiv_int_impl!(i64, i64::MIN);
-
-macro_rules! checkeddiv_uint_impl {
-    ($($t:ty)*) => ($(
-        impl CheckedDiv for $t {
-            #[inline]
-            fn checked_div(&self, v: &$t) -> Option<$t> {
-                if *v == 0 {
-                    None
-                } else {
-                    Some(*self / *v)
-                }
-            }
-        }
-    )*)
-}
-
-checkeddiv_uint_impl!(usize u8 u16 u32 u64);
-
-pub trait PrimInt
-    : Sized
-    + Copy
-    + Num + NumCast
-    + Bounded
-    + PartialOrd + Ord + Eq
-    + Not<Output=Self>
-    + BitAnd<Output=Self>
-    + BitOr<Output=Self>
-    + BitXor<Output=Self>
-    + Shl<usize, Output=Self>
-    + Shr<usize, Output=Self>
-    + CheckedAdd<Output=Self>
-    + CheckedSub<Output=Self>
-    + CheckedMul<Output=Self>
-    + CheckedDiv<Output=Self>
-    + Saturating
-{
-    /// Returns the number of ones in the binary representation of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0b01001100u8;
-    ///
-    /// assert_eq!(n.count_ones(), 3);
-    /// ```
-    fn count_ones(self) -> u32;
-
-    /// Returns the number of zeros in the binary representation of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0b01001100u8;
-    ///
-    /// assert_eq!(n.count_zeros(), 5);
-    /// ```
-    fn count_zeros(self) -> u32;
-
-    /// Returns the number of leading zeros in the binary representation
-    /// of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0b0101000u16;
-    ///
-    /// assert_eq!(n.leading_zeros(), 10);
-    /// ```
-    fn leading_zeros(self) -> u32;
-
-    /// Returns the number of trailing zeros in the binary representation
-    /// of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0b0101000u16;
-    ///
-    /// assert_eq!(n.trailing_zeros(), 3);
-    /// ```
-    fn trailing_zeros(self) -> u32;
-
-    /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
-    /// the truncated bits to the end of the resulting integer.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0x3456789ABCDEF012u64;
-    ///
-    /// assert_eq!(n.rotate_left(12), m);
-    /// ```
-    fn rotate_left(self, n: u32) -> Self;
-
-    /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
-    /// the truncated bits to the beginning of the resulting integer.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0xDEF0123456789ABCu64;
-    ///
-    /// assert_eq!(n.rotate_right(12), m);
-    /// ```
-    fn rotate_right(self, n: u32) -> Self;
-
-    /// Shifts the bits to the left by a specified amount amount, `n`, filling
-    /// zeros in the least significant bits.
-    ///
-    /// This is bitwise equivalent to signed `Shl`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0x3456789ABCDEF000u64;
-    ///
-    /// assert_eq!(n.signed_shl(12), m);
-    /// ```
-    fn signed_shl(self, n: u32) -> Self;
-
-    /// Shifts the bits to the right by a specified amount amount, `n`, copying
-    /// the "sign bit" in the most significant bits even for unsigned types.
-    ///
-    /// This is bitwise equivalent to signed `Shr`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0xFEDCBA9876543210u64;
-    /// let m = 0xFFFFEDCBA9876543u64;
-    ///
-    /// assert_eq!(n.signed_shr(12), m);
-    /// ```
-    fn signed_shr(self, n: u32) -> Self;
-
-    /// Shifts the bits to the left by a specified amount amount, `n`, filling
-    /// zeros in the least significant bits.
-    ///
-    /// This is bitwise equivalent to unsigned `Shl`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFi64;
-    /// let m = 0x3456789ABCDEF000i64;
-    ///
-    /// assert_eq!(n.unsigned_shl(12), m);
-    /// ```
-    fn unsigned_shl(self, n: u32) -> Self;
-
-    /// Shifts the bits to the right by a specified amount amount, `n`, filling
-    /// zeros in the most significant bits.
-    ///
-    /// This is bitwise equivalent to unsigned `Shr`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0xFEDCBA9876543210i64;
-    /// let m = 0x000FEDCBA9876543i64;
-    ///
-    /// assert_eq!(n.unsigned_shr(12), m);
-    /// ```
-    fn unsigned_shr(self, n: u32) -> Self;
-
-    /// Reverses the byte order of the integer.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0xEFCDAB8967452301u64;
-    ///
-    /// assert_eq!(n.swap_bytes(), m);
-    /// ```
-    fn swap_bytes(self) -> Self;
-
-    /// Convert an integer from big endian to the target's endianness.
-    ///
-    /// On big endian this is a no-op. On little endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "big") {
-    ///     assert_eq!(u64::from_be(n), n)
-    /// } else {
-    ///     assert_eq!(u64::from_be(n), n.swap_bytes())
-    /// }
-    /// ```
-    fn from_be(x: Self) -> Self;
-
-    /// Convert an integer from little endian to the target's endianness.
-    ///
-    /// On little endian this is a no-op. On big endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "little") {
-    ///     assert_eq!(u64::from_le(n), n)
-    /// } else {
-    ///     assert_eq!(u64::from_le(n), n.swap_bytes())
-    /// }
-    /// ```
-    fn from_le(x: Self) -> Self;
-
-    /// Convert `self` to big endian from the target's endianness.
-    ///
-    /// On big endian this is a no-op. On little endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "big") {
-    ///     assert_eq!(n.to_be(), n)
-    /// } else {
-    ///     assert_eq!(n.to_be(), n.swap_bytes())
-    /// }
-    /// ```
-    fn to_be(self) -> Self;
-
-    /// Convert `self` to little endian from the target's endianness.
-    ///
-    /// On little endian this is a no-op. On big endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "little") {
-    ///     assert_eq!(n.to_le(), n)
-    /// } else {
-    ///     assert_eq!(n.to_le(), n.swap_bytes())
-    /// }
-    /// ```
-    fn to_le(self) -> Self;
-
-    /// Raises self to the power of `exp`, using exponentiation by squaring.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use num::traits::PrimInt;
-    ///
-    /// assert_eq!(2i32.pow(4), 16);
-    /// ```
-    fn pow(self, mut exp: u32) -> Self;
-}
-
-macro_rules! prim_int_impl {
-    ($T:ty, $S:ty, $U:ty) => (
-        impl PrimInt for $T {
-            fn count_ones(self) -> u32 {
-                <$T>::count_ones(self)
-            }
-
-            fn count_zeros(self) -> u32 {
-                <$T>::count_zeros(self)
-            }
-
-            fn leading_zeros(self) -> u32 {
-                <$T>::leading_zeros(self)
-            }
-
-            fn trailing_zeros(self) -> u32 {
-                <$T>::trailing_zeros(self)
-            }
-
-            fn rotate_left(self, n: u32) -> Self {
-                <$T>::rotate_left(self, n)
-            }
-
-            fn rotate_right(self, n: u32) -> Self {
-                <$T>::rotate_right(self, n)
-            }
-
-            fn signed_shl(self, n: u32) -> Self {
-                ((self as $S) << n) as $T
-            }
-
-            fn signed_shr(self, n: u32) -> Self {
-                ((self as $S) >> n) as $T
-            }
-
-            fn unsigned_shl(self, n: u32) -> Self {
-                ((self as $U) << n) as $T
-            }
-
-            fn unsigned_shr(self, n: u32) -> Self {
-                ((self as $U) >> n) as $T
-            }
-
-            fn swap_bytes(self) -> Self {
-                <$T>::swap_bytes(self)
-            }
-
-            fn from_be(x: Self) -> Self {
-                <$T>::from_be(x)
-            }
-
-            fn from_le(x: Self) -> Self {
-                <$T>::from_le(x)
-            }
-
-            fn to_be(self) -> Self {
-                <$T>::to_be(self)
-            }
-
-            fn to_le(self) -> Self {
-                <$T>::to_le(self)
-            }
-
-            fn pow(self, exp: u32) -> Self {
-                <$T>::pow(self, exp)
-            }
-        }
-    )
-}
-
-// prim_int_impl!(type, signed, unsigned);
-prim_int_impl!(u8,    i8,    u8);
-prim_int_impl!(u16,   i16,   u16);
-prim_int_impl!(u32,   i32,   u32);
-prim_int_impl!(u64,   i64,   u64);
-prim_int_impl!(usize, isize, usize);
-prim_int_impl!(i8,    i8,    u8);
-prim_int_impl!(i16,   i16,   u16);
-prim_int_impl!(i32,   i32,   u32);
-prim_int_impl!(i64,   i64,   u64);
-prim_int_impl!(isize, isize, usize);
-
-/// A generic trait for converting a value to a number.
-pub trait ToPrimitive {
-    /// Converts the value of `self` to an `isize`.
-    #[inline]
-    fn to_isize(&self) -> Option<isize> {
-        self.to_i64().and_then(|x| x.to_isize())
-    }
-
-    /// Converts the value of `self` to an `i8`.
-    #[inline]
-    fn to_i8(&self) -> Option<i8> {
-        self.to_i64().and_then(|x| x.to_i8())
-    }
-
-    /// Converts the value of `self` to an `i16`.
-    #[inline]
-    fn to_i16(&self) -> Option<i16> {
-        self.to_i64().and_then(|x| x.to_i16())
-    }
-
-    /// Converts the value of `self` to an `i32`.
-    #[inline]
-    fn to_i32(&self) -> Option<i32> {
-        self.to_i64().and_then(|x| x.to_i32())
-    }
-
-    /// Converts the value of `self` to an `i64`.
-    fn to_i64(&self) -> Option<i64>;
-
-    /// Converts the value of `self` to a `usize`.
-    #[inline]
-    fn to_usize(&self) -> Option<usize> {
-        self.to_u64().and_then(|x| x.to_usize())
-    }
-
-    /// Converts the value of `self` to an `u8`.
-    #[inline]
-    fn to_u8(&self) -> Option<u8> {
-        self.to_u64().and_then(|x| x.to_u8())
-    }
-
-    /// Converts the value of `self` to an `u16`.
-    #[inline]
-    fn to_u16(&self) -> Option<u16> {
-        self.to_u64().and_then(|x| x.to_u16())
-    }
-
-    /// Converts the value of `self` to an `u32`.
-    #[inline]
-    fn to_u32(&self) -> Option<u32> {
-        self.to_u64().and_then(|x| x.to_u32())
-    }
-
-    /// Converts the value of `self` to an `u64`.
-    #[inline]
-    fn to_u64(&self) -> Option<u64>;
-
-    /// Converts the value of `self` to an `f32`.
-    #[inline]
-    fn to_f32(&self) -> Option<f32> {
-        self.to_f64().and_then(|x| x.to_f32())
-    }
-
-    /// Converts the value of `self` to an `f64`.
-    #[inline]
-    fn to_f64(&self) -> Option<f64> {
-        self.to_i64().and_then(|x| x.to_f64())
-    }
-}
-
-macro_rules! impl_to_primitive_int_to_int {
-    ($SrcT:ty, $DstT:ty, $slf:expr) => (
-        {
-            if size_of::<$SrcT>() <= size_of::<$DstT>() {
-                Some($slf as $DstT)
-            } else {
-                let n = $slf as i64;
-                let min_value: $DstT = Bounded::min_value();
-                let max_value: $DstT = Bounded::max_value();
-                if min_value as i64 <= n && n <= max_value as i64 {
-                    Some($slf as $DstT)
-                } else {
-                    None
-                }
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_int_to_uint {
-    ($SrcT:ty, $DstT:ty, $slf:expr) => (
-        {
-            let zero: $SrcT = Zero::zero();
-            let max_value: $DstT = Bounded::max_value();
-            if zero <= $slf && $slf as u64 <= max_value as u64 {
-                Some($slf as $DstT)
-            } else {
-                None
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_int {
-    ($T:ty) => (
-        impl ToPrimitive for $T {
-            #[inline]
-            fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
-            #[inline]
-            fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
-            #[inline]
-            fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
-            #[inline]
-            fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
-            #[inline]
-            fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
-
-            #[inline]
-            fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
-            #[inline]
-            fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
-            #[inline]
-            fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
-            #[inline]
-            fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
-            #[inline]
-            fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
-
-            #[inline]
-            fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
-            #[inline]
-            fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
-        }
-    )
-}
-
-impl_to_primitive_int! { isize }
-impl_to_primitive_int! { i8 }
-impl_to_primitive_int! { i16 }
-impl_to_primitive_int! { i32 }
-impl_to_primitive_int! { i64 }
-
-macro_rules! impl_to_primitive_uint_to_int {
-    ($DstT:ty, $slf:expr) => (
-        {
-            let max_value: $DstT = Bounded::max_value();
-            if $slf as u64 <= max_value as u64 {
-                Some($slf as $DstT)
-            } else {
-                None
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_uint_to_uint {
-    ($SrcT:ty, $DstT:ty, $slf:expr) => (
-        {
-            if size_of::<$SrcT>() <= size_of::<$DstT>() {
-                Some($slf as $DstT)
-            } else {
-                let zero: $SrcT = Zero::zero();
-                let max_value: $DstT = Bounded::max_value();
-                if zero <= $slf && $slf as u64 <= max_value as u64 {
-                    Some($slf as $DstT)
-                } else {
-                    None
-                }
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_uint {
-    ($T:ty) => (
-        impl ToPrimitive for $T {
-            #[inline]
-            fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
-            #[inline]
-            fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
-            #[inline]
-            fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
-            #[inline]
-            fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
-            #[inline]
-            fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
-
-            #[inline]
-            fn to_usize(&self) -> Option<usize> {
-                impl_to_primitive_uint_to_uint!($T, usize, *self)
-            }
-            #[inline]
-            fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
-            #[inline]
-            fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
-            #[inline]
-            fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
-            #[inline]
-            fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
-
-            #[inline]
-            fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
-            #[inline]
-            fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
-        }
-    )
-}
-
-impl_to_primitive_uint! { usize }
-impl_to_primitive_uint! { u8 }
-impl_to_primitive_uint! { u16 }
-impl_to_primitive_uint! { u32 }
-impl_to_primitive_uint! { u64 }
-
-macro_rules! impl_to_primitive_float_to_float {
-    ($SrcT:ident, $DstT:ident, $slf:expr) => (
-        if size_of::<$SrcT>() <= size_of::<$DstT>() {
-            Some($slf as $DstT)
-        } else {
-            let n = $slf as f64;
-            let max_value: $SrcT = ::std::$SrcT::MAX;
-            if -max_value as f64 <= n && n <= max_value as f64 {
-                Some($slf as $DstT)
-            } else {
-                None
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_float {
-    ($T:ident) => (
-        impl ToPrimitive for $T {
-            #[inline]
-            fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
-            #[inline]
-            fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
-            #[inline]
-            fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
-            #[inline]
-            fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
-            #[inline]
-            fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
-
-            #[inline]
-            fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
-            #[inline]
-            fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
-            #[inline]
-            fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
-            #[inline]
-            fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
-            #[inline]
-            fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
-
-            #[inline]
-            fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
-            #[inline]
-            fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
-        }
-    )
-}
-
-impl_to_primitive_float! { f32 }
-impl_to_primitive_float! { f64 }
-
-/// A generic trait for converting a number to a value.
-pub trait FromPrimitive: Sized {
-    /// Convert an `isize` to return an optional value of this type. If the
-    /// value cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_isize(n: isize) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Convert an `i8` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_i8(n: i8) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Convert an `i16` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_i16(n: i16) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Convert an `i32` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_i32(n: i32) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Convert an `i64` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    fn from_i64(n: i64) -> Option<Self>;
-
-    /// Convert a `usize` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_usize(n: usize) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Convert an `u8` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_u8(n: u8) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Convert an `u16` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_u16(n: u16) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Convert an `u32` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_u32(n: u32) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Convert an `u64` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    fn from_u64(n: u64) -> Option<Self>;
-
-    /// Convert a `f32` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_f32(n: f32) -> Option<Self> {
-        FromPrimitive::from_f64(n as f64)
-    }
-
-    /// Convert a `f64` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_f64(n: f64) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-}
-
-macro_rules! impl_from_primitive {
-    ($T:ty, $to_ty:ident) => (
-        #[allow(deprecated)]
-        impl FromPrimitive for $T {
-            #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
-
-            #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
-
-            #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
-        }
-    )
-}
-
-impl_from_primitive! { isize, to_isize }
-impl_from_primitive! { i8, to_i8 }
-impl_from_primitive! { i16, to_i16 }
-impl_from_primitive! { i32, to_i32 }
-impl_from_primitive! { i64, to_i64 }
-impl_from_primitive! { usize, to_usize }
-impl_from_primitive! { u8, to_u8 }
-impl_from_primitive! { u16, to_u16 }
-impl_from_primitive! { u32, to_u32 }
-impl_from_primitive! { u64, to_u64 }
-impl_from_primitive! { f32, to_f32 }
-impl_from_primitive! { f64, to_f64 }
-
-/// Cast from one machine scalar to another.
-///
-/// # Examples
-///
-/// ```
-/// use num;
-///
-/// let twenty: f32 = num::cast(0x14).unwrap();
-/// assert_eq!(twenty, 20f32);
-/// ```
-///
-#[inline]
-pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> {
-    NumCast::from(n)
-}
-
-/// An interface for casting between machine scalars.
-pub trait NumCast: Sized + ToPrimitive {
-    /// Creates a number from another value that can be converted into
-    /// a primitive via the `ToPrimitive` trait.
-    fn from<T: ToPrimitive>(n: T) -> Option<Self>;
-}
-
-macro_rules! impl_num_cast {
-    ($T:ty, $conv:ident) => (
-        impl NumCast for $T {
-            #[inline]
-            #[allow(deprecated)]
-            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
-                // `$conv` could be generated using `concat_idents!`, but that
-                // macro seems to be broken at the moment
-                n.$conv()
-            }
-        }
-    )
-}
-
-impl_num_cast! { u8,    to_u8 }
-impl_num_cast! { u16,   to_u16 }
-impl_num_cast! { u32,   to_u32 }
-impl_num_cast! { u64,   to_u64 }
-impl_num_cast! { usize,  to_usize }
-impl_num_cast! { i8,    to_i8 }
-impl_num_cast! { i16,   to_i16 }
-impl_num_cast! { i32,   to_i32 }
-impl_num_cast! { i64,   to_i64 }
-impl_num_cast! { isize,   to_isize }
-impl_num_cast! { f32,   to_f32 }
-impl_num_cast! { f64,   to_f64 }
-
-pub trait Float
-    : Num
-    + Copy
-    + NumCast
-    + PartialOrd
-    + Neg<Output = Self>
-{
-    /// Returns the `NaN` value.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let nan: f32 = Float::nan();
-    ///
-    /// assert!(nan.is_nan());
-    /// ```
-    fn nan() -> Self;
-    /// Returns the infinite value.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f32;
-    ///
-    /// let infinity: f32 = Float::infinity();
-    ///
-    /// assert!(infinity.is_infinite());
-    /// assert!(!infinity.is_finite());
-    /// assert!(infinity > f32::MAX);
-    /// ```
-    fn infinity() -> Self;
-    /// Returns the negative infinite value.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f32;
-    ///
-    /// let neg_infinity: f32 = Float::neg_infinity();
-    ///
-    /// assert!(neg_infinity.is_infinite());
-    /// assert!(!neg_infinity.is_finite());
-    /// assert!(neg_infinity < f32::MIN);
-    /// ```
-    fn neg_infinity() -> Self;
-    /// Returns `-0.0`.
-    ///
-    /// ```
-    /// use num::traits::{Zero, Float};
-    ///
-    /// let inf: f32 = Float::infinity();
-    /// let zero: f32 = Zero::zero();
-    /// let neg_zero: f32 = Float::neg_zero();
-    ///
-    /// assert_eq!(zero, neg_zero);
-    /// assert_eq!(7.0f32/inf, zero);
-    /// assert_eq!(zero * 10.0, zero);
-    /// ```
-    fn neg_zero() -> Self;
-
-    /// Returns the smallest finite value that this type can represent.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x: f64 = Float::min_value();
-    ///
-    /// assert_eq!(x, f64::MIN);
-    /// ```
-    fn min_value() -> Self;
-
-    /// Returns the smallest positive, normalized value that this type can represent.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x: f64 = Float::min_positive_value();
-    ///
-    /// assert_eq!(x, f64::MIN_POSITIVE);
-    /// ```
-    fn min_positive_value() -> Self;
-
-    /// Returns the largest finite value that this type can represent.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x: f64 = Float::max_value();
-    /// assert_eq!(x, f64::MAX);
-    /// ```
-    fn max_value() -> Self;
-
-    /// Returns `true` if this value is `NaN` and false otherwise.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let nan = f64::NAN;
-    /// let f = 7.0;
-    ///
-    /// assert!(nan.is_nan());
-    /// assert!(!f.is_nan());
-    /// ```
-    fn is_nan(self) -> bool;
-
-    /// Returns `true` if this value is positive infinity or negative infinity and
-    /// false otherwise.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f32;
-    ///
-    /// let f = 7.0f32;
-    /// let inf: f32 = Float::infinity();
-    /// let neg_inf: f32 = Float::neg_infinity();
-    /// let nan: f32 = f32::NAN;
-    ///
-    /// assert!(!f.is_infinite());
-    /// assert!(!nan.is_infinite());
-    ///
-    /// assert!(inf.is_infinite());
-    /// assert!(neg_inf.is_infinite());
-    /// ```
-    fn is_infinite(self) -> bool;
-
-    /// Returns `true` if this number is neither infinite nor `NaN`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f32;
-    ///
-    /// let f = 7.0f32;
-    /// let inf: f32 = Float::infinity();
-    /// let neg_inf: f32 = Float::neg_infinity();
-    /// let nan: f32 = f32::NAN;
-    ///
-    /// assert!(f.is_finite());
-    ///
-    /// assert!(!nan.is_finite());
-    /// assert!(!inf.is_finite());
-    /// assert!(!neg_inf.is_finite());
-    /// ```
-    fn is_finite(self) -> bool;
-
-    /// Returns `true` if the number is neither zero, infinite,
-    /// [subnormal][subnormal], or `NaN`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f32;
-    ///
-    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
-    /// let max = f32::MAX;
-    /// let lower_than_min = 1.0e-40_f32;
-    /// let zero = 0.0f32;
-    ///
-    /// assert!(min.is_normal());
-    /// assert!(max.is_normal());
-    ///
-    /// assert!(!zero.is_normal());
-    /// assert!(!f32::NAN.is_normal());
-    /// assert!(!f32::INFINITY.is_normal());
-    /// // Values between `0` and `min` are Subnormal.
-    /// assert!(!lower_than_min.is_normal());
-    /// ```
-    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
-    fn is_normal(self) -> bool;
-
-    /// Returns the floating point category of the number. If only one property
-    /// is going to be tested, it is generally faster to use the specific
-    /// predicate instead.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::num::FpCategory;
-    /// use std::f32;
-    ///
-    /// let num = 12.4f32;
-    /// let inf = f32::INFINITY;
-    ///
-    /// assert_eq!(num.classify(), FpCategory::Normal);
-    /// assert_eq!(inf.classify(), FpCategory::Infinite);
-    /// ```
-    fn classify(self) -> FpCategory;
-
-    /// Returns the largest integer less than or equal to a number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let f = 3.99;
-    /// let g = 3.0;
-    ///
-    /// assert_eq!(f.floor(), 3.0);
-    /// assert_eq!(g.floor(), 3.0);
-    /// ```
-    fn floor(self) -> Self;
-
-    /// Returns the smallest integer greater than or equal to a number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let f = 3.01;
-    /// let g = 4.0;
-    ///
-    /// assert_eq!(f.ceil(), 4.0);
-    /// assert_eq!(g.ceil(), 4.0);
-    /// ```
-    fn ceil(self) -> Self;
-
-    /// Returns the nearest integer to a number. Round half-way cases away from
-    /// `0.0`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let f = 3.3;
-    /// let g = -3.3;
-    ///
-    /// assert_eq!(f.round(), 3.0);
-    /// assert_eq!(g.round(), -3.0);
-    /// ```
-    fn round(self) -> Self;
-
-    /// Return the integer part of a number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let f = 3.3;
-    /// let g = -3.7;
-    ///
-    /// assert_eq!(f.trunc(), 3.0);
-    /// assert_eq!(g.trunc(), -3.0);
-    /// ```
-    fn trunc(self) -> Self;
-
-    /// Returns the fractional part of a number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 3.5;
-    /// let y = -3.5;
-    /// let abs_difference_x = (x.fract() - 0.5).abs();
-    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
-    ///
-    /// assert!(abs_difference_x < 1e-10);
-    /// assert!(abs_difference_y < 1e-10);
-    /// ```
-    fn fract(self) -> Self;
-
-    /// Computes the absolute value of `self`. Returns `Float::nan()` if the
-    /// number is `Float::nan()`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x = 3.5;
-    /// let y = -3.5;
-    ///
-    /// let abs_difference_x = (x.abs() - x).abs();
-    /// let abs_difference_y = (y.abs() - (-y)).abs();
-    ///
-    /// assert!(abs_difference_x < 1e-10);
-    /// assert!(abs_difference_y < 1e-10);
-    ///
-    /// assert!(f64::NAN.abs().is_nan());
-    /// ```
-    fn abs(self) -> Self;
-
-    /// Returns a number that represents the sign of `self`.
-    ///
-    /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
-    /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
-    /// - `Float::nan()` if the number is `Float::nan()`
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let f = 3.5;
-    ///
-    /// assert_eq!(f.signum(), 1.0);
-    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
-    ///
-    /// assert!(f64::NAN.signum().is_nan());
-    /// ```
-    fn signum(self) -> Self;
-
-    /// Returns `true` if `self` is positive, including `+0.0` and
-    /// `Float::infinity()`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let nan: f64 = f64::NAN;
-    ///
-    /// let f = 7.0;
-    /// let g = -7.0;
-    ///
-    /// assert!(f.is_sign_positive());
-    /// assert!(!g.is_sign_positive());
-    /// // Requires both tests to determine if is `NaN`
-    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
-    /// ```
-    fn is_sign_positive(self) -> bool;
-
-    /// Returns `true` if `self` is negative, including `-0.0` and
-    /// `Float::neg_infinity()`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let nan = f64::NAN;
-    ///
-    /// let f = 7.0;
-    /// let g = -7.0;
-    ///
-    /// assert!(!f.is_sign_negative());
-    /// assert!(g.is_sign_negative());
-    /// // Requires both tests to determine if is `NaN`.
-    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
-    /// ```
-    fn is_sign_negative(self) -> bool;
-
-    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
-    /// error. This produces a more accurate result with better performance than
-    /// a separate multiplication operation followed by an add.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let m = 10.0;
-    /// let x = 4.0;
-    /// let b = 60.0;
-    ///
-    /// // 100.0
-    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn mul_add(self, a: Self, b: Self) -> Self;
-    /// Take the reciprocal (inverse) of a number, `1/x`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 2.0;
-    /// let abs_difference = (x.recip() - (1.0/x)).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn recip(self) -> Self;
-
-    /// Raise a number to an integer power.
-    ///
-    /// Using this function is generally faster than using `powf`
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 2.0;
-    /// let abs_difference = (x.powi(2) - x*x).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn powi(self, n: i32) -> Self;
-
-    /// Raise a number to a floating point power.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 2.0;
-    /// let abs_difference = (x.powf(2.0) - x*x).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn powf(self, n: Self) -> Self;
-
-    /// Take the square root of a number.
-    ///
-    /// Returns NaN if `self` is a negative number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let positive = 4.0;
-    /// let negative = -4.0;
-    ///
-    /// let abs_difference = (positive.sqrt() - 2.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// assert!(negative.sqrt().is_nan());
-    /// ```
-    fn sqrt(self) -> Self;
-
-    /// Returns `e^(self)`, (the exponential function).
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let one = 1.0;
-    /// // e^1
-    /// let e = one.exp();
-    ///
-    /// // ln(e) - 1 == 0
-    /// let abs_difference = (e.ln() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn exp(self) -> Self;
-
-    /// Returns `2^(self)`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let f = 2.0;
-    ///
-    /// // 2^2 - 4 == 0
-    /// let abs_difference = (f.exp2() - 4.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn exp2(self) -> Self;
-
-    /// Returns the natural logarithm of the number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let one = 1.0;
-    /// // e^1
-    /// let e = one.exp();
-    ///
-    /// // ln(e) - 1 == 0
-    /// let abs_difference = (e.ln() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn ln(self) -> Self;
-
-    /// Returns the logarithm of the number with respect to an arbitrary base.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let ten = 10.0;
-    /// let two = 2.0;
-    ///
-    /// // log10(10) - 1 == 0
-    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
-    ///
-    /// // log2(2) - 1 == 0
-    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
-    ///
-    /// assert!(abs_difference_10 < 1e-10);
-    /// assert!(abs_difference_2 < 1e-10);
-    /// ```
-    fn log(self, base: Self) -> Self;
-
-    /// Returns the base 2 logarithm of the number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let two = 2.0;
-    ///
-    /// // log2(2) - 1 == 0
-    /// let abs_difference = (two.log2() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn log2(self) -> Self;
-
-    /// Returns the base 10 logarithm of the number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let ten = 10.0;
-    ///
-    /// // log10(10) - 1 == 0
-    /// let abs_difference = (ten.log10() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn log10(self) -> Self;
-
-    /// Returns the maximum of the two numbers.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 1.0;
-    /// let y = 2.0;
-    ///
-    /// assert_eq!(x.max(y), y);
-    /// ```
-    fn max(self, other: Self) -> Self;
-
-    /// Returns the minimum of the two numbers.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 1.0;
-    /// let y = 2.0;
-    ///
-    /// assert_eq!(x.min(y), x);
-    /// ```
-    fn min(self, other: Self) -> Self;
-
-    /// The positive difference of two numbers.
-    ///
-    /// * If `self <= other`: `0:0`
-    /// * Else: `self - other`
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 3.0;
-    /// let y = -3.0;
-    ///
-    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
-    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
-    ///
-    /// assert!(abs_difference_x < 1e-10);
-    /// assert!(abs_difference_y < 1e-10);
-    /// ```
-    fn abs_sub(self, other: Self) -> Self;
-
-    /// Take the cubic root of a number.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 8.0;
-    ///
-    /// // x^(1/3) - 2 == 0
-    /// let abs_difference = (x.cbrt() - 2.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn cbrt(self) -> Self;
-
-    /// Calculate the length of the hypotenuse of a right-angle triangle given
-    /// legs of length `x` and `y`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 2.0;
-    /// let y = 3.0;
-    ///
-    /// // sqrt(x^2 + y^2)
-    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn hypot(self, other: Self) -> Self;
-
-    /// Computes the sine of a number (in radians).
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::PI/2.0;
-    ///
-    /// let abs_difference = (x.sin() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn sin(self) -> Self;
-
-    /// Computes the cosine of a number (in radians).
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x = 2.0*f64::consts::PI;
-    ///
-    /// let abs_difference = (x.cos() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn cos(self) -> Self;
-
-    /// Computes the tangent of a number (in radians).
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::PI/4.0;
-    /// let abs_difference = (x.tan() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-14);
-    /// ```
-    fn tan(self) -> Self;
-
-    /// Computes the arcsine of a number. Return value is in radians in
-    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
-    /// [-1, 1].
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let f = f64::consts::PI / 2.0;
-    ///
-    /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn asin(self) -> Self;
-
-    /// Computes the arccosine of a number. Return value is in radians in
-    /// the range [0, pi] or NaN if the number is outside the range
-    /// [-1, 1].
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let f = f64::consts::PI / 4.0;
-    ///
-    /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn acos(self) -> Self;
-
-    /// Computes the arctangent of a number. Return value is in radians in the
-    /// range [-pi/2, pi/2];
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let f = 1.0;
-    ///
-    /// // atan(tan(1))
-    /// let abs_difference = (f.tan().atan() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn atan(self) -> Self;
-
-    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
-    ///
-    /// * `x = 0`, `y = 0`: `0`
-    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
-    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
-    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let pi = f64::consts::PI;
-    /// // All angles from horizontal right (+x)
-    /// // 45 deg counter-clockwise
-    /// let x1 = 3.0;
-    /// let y1 = -3.0;
-    ///
-    /// // 135 deg clockwise
-    /// let x2 = -3.0;
-    /// let y2 = 3.0;
-    ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
-    ///
-    /// assert!(abs_difference_1 < 1e-10);
-    /// assert!(abs_difference_2 < 1e-10);
-    /// ```
-    fn atan2(self, other: Self) -> Self;
-
-    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
-    /// `(sin(x), cos(x))`.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::PI/4.0;
-    /// let f = x.sin_cos();
-    ///
-    /// let abs_difference_0 = (f.0 - x.sin()).abs();
-    /// let abs_difference_1 = (f.1 - x.cos()).abs();
-    ///
-    /// assert!(abs_difference_0 < 1e-10);
-    /// assert!(abs_difference_0 < 1e-10);
-    /// ```
-    fn sin_cos(self) -> (Self, Self);
-
-    /// Returns `e^(self) - 1` in a way that is accurate even if the
-    /// number is close to zero.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 7.0;
-    ///
-    /// // e^(ln(7)) - 1
-    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn exp_m1(self) -> Self;
-
-    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
-    /// the operations were performed separately.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let x = f64::consts::E - 1.0;
-    ///
-    /// // ln(1 + (e - 1)) == ln(e) == 1
-    /// let abs_difference = (x.ln_1p() - 1.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn ln_1p(self) -> Self;
-
-    /// Hyperbolic sine function.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
-    /// let x = 1.0;
-    ///
-    /// let f = x.sinh();
-    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
-    /// let g = (e*e - 1.0)/(2.0*e);
-    /// let abs_difference = (f - g).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    fn sinh(self) -> Self;
-
-    /// Hyperbolic cosine function.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
-    /// let x = 1.0;
-    /// let f = x.cosh();
-    /// // Solving cosh() at 1 gives this result
-    /// let g = (e*e + 1.0)/(2.0*e);
-    /// let abs_difference = (f - g).abs();
-    ///
-    /// // Same result
-    /// assert!(abs_difference < 1.0e-10);
-    /// ```
-    fn cosh(self) -> Self;
-
-    /// Hyperbolic tangent function.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
-    /// let x = 1.0;
-    ///
-    /// let f = x.tanh();
-    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
-    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
-    /// let abs_difference = (f - g).abs();
-    ///
-    /// assert!(abs_difference < 1.0e-10);
-    /// ```
-    fn tanh(self) -> Self;
-
-    /// Inverse hyperbolic sine function.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 1.0;
-    /// let f = x.sinh().asinh();
-    ///
-    /// let abs_difference = (f - x).abs();
-    ///
-    /// assert!(abs_difference < 1.0e-10);
-    /// ```
-    fn asinh(self) -> Self;
-
-    /// Inverse hyperbolic cosine function.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let x = 1.0;
-    /// let f = x.cosh().acosh();
-    ///
-    /// let abs_difference = (f - x).abs();
-    ///
-    /// assert!(abs_difference < 1.0e-10);
-    /// ```
-    fn acosh(self) -> Self;
-
-    /// Inverse hyperbolic tangent function.
-    ///
-    /// ```
-    /// use num::traits::Float;
-    /// use std::f64;
-    ///
-    /// let e = f64::consts::E;
-    /// let f = e.tanh().atanh();
-    ///
-    /// let abs_difference = (f - e).abs();
-    ///
-    /// assert!(abs_difference < 1.0e-10);
-    /// ```
-    fn atanh(self) -> Self;
-
-
-    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
-    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
-    /// The floating point encoding is documented in the [Reference][floating-point].
-    ///
-    /// ```
-    /// use num::traits::Float;
-    ///
-    /// let num = 2.0f32;
-    ///
-    /// // (8388608, -22, 1)
-    /// let (mantissa, exponent, sign) = Float::integer_decode(num);
-    /// let sign_f = sign as f32;
-    /// let mantissa_f = mantissa as f32;
-    /// let exponent_f = num.powf(exponent as f32);
-    ///
-    /// // 1 * 8388608 * 2^(-22) == 2
-    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    /// [floating-point]: ../../../../../reference.html#machine-types
-    fn integer_decode(self) -> (u64, i16, i8);
-}
-
-macro_rules! float_impl {
-    ($T:ident $decode:ident) => (
-        impl Float for $T {
-            fn nan() -> Self {
-                ::std::$T::NAN
-            }
-
-            fn infinity() -> Self {
-                ::std::$T::INFINITY
-            }
-
-            fn neg_infinity() -> Self {
-                ::std::$T::NEG_INFINITY
-            }
-
-            fn neg_zero() -> Self {
-                -0.0
-            }
-
-            fn min_value() -> Self {
-                ::std::$T::MIN
-            }
-
-            fn min_positive_value() -> Self {
-                ::std::$T::MIN_POSITIVE
-            }
-
-            fn max_value() -> Self {
-                ::std::$T::MAX
-            }
-
-            fn is_nan(self) -> bool {
-                <$T>::is_nan(self)
-            }
-
-            fn is_infinite(self) -> bool {
-                <$T>::is_infinite(self)
-            }
-
-            fn is_finite(self) -> bool {
-                <$T>::is_finite(self)
-            }
-
-            fn is_normal(self) -> bool {
-                <$T>::is_normal(self)
-            }
-
-            fn classify(self) -> FpCategory {
-                <$T>::classify(self)
-            }
-
-            fn floor(self) -> Self {
-                <$T>::floor(self)
-            }
-
-            fn ceil(self) -> Self {
-                <$T>::ceil(self)
-            }
-
-            fn round(self) -> Self {
-                <$T>::round(self)
-            }
-
-            fn trunc(self) -> Self {
-                <$T>::trunc(self)
-            }
-
-            fn fract(self) -> Self {
-                <$T>::fract(self)
-            }
-
-            fn abs(self) -> Self {
-                <$T>::abs(self)
-            }
-
-            fn signum(self) -> Self {
-                <$T>::signum(self)
-            }
-
-            fn is_sign_positive(self) -> bool {
-                <$T>::is_sign_positive(self)
-            }
-
-            fn is_sign_negative(self) -> bool {
-                <$T>::is_sign_negative(self)
-            }
-
-            fn mul_add(self, a: Self, b: Self) -> Self {
-                <$T>::mul_add(self, a, b)
-            }
-
-            fn recip(self) -> Self {
-                <$T>::recip(self)
-            }
-
-            fn powi(self, n: i32) -> Self {
-                <$T>::powi(self, n)
-            }
-
-            fn powf(self, n: Self) -> Self {
-                <$T>::powf(self, n)
-            }
-
-            fn sqrt(self) -> Self {
-                <$T>::sqrt(self)
-            }
-
-            fn exp(self) -> Self {
-                <$T>::exp(self)
-            }
-
-            fn exp2(self) -> Self {
-                <$T>::exp2(self)
-            }
-
-            fn ln(self) -> Self {
-                <$T>::ln(self)
-            }
-
-            fn log(self, base: Self) -> Self {
-                <$T>::log(self, base)
-            }
-
-            fn log2(self) -> Self {
-                <$T>::log2(self)
-            }
-
-            fn log10(self) -> Self {
-                <$T>::log10(self)
-            }
-
-            fn max(self, other: Self) -> Self {
-                <$T>::max(self, other)
-            }
-
-            fn min(self, other: Self) -> Self {
-                <$T>::min(self, other)
-            }
-
-            fn abs_sub(self, other: Self) -> Self {
-                <$T>::abs_sub(self, other)
-            }
-
-            fn cbrt(self) -> Self {
-                <$T>::cbrt(self)
-            }
-
-            fn hypot(self, other: Self) -> Self {
-                <$T>::hypot(self, other)
-            }
-
-            fn sin(self) -> Self {
-                <$T>::sin(self)
-            }
-
-            fn cos(self) -> Self {
-                <$T>::cos(self)
-            }
-
-            fn tan(self) -> Self {
-                <$T>::tan(self)
-            }
-
-            fn asin(self) -> Self {
-                <$T>::asin(self)
-            }
-
-            fn acos(self) -> Self {
-                <$T>::acos(self)
-            }
-
-            fn atan(self) -> Self {
-                <$T>::atan(self)
-            }
-
-            fn atan2(self, other: Self) -> Self {
-                <$T>::atan2(self, other)
-            }
-
-            fn sin_cos(self) -> (Self, Self) {
-                <$T>::sin_cos(self)
-            }
-
-            fn exp_m1(self) -> Self {
-                <$T>::exp_m1(self)
-            }
-
-            fn ln_1p(self) -> Self {
-                <$T>::ln_1p(self)
-            }
-
-            fn sinh(self) -> Self {
-                <$T>::sinh(self)
-            }
-
-            fn cosh(self) -> Self {
-                <$T>::cosh(self)
-            }
-
-            fn tanh(self) -> Self {
-                <$T>::tanh(self)
-            }
-
-            fn asinh(self) -> Self {
-                <$T>::asinh(self)
-            }
-
-            fn acosh(self) -> Self {
-                <$T>::acosh(self)
-            }
-
-            fn atanh(self) -> Self {
-                <$T>::atanh(self)
-            }
-
-            fn integer_decode(self) -> (u64, i16, i8) {
-                $decode(self)
-            }
-        }
-    )
-}
-
-fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
-    let bits: u32 = unsafe { mem::transmute(f) };
-    let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
-    let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
-    let mantissa = if exponent == 0 {
-        (bits & 0x7fffff) << 1
-    } else {
-        (bits & 0x7fffff) | 0x800000
-    };
-    // Exponent bias + mantissa shift
-    exponent -= 127 + 23;
-    (mantissa as u64, exponent, sign)
-}
-
-fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
-    let bits: u64 = unsafe { mem::transmute(f) };
-    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
-    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
-    let mantissa = if exponent == 0 {
-        (bits & 0xfffffffffffff) << 1
-    } else {
-        (bits & 0xfffffffffffff) | 0x10000000000000
-    };
-    // Exponent bias + mantissa shift
-    exponent -= 1023 + 52;
-    (mantissa, exponent, sign)
-}
-
-float_impl!(f32 integer_decode_f32);
-float_impl!(f64 integer_decode_f64);
-
-
-#[test]
-fn from_str_radix_unwrap() {
-    // The Result error must impl Debug to allow unwrap()
-
-    let i: i32 = Num::from_str_radix("0", 10).unwrap();
-    assert_eq!(i, 0);
-
-    let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
-    assert_eq!(f, 0.0);
-}

+ 12 - 0
traits/Cargo.toml

@@ -0,0 +1,12 @@
+[package]
+authors = ["The Rust Project Developers"]
+description = "Numeric traits for generic mathematics"
+documentation = "http://rust-num.github.io/num"
+homepage = "https://github.com/rust-num/num"
+keywords = ["mathematics", "numerics"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-num/num"
+name = "num-traits"
+version = "0.1.0"
+
+[dependencies]

+ 69 - 0
traits/src/bounds.rs

@@ -0,0 +1,69 @@
+use std::{usize, u8, u16, u32, u64};
+use std::{isize, i8, i16, i32, i64};
+use std::{f32, f64};
+
+/// Numbers which have upper and lower bounds
+pub trait Bounded {
+    // FIXME (#5527): These should be associated constants
+    /// returns the smallest finite number this type can represent
+    fn min_value() -> Self;
+    /// returns the largest finite number this type can represent
+    fn max_value() -> Self;
+}
+
+macro_rules! bounded_impl {
+    ($t:ty, $min:expr, $max:expr) => {
+        impl Bounded for $t {
+            #[inline]
+            fn min_value() -> $t { $min }
+
+            #[inline]
+            fn max_value() -> $t { $max }
+        }
+    }
+}
+
+bounded_impl!(usize, usize::MIN, usize::MAX);
+bounded_impl!(u8,    u8::MIN,    u8::MAX);
+bounded_impl!(u16,   u16::MIN,   u16::MAX);
+bounded_impl!(u32,   u32::MIN,   u32::MAX);
+bounded_impl!(u64,   u64::MIN,   u64::MAX);
+
+bounded_impl!(isize, isize::MIN, isize::MAX);
+bounded_impl!(i8,    i8::MIN,    i8::MAX);
+bounded_impl!(i16,   i16::MIN,   i16::MAX);
+bounded_impl!(i32,   i32::MIN,   i32::MAX);
+bounded_impl!(i64,   i64::MIN,   i64::MAX);
+
+bounded_impl!(f32, f32::MIN, f32::MAX);
+
+macro_rules! for_each_tuple_ {
+    ( $m:ident !! ) => (
+        $m! { }
+    );
+    ( $m:ident !! $h:ident, $($t:ident,)* ) => (
+        $m! { $h $($t)* }
+        for_each_tuple_! { $m !! $($t,)* }
+    );
+}
+macro_rules! for_each_tuple {
+    ( $m:ident ) => (
+        for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
+    );
+}
+
+macro_rules! bounded_tuple {
+    ( $($name:ident)* ) => (
+        impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
+            fn min_value() -> Self {
+                ($($name::min_value(),)*)
+            }
+            fn max_value() -> Self {
+                ($($name::max_value(),)*)
+            }
+        }
+    );
+}
+
+for_each_tuple!(bounded_tuple);
+bounded_impl!(f64, f64::MIN, f64::MAX);

+ 433 - 0
traits/src/cast.rs

@@ -0,0 +1,433 @@
+use std::mem::size_of;
+
+use identities::Zero;
+use bounds::Bounded;
+
+/// A generic trait for converting a value to a number.
+pub trait ToPrimitive {
+    /// Converts the value of `self` to an `isize`.
+    #[inline]
+    fn to_isize(&self) -> Option<isize> {
+        self.to_i64().and_then(|x| x.to_isize())
+    }
+
+    /// Converts the value of `self` to an `i8`.
+    #[inline]
+    fn to_i8(&self) -> Option<i8> {
+        self.to_i64().and_then(|x| x.to_i8())
+    }
+
+    /// Converts the value of `self` to an `i16`.
+    #[inline]
+    fn to_i16(&self) -> Option<i16> {
+        self.to_i64().and_then(|x| x.to_i16())
+    }
+
+    /// Converts the value of `self` to an `i32`.
+    #[inline]
+    fn to_i32(&self) -> Option<i32> {
+        self.to_i64().and_then(|x| x.to_i32())
+    }
+
+    /// Converts the value of `self` to an `i64`.
+    fn to_i64(&self) -> Option<i64>;
+
+    /// Converts the value of `self` to a `usize`.
+    #[inline]
+    fn to_usize(&self) -> Option<usize> {
+        self.to_u64().and_then(|x| x.to_usize())
+    }
+
+    /// Converts the value of `self` to an `u8`.
+    #[inline]
+    fn to_u8(&self) -> Option<u8> {
+        self.to_u64().and_then(|x| x.to_u8())
+    }
+
+    /// Converts the value of `self` to an `u16`.
+    #[inline]
+    fn to_u16(&self) -> Option<u16> {
+        self.to_u64().and_then(|x| x.to_u16())
+    }
+
+    /// Converts the value of `self` to an `u32`.
+    #[inline]
+    fn to_u32(&self) -> Option<u32> {
+        self.to_u64().and_then(|x| x.to_u32())
+    }
+
+    /// Converts the value of `self` to an `u64`.
+    #[inline]
+    fn to_u64(&self) -> Option<u64>;
+
+    /// Converts the value of `self` to an `f32`.
+    #[inline]
+    fn to_f32(&self) -> Option<f32> {
+        self.to_f64().and_then(|x| x.to_f32())
+    }
+
+    /// Converts the value of `self` to an `f64`.
+    #[inline]
+    fn to_f64(&self) -> Option<f64> {
+        self.to_i64().and_then(|x| x.to_f64())
+    }
+}
+
+macro_rules! impl_to_primitive_int_to_int {
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
+        {
+            if size_of::<$SrcT>() <= size_of::<$DstT>() {
+                Some($slf as $DstT)
+            } else {
+                let n = $slf as i64;
+                let min_value: $DstT = Bounded::min_value();
+                let max_value: $DstT = Bounded::max_value();
+                if min_value as i64 <= n && n <= max_value as i64 {
+                    Some($slf as $DstT)
+                } else {
+                    None
+                }
+            }
+        }
+    )
+}
+
+macro_rules! impl_to_primitive_int_to_uint {
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
+        {
+            let zero: $SrcT = Zero::zero();
+            let max_value: $DstT = Bounded::max_value();
+            if zero <= $slf && $slf as u64 <= max_value as u64 {
+                Some($slf as $DstT)
+            } else {
+                None
+            }
+        }
+    )
+}
+
+macro_rules! impl_to_primitive_int {
+    ($T:ty) => (
+        impl ToPrimitive for $T {
+            #[inline]
+            fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
+            #[inline]
+            fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
+            #[inline]
+            fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
+            #[inline]
+            fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
+            #[inline]
+            fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
+
+            #[inline]
+            fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
+            #[inline]
+            fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
+            #[inline]
+            fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
+            #[inline]
+            fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
+            #[inline]
+            fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
+
+            #[inline]
+            fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
+            #[inline]
+            fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
+        }
+    )
+}
+
+impl_to_primitive_int!(isize);
+impl_to_primitive_int!(i8);
+impl_to_primitive_int!(i16);
+impl_to_primitive_int!(i32);
+impl_to_primitive_int!(i64);
+
+macro_rules! impl_to_primitive_uint_to_int {
+    ($DstT:ty, $slf:expr) => (
+        {
+            let max_value: $DstT = Bounded::max_value();
+            if $slf as u64 <= max_value as u64 {
+                Some($slf as $DstT)
+            } else {
+                None
+            }
+        }
+    )
+}
+
+macro_rules! impl_to_primitive_uint_to_uint {
+    ($SrcT:ty, $DstT:ty, $slf:expr) => (
+        {
+            if size_of::<$SrcT>() <= size_of::<$DstT>() {
+                Some($slf as $DstT)
+            } else {
+                let zero: $SrcT = Zero::zero();
+                let max_value: $DstT = Bounded::max_value();
+                if zero <= $slf && $slf as u64 <= max_value as u64 {
+                    Some($slf as $DstT)
+                } else {
+                    None
+                }
+            }
+        }
+    )
+}
+
+macro_rules! impl_to_primitive_uint {
+    ($T:ty) => (
+        impl ToPrimitive for $T {
+            #[inline]
+            fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
+            #[inline]
+            fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
+            #[inline]
+            fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
+            #[inline]
+            fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
+            #[inline]
+            fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
+
+            #[inline]
+            fn to_usize(&self) -> Option<usize> {
+                impl_to_primitive_uint_to_uint!($T, usize, *self)
+            }
+            #[inline]
+            fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
+            #[inline]
+            fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
+            #[inline]
+            fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
+            #[inline]
+            fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
+
+            #[inline]
+            fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
+            #[inline]
+            fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
+        }
+    )
+}
+
+impl_to_primitive_uint!(usize);
+impl_to_primitive_uint!(u8);
+impl_to_primitive_uint!(u16);
+impl_to_primitive_uint!(u32);
+impl_to_primitive_uint!(u64);
+
+macro_rules! impl_to_primitive_float_to_float {
+    ($SrcT:ident, $DstT:ident, $slf:expr) => (
+        if size_of::<$SrcT>() <= size_of::<$DstT>() {
+            Some($slf as $DstT)
+        } else {
+            let n = $slf as f64;
+            let max_value: $SrcT = ::std::$SrcT::MAX;
+            if -max_value as f64 <= n && n <= max_value as f64 {
+                Some($slf as $DstT)
+            } else {
+                None
+            }
+        }
+    )
+}
+
+macro_rules! impl_to_primitive_float {
+    ($T:ident) => (
+        impl ToPrimitive for $T {
+            #[inline]
+            fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
+            #[inline]
+            fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
+            #[inline]
+            fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
+            #[inline]
+            fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
+            #[inline]
+            fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
+
+            #[inline]
+            fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
+            #[inline]
+            fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
+            #[inline]
+            fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
+            #[inline]
+            fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
+            #[inline]
+            fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
+
+            #[inline]
+            fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
+            #[inline]
+            fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
+        }
+    )
+}
+
+impl_to_primitive_float!(f32);
+impl_to_primitive_float!(f64);
+
+/// A generic trait for converting a number to a value.
+pub trait FromPrimitive: Sized {
+    /// Convert an `isize` to return an optional value of this type. If the
+    /// value cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_isize(n: isize) -> Option<Self> {
+        FromPrimitive::from_i64(n as i64)
+    }
+
+    /// Convert an `i8` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_i8(n: i8) -> Option<Self> {
+        FromPrimitive::from_i64(n as i64)
+    }
+
+    /// Convert an `i16` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_i16(n: i16) -> Option<Self> {
+        FromPrimitive::from_i64(n as i64)
+    }
+
+    /// Convert an `i32` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_i32(n: i32) -> Option<Self> {
+        FromPrimitive::from_i64(n as i64)
+    }
+
+    /// Convert an `i64` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    fn from_i64(n: i64) -> Option<Self>;
+
+    /// Convert a `usize` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_usize(n: usize) -> Option<Self> {
+        FromPrimitive::from_u64(n as u64)
+    }
+
+    /// Convert an `u8` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_u8(n: u8) -> Option<Self> {
+        FromPrimitive::from_u64(n as u64)
+    }
+
+    /// Convert an `u16` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_u16(n: u16) -> Option<Self> {
+        FromPrimitive::from_u64(n as u64)
+    }
+
+    /// Convert an `u32` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_u32(n: u32) -> Option<Self> {
+        FromPrimitive::from_u64(n as u64)
+    }
+
+    /// Convert an `u64` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    fn from_u64(n: u64) -> Option<Self>;
+
+    /// Convert a `f32` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_f32(n: f32) -> Option<Self> {
+        FromPrimitive::from_f64(n as f64)
+    }
+
+    /// Convert a `f64` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_f64(n: f64) -> Option<Self> {
+        FromPrimitive::from_i64(n as i64)
+    }
+}
+
+macro_rules! impl_from_primitive {
+    ($T:ty, $to_ty:ident) => (
+        #[allow(deprecated)]
+        impl FromPrimitive for $T {
+            #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
+
+            #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
+
+            #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
+        }
+    )
+}
+
+impl_from_primitive!(isize, to_isize);
+impl_from_primitive!(i8,    to_i8);
+impl_from_primitive!(i16,   to_i16);
+impl_from_primitive!(i32,   to_i32);
+impl_from_primitive!(i64,   to_i64);
+impl_from_primitive!(usize, to_usize);
+impl_from_primitive!(u8,    to_u8);
+impl_from_primitive!(u16,   to_u16);
+impl_from_primitive!(u32,   to_u32);
+impl_from_primitive!(u64,   to_u64);
+impl_from_primitive!(f32,   to_f32);
+impl_from_primitive!(f64,   to_f64);
+
+/// Cast from one machine scalar to another.
+///
+/// # Examples
+///
+/// ```
+/// # use num_traits as num;
+/// let twenty: f32 = num::cast(0x14).unwrap();
+/// assert_eq!(twenty, 20f32);
+/// ```
+///
+#[inline]
+pub fn cast<T: NumCast, U: NumCast>(n: T) -> Option<U> {
+    NumCast::from(n)
+}
+
+/// An interface for casting between machine scalars.
+pub trait NumCast: Sized + ToPrimitive {
+    /// Creates a number from another value that can be converted into
+    /// a primitive via the `ToPrimitive` trait.
+    fn from<T: ToPrimitive>(n: T) -> Option<Self>;
+}
+
+macro_rules! impl_num_cast {
+    ($T:ty, $conv:ident) => (
+        impl NumCast for $T {
+            #[inline]
+            #[allow(deprecated)]
+            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
+                // `$conv` could be generated using `concat_idents!`, but that
+                // macro seems to be broken at the moment
+                n.$conv()
+            }
+        }
+    )
+}
+
+impl_num_cast!(u8,    to_u8);
+impl_num_cast!(u16,   to_u16);
+impl_num_cast!(u32,   to_u32);
+impl_num_cast!(u64,   to_u64);
+impl_num_cast!(usize, to_usize);
+impl_num_cast!(i8,    to_i8);
+impl_num_cast!(i16,   to_i16);
+impl_num_cast!(i32,   to_i32);
+impl_num_cast!(i64,   to_i64);
+impl_num_cast!(isize, to_isize);
+impl_num_cast!(f32,   to_f32);
+impl_num_cast!(f64,   to_f64);

+ 1126 - 0
traits/src/float.rs

@@ -0,0 +1,1126 @@
+use std::mem;
+use std::ops::Neg;
+use std::num::FpCategory;
+
+use {Num, NumCast};
+
+pub trait Float
+    : Num
+    + Copy
+    + NumCast
+    + PartialOrd
+    + Neg<Output = Self>
+{
+    /// Returns the `NaN` value.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let nan: f32 = Float::nan();
+    ///
+    /// assert!(nan.is_nan());
+    /// ```
+    fn nan() -> Self;
+    /// Returns the infinite value.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f32;
+    ///
+    /// let infinity: f32 = Float::infinity();
+    ///
+    /// assert!(infinity.is_infinite());
+    /// assert!(!infinity.is_finite());
+    /// assert!(infinity > f32::MAX);
+    /// ```
+    fn infinity() -> Self;
+    /// Returns the negative infinite value.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f32;
+    ///
+    /// let neg_infinity: f32 = Float::neg_infinity();
+    ///
+    /// assert!(neg_infinity.is_infinite());
+    /// assert!(!neg_infinity.is_finite());
+    /// assert!(neg_infinity < f32::MIN);
+    /// ```
+    fn neg_infinity() -> Self;
+    /// Returns `-0.0`.
+    ///
+    /// ```
+    /// use num_traits::{Zero, Float};
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Zero::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
+    fn neg_zero() -> Self;
+
+    /// Returns the smallest finite value that this type can represent.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::min_value();
+    ///
+    /// assert_eq!(x, f64::MIN);
+    /// ```
+    fn min_value() -> Self;
+
+    /// Returns the smallest positive, normalized value that this type can represent.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::min_positive_value();
+    ///
+    /// assert_eq!(x, f64::MIN_POSITIVE);
+    /// ```
+    fn min_positive_value() -> Self;
+
+    /// Returns the largest finite value that this type can represent.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::max_value();
+    /// assert_eq!(x, f64::MAX);
+    /// ```
+    fn max_value() -> Self;
+
+    /// Returns `true` if this value is `NaN` and false otherwise.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    /// let f = 7.0;
+    ///
+    /// assert!(nan.is_nan());
+    /// assert!(!f.is_nan());
+    /// ```
+    fn is_nan(self) -> bool;
+
+    /// Returns `true` if this value is positive infinity or negative infinity and
+    /// false otherwise.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(!f.is_infinite());
+    /// assert!(!nan.is_infinite());
+    ///
+    /// assert!(inf.is_infinite());
+    /// assert!(neg_inf.is_infinite());
+    /// ```
+    fn is_infinite(self) -> bool;
+
+    /// Returns `true` if this number is neither infinite nor `NaN`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(f.is_finite());
+    ///
+    /// assert!(!nan.is_finite());
+    /// assert!(!inf.is_finite());
+    /// assert!(!neg_inf.is_finite());
+    /// ```
+    fn is_finite(self) -> bool;
+
+    /// Returns `true` if the number is neither zero, infinite,
+    /// [subnormal][subnormal], or `NaN`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f32;
+    ///
+    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+    /// let max = f32::MAX;
+    /// let lower_than_min = 1.0e-40_f32;
+    /// let zero = 0.0f32;
+    ///
+    /// assert!(min.is_normal());
+    /// assert!(max.is_normal());
+    ///
+    /// assert!(!zero.is_normal());
+    /// assert!(!f32::NAN.is_normal());
+    /// assert!(!f32::INFINITY.is_normal());
+    /// // Values between `0` and `min` are Subnormal.
+    /// assert!(!lower_than_min.is_normal());
+    /// ```
+    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    fn is_normal(self) -> bool;
+
+    /// Returns the floating point category of the number. If only one property
+    /// is going to be tested, it is generally faster to use the specific
+    /// predicate instead.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::num::FpCategory;
+    /// use std::f32;
+    ///
+    /// let num = 12.4f32;
+    /// let inf = f32::INFINITY;
+    ///
+    /// assert_eq!(num.classify(), FpCategory::Normal);
+    /// assert_eq!(inf.classify(), FpCategory::Infinite);
+    /// ```
+    fn classify(self) -> FpCategory;
+
+    /// Returns the largest integer less than or equal to a number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let f = 3.99;
+    /// let g = 3.0;
+    ///
+    /// assert_eq!(f.floor(), 3.0);
+    /// assert_eq!(g.floor(), 3.0);
+    /// ```
+    fn floor(self) -> Self;
+
+    /// Returns the smallest integer greater than or equal to a number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let f = 3.01;
+    /// let g = 4.0;
+    ///
+    /// assert_eq!(f.ceil(), 4.0);
+    /// assert_eq!(g.ceil(), 4.0);
+    /// ```
+    fn ceil(self) -> Self;
+
+    /// Returns the nearest integer to a number. Round half-way cases away from
+    /// `0.0`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.3;
+    ///
+    /// assert_eq!(f.round(), 3.0);
+    /// assert_eq!(g.round(), -3.0);
+    /// ```
+    fn round(self) -> Self;
+
+    /// Return the integer part of a number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.7;
+    ///
+    /// assert_eq!(f.trunc(), 3.0);
+    /// assert_eq!(g.trunc(), -3.0);
+    /// ```
+    fn trunc(self) -> Self;
+
+    /// Returns the fractional part of a number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    /// let abs_difference_x = (x.fract() - 0.5).abs();
+    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    fn fract(self) -> Self;
+
+    /// Computes the absolute value of `self`. Returns `Float::nan()` if the
+    /// number is `Float::nan()`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    ///
+    /// let abs_difference_x = (x.abs() - x).abs();
+    /// let abs_difference_y = (y.abs() - (-y)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    ///
+    /// assert!(f64::NAN.abs().is_nan());
+    /// ```
+    fn abs(self) -> Self;
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
+    /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
+    /// - `Float::nan()` if the number is `Float::nan()`
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let f = 3.5;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f64::NAN.signum().is_nan());
+    /// ```
+    fn signum(self) -> Self;
+
+    /// Returns `true` if `self` is positive, including `+0.0` and
+    /// `Float::infinity()`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let nan: f64 = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(f.is_sign_positive());
+    /// assert!(!g.is_sign_positive());
+    /// // Requires both tests to determine if is `NaN`
+    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
+    /// ```
+    fn is_sign_positive(self) -> bool;
+
+    /// Returns `true` if `self` is negative, including `-0.0` and
+    /// `Float::neg_infinity()`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(!f.is_sign_negative());
+    /// assert!(g.is_sign_negative());
+    /// // Requires both tests to determine if is `NaN`.
+    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
+    /// ```
+    fn is_sign_negative(self) -> bool;
+
+    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+    /// error. This produces a more accurate result with better performance than
+    /// a separate multiplication operation followed by an add.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let m = 10.0;
+    /// let x = 4.0;
+    /// let b = 60.0;
+    ///
+    /// // 100.0
+    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn mul_add(self, a: Self, b: Self) -> Self;
+    /// Take the reciprocal (inverse) of a number, `1/x`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn recip(self) -> Self;
+
+    /// Raise a number to an integer power.
+    ///
+    /// Using this function is generally faster than using `powf`
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powi(2) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn powi(self, n: i32) -> Self;
+
+    /// Raise a number to a floating point power.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn powf(self, n: Self) -> Self;
+
+    /// Take the square root of a number.
+    ///
+    /// Returns NaN if `self` is a negative number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let positive = 4.0;
+    /// let negative = -4.0;
+    ///
+    /// let abs_difference = (positive.sqrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// assert!(negative.sqrt().is_nan());
+    /// ```
+    fn sqrt(self) -> Self;
+
+    /// Returns `e^(self)`, (the exponential function).
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn exp(self) -> Self;
+
+    /// Returns `2^(self)`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let f = 2.0;
+    ///
+    /// // 2^2 - 4 == 0
+    /// let abs_difference = (f.exp2() - 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn exp2(self) -> Self;
+
+    /// Returns the natural logarithm of the number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn ln(self) -> Self;
+
+    /// Returns the logarithm of the number with respect to an arbitrary base.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let ten = 10.0;
+    /// let two = 2.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+    ///
+    /// assert!(abs_difference_10 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    fn log(self, base: Self) -> Self;
+
+    /// Returns the base 2 logarithm of the number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let two = 2.0;
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference = (two.log2() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn log2(self) -> Self;
+
+    /// Returns the base 10 logarithm of the number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let ten = 10.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference = (ten.log10() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn log10(self) -> Self;
+
+    /// Returns the maximum of the two numbers.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.max(y), y);
+    /// ```
+    fn max(self, other: Self) -> Self;
+
+    /// Returns the minimum of the two numbers.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.min(y), x);
+    /// ```
+    fn min(self, other: Self) -> Self;
+
+    /// The positive difference of two numbers.
+    ///
+    /// * If `self <= other`: `0:0`
+    /// * Else: `self - other`
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 3.0;
+    /// let y = -3.0;
+    ///
+    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    fn abs_sub(self, other: Self) -> Self;
+
+    /// Take the cubic root of a number.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 8.0;
+    ///
+    /// // x^(1/3) - 2 == 0
+    /// let abs_difference = (x.cbrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn cbrt(self) -> Self;
+
+    /// Calculate the length of the hypotenuse of a right-angle triangle given
+    /// legs of length `x` and `y`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 2.0;
+    /// let y = 3.0;
+    ///
+    /// // sqrt(x^2 + y^2)
+    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn hypot(self, other: Self) -> Self;
+
+    /// Computes the sine of a number (in radians).
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/2.0;
+    ///
+    /// let abs_difference = (x.sin() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn sin(self) -> Self;
+
+    /// Computes the cosine of a number (in radians).
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x = 2.0*f64::consts::PI;
+    ///
+    /// let abs_difference = (x.cos() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn cos(self) -> Self;
+
+    /// Computes the tangent of a number (in radians).
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let abs_difference = (x.tan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-14);
+    /// ```
+    fn tan(self) -> Self;
+
+    /// Computes the arcsine of a number. Return value is in radians in
+    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 2.0;
+    ///
+    /// // asin(sin(pi/2))
+    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn asin(self) -> Self;
+
+    /// Computes the arccosine of a number. Return value is in radians in
+    /// the range [0, pi] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 4.0;
+    ///
+    /// // acos(cos(pi/4))
+    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn acos(self) -> Self;
+
+    /// Computes the arctangent of a number. Return value is in radians in the
+    /// range [-pi/2, pi/2];
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let f = 1.0;
+    ///
+    /// // atan(tan(1))
+    /// let abs_difference = (f.tan().atan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn atan(self) -> Self;
+
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    ///
+    /// * `x = 0`, `y = 0`: `0`
+    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let pi = f64::consts::PI;
+    /// // All angles from horizontal right (+x)
+    /// // 45 deg counter-clockwise
+    /// let x1 = 3.0;
+    /// let y1 = -3.0;
+    ///
+    /// // 135 deg clockwise
+    /// let x2 = -3.0;
+    /// let y2 = 3.0;
+    ///
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    ///
+    /// assert!(abs_difference_1 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    fn atan2(self, other: Self) -> Self;
+
+    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
+    /// `(sin(x), cos(x))`.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let f = x.sin_cos();
+    ///
+    /// let abs_difference_0 = (f.0 - x.sin()).abs();
+    /// let abs_difference_1 = (f.1 - x.cos()).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_0 < 1e-10);
+    /// ```
+    fn sin_cos(self) -> (Self, Self);
+
+    /// Returns `e^(self) - 1` in a way that is accurate even if the
+    /// number is close to zero.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 7.0;
+    ///
+    /// // e^(ln(7)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn exp_m1(self) -> Self;
+
+    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+    /// the operations were performed separately.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::E - 1.0;
+    ///
+    /// // ln(1 + (e - 1)) == ln(e) == 1
+    /// let abs_difference = (x.ln_1p() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn ln_1p(self) -> Self;
+
+    /// Hyperbolic sine function.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.sinh();
+    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    fn sinh(self) -> Self;
+
+    /// Hyperbolic cosine function.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    /// let f = x.cosh();
+    /// // Solving cosh() at 1 gives this result
+    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// // Same result
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    fn cosh(self) -> Self;
+
+    /// Hyperbolic tangent function.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.tanh();
+    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    fn tanh(self) -> Self;
+
+    /// Inverse hyperbolic sine function.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.sinh().asinh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    fn asinh(self) -> Self;
+
+    /// Inverse hyperbolic cosine function.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.cosh().acosh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    fn acosh(self) -> Self;
+
+    /// Inverse hyperbolic tangent function.
+    ///
+    /// ```
+    /// use num_traits::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let f = e.tanh().atanh();
+    ///
+    /// let abs_difference = (f - e).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    fn atanh(self) -> Self;
+
+
+    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+    /// The floating point encoding is documented in the [Reference][floating-point].
+    ///
+    /// ```
+    /// use num_traits::Float;
+    ///
+    /// let num = 2.0f32;
+    ///
+    /// // (8388608, -22, 1)
+    /// let (mantissa, exponent, sign) = Float::integer_decode(num);
+    /// let sign_f = sign as f32;
+    /// let mantissa_f = mantissa as f32;
+    /// let exponent_f = num.powf(exponent as f32);
+    ///
+    /// // 1 * 8388608 * 2^(-22) == 2
+    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    /// [floating-point]: ../../../../../reference.html#machine-types
+    fn integer_decode(self) -> (u64, i16, i8);
+}
+
+macro_rules! float_impl {
+    ($T:ident $decode:ident) => (
+        impl Float for $T {
+            fn nan() -> Self {
+                ::std::$T::NAN
+            }
+
+            fn infinity() -> Self {
+                ::std::$T::INFINITY
+            }
+
+            fn neg_infinity() -> Self {
+                ::std::$T::NEG_INFINITY
+            }
+
+            fn neg_zero() -> Self {
+                -0.0
+            }
+
+            fn min_value() -> Self {
+                ::std::$T::MIN
+            }
+
+            fn min_positive_value() -> Self {
+                ::std::$T::MIN_POSITIVE
+            }
+
+            fn max_value() -> Self {
+                ::std::$T::MAX
+            }
+
+            fn is_nan(self) -> bool {
+                <$T>::is_nan(self)
+            }
+
+            fn is_infinite(self) -> bool {
+                <$T>::is_infinite(self)
+            }
+
+            fn is_finite(self) -> bool {
+                <$T>::is_finite(self)
+            }
+
+            fn is_normal(self) -> bool {
+                <$T>::is_normal(self)
+            }
+
+            fn classify(self) -> FpCategory {
+                <$T>::classify(self)
+            }
+
+            fn floor(self) -> Self {
+                <$T>::floor(self)
+            }
+
+            fn ceil(self) -> Self {
+                <$T>::ceil(self)
+            }
+
+            fn round(self) -> Self {
+                <$T>::round(self)
+            }
+
+            fn trunc(self) -> Self {
+                <$T>::trunc(self)
+            }
+
+            fn fract(self) -> Self {
+                <$T>::fract(self)
+            }
+
+            fn abs(self) -> Self {
+                <$T>::abs(self)
+            }
+
+            fn signum(self) -> Self {
+                <$T>::signum(self)
+            }
+
+            fn is_sign_positive(self) -> bool {
+                <$T>::is_sign_positive(self)
+            }
+
+            fn is_sign_negative(self) -> bool {
+                <$T>::is_sign_negative(self)
+            }
+
+            fn mul_add(self, a: Self, b: Self) -> Self {
+                <$T>::mul_add(self, a, b)
+            }
+
+            fn recip(self) -> Self {
+                <$T>::recip(self)
+            }
+
+            fn powi(self, n: i32) -> Self {
+                <$T>::powi(self, n)
+            }
+
+            fn powf(self, n: Self) -> Self {
+                <$T>::powf(self, n)
+            }
+
+            fn sqrt(self) -> Self {
+                <$T>::sqrt(self)
+            }
+
+            fn exp(self) -> Self {
+                <$T>::exp(self)
+            }
+
+            fn exp2(self) -> Self {
+                <$T>::exp2(self)
+            }
+
+            fn ln(self) -> Self {
+                <$T>::ln(self)
+            }
+
+            fn log(self, base: Self) -> Self {
+                <$T>::log(self, base)
+            }
+
+            fn log2(self) -> Self {
+                <$T>::log2(self)
+            }
+
+            fn log10(self) -> Self {
+                <$T>::log10(self)
+            }
+
+            fn max(self, other: Self) -> Self {
+                <$T>::max(self, other)
+            }
+
+            fn min(self, other: Self) -> Self {
+                <$T>::min(self, other)
+            }
+
+            fn abs_sub(self, other: Self) -> Self {
+                <$T>::abs_sub(self, other)
+            }
+
+            fn cbrt(self) -> Self {
+                <$T>::cbrt(self)
+            }
+
+            fn hypot(self, other: Self) -> Self {
+                <$T>::hypot(self, other)
+            }
+
+            fn sin(self) -> Self {
+                <$T>::sin(self)
+            }
+
+            fn cos(self) -> Self {
+                <$T>::cos(self)
+            }
+
+            fn tan(self) -> Self {
+                <$T>::tan(self)
+            }
+
+            fn asin(self) -> Self {
+                <$T>::asin(self)
+            }
+
+            fn acos(self) -> Self {
+                <$T>::acos(self)
+            }
+
+            fn atan(self) -> Self {
+                <$T>::atan(self)
+            }
+
+            fn atan2(self, other: Self) -> Self {
+                <$T>::atan2(self, other)
+            }
+
+            fn sin_cos(self) -> (Self, Self) {
+                <$T>::sin_cos(self)
+            }
+
+            fn exp_m1(self) -> Self {
+                <$T>::exp_m1(self)
+            }
+
+            fn ln_1p(self) -> Self {
+                <$T>::ln_1p(self)
+            }
+
+            fn sinh(self) -> Self {
+                <$T>::sinh(self)
+            }
+
+            fn cosh(self) -> Self {
+                <$T>::cosh(self)
+            }
+
+            fn tanh(self) -> Self {
+                <$T>::tanh(self)
+            }
+
+            fn asinh(self) -> Self {
+                <$T>::asinh(self)
+            }
+
+            fn acosh(self) -> Self {
+                <$T>::acosh(self)
+            }
+
+            fn atanh(self) -> Self {
+                <$T>::atanh(self)
+            }
+
+            fn integer_decode(self) -> (u64, i16, i8) {
+                $decode(self)
+            }
+        }
+    )
+}
+
+fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
+    let bits: u32 = unsafe { mem::transmute(f) };
+    let sign: i8 = if bits >> 31 == 0 {
+        1
+    } else {
+        -1
+    };
+    let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
+    let mantissa = if exponent == 0 {
+        (bits & 0x7fffff) << 1
+    } else {
+        (bits & 0x7fffff) | 0x800000
+    };
+    // Exponent bias + mantissa shift
+    exponent -= 127 + 23;
+    (mantissa as u64, exponent, sign)
+}
+
+fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
+    let bits: u64 = unsafe { mem::transmute(f) };
+    let sign: i8 = if bits >> 63 == 0 {
+        1
+    } else {
+        -1
+    };
+    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
+    let mantissa = if exponent == 0 {
+        (bits & 0xfffffffffffff) << 1
+    } else {
+        (bits & 0xfffffffffffff) | 0x10000000000000
+    };
+    // Exponent bias + mantissa shift
+    exponent -= 1023 + 52;
+    (mantissa, exponent, sign)
+}
+
+float_impl!(f32 integer_decode_f32);
+float_impl!(f64 integer_decode_f64);

+ 95 - 0
traits/src/identities.rs

@@ -0,0 +1,95 @@
+use std::ops::{Add, Mul};
+
+/// Defines an additive identity element for `Self`.
+pub trait Zero: Sized + Add<Self, Output = Self> {
+    /// Returns the additive identity element of `Self`, `0`.
+    ///
+    /// # Laws
+    ///
+    /// ```{.text}
+    /// a + 0 = a       ∀ a ∈ Self
+    /// 0 + a = a       ∀ a ∈ Self
+    /// ```
+    ///
+    /// # Purity
+    ///
+    /// This function should return the same result at all times regardless of
+    /// external mutable state, for example values stored in TLS or in
+    /// `static mut`s.
+    // FIXME (#5527): This should be an associated constant
+    fn zero() -> Self;
+
+    /// Returns `true` if `self` is equal to the additive identity.
+    #[inline]
+    fn is_zero(&self) -> bool;
+}
+
+macro_rules! zero_impl {
+    ($t:ty, $v:expr) => {
+        impl Zero for $t {
+            #[inline]
+            fn zero() -> $t { $v }
+            #[inline]
+            fn is_zero(&self) -> bool { *self == $v }
+        }
+    }
+}
+
+zero_impl!(usize, 0usize);
+zero_impl!(u8,    0u8);
+zero_impl!(u16,   0u16);
+zero_impl!(u32,   0u32);
+zero_impl!(u64,   0u64);
+
+zero_impl!(isize, 0isize);
+zero_impl!(i8,    0i8);
+zero_impl!(i16,   0i16);
+zero_impl!(i32,   0i32);
+zero_impl!(i64,   0i64);
+
+zero_impl!(f32, 0.0f32);
+zero_impl!(f64, 0.0f64);
+
+/// Defines a multiplicative identity element for `Self`.
+pub trait One: Sized + Mul<Self, Output = Self> {
+    /// Returns the multiplicative identity element of `Self`, `1`.
+    ///
+    /// # Laws
+    ///
+    /// ```{.text}
+    /// a * 1 = a       ∀ a ∈ Self
+    /// 1 * a = a       ∀ a ∈ Self
+    /// ```
+    ///
+    /// # Purity
+    ///
+    /// This function should return the same result at all times regardless of
+    /// external mutable state, for example values stored in TLS or in
+    /// `static mut`s.
+    // FIXME (#5527): This should be an associated constant
+    fn one() -> Self;
+}
+
+macro_rules! one_impl {
+    ($t:ty, $v:expr) => {
+        impl One for $t {
+            #[inline]
+            fn one() -> $t { $v }
+        }
+    }
+}
+
+one_impl!(usize, 1usize);
+one_impl!(u8,    1u8);
+one_impl!(u16,   1u16);
+one_impl!(u32,   1u32);
+one_impl!(u64,   1u64);
+
+one_impl!(isize, 1isize);
+one_impl!(i8,    1i8);
+one_impl!(i16,   1i16);
+one_impl!(i32,   1i32);
+one_impl!(i64,   1i64);
+
+one_impl!(f32, 1.0f32);
+one_impl!(f64, 1.0f64);

+ 360 - 0
traits/src/int.rs

@@ -0,0 +1,360 @@
+use std::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
+
+use {Num, NumCast};
+use bounds::Bounded;
+use ops::checked::*;
+use ops::saturating::Saturating;
+
+pub trait PrimInt
+    : Sized
+    + Copy
+    + Num + NumCast
+    + Bounded
+    + PartialOrd + Ord + Eq
+    + Not<Output=Self>
+    + BitAnd<Output=Self>
+    + BitOr<Output=Self>
+    + BitXor<Output=Self>
+    + Shl<usize, Output=Self>
+    + Shr<usize, Output=Self>
+    + CheckedAdd<Output=Self>
+    + CheckedSub<Output=Self>
+    + CheckedMul<Output=Self>
+    + CheckedDiv<Output=Self>
+    + Saturating
+{
+    /// Returns the number of ones in the binary representation of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0b01001100u8;
+    ///
+    /// assert_eq!(n.count_ones(), 3);
+    /// ```
+    fn count_ones(self) -> u32;
+
+    /// Returns the number of zeros in the binary representation of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0b01001100u8;
+    ///
+    /// assert_eq!(n.count_zeros(), 5);
+    /// ```
+    fn count_zeros(self) -> u32;
+
+    /// Returns the number of leading zeros in the binary representation
+    /// of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0b0101000u16;
+    ///
+    /// assert_eq!(n.leading_zeros(), 10);
+    /// ```
+    fn leading_zeros(self) -> u32;
+
+    /// Returns the number of trailing zeros in the binary representation
+    /// of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0b0101000u16;
+    ///
+    /// assert_eq!(n.trailing_zeros(), 3);
+    /// ```
+    fn trailing_zeros(self) -> u32;
+
+    /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
+    /// the truncated bits to the end of the resulting integer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    /// let m = 0x3456789ABCDEF012u64;
+    ///
+    /// assert_eq!(n.rotate_left(12), m);
+    /// ```
+    fn rotate_left(self, n: u32) -> Self;
+
+    /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
+    /// the truncated bits to the beginning of the resulting integer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    /// let m = 0xDEF0123456789ABCu64;
+    ///
+    /// assert_eq!(n.rotate_right(12), m);
+    /// ```
+    fn rotate_right(self, n: u32) -> Self;
+
+    /// Shifts the bits to the left by a specified amount amount, `n`, filling
+    /// zeros in the least significant bits.
+    ///
+    /// This is bitwise equivalent to signed `Shl`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    /// let m = 0x3456789ABCDEF000u64;
+    ///
+    /// assert_eq!(n.signed_shl(12), m);
+    /// ```
+    fn signed_shl(self, n: u32) -> Self;
+
+    /// Shifts the bits to the right by a specified amount amount, `n`, copying
+    /// the "sign bit" in the most significant bits even for unsigned types.
+    ///
+    /// This is bitwise equivalent to signed `Shr`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0xFEDCBA9876543210u64;
+    /// let m = 0xFFFFEDCBA9876543u64;
+    ///
+    /// assert_eq!(n.signed_shr(12), m);
+    /// ```
+    fn signed_shr(self, n: u32) -> Self;
+
+    /// Shifts the bits to the left by a specified amount amount, `n`, filling
+    /// zeros in the least significant bits.
+    ///
+    /// This is bitwise equivalent to unsigned `Shl`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFi64;
+    /// let m = 0x3456789ABCDEF000i64;
+    ///
+    /// assert_eq!(n.unsigned_shl(12), m);
+    /// ```
+    fn unsigned_shl(self, n: u32) -> Self;
+
+    /// Shifts the bits to the right by a specified amount amount, `n`, filling
+    /// zeros in the most significant bits.
+    ///
+    /// This is bitwise equivalent to unsigned `Shr`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0xFEDCBA9876543210i64;
+    /// let m = 0x000FEDCBA9876543i64;
+    ///
+    /// assert_eq!(n.unsigned_shr(12), m);
+    /// ```
+    fn unsigned_shr(self, n: u32) -> Self;
+
+    /// Reverses the byte order of the integer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    /// let m = 0xEFCDAB8967452301u64;
+    ///
+    /// assert_eq!(n.swap_bytes(), m);
+    /// ```
+    fn swap_bytes(self) -> Self;
+
+    /// Convert an integer from big endian to the target's endianness.
+    ///
+    /// On big endian this is a no-op. On little endian the bytes are swapped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    ///
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(u64::from_be(n), n)
+    /// } else {
+    ///     assert_eq!(u64::from_be(n), n.swap_bytes())
+    /// }
+    /// ```
+    fn from_be(x: Self) -> Self;
+
+    /// Convert an integer from little endian to the target's endianness.
+    ///
+    /// On little endian this is a no-op. On big endian the bytes are swapped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    ///
+    /// if cfg!(target_endian = "little") {
+    ///     assert_eq!(u64::from_le(n), n)
+    /// } else {
+    ///     assert_eq!(u64::from_le(n), n.swap_bytes())
+    /// }
+    /// ```
+    fn from_le(x: Self) -> Self;
+
+    /// Convert `self` to big endian from the target's endianness.
+    ///
+    /// On big endian this is a no-op. On little endian the bytes are swapped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    ///
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(n.to_be(), n)
+    /// } else {
+    ///     assert_eq!(n.to_be(), n.swap_bytes())
+    /// }
+    /// ```
+    fn to_be(self) -> Self;
+
+    /// Convert `self` to little endian from the target's endianness.
+    ///
+    /// On little endian this is a no-op. On big endian the bytes are swapped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// let n = 0x0123456789ABCDEFu64;
+    ///
+    /// if cfg!(target_endian = "little") {
+    ///     assert_eq!(n.to_le(), n)
+    /// } else {
+    ///     assert_eq!(n.to_le(), n.swap_bytes())
+    /// }
+    /// ```
+    fn to_le(self) -> Self;
+
+    /// Raises self to the power of `exp`, using exponentiation by squaring.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::PrimInt;
+    ///
+    /// assert_eq!(2i32.pow(4), 16);
+    /// ```
+    fn pow(self, mut exp: u32) -> Self;
+}
+
+macro_rules! prim_int_impl {
+    ($T:ty, $S:ty, $U:ty) => (
+        impl PrimInt for $T {
+            fn count_ones(self) -> u32 {
+                <$T>::count_ones(self)
+            }
+
+            fn count_zeros(self) -> u32 {
+                <$T>::count_zeros(self)
+            }
+
+            fn leading_zeros(self) -> u32 {
+                <$T>::leading_zeros(self)
+            }
+
+            fn trailing_zeros(self) -> u32 {
+                <$T>::trailing_zeros(self)
+            }
+
+            fn rotate_left(self, n: u32) -> Self {
+                <$T>::rotate_left(self, n)
+            }
+
+            fn rotate_right(self, n: u32) -> Self {
+                <$T>::rotate_right(self, n)
+            }
+
+            fn signed_shl(self, n: u32) -> Self {
+                ((self as $S) << n) as $T
+            }
+
+            fn signed_shr(self, n: u32) -> Self {
+                ((self as $S) >> n) as $T
+            }
+
+            fn unsigned_shl(self, n: u32) -> Self {
+                ((self as $U) << n) as $T
+            }
+
+            fn unsigned_shr(self, n: u32) -> Self {
+                ((self as $U) >> n) as $T
+            }
+
+            fn swap_bytes(self) -> Self {
+                <$T>::swap_bytes(self)
+            }
+
+            fn from_be(x: Self) -> Self {
+                <$T>::from_be(x)
+            }
+
+            fn from_le(x: Self) -> Self {
+                <$T>::from_le(x)
+            }
+
+            fn to_be(self) -> Self {
+                <$T>::to_be(self)
+            }
+
+            fn to_le(self) -> Self {
+                <$T>::to_le(self)
+            }
+
+            fn pow(self, exp: u32) -> Self {
+                <$T>::pow(self, exp)
+            }
+        }
+    )
+}
+
+// prim_int_impl!(type, signed, unsigned);
+prim_int_impl!(u8,    i8,    u8);
+prim_int_impl!(u16,   i16,   u16);
+prim_int_impl!(u32,   i32,   u32);
+prim_int_impl!(u64,   i64,   u64);
+prim_int_impl!(usize, isize, usize);
+prim_int_impl!(i8,    i8,    u8);
+prim_int_impl!(i16,   i16,   u16);
+prim_int_impl!(i32,   i32,   u32);
+prim_int_impl!(i64,   i64,   u64);
+prim_int_impl!(isize, isize, usize);

+ 233 - 0
traits/src/lib.rs

@@ -0,0 +1,233 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Numeric traits for generic mathematics
+
+use std::ops::{Add, Sub, Mul, Div, Rem};
+
+pub use bounds::Bounded;
+pub use float::Float;
+pub use identities::{Zero, One};
+pub use ops::checked::*;
+pub use ops::saturating::Saturating;
+pub use sign::{Signed, Unsigned};
+pub use cast::*;
+pub use int::PrimInt;
+
+pub mod identities;
+pub mod sign;
+pub mod ops;
+pub mod bounds;
+pub mod float;
+pub mod cast;
+pub mod int;
+
+/// The base trait for numeric types
+pub trait Num: PartialEq + Zero + One
+    + Add<Output = Self> + Sub<Output = Self>
+    + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self>
+{
+    type FromStrRadixErr;
+
+    /// Convert from a string and radix <= 36.
+    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
+}
+
+macro_rules! int_trait_impl {
+    ($name:ident for $($t:ty)*) => ($(
+        impl $name for $t {
+            type FromStrRadixErr = ::std::num::ParseIntError;
+            fn from_str_radix(s: &str, radix: u32)
+                              -> Result<Self, ::std::num::ParseIntError>
+            {
+                <$t>::from_str_radix(s, radix)
+            }
+        }
+    )*)
+}
+int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
+
+#[derive(Debug)]
+pub enum FloatErrorKind {
+    Empty,
+    Invalid,
+}
+// FIXME: std::num::ParseFloatError is stable in 1.0, but opaque to us,
+// so there's not really any way for us to reuse it.
+#[derive(Debug)]
+pub struct ParseFloatError {
+    pub kind: FloatErrorKind,
+}
+
+// FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
+// with this implementation ourselves until we want to make a breaking change.
+// (would have to drop it from `Num` though)
+macro_rules! float_trait_impl {
+    ($name:ident for $($t:ty)*) => ($(
+        impl $name for $t {
+            type FromStrRadixErr = ParseFloatError;
+
+            fn from_str_radix(src: &str, radix: u32)
+                              -> Result<Self, Self::FromStrRadixErr>
+            {
+                use self::FloatErrorKind::*;
+                use self::ParseFloatError as PFE;
+
+                // Special values
+                match src {
+                    "inf"   => return Ok(Float::infinity()),
+                    "-inf"  => return Ok(Float::neg_infinity()),
+                    "NaN"   => return Ok(Float::nan()),
+                    _       => {},
+                }
+
+                fn slice_shift_char(src: &str) -> Option<(char, &str)> {
+                    src.chars().nth(0).map(|ch| (ch, &src[1..]))
+                }
+
+                let (is_positive, src) =  match slice_shift_char(src) {
+                    None             => return Err(PFE { kind: Empty }),
+                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
+                    Some(('-', src)) => (false, src),
+                    Some((_, _))     => (true,  src),
+                };
+
+                // The significand to accumulate
+                let mut sig = if is_positive { 0.0 } else { -0.0 };
+                // Necessary to detect overflow
+                let mut prev_sig = sig;
+                let mut cs = src.chars().enumerate();
+                // Exponent prefix and exponent index offset
+                let mut exp_info = None::<(char, usize)>;
+
+                // Parse the integer part of the significand
+                for (i, c) in cs.by_ref() {
+                    match c.to_digit(radix) {
+                        Some(digit) => {
+                            // shift significand one digit left
+                            sig = sig * (radix as $t);
+
+                            // add/subtract current digit depending on sign
+                            if is_positive {
+                                sig = sig + ((digit as isize) as $t);
+                            } else {
+                                sig = sig - ((digit as isize) as $t);
+                            }
+
+                            // Detect overflow by comparing to last value, except
+                            // if we've not seen any non-zero digits.
+                            if prev_sig != 0.0 {
+                                if is_positive && sig <= prev_sig
+                                    { return Ok(Float::infinity()); }
+                                if !is_positive && sig >= prev_sig
+                                    { return Ok(Float::neg_infinity()); }
+
+                                // Detect overflow by reversing the shift-and-add process
+                                if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
+                                    { return Ok(Float::infinity()); }
+                                if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
+                                    { return Ok(Float::neg_infinity()); }
+                            }
+                            prev_sig = sig;
+                        },
+                        None => match c {
+                            'e' | 'E' | 'p' | 'P' => {
+                                exp_info = Some((c, i + 1));
+                                break;  // start of exponent
+                            },
+                            '.' => {
+                                break;  // start of fractional part
+                            },
+                            _ => {
+                                return Err(PFE { kind: Invalid });
+                            },
+                        },
+                    }
+                }
+
+                // If we are not yet at the exponent parse the fractional
+                // part of the significand
+                if exp_info.is_none() {
+                    let mut power = 1.0;
+                    for (i, c) in cs.by_ref() {
+                        match c.to_digit(radix) {
+                            Some(digit) => {
+                                // Decrease power one order of magnitude
+                                power = power / (radix as $t);
+                                // add/subtract current digit depending on sign
+                                sig = if is_positive {
+                                    sig + (digit as $t) * power
+                                } else {
+                                    sig - (digit as $t) * power
+                                };
+                                // Detect overflow by comparing to last value
+                                if is_positive && sig < prev_sig
+                                    { return Ok(Float::infinity()); }
+                                if !is_positive && sig > prev_sig
+                                    { return Ok(Float::neg_infinity()); }
+                                prev_sig = sig;
+                            },
+                            None => match c {
+                                'e' | 'E' | 'p' | 'P' => {
+                                    exp_info = Some((c, i + 1));
+                                    break; // start of exponent
+                                },
+                                _ => {
+                                    return Err(PFE { kind: Invalid });
+                                },
+                            },
+                        }
+                    }
+                }
+
+                // Parse and calculate the exponent
+                let exp = match exp_info {
+                    Some((c, offset)) => {
+                        let base = match c {
+                            'E' | 'e' if radix == 10 => 10.0,
+                            'P' | 'p' if radix == 16 => 2.0,
+                            _ => return Err(PFE { kind: Invalid }),
+                        };
+
+                        // Parse the exponent as decimal integer
+                        let src = &src[offset..];
+                        let (is_positive, exp) = match slice_shift_char(src) {
+                            Some(('-', src)) => (false, src.parse::<usize>()),
+                            Some(('+', src)) => (true,  src.parse::<usize>()),
+                            Some((_, _))     => (true,  src.parse::<usize>()),
+                            None             => return Err(PFE { kind: Invalid }),
+                        };
+
+                        match (is_positive, exp) {
+                            (true,  Ok(exp)) => base.powi(exp as i32),
+                            (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
+                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
+                        }
+                    },
+                    None => 1.0, // no exponent
+                };
+
+                Ok(sig * exp)
+            }
+        }
+    )*)
+}
+float_trait_impl!(Num for f32 f64);
+
+#[test]
+fn from_str_radix_unwrap() {
+    // The Result error must impl Debug to allow unwrap()
+
+    let i: i32 = Num::from_str_radix("0", 10).unwrap();
+    assert_eq!(i, 0);
+
+    let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
+    assert_eq!(f, 0.0);
+}

+ 91 - 0
traits/src/ops/checked.rs

@@ -0,0 +1,91 @@
+use std::ops::{Add, Sub, Mul, Div};
+
+/// Performs addition that returns `None` instead of wrapping around on
+/// overflow.
+pub trait CheckedAdd: Sized + Add<Self, Output=Self> {
+    /// Adds two numbers, checking for overflow. If overflow happens, `None` is
+    /// returned.
+    fn checked_add(&self, v: &Self) -> Option<Self>;
+}
+
+macro_rules! checked_impl {
+    ($trait_name:ident, $method:ident, $t:ty) => {
+        impl $trait_name for $t {
+            #[inline]
+            fn $method(&self, v: &$t) -> Option<$t> {
+                <$t>::$method(*self, *v)
+            }
+        }
+    }
+}
+
+checked_impl!(CheckedAdd, checked_add, u8);
+checked_impl!(CheckedAdd, checked_add, u16);
+checked_impl!(CheckedAdd, checked_add, u32);
+checked_impl!(CheckedAdd, checked_add, u64);
+checked_impl!(CheckedAdd, checked_add, usize);
+
+checked_impl!(CheckedAdd, checked_add, i8);
+checked_impl!(CheckedAdd, checked_add, i16);
+checked_impl!(CheckedAdd, checked_add, i32);
+checked_impl!(CheckedAdd, checked_add, i64);
+checked_impl!(CheckedAdd, checked_add, isize);
+
+/// Performs subtraction that returns `None` instead of wrapping around on underflow.
+pub trait CheckedSub: Sized + Sub<Self, Output=Self> {
+    /// Subtracts two numbers, checking for underflow. If underflow happens,
+    /// `None` is returned.
+    fn checked_sub(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedSub, checked_sub, u8);
+checked_impl!(CheckedSub, checked_sub, u16);
+checked_impl!(CheckedSub, checked_sub, u32);
+checked_impl!(CheckedSub, checked_sub, u64);
+checked_impl!(CheckedSub, checked_sub, usize);
+
+checked_impl!(CheckedSub, checked_sub, i8);
+checked_impl!(CheckedSub, checked_sub, i16);
+checked_impl!(CheckedSub, checked_sub, i32);
+checked_impl!(CheckedSub, checked_sub, i64);
+checked_impl!(CheckedSub, checked_sub, isize);
+
+/// Performs multiplication that returns `None` instead of wrapping around on underflow or
+/// overflow.
+pub trait CheckedMul: Sized + Mul<Self, Output=Self> {
+    /// Multiplies two numbers, checking for underflow or overflow. If underflow
+    /// or overflow happens, `None` is returned.
+    fn checked_mul(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedMul, checked_mul, u8);
+checked_impl!(CheckedMul, checked_mul, u16);
+checked_impl!(CheckedMul, checked_mul, u32);
+checked_impl!(CheckedMul, checked_mul, u64);
+checked_impl!(CheckedMul, checked_mul, usize);
+
+checked_impl!(CheckedMul, checked_mul, i8);
+checked_impl!(CheckedMul, checked_mul, i16);
+checked_impl!(CheckedMul, checked_mul, i32);
+checked_impl!(CheckedMul, checked_mul, i64);
+checked_impl!(CheckedMul, checked_mul, isize);
+
+/// Performs division that returns `None` instead of panicking on division by zero and instead of
+/// wrapping around on underflow and overflow.
+pub trait CheckedDiv: Sized + Div<Self, Output=Self> {
+    /// Divides two numbers, checking for underflow, overflow and division by
+    /// zero. If any of that happens, `None` is returned.
+    fn checked_div(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedDiv, checked_div, u8);
+checked_impl!(CheckedDiv, checked_div, u16);
+checked_impl!(CheckedDiv, checked_div, u32);
+checked_impl!(CheckedDiv, checked_div, u64);
+checked_impl!(CheckedDiv, checked_div, usize);
+
+checked_impl!(CheckedDiv, checked_div, i8);
+checked_impl!(CheckedDiv, checked_div, i16);
+checked_impl!(CheckedDiv, checked_div, i32);
+checked_impl!(CheckedDiv, checked_div, i64);
+checked_impl!(CheckedDiv, checked_div, isize);

+ 2 - 0
traits/src/ops/mod.rs

@@ -0,0 +1,2 @@
+pub mod saturating;
+pub mod checked;

+ 26 - 0
traits/src/ops/saturating.rs

@@ -0,0 +1,26 @@
+/// Saturating math operations
+pub trait Saturating {
+    /// Saturating addition operator.
+    /// Returns a+b, saturating at the numeric bounds instead of overflowing.
+    fn saturating_add(self, v: Self) -> Self;
+
+    /// Saturating subtraction operator.
+    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
+    fn saturating_sub(self, v: Self) -> Self;
+}
+
+macro_rules! saturating_impl {
+    ($trait_name:ident for $($t:ty)*) => {$(
+        impl $trait_name for $t {
+            fn saturating_add(self, v: Self) -> Self {
+                Self::saturating_add(self, v)
+            }
+
+            fn saturating_sub(self, v: Self) -> Self {
+                Self::saturating_sub(self, v)
+            }
+        }
+    )*}
+}
+
+saturating_impl!(Saturating for isize usize i8 u8 i16 u16 i32 u32 i64 u64);

+ 126 - 0
traits/src/sign.rs

@@ -0,0 +1,126 @@
+use std::ops::Neg;
+use std::{f32, f64};
+
+use Num;
+
+/// Useful functions for signed numbers (i.e. numbers that can be negative).
+pub trait Signed: Sized + Num + Neg<Output = Self> {
+    /// Computes the absolute value.
+    ///
+    /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
+    ///
+    /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
+    fn abs(&self) -> Self;
+
+    /// The positive difference of two numbers.
+    ///
+    /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
+    /// between `self` and `other` is returned.
+    fn abs_sub(&self, other: &Self) -> Self;
+
+    /// Returns the sign of the number.
+    ///
+    /// For `f32` and `f64`:
+    ///
+    /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// * `NaN` if the number is `NaN`
+    ///
+    /// For signed integers:
+    ///
+    /// * `0` if the number is zero
+    /// * `1` if the number is positive
+    /// * `-1` if the number is negative
+    fn signum(&self) -> Self;
+
+    /// Returns true if the number is positive and false if the number is zero or negative.
+    fn is_positive(&self) -> bool;
+
+    /// Returns true if the number is negative and false if the number is zero or positive.
+    fn is_negative(&self) -> bool;
+}
+
+macro_rules! signed_impl {
+    ($($t:ty)*) => ($(
+        impl Signed for $t {
+            #[inline]
+            fn abs(&self) -> $t {
+                if self.is_negative() { -*self } else { *self }
+            }
+
+            #[inline]
+            fn abs_sub(&self, other: &$t) -> $t {
+                if *self <= *other { 0 } else { *self - *other }
+            }
+
+            #[inline]
+            fn signum(&self) -> $t {
+                match *self {
+                    n if n > 0 => 1,
+                    0 => 0,
+                    _ => -1,
+                }
+            }
+
+            #[inline]
+            fn is_positive(&self) -> bool { *self > 0 }
+
+            #[inline]
+            fn is_negative(&self) -> bool { *self < 0 }
+        }
+    )*)
+}
+
+signed_impl!(isize i8 i16 i32 i64);
+
+macro_rules! signed_float_impl {
+    ($t:ty, $nan:expr, $inf:expr, $neg_inf:expr) => {
+        impl Signed for $t {
+            /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
+            #[inline]
+            fn abs(&self) -> $t {
+                <$t>::abs(*self)
+            }
+
+            /// The positive difference of two numbers. Returns `0.0` if the number is
+            /// less than or equal to `other`, otherwise the difference between`self`
+            /// and `other` is returned.
+            #[inline]
+            fn abs_sub(&self, other: &$t) -> $t {
+                <$t>::abs_sub(*self, *other)
+            }
+
+            /// # Returns
+            ///
+            /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+            /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+            /// - `NAN` if the number is NaN
+            #[inline]
+            fn signum(&self) -> $t {
+                <$t>::signum(*self)
+            }
+
+            /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
+            #[inline]
+            fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == $inf }
+
+            /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
+            #[inline]
+            fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == $neg_inf }
+        }
+    }
+}
+
+signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY);
+signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY);
+
+/// A trait for values which cannot be negative
+pub trait Unsigned: Num {}
+
+macro_rules! empty_trait_impl {
+    ($name:ident for $($t:ty)*) => ($(
+        impl $name for $t {}
+    )*)
+}
+
+empty_trait_impl!(Unsigned for usize u8 u16 u32 u64);

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio