Skip to content

Commit 713a360

Browse files
authored
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.
2 parents 81601cd + df0e5a9 commit 713a360

File tree

5 files changed

+86
-58
lines changed

5 files changed

+86
-58
lines changed

src/libcore/internal_macros.rs

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
// implements the unary operator "op &T"
13+
// based on "op T" where T is expected to be `Copy`able
14+
macro_rules! forward_ref_unop {
15+
(impl $imp:ident, $method:ident for $t:ty) => {
16+
#[stable(feature = "rust1", since = "1.0.0")]
17+
impl<'a> $imp for &'a $t {
18+
type Output = <$t as $imp>::Output;
19+
20+
#[inline]
21+
fn $method(self) -> <$t as $imp>::Output {
22+
$imp::$method(*self)
23+
}
24+
}
25+
}
26+
}
27+
28+
// implements binary operators "&T op U", "T op &U", "&T op &U"
29+
// based on "T op U" where T and U are expected to be `Copy`able
30+
macro_rules! forward_ref_binop {
31+
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
32+
#[stable(feature = "rust1", since = "1.0.0")]
33+
impl<'a> $imp<$u> for &'a $t {
34+
type Output = <$t as $imp<$u>>::Output;
35+
36+
#[inline]
37+
fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
38+
$imp::$method(*self, other)
39+
}
40+
}
41+
42+
#[stable(feature = "rust1", since = "1.0.0")]
43+
impl<'a> $imp<&'a $u> for $t {
44+
type Output = <$t as $imp<$u>>::Output;
45+
46+
#[inline]
47+
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
48+
$imp::$method(self, *other)
49+
}
50+
}
51+
52+
#[stable(feature = "rust1", since = "1.0.0")]
53+
impl<'a, 'b> $imp<&'a $u> for &'b $t {
54+
type Output = <$t as $imp<$u>>::Output;
55+
56+
#[inline]
57+
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
58+
$imp::$method(*self, *other)
59+
}
60+
}
61+
}
62+
}

src/libcore/iter/traits.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010
use ops::{Mul, Add};
11+
use num::Wrapping;
1112

1213
/// Conversion from an `Iterator`.
1314
///
@@ -584,35 +585,39 @@ pub trait Product<A = Self>: Sized {
584585

585586
// NB: explicitly use Add and Mul here to inherit overflow checks
586587
macro_rules! integer_sum_product {
587-
($($a:ident)*) => ($(
588+
(@impls $zero:expr, $one:expr, $($a:ty)*) => ($(
588589
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
589590
impl Sum for $a {
590591
fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
591-
iter.fold(0, Add::add)
592+
iter.fold($zero, Add::add)
592593
}
593594
}
594595

595596
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
596597
impl Product for $a {
597598
fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
598-
iter.fold(1, Mul::mul)
599+
iter.fold($one, Mul::mul)
599600
}
600601
}
601602

602603
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
603604
impl<'a> Sum<&'a $a> for $a {
604605
fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
605-
iter.cloned().fold(0, Add::add)
606+
iter.fold($zero, Add::add)
606607
}
607608
}
608609

609610
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
610611
impl<'a> Product<&'a $a> for $a {
611612
fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
612-
iter.cloned().fold(1, Mul::mul)
613+
iter.fold($one, Mul::mul)
613614
}
614615
}
615-
)*)
616+
)*);
617+
($($a:ty)*) => (
618+
integer_sum_product!(@impls 0, 1, $($a)+);
619+
integer_sum_product!(@impls Wrapping(0), Wrapping(1), $(Wrapping<$a>)+);
620+
);
616621
}
617622

618623
macro_rules! float_sum_product {

src/libcore/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ use prelude::v1::*;
100100
#[macro_use]
101101
mod macros;
102102

103+
#[macro_use]
104+
mod internal_macros;
105+
103106
#[path = "num/float_macros.rs"]
104107
#[macro_use]
105108
mod float_macros;

src/libcore/num/wrapping.rs

+10
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ macro_rules! wrapping_impl {
131131
Wrapping(self.0.wrapping_add(other.0))
132132
}
133133
}
134+
forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t> }
134135

135136
#[stable(feature = "op_assign_traits", since = "1.8.0")]
136137
impl AddAssign for Wrapping<$t> {
@@ -149,6 +150,7 @@ macro_rules! wrapping_impl {
149150
Wrapping(self.0.wrapping_sub(other.0))
150151
}
151152
}
153+
forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t> }
152154

