about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>2014-01-18 17:08:23 +1100
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>2014-01-20 18:09:46 +1100
commitcf56624a4ad7703c8f3fc327b8c385da0a803ea5 (patch)
tree0a46f95db2c26f4beb50f7785a82f46348ff9083 /src/libstd
parent764f2cb6f3517869e31fc7b93ff11dd840db8d30 (diff)
downloadrust-cf56624a4ad7703c8f3fc327b8c385da0a803ea5.tar.gz
rust-cf56624a4ad7703c8f3fc327b8c385da0a803ea5.zip
Add operator trait constraints to std::num::{Zero, One} and document their appropriate use
Zero and One have precise definitions in mathematics. Documentation has been added to describe the appropriate uses for these traits and the laws that they should satisfy.

For more information regarding these identities, see the following wikipedia pages:

- http://wikipedia.org/wiki/Additive_identity
- http://wikipedia.org/wiki/Multiplicative_identity
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/bool.rs7
-rw-r--r--src/libstd/char.rs10
-rw-r--r--src/libstd/iter.rs6
-rw-r--r--src/libstd/num/mod.rs62
-rw-r--r--src/libstd/tuple.rs13
-rw-r--r--src/libstd/unit.rs10
6 files changed, 52 insertions, 56 deletions
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
index d080262ccc7..af745f94fb5 100644
--- a/src/libstd/bool.rs
+++ b/src/libstd/bool.rs
@@ -40,7 +40,6 @@ use num::FromPrimitive;
 #[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering};
 #[cfg(not(test))] use ops::{Not, BitAnd, BitOr, BitXor};
 #[cfg(not(test))] use default::Default;
-#[cfg(not(test))] use num::Zero;
 
 /////////////////////////////////////////////////////////////////////////////
 // Freestanding functions
@@ -309,12 +308,6 @@ impl Default for bool {
     fn default() -> bool { false }
 }
 
-#[cfg(not(test))]
-impl Zero for bool {
-    fn zero() -> bool { false }
-    fn is_zero(&self) -> bool { *self == false }
-}
-
 #[cfg(test)]
 mod tests {
     use prelude::*;
diff --git a/src/libstd/char.rs b/src/libstd/char.rs
index 4e9c72de618..71a297d7176 100644
--- a/src/libstd/char.rs
+++ b/src/libstd/char.rs
@@ -22,7 +22,6 @@ use str;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
 #[cfg(not(test))] use default::Default;
-#[cfg(not(test))] use num::Zero;
 
 // UTF-8 ranges and tags for encoding characters
 static TAG_CONT: uint = 128u;
@@ -449,15 +448,6 @@ impl Default for char {
     fn default() -> char { '\x00' }
 }
 
-#[cfg(not(test))]
-impl Zero for char {
-    #[inline]
-    fn zero() -> char { '\x00' }
-
-    #[inline]
-    fn is_zero(&self) -> bool { *self == '\x00' }
-}
-
 #[test]
 fn test_is_lowercase() {
     assert!('a'.is_lowercase());
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index fcf0f4f2444..8081c6ed8db 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -2872,6 +2872,12 @@ mod tests {
             }
         }
 
+        impl Mul<Foo, Foo> for Foo {
+            fn mul(&self, _: &Foo) -> Foo {
+                Foo
+            }
+        }
+
         impl num::One for Foo {
             fn one() -> Foo {
                 Foo
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index c374d6c2157..23a852cc357 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -50,19 +50,59 @@ pub trait Orderable: Ord {
 /// Returns the number constrained within the range `mn <= self <= mx`.
 #[inline(always)] pub fn clamp<T: Orderable>(value: T, mn: T, mx: T) -> T { value.clamp(&mn, &mx) }
 
-pub trait Zero {
-    fn zero() -> Self;      // FIXME (#5527): This should be an associated constant
+/// Defines an additive identity element for `Self`.
+///
+/// # Deriving
+///
+/// This trait can be automatically be derived using `#[deriving(Zero)]`
+/// attribute. If you choose to use this, make sure that the laws outlined in
+/// the documentation for `Zero::zero` still hold.
+pub trait Zero: Add<Self, Self> {
+    /// Returns the additive identity element of `Self`, `0`.
+    ///
+    /// # Laws
+    ///
+    /// ~~~
+    /// 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.
     fn is_zero(&self) -> bool;
 }
 
-/// Returns `0` of appropriate type.
+/// Returns the additive identity, `0`.
 #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
 
-pub trait One {
-    fn one() -> Self;       // FIXME (#5527): This should be an associated constant
+/// Defines a multiplicative identity element for `Self`.
+pub trait One: Mul<Self, Self> {
+    /// Returns the multiplicative identity element of `Self`, `1`.
+    ///
+    /// # Laws
+    ///
+    /// ~~~
+    /// 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;
 }
 
-/// Returns `1` of appropriate type.
+/// Returns the multiplicative identity, `1`.
 #[inline(always)] pub fn one<T: One>() -> T { One::one() }
 
 pub trait Signed: Num
@@ -993,16 +1033,6 @@ pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
     FromStrRadix::from_str_radix(str, radix)
 }
 
-impl<T: Zero + 'static> Zero for @T {
-    fn zero() -> @T { @Zero::zero() }
-    fn is_zero(&self) -> bool { (**self).is_zero() }
-}
-
-impl<T: Zero> Zero for ~T {
-    fn zero() -> ~T { ~Zero::zero() }
-    fn is_zero(&self) -> bool { (**self).is_zero() }
-}
-
 /// Saturating math operations
 pub trait Saturating {
     /// Saturating addition operator.
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 313fd9c79b4..8e278aeb2ea 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -15,7 +15,6 @@
 use clone::Clone;
 #[cfg(not(test))] use cmp::*;
 #[cfg(not(test))] use default::Default;
-#[cfg(not(test))] use num::Zero;
 
 /// Method extensions to pairs where both types satisfy the `Clone` bound
 pub trait CopyableTuple<T, U> {
@@ -177,18 +176,6 @@ macro_rules! tuple_impls {
                     ($({ let x: $T = Default::default(); x},)+)
                 }
             }
-
-            #[cfg(not(test))]
-            impl<$($T:Zero),+> Zero for ($($T,)+) {
-                #[inline]
-                fn zero() -> ($($T,)+) {
-                    ($({ let x: $T = Zero::zero(); x},)+)
-                }
-                #[inline]
-                fn is_zero(&self) -> bool {
-                    $(self.$get_ref_fn().is_zero())&&+
-                }
-            }
         )+
     }
 }
diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs
index c27f6e3d086..786a7f42bb3 100644
--- a/src/libstd/unit.rs
+++ b/src/libstd/unit.rs
@@ -12,8 +12,6 @@
 
 #[cfg(not(test))]
 use prelude::*;
-#[cfg(not(test))]
-use num::Zero;
 
 #[cfg(not(test))]
 impl Eq for () {
@@ -46,11 +44,3 @@ impl Default for () {
     #[inline]
     fn default() -> () { () }
 }
-
-#[cfg(not(test))]
-impl Zero for () {
-    #[inline]
-    fn zero() -> () { () }
-    #[inline]
-    fn is_zero(&self) -> bool { true }
-}