about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-11-04 14:14:48 -0700
committerGitHub <noreply@github.com>2016-11-04 14:14:48 -0700
commit713a360560ab70651d10f09c9949673fa5e42fcd (patch)
tree22ab79e011a9a40c74bd0d843f124c69d5a3be81 /src/libcore
parent81601cd3a393d1cb8ca82eb1b2270d24c5d7724f (diff)
parentdf0e5a97fb326ade900567d80977f40b83aea565 (diff)
downloadrust-713a360560ab70651d10f09c9949673fa5e42fcd.tar.gz
rust-713a360560ab70651d10f09c9949673fa5e42fcd.zip
Auto merge of #37356 - cristicbz:wrapsum, r=alexcrichton
Add impls for `&Wrapping`. Also `Sum`, `Product` impls for both `Wrapping` and `&Wrapping`.

There are two changes here (split into two commits):
- Ops for references to `&Wrapping`  (`Add`, `Sub`, `Mul` etc.) similar to the way they are implemented for primitives.
- Impls for `iter::{Sum,Product}` for `Wrapping`.

As far as I know `impl` stability attributes don't really matter so I didn't bother breaking up the macro for two different kinds of stability. Happy to change if it does matter.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/internal_macros.rs62
-rw-r--r--src/libcore/iter/traits.rs17
-rw-r--r--src/libcore/lib.rs3
-rw-r--r--src/libcore/num/wrapping.rs10
-rw-r--r--src/libcore/ops.rs52
5 files changed, 86 insertions, 58 deletions
diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs
new file mode 100644
index 00000000000..f2cdc9d6a98
--- /dev/null
+++ b/src/libcore/internal_macros.rs
@@ -0,0 +1,62 @@
+// Copyright 2016 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.
+
+
+// implements the unary operator "op &T"
+// based on "op T" where T is expected to be `Copy`able
+macro_rules! forward_ref_unop {
+    (impl $imp:ident, $method:ident for $t:ty) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a> $imp for &'a $t {
+            type Output = <$t as $imp>::Output;
+
+            #[inline]
+            fn $method(self) -> <$t as $imp>::Output {
+                $imp::$method(*self)
+            }
+        }
+    }
+}
+
+// implements binary operators "&T op U", "T op &U", "&T op &U"
+// based on "T op U" where T and U are expected to be `Copy`able
+macro_rules! forward_ref_binop {
+    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a> $imp<$u> for &'a $t {
+            type Output = <$t as $imp<$u>>::Output;
+
+            #[inline]
+            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
+                $imp::$method(*self, other)
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a> $imp<&'a $u> for $t {
+            type Output = <$t as $imp<$u>>::Output;
+
+            #[inline]
+            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
+                $imp::$method(self, *other)
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, 'b> $imp<&'a $u> for &'b $t {
+            type Output = <$t as $imp<$u>>::Output;
+
+            #[inline]
+            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
+                $imp::$method(*self, *other)
+            }
+        }
+    }
+}
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 2b0dd63a571..bc4be073c5f 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 use ops::{Mul, Add};
+use num::Wrapping;
 
 /// Conversion from an `Iterator`.
 ///
@@ -584,35 +585,39 @@ pub trait Product<A = Self>: Sized {
 
 // NB: explicitly use Add and Mul here to inherit overflow checks
 macro_rules! integer_sum_product {
-    ($($a:ident)*) => ($(
+    (@impls $zero:expr, $one:expr, $($a:ty)*) => ($(
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Sum for $a {
             fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold(0, Add::add)
+                iter.fold($zero, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Product for $a {
             fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold(1, Mul::mul)
+                iter.fold($one, Mul::mul)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Sum<&'a $a> for $a {
             fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.cloned().fold(0, Add::add)
+                iter.fold($zero, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Product<&'a $a> for $a {
             fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.cloned().fold(1, Mul::mul)
+                iter.fold($one, Mul::mul)
             }
         }
-    )*)
+    )*);
+    ($($a:ty)*) => (
+        integer_sum_product!(@impls 0, 1, $($a)+);
+        integer_sum_product!(@impls Wrapping(0), Wrapping(1), $(Wrapping<$a>)+);
+    );
 }
 
 macro_rules! float_sum_product {
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 28101d21fc2..07f5e725e20 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -100,6 +100,9 @@ use prelude::v1::*;
 #[macro_use]
 mod macros;
 
+#[macro_use]
+mod internal_macros;
+
 #[path = "num/float_macros.rs"]
 #[macro_use]
 mod float_macros;
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index d35c451ac26..50d64838a5c 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -131,6 +131,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0.wrapping_add(other.0))
             }
         }
+        forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl AddAssign for Wrapping<$t> {
@@ -149,6 +150,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0.wrapping_sub(other.0))
             }
         }
+        forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl SubAssign for Wrapping<$t> {
@@ -167,6 +169,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0.wrapping_mul(other.0))
             }
         }
+        forward_ref_binop! { impl Mul, mul for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl MulAssign for Wrapping<$t> {
@@ -185,6 +188,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0.wrapping_div(other.0))
             }
         }
+        forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl DivAssign for Wrapping<$t> {
@@ -203,6 +207,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0.wrapping_rem(other.0))
             }
         }
+        forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl RemAssign for Wrapping<$t> {
@@ -221,6 +226,7 @@ macro_rules! wrapping_impl {
                 Wrapping(!self.0)
             }
         }
+        forward_ref_unop! { impl Not, not for Wrapping<$t> }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl BitXor for Wrapping<$t> {
@@ -231,6 +237,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0 ^ other.0)
             }
         }
+        forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl BitXorAssign for Wrapping<$t> {
@@ -249,6 +256,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0 | other.0)
             }
         }
+        forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl BitOrAssign for Wrapping<$t> {
@@ -267,6 +275,7 @@ macro_rules! wrapping_impl {
                 Wrapping(self.0 & other.0)
             }
         }
+        forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl BitAndAssign for Wrapping<$t> {
@@ -284,6 +293,7 @@ macro_rules! wrapping_impl {
                 Wrapping(0) - self
             }
         }
+        forward_ref_unop! { impl Neg, neg for Wrapping<$t> }
     )*)
 }
 
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 06838ee89bd..07ae5b920b2 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -196,58 +196,6 @@ pub trait Drop {
     fn drop(&mut self);
 }
 
-// implements the unary operator "op &T"
-// based on "op T" where T is expected to be `Copy`able
-macro_rules! forward_ref_unop {
-    (impl $imp:ident, $method:ident for $t:ty) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a> $imp for &'a $t {
-            type Output = <$t as $imp>::Output;
-
-            #[inline]
-            fn $method(self) -> <$t as $imp>::Output {
-                $imp::$method(*self)
-            }
-        }
-    }
-}
-
-// implements binary operators "&T op U", "T op &U", "&T op &U"
-// based on "T op U" where T and U are expected to be `Copy`able
-macro_rules! forward_ref_binop {
-    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a> $imp<$u> for &'a $t {
-            type Output = <$t as $imp<$u>>::Output;
-
-            #[inline]
-            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
-                $imp::$method(*self, other)
-            }
-        }
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a> $imp<&'a $u> for $t {
-            type Output = <$t as $imp<$u>>::Output;
-
-            #[inline]
-            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
-                $imp::$method(self, *other)
-            }
-        }
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b> $imp<&'a $u> for &'b $t {
-            type Output = <$t as $imp<$u>>::Output;
-
-            #[inline]
-            fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
-                $imp::$method(*self, *other)
-            }
-        }
-    }
-}
-
 /// The `Add` trait is used to specify the functionality of `+`.
 ///
 /// # Examples