153155
#[stable(feature = "op_assign_traits", since = "1.8.0")]
154156
impl SubAssign for Wrapping<$t> {
@@ -167,6 +169,7 @@ macro_rules! wrapping_impl {
167169
Wrapping(self.0.wrapping_mul(other.0))
168170
}
169171
}
172+
forward_ref_binop! { impl Mul, mul for Wrapping<$t>, Wrapping<$t> }
170173

171174
#[stable(feature = "op_assign_traits", since = "1.8.0")]
172175
impl MulAssign for Wrapping<$t> {
@@ -185,6 +188,7 @@ macro_rules! wrapping_impl {
185188
Wrapping(self.0.wrapping_div(other.0))
186189
}
187190
}
191+
forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t> }
188192

189193
#[stable(feature = "op_assign_traits", since = "1.8.0")]
190194
impl DivAssign for Wrapping<$t> {
@@ -203,6 +207,7 @@ macro_rules! wrapping_impl {
203207
Wrapping(self.0.wrapping_rem(other.0))
204208
}
205209
}
210+
forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t> }
206211

207212
#[stable(feature = "op_assign_traits", since = "1.8.0")]
208213
impl RemAssign for Wrapping<$t> {
@@ -221,6 +226,7 @@ macro_rules! wrapping_impl {
221226
Wrapping(!self.0)
222227
}
223228
}
229+
forward_ref_unop! { impl Not, not for Wrapping<$t> }
224230

225231
#[stable(feature = "rust1", since = "1.0.0")]
226232
impl BitXor for Wrapping<$t> {
@@ -231,6 +237,7 @@ macro_rules! wrapping_impl {
231237
Wrapping(self.0 ^ other.0)
232238
}
233239
}
240+
forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t> }
234241

235242
#[stable(feature = "op_assign_traits", since = "1.8.0")]
236243
impl BitXorAssign for Wrapping<$t> {
@@ -249,6 +256,7 @@ macro_rules! wrapping_impl {
249256
Wrapping(self.0 | other.0)
250257
}
251258
}
259+
forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t> }
252260

253261
#[stable(feature = "op_assign_traits", since = "1.8.0")]
254262
impl BitOrAssign for Wrapping<$t> {
@@ -267,6 +275,7 @@ macro_rules! wrapping_impl {
267275
Wrapping(self.0 & other.0)
268276
}
269277
}
278+
forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t> }
270279

271280
#[stable(feature = "op_assign_traits", since = "1.8.0")]
272281
impl BitAndAssign for Wrapping<$t> {
@@ -284,6 +293,7 @@ macro_rules! wrapping_impl {
284293
Wrapping(0) - self
285294
}
286295
}
296+
forward_ref_unop! { impl Neg, neg for Wrapping<$t> }
287297
)*)
288298
}
289299

src/libcore/ops.rs

-52
Original file line numberDiff line numberDiff line change
@@ -196,58 +196,6 @@ pub trait Drop {
196196
fn drop(&mut self);
197197
}
198198

199-
// implements the unary operator "op &T"
200-
// based on "op T" where T is expected to be `Copy`able
201-
macro_rules! forward_ref_unop {
202-
(impl $imp:ident, $method:ident for $t:ty) => {
203-
#[stable(feature = "rust1", since = "1.0.0")]
204-
impl<'a> $imp for &'a $t {
205-
type Output = <$t as $imp>::Output;
206-
207-
#[inline]
208-
fn $method(self) -> <$t as $imp>::Output {
209-
$imp::$method(*self)
210-
}
211-
}
212-
}
213-
}
214-
215-
// implements binary operators "&T op U", "T op &U", "&T op &U"
216-
// based on "T op U" where T and U are expected to be `Copy`able
217-
macro_rules! forward_ref_binop {
218-
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
219-
#[stable(feature = "rust1", since = "1.0.0")]
220-
impl<'a> $imp<$u> for &'a $t {
221-
type Output = <$t as $imp<$u>>::Output;
222-
223-
#[inline]
224-
fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
225-
$imp::$method(*self, other)
226-
}
227-
}
228-
229-
#[stable(feature = "rust1", since = "1.0.0")]
230-
impl<'a> $imp<&'a $u> for $t {
231-
type Output = <$t as $imp<$u>>::Output;
232-
233-
#[inline]
234-
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
235-
$imp::$method(self, *other)
236-
}
237-
}
238-
239-
#[stable(feature = "rust1", since = "1.0.0")]
240-
impl<'a, 'b> $imp<&'a $u> for &'b $t {
241-
type Output = <$t as $imp<$u>>::Output;
242-
243-
#[inline]
244-
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
245-
$imp::$method(*self, *other)
246-
}
247-
}
248-
}
249-
}
250-
251199
/// The `Add` trait is used to specify the functionality of `+`.
252200
///
253201
/// # Examples

0 commit comments

Comments
 (0)