From 0fcb85997db852350c104b40e3d7c78214bb0708 Mon Sep 17 00:00:00 2001
From: Brendan Zabarauskas <bjzaba@yahoo.com.au>
Date: Sat, 7 Sep 2013 17:15:35 +1000
Subject: [PATCH 1/3] Moved checked trait impls out of std::num

This follows the same pattern as the other numeric trait impls, and reduces the clutter in std::num.
---
 src/libstd/num/i16.rs  |  33 +++-
 src/libstd/num/i32.rs  |  33 +++-
 src/libstd/num/i64.rs  |  35 +++-
 src/libstd/num/i8.rs   |  33 +++-
 src/libstd/num/int.rs  |  70 +++++++-
 src/libstd/num/num.rs  | 379 +----------------------------------------
 src/libstd/num/u16.rs  |  35 ++++
 src/libstd/num/u32.rs  |  35 ++++
 src/libstd/num/u64.rs  |  37 ++++
 src/libstd/num/u8.rs   |  35 ++++
 src/libstd/num/uint.rs |  69 ++++++++
 11 files changed, 411 insertions(+), 383 deletions(-)

diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs
index eec20297a53..5c077c7e633 100644
--- a/src/libstd/num/i16.rs
+++ b/src/libstd/num/i16.rs
@@ -10,7 +10,8 @@
 
 //! Operations and constants for `i16`
 
-use num::BitCount;
+use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
 use unstable::intrinsics;
 
 pub use self::generated::*;
@@ -30,3 +31,33 @@ impl BitCount for i16 {
     #[inline]
     fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self) } }
 }
