Skip to content

Commit

Permalink
Auto merge of #37356 - cristicbz:wrapsum, r=alexcrichton
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors authored Nov 4, 2016
2 parents 81601cd + df0e5a9 commit 713a360
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 58 deletions.
62 changes: 62 additions & 0 deletions src/libcore/internal_macros.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
}
17 changes: 11 additions & 6 deletions src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
///
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions src/libcore/num/wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -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> {
Expand All @@ -284,6 +293,7 @@ macro_rules! wrapping_impl {
Wrapping(0) - self
}
}
forward_ref_unop! { impl Neg, neg for Wrapping<$t> }
)*)
}

Expand Down
52 changes: 0 additions & 52 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 713a360

Please sign in to comment.