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.
This commit is contained in:
commit
713a360560
5 changed files with 86 additions and 58 deletions
62
src/libcore/internal_macros.rs
Normal file
62
src/libcore/internal_macros.rs
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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> }
|
||||
)*)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue