Skip to content

Commit 5c3bfb8

Browse files
add std::num::Wrapping to difference.rs (#322)
1 parent 4a85187 commit 5c3bfb8

File tree

1 file changed

+53
-88
lines changed

1 file changed

+53
-88
lines changed

src/difference.rs

Lines changed: 53 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -36,68 +36,12 @@ pub trait Semigroup : ::std::marker::Sized + Data + Clone {
3636
fn is_zero(&self) -> bool;
3737
}
3838

39-
impl Semigroup for isize {
40-
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
41-
#[inline] fn is_zero(&self) -> bool { self == &0 }
42-
}
43-
44-
impl Semigroup for i128 {
45-
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
46-
#[inline] fn is_zero(&self) -> bool { self == &0 }
47-
}
48-
49-
impl Semigroup for i64 {
50-
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
51-
#[inline] fn is_zero(&self) -> bool { self == &0 }
52-
}
53-
54-
impl Semigroup for i32 {
55-
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
56-
#[inline] fn is_zero(&self) -> bool { self == &0 }
57-
}
58-
59-
impl Semigroup for i16 {
60-
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
61-
#[inline] fn is_zero(&self) -> bool { self == &0 }
62-
}
63-
64-
impl Semigroup for i8 {
65-
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
66-
#[inline] fn is_zero(&self) -> bool { self == &0 }
67-
}
68-
69-
7039
/// A semigroup with an explicit zero element.
7140
pub trait Monoid : Semigroup {
7241
/// A zero element under the semigroup addition operator.
7342
fn zero() -> Self;
7443
}
7544

76-
impl Monoid for isize {
77-
#[inline] fn zero() -> Self { 0 }
78-
}
79-
80-
impl Monoid for i128 {
81-
#[inline] fn zero() -> Self { 0 }
82-
}
83-
84-
impl Monoid for i64 {
85-
#[inline] fn zero() -> Self { 0 }
86-
}
87-
88-
impl Monoid for i32 {
89-
#[inline] fn zero() -> Self { 0 }
90-
}
91-
92-
impl Monoid for i16 {
93-
#[inline] fn zero() -> Self { 0 }
94-
}
95-
96-
impl Monoid for i8 {
97-
#[inline] fn zero() -> Self { 0 }
98-
}
99-
100-
10145
/// A `Monoid` with negation.
10246
///
10347
/// This trait extends the requirements of `Semigroup` to include a negation operator.
@@ -108,31 +52,6 @@ pub trait Abelian : Monoid {
10852
fn negate(self) -> Self;
10953
}
11054

111-
112-
impl Abelian for isize {
113-
#[inline] fn negate(self) -> Self { -self }
114-
}
115-
116-
impl Abelian for i128 {
117-
#[inline] fn negate(self) -> Self { -self }
118-
}
119-
120-
impl Abelian for i64 {
121-
#[inline] fn negate(self) -> Self { -self }
122-
}
123-
124-
impl Abelian for i32 {
125-
#[inline] fn negate(self) -> Self { -self }
126-
}
127-
128-
impl Abelian for i16 {
129-
#[inline] fn negate(self) -> Self { -self }
130-
}
131-
132-
impl Abelian for i8 {
133-
#[inline] fn negate(self) -> Self { -self }
134-
}
135-
13655
/// A replacement for `std::ops::Mul` for types that do not implement it.
13756
pub trait Multiply<Rhs = Self> {
13857
/// Output type per the `Mul` trait.
@@ -141,21 +60,66 @@ pub trait Multiply<Rhs = Self> {
14160
fn multiply(self, rhs: &Rhs) -> Self::Output;
14261
}
14362

144-
macro_rules! multiply_derive {
63+
/// Implementation for built-in signed integers.
64+
macro_rules! builtin_implementation {
65+
($t:ty) => {
66+
impl Semigroup for $t {
67+
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
68+
#[inline] fn is_zero(&self) -> bool { self == &0 }
69+
}
70+
71+
impl Monoid for $t {
72+
#[inline] fn zero() -> Self { 0 }
73+
}
74+
75+
impl Abelian for $t {
76+
#[inline] fn negate(self) -> Self { -self }
77+
}
78+
79+
impl Multiply<Self> for $t {
80+
type Output = Self;
81+
fn multiply(self, rhs: &Self) -> Self { self * rhs}
82+
}
83+
};
84+
}
85+
86+
builtin_implementation!(i8);
87+
builtin_implementation!(i16);
88+
builtin_implementation!(i32);
89+
builtin_implementation!(i64);
90+
builtin_implementation!(i128);
91+
builtin_implementation!(isize);
92+
93+
/// Implementations for wrapping signed integers, which have a different zero.
94+
macro_rules! wrapping_implementation {
14595
($t:ty) => {
96+
impl Semigroup for $t {
97+
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
98+
#[inline] fn is_zero(&self) -> bool { self == &std::num::Wrapping(0) }
99+
}
100+
101+
impl Monoid for $t {
102+
#[inline] fn zero() -> Self { std::num::Wrapping(0) }
103+
}
104+
105+
impl Abelian for $t {
106+
#[inline] fn negate(self) -> Self { -self }
107+
}
108+
146109
impl Multiply<Self> for $t {
147110
type Output = Self;
148111
fn multiply(self, rhs: &Self) -> Self { self * rhs}
149112
}
150113
};
151114
}
152115

153-
multiply_derive!(i8);
154-
multiply_derive!(i16);
155-
multiply_derive!(i32);
156-
multiply_derive!(i64);
157-
multiply_derive!(i128);
158-
multiply_derive!(isize);
116+
wrapping_implementation!(std::num::Wrapping<i8>);
117+
wrapping_implementation!(std::num::Wrapping<i16>);
118+
wrapping_implementation!(std::num::Wrapping<i32>);
119+
wrapping_implementation!(std::num::Wrapping<i64>);
120+
wrapping_implementation!(std::num::Wrapping<i128>);
121+
wrapping_implementation!(std::num::Wrapping<isize>);
122+
159123

160124
pub use self::present::Present;
161125
mod present {
@@ -189,6 +153,7 @@ mod tuples {
189153

190154
use super::{Semigroup, Monoid, Abelian, Multiply};
191155

156+
/// Implementations for tuples. The two arguments must have the same length.
192157
macro_rules! tuple_implementation {
193158
( ($($name:ident)*), ($($name2:ident)*) ) => (
194159
impl<$($name: Semigroup),*> Semigroup for ($($name,)*) {

0 commit comments

Comments
 (0)