+
+impl CheckedAdd for i16 {
+    #[inline]
+    fn checked_add(&self, v: &i16) -> Option<i16> {
+        unsafe {
+            let (x, y) = intrinsics::i16_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for i16 {
+    #[inline]
+    fn checked_sub(&self, v: &i16) -> Option<i16> {
+        unsafe {
+            let (x, y) = intrinsics::i16_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedMul for i16 {
+    #[inline]
+    fn checked_mul(&self, v: &i16) -> Option<i16> {
+        unsafe {
+            let (x, y) = intrinsics::i16_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs
index 769187cc66d..f076e33b3a2 100644
--- a/src/libstd/num/i32.rs
+++ b/src/libstd/num/i32.rs
@@ -10,7 +10,8 @@
 
 //! Operations and constants for `i32`
 
-use num::BitCount;
+use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
 use unstable::intrinsics;
 
 pub use self::generated::*;
@@ -30,3 +31,33 @@ impl BitCount for i32 {
     #[inline]
     fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self) } }
 }
+
+impl CheckedAdd for i32 {
+    #[inline]
+    fn checked_add(&self, v: &i32) -> Option<i32> {
+        unsafe {
+            let (x, y) = intrinsics::i32_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for i32 {
+    #[inline]
+    fn checked_sub(&self, v: &i32) -> Option<i32> {
+        unsafe {
+            let (x, y) = intrinsics::i32_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedMul for i32 {
+    #[inline]
+    fn checked_mul(&self, v: &i32) -> Option<i32> {
+        unsafe {
+            let (x, y) = intrinsics::i32_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs
index ae0e59d1661..10df7e37b88 100644
--- a/src/libstd/num/i64.rs
+++ b/src/libstd/num/i64.rs
@@ -10,7 +10,8 @@
 
 //! Operations and constants for `i64`
 
-use num::BitCount;
+use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
 use unstable::intrinsics;
 
 pub use self::generated::*;
@@ -30,3 +31,35 @@ impl BitCount for i64 {
     #[inline]
     fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self) } }
 }
+
+impl CheckedAdd for i64 {
+    #[inline]
+    fn checked_add(&self, v: &i64) -> Option<i64> {
+        unsafe {
+            let (x, y) = intrinsics::i64_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for i64 {
+    #[inline]
+    fn checked_sub(&self, v: &i64) -> Option<i64> {
+        unsafe {
+            let (x, y) = intrinsics::i64_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+// FIXME: #8449: should not be disabled on 32-bit
+#[cfg(target_word_size = "64")]
+impl CheckedMul for i64 {
+    #[inline]
+    fn checked_mul(&self, v: &i64) -> Option<i64> {
+        unsafe {
+            let (x, y) = intrinsics::i64_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs
index 31a1f4241f5..a807f6b9e53 100644
--- a/src/libstd/num/i8.rs
+++ b/src/libstd/num/i8.rs
@@ -10,7 +10,8 @@
 
 //! Operations and constants for `i8`
 
-use num::BitCount;
+use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
 use unstable::intrinsics;
 
 pub use self::generated::*;
@@ -30,3 +31,33 @@ impl BitCount for i8 {
     #[inline]
     fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self) } }
 }
+
+impl CheckedAdd for i8 {
+    #[inline]
+    fn checked_add(&self, v: &i8) -> Option<i8> {
+        unsafe {
+            let (x, y) = intrinsics::i8_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for i8 {
+    #[inline]
+    fn checked_sub(&self, v: &i8) -> Option<i8> {
+        unsafe {
+            let (x, y) = intrinsics::i8_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedMul for i8 {
+    #[inline]
+    fn checked_mul(&self, v: &i8) -> Option<i8> {
+        unsafe {
+            let (x, y) = intrinsics::i8_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index d39b4b2b911..c5364fa3dab 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -12,7 +12,9 @@
 
 #[allow(non_uppercase_statics)];
 
-use num::BitCount;
+use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
+use unstable::intrinsics;
 
 pub use self::generated::*;
 
@@ -51,6 +53,72 @@ impl BitCount for int {
     fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int }
 }
 
+#[cfg(target_word_size = "32")]
+impl CheckedAdd for int {
+    #[inline]
+    fn checked_add(&self, v: &int) -> Option<int> {
+        unsafe {
+            let (x, y) = intrinsics::i32_add_with_overflow(*self as i32, *v as i32);
+            if y { None } else { Some(x as int) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "64")]
+impl CheckedAdd for int {
+    #[inline]
+    fn checked_add(&self, v: &int) -> Option<int> {
+        unsafe {
+            let (x, y) = intrinsics::i64_add_with_overflow(*self as i64, *v as i64);
+            if y { None } else { Some(x as int) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "32")]
+impl CheckedSub for int {
+    #[inline]
+    fn checked_sub(&self, v: &int) -> Option<int> {
+        unsafe {
+            let (x, y) = intrinsics::i32_sub_with_overflow(*self as i32, *v as i32);
+            if y { None } else { Some(x as int) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "64")]
+impl CheckedSub for int {
+    #[inline]
+    fn checked_sub(&self, v: &int) -> Option<int> {
+        unsafe {
+            let (x, y) = intrinsics::i64_sub_with_overflow(*self as i64, *v as i64);
+            if y { None } else { Some(x as int) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "32")]
+impl CheckedMul for int {
+    #[inline]
+    fn checked_mul(&self, v: &int) -> Option<int> {
+        unsafe {
+            let (x, y) = intrinsics::i32_mul_with_overflow(*self as i32, *v as i32);
+            if y { None } else { Some(x as int) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "64")]
+impl CheckedMul for int {
+    #[inline]
+    fn checked_mul(&self, v: &int) -> Option<int> {
+        unsafe {
+            let (x, y) = intrinsics::i64_mul_with_overflow(*self as i64, *v as i64);
+            if y { None } else { Some(x as int) }
+        }
+    }
+}
+
 /// Returns `base` raised to the power of `exponent`
 pub fn pow(base: int, exponent: uint) -> int {
     if exponent == 0u {
diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs
index ac8f0022b95..724bc6dda01 100644
--- a/src/libstd/num/num.rs
+++ b/src/libstd/num/num.rs
@@ -19,7 +19,6 @@ use cmp::{Eq, ApproxEq, Ord};
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
 use option::{Option, Some, None};
-use unstable::intrinsics;
 
 pub mod strconv;
 
@@ -493,7 +492,7 @@ pub trait Saturating {
     fn saturating_sub(self, v: Self) -> Self;
 }
 
-impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
+impl<T: CheckedAdd + CheckedSub + Zero + Ord + Bounded> Saturating for T {
     #[inline]
     fn saturating_add(self, v: T) -> T {
         match self.checked_add(&v) {
@@ -523,390 +522,14 @@ pub trait CheckedAdd: Add<Self, Self> {
     fn checked_add(&self, v: &Self) -> Option<Self>;
 }
 
-impl CheckedAdd for i8 {
-    #[inline]
-    fn checked_add(&self, v: &i8) -> Option<i8> {
-        unsafe {
-            let (x, y) = intrinsics::i8_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedAdd for i16 {
-    #[inline]
-    fn checked_add(&self, v: &i16) -> Option<i16> {
-        unsafe {
-            let (x, y) = intrinsics::i16_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedAdd for i32 {
-    #[inline]
-    fn checked_add(&self, v: &i32) -> Option<i32> {
-        unsafe {
-            let (x, y) = intrinsics::i32_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedAdd for i64 {
-    #[inline]
-    fn checked_add(&self, v: &i64) -> Option<i64> {
-        unsafe {
-            let (x, y) = intrinsics::i64_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedAdd for int {
-    #[inline]
-    fn checked_add(&self, v: &int) -> Option<int> {
-        unsafe {
-            let (x, y) = intrinsics::i32_add_with_overflow(*self as i32, *v as i32);
-            if y { None } else { Some(x as int) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedAdd for int {
-    #[inline]
-    fn checked_add(&self, v: &int) -> Option<int> {
-        unsafe {
-            let (x, y) = intrinsics::i64_add_with_overflow(*self as i64, *v as i64);
-            if y { None } else { Some(x as int) }
-        }
-    }
-}
-
-impl CheckedAdd for u8 {
-    #[inline]
-    fn checked_add(&self, v: &u8) -> Option<u8> {
-        unsafe {
-            let (x, y) = intrinsics::u8_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedAdd for u16 {
-    #[inline]
-    fn checked_add(&self, v: &u16) -> Option<u16> {
-        unsafe {
-            let (x, y) = intrinsics::u16_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedAdd for u32 {
-    #[inline]
-    fn checked_add(&self, v: &u32) -> Option<u32> {
-        unsafe {
-            let (x, y) = intrinsics::u32_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedAdd for u64 {
-    #[inline]
-    fn checked_add(&self, v: &u64) -> Option<u64> {
-        unsafe {
-            let (x, y) = intrinsics::u64_add_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedAdd for uint {
-    #[inline]
-    fn checked_add(&self, v: &uint) -> Option<uint> {
-        unsafe {
-            let (x, y) = intrinsics::u32_add_with_overflow(*self as u32, *v as u32);
-            if y { None } else { Some(x as uint) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedAdd for uint {
-    #[inline]
-    fn checked_add(&self, v: &uint) -> Option<uint> {
-        unsafe {
-            let (x, y) = intrinsics::u64_add_with_overflow(*self as u64, *v as u64);
-            if y { None } else { Some(x as uint) }
-        }
-    }
-}
-
 pub trait CheckedSub: Sub<Self, Self> {
     fn checked_sub(&self, v: &Self) -> Option<Self>;
 }
 
-impl CheckedSub for i8 {
-    #[inline]
-    fn checked_sub(&self, v: &i8) -> Option<i8> {
-        unsafe {
-            let (x, y) = intrinsics::i8_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedSub for i16 {
-    #[inline]
-    fn checked_sub(&self, v: &i16) -> Option<i16> {
-        unsafe {
-            let (x, y) = intrinsics::i16_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedSub for i32 {
-    #[inline]
-    fn checked_sub(&self, v: &i32) -> Option<i32> {
-        unsafe {
-            let (x, y) = intrinsics::i32_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedSub for i64 {
-    #[inline]
-    fn checked_sub(&self, v: &i64) -> Option<i64> {
-        unsafe {
-            let (x, y) = intrinsics::i64_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedSub for int {
-    #[inline]
-    fn checked_sub(&self, v: &int) -> Option<int> {
-        unsafe {
-            let (x, y) = intrinsics::i32_sub_with_overflow(*self as i32, *v as i32);
-            if y { None } else { Some(x as int) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedSub for int {
-    #[inline]
-    fn checked_sub(&self, v: &int) -> Option<int> {
-        unsafe {
-            let (x, y) = intrinsics::i64_sub_with_overflow(*self as i64, *v as i64);
-            if y { None } else { Some(x as int) }
-        }
-    }
-}
-
-impl CheckedSub for u8 {
-    #[inline]
-    fn checked_sub(&self, v: &u8) -> Option<u8> {
-        unsafe {
-            let (x, y) = intrinsics::u8_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedSub for u16 {
-    #[inline]
-    fn checked_sub(&self, v: &u16) -> Option<u16> {
-        unsafe {
-            let (x, y) = intrinsics::u16_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedSub for u32 {
-    #[inline]
-    fn checked_sub(&self, v: &u32) -> Option<u32> {
-        unsafe {
-            let (x, y) = intrinsics::u32_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedSub for u64 {
-    #[inline]
-    fn checked_sub(&self, v: &u64) -> Option<u64> {
-        unsafe {
-            let (x, y) = intrinsics::u64_sub_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedSub for uint {
-    #[inline]
-    fn checked_sub(&self, v: &uint) -> Option<uint> {
-        unsafe {
-            let (x, y) = intrinsics::u32_sub_with_overflow(*self as u32, *v as u32);
-            if y { None } else { Some(x as uint) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedSub for uint {
-    #[inline]
-    fn checked_sub(&self, v: &uint) -> Option<uint> {
-        unsafe {
-            let (x, y) = intrinsics::u64_sub_with_overflow(*self as u64, *v as u64);
-            if y { None } else { Some(x as uint) }
-        }
-    }
-}
-
 pub trait CheckedMul: Mul<Self, Self> {
     fn checked_mul(&self, v: &Self) -> Option<Self>;
 }
 
-impl CheckedMul for i8 {
-    #[inline]
-    fn checked_mul(&self, v: &i8) -> Option<i8> {
-        unsafe {
-            let (x, y) = intrinsics::i8_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedMul for i16 {
-    #[inline]
-    fn checked_mul(&self, v: &i16) -> Option<i16> {
-        unsafe {
-            let (x, y) = intrinsics::i16_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedMul for i32 {
-    #[inline]
-    fn checked_mul(&self, v: &i32) -> Option<i32> {
-        unsafe {
-            let (x, y) = intrinsics::i32_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-// FIXME: #8449: should not be disabled on 32-bit
-#[cfg(target_word_size = "64")]
-impl CheckedMul for i64 {
-    #[inline]
-    fn checked_mul(&self, v: &i64) -> Option<i64> {
-        unsafe {
-            let (x, y) = intrinsics::i64_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedMul for int {
-    #[inline]
-    fn checked_mul(&self, v: &int) -> Option<int> {
-        unsafe {
-            let (x, y) = intrinsics::i32_mul_with_overflow(*self as i32, *v as i32);
-            if y { None } else { Some(x as int) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedMul for int {
-    #[inline]
-    fn checked_mul(&self, v: &int) -> Option<int> {
-        unsafe {
-            let (x, y) = intrinsics::i64_mul_with_overflow(*self as i64, *v as i64);
-            if y { None } else { Some(x as int) }
-        }
-    }
-}
-
-impl CheckedMul for u8 {
-    #[inline]
-    fn checked_mul(&self, v: &u8) -> Option<u8> {
-        unsafe {
-            let (x, y) = intrinsics::u8_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedMul for u16 {
-    #[inline]
-    fn checked_mul(&self, v: &u16) -> Option<u16> {
-        unsafe {
-            let (x, y) = intrinsics::u16_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-impl CheckedMul for u32 {
-    #[inline]
-    fn checked_mul(&self, v: &u32) -> Option<u32> {
-        unsafe {
-            let (x, y) = intrinsics::u32_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-// FIXME: #8449: should not be disabled on 32-bit
-#[cfg(target_word_size = "64")]
-impl CheckedMul for u64 {
-    #[inline]
-    fn checked_mul(&self, v: &u64) -> Option<u64> {
-        unsafe {
-            let (x, y) = intrinsics::u64_mul_with_overflow(*self, *v);
-            if y { None } else { Some(x) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "32")]
-impl CheckedMul for uint {
-    #[inline]
-    fn checked_mul(&self, v: &uint) -> Option<uint> {
-        unsafe {
-            let (x, y) = intrinsics::u32_mul_with_overflow(*self as u32, *v as u32);
-            if y { None } else { Some(x as uint) }
-        }
-    }
-}
-
-#[cfg(target_word_size = "64")]
-impl CheckedMul for uint {
-    #[inline]
-    fn checked_mul(&self, v: &uint) -> Option<uint> {
-        unsafe {
-            let (x, y) = intrinsics::u64_mul_with_overflow(*self as u64, *v as u64);
-            if y { None } else { Some(x as uint) }
-        }
-    }
-}
-
 pub trait CheckedDiv: Div<Self, Self> {
     fn checked_div(&self, v: &Self) -> Option<Self>;
 }
diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs
index 3a4c2420f9e..e227947ca6e 100644
--- a/src/libstd/num/u16.rs
+++ b/src/libstd/num/u16.rs
@@ -10,5 +10,40 @@
 
 //! Operations and constants for `u16`
 
+use num::{CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
+use unstable::intrinsics;
+
 pub use self::generated::*;
+
 uint_module!(u16, i16, 16)
+
+impl CheckedAdd for u16 {
+    #[inline]
+    fn checked_add(&self, v: &u16) -> Option<u16> {
+        unsafe {
+            let (x, y) = intrinsics::u16_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for u16 {
+    #[inline]
+    fn checked_sub(&self, v: &u16) -> Option<u16> {
+        unsafe {
+            let (x, y) = intrinsics::u16_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedMul for u16 {
+    #[inline]
+    fn checked_mul(&self, v: &u16) -> Option<u16> {
+        unsafe {
+            let (x, y) = intrinsics::u16_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs
index f87fa7fcd42..4dbd543da7b 100644
--- a/src/libstd/num/u32.rs
+++ b/src/libstd/num/u32.rs
@@ -10,5 +10,40 @@
 
 //! Operations and constants for `u32`
 
+use num::{CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
+use unstable::intrinsics;
+
 pub use self::generated::*;
+
 uint_module!(u32, i32, 32)
+
+impl CheckedAdd for u32 {
+    #[inline]
+    fn checked_add(&self, v: &u32) -> Option<u32> {
+        unsafe {
+            let (x, y) = intrinsics::u32_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for u32 {
+    #[inline]
+    fn checked_sub(&self, v: &u32) -> Option<u32> {
+        unsafe {
+            let (x, y) = intrinsics::u32_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedMul for u32 {
+    #[inline]
+    fn checked_mul(&self, v: &u32) -> Option<u32> {
+        unsafe {
+            let (x, y) = intrinsics::u32_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index 792db155569..b311183ba11 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -10,5 +10,42 @@
 
 //! Operations and constants for `u64`
 
+use num::{CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
+use unstable::intrinsics;
+
 pub use self::generated::*;
+
 uint_module!(u64, i64, 64)
+
+impl CheckedAdd for u64 {
+    #[inline]
+    fn checked_add(&self, v: &u64) -> Option<u64> {
+        unsafe {
+            let (x, y) = intrinsics::u64_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for u64 {
+    #[inline]
+    fn checked_sub(&self, v: &u64) -> Option<u64> {
+        unsafe {
+            let (x, y) = intrinsics::u64_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+// FIXME: #8449: should not be disabled on 32-bit
+#[cfg(target_word_size = "64")]
+impl CheckedMul for u64 {
+    #[inline]
+    fn checked_mul(&self, v: &u64) -> Option<u64> {
+        unsafe {
+            let (x, y) = intrinsics::u64_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs
index e21e80f8406..ca54af5cecc 100644
--- a/src/libstd/num/u8.rs
+++ b/src/libstd/num/u8.rs
@@ -10,5 +10,40 @@
 
 //! Operations and constants for `u8`
 
+use num::{CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
+use unstable::intrinsics;
+
 pub use self::generated::*;
+
 uint_module!(u8, i8, 8)
+
+impl CheckedAdd for u8 {
+    #[inline]
+    fn checked_add(&self, v: &u8) -> Option<u8> {
+        unsafe {
+            let (x, y) = intrinsics::u8_add_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedSub for u8 {
+    #[inline]
+    fn checked_sub(&self, v: &u8) -> Option<u8> {
+        unsafe {
+            let (x, y) = intrinsics::u8_sub_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
+
+impl CheckedMul for u8 {
+    #[inline]
+    fn checked_mul(&self, v: &u8) -> Option<u8> {
+        unsafe {
+            let (x, y) = intrinsics::u8_mul_with_overflow(*self, *v);
+            if y { None } else { Some(x) }
+        }
+    }
+}
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index e23bdc576d3..dfdd6cf72f7 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -11,6 +11,9 @@
 //! Operations and constants for `uint`
 
 use num;
+use num::{CheckedAdd, CheckedSub, CheckedMul};
+use option::{Option, Some, None};
+use unstable::intrinsics;
 use sys;
 
 pub use self::generated::*;
@@ -101,6 +104,72 @@ pub fn next_power_of_two(n: uint) -> uint {
     return tmp + 1u;
 }
 
+#[cfg(target_word_size = "32")]
+impl CheckedAdd for uint {
+    #[inline]
+    fn checked_add(&self, v: &uint) -> Option<uint> {
+        unsafe {
+            let (x, y) = intrinsics::u32_add_with_overflow(*self as u32, *v as u32);
+            if y { None } else { Some(x as uint) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "64")]
+impl CheckedAdd for uint {
+    #[inline]
+    fn checked_add(&self, v: &uint) -> Option<uint> {
+        unsafe {
+            let (x, y) = intrinsics::u64_add_with_overflow(*self as u64, *v as u64);
+            if y { None } else { Some(x as uint) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "32")]
+impl CheckedSub for uint {
+    #[inline]
+    fn checked_sub(&self, v: &uint) -> Option<uint> {
+        unsafe {
+            let (x, y) = intrinsics::u32_sub_with_overflow(*self as u32, *v as u32);
+            if y { None } else { Some(x as uint) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "64")]
+impl CheckedSub for uint {
+    #[inline]
+    fn checked_sub(&self, v: &uint) -> Option<uint> {
+        unsafe {
+            let (x, y) = intrinsics::u64_sub_with_overflow(*self as u64, *v as u64);
+            if y { None } else { Some(x as uint) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "32")]
+impl CheckedMul for uint {
+    #[inline]
+    fn checked_mul(&self, v: &uint) -> Option<uint> {
+        unsafe {
+            let (x, y) = intrinsics::u32_mul_with_overflow(*self as u32, *v as u32);
+            if y { None } else { Some(x as uint) }
+        }
+    }
+}
+
+#[cfg(target_word_size = "64")]
+impl CheckedMul for uint {
+    #[inline]
+    fn checked_mul(&self, v: &uint) -> Option<uint> {
+        unsafe {
+            let (x, y) = intrinsics::u64_mul_with_overflow(*self as u64, *v as u64);
+            if y { None } else { Some(x as uint) }
+        }
+    }
+}
+
 #[test]
 fn test_next_power_of_two() {
     assert!((next_power_of_two(0u) == 0u));

From 8445009a846877fe66160d126566e9757db05cd2 Mon Sep 17 00:00:00 2001
From: Brendan Zabarauskas <bjzaba@yahoo.com.au>
Date: Sat, 7 Sep 2013 17:16:56 +1000
Subject: [PATCH 2/3] Add Clone and DeepClone constraints to Primitive trait

---
 src/libstd/num/num.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs
index 724bc6dda01..135124b04c1 100644
--- a/src/libstd/num/num.rs
+++ b/src/libstd/num/num.rs
@@ -15,6 +15,7 @@
 
 #[allow(missing_doc)];
 
+use clone::{Clone, DeepClone};
 use cmp::{Eq, ApproxEq, Ord};
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
@@ -274,7 +275,9 @@ pub trait Bounded {
 /// Specifies the available operations common to all of Rust's core numeric primitives.
 /// These may not always make sense from a purely mathematical point of view, but
 /// may be useful for systems programming.
-pub trait Primitive: Num
+pub trait Primitive: Clone
+                   + DeepClone
+                   + Num
                    + NumCast
                    + Bounded
                    + Neg<Self>

From 2c31053d20ba8f4bd9120d2025d8eb226b94179a Mon Sep 17 00:00:00 2001
From: Brendan Zabarauskas <bjzaba@yahoo.com.au>
Date: Mon, 9 Sep 2013 03:51:29 +1000
Subject: [PATCH 3/3] Fix unused import warnings on 32bit systems

---
 src/libstd/num/i64.rs | 4 +++-
 src/libstd/num/u64.rs | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs
index 10df7e37b88..d991bf03300 100644
--- a/src/libstd/num/i64.rs
+++ b/src/libstd/num/i64.rs
@@ -10,7 +10,9 @@
 
 //! Operations and constants for `i64`
 
-use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use num::{BitCount, CheckedAdd, CheckedSub};
+#[cfg(target_word_size = "64")]
+use num::CheckedMul;
 use option::{Option, Some, None};
 use unstable::intrinsics;
 
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index b311183ba11..d3077333077 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -10,7 +10,9 @@
 
 //! Operations and constants for `u64`
 
-use num::{CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedAdd, CheckedSub};
+#[cfg(target_word_size = "64")]
+use num::CheckedMul;
 use option::{Option, Some, None};
 use unstable::intrinsics;