@@ -36,68 +36,12 @@ pub trait Semigroup : ::std::marker::Sized + Data + Clone {
36
36
fn is_zero ( & self ) -> bool ;
37
37
}
38
38
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
-
70
39
/// A semigroup with an explicit zero element.
71
40
pub trait Monoid : Semigroup {
72
41
/// A zero element under the semigroup addition operator.
73
42
fn zero ( ) -> Self ;
74
43
}
75
44
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
-
101
45
/// A `Monoid` with negation.
102
46
///
103
47
/// This trait extends the requirements of `Semigroup` to include a negation operator.
@@ -108,31 +52,6 @@ pub trait Abelian : Monoid {
108
52
fn negate ( self ) -> Self ;
109
53
}
110
54
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
-
136
55
/// A replacement for `std::ops::Mul` for types that do not implement it.
137
56
pub trait Multiply < Rhs = Self > {
138
57
/// Output type per the `Mul` trait.
@@ -141,21 +60,66 @@ pub trait Multiply<Rhs = Self> {
141
60
fn multiply ( self , rhs : & Rhs ) -> Self :: Output ;
142
61
}
143
62
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 {
145
95
( $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
+
146
109
impl Multiply <Self > for $t {
147
110
type Output = Self ;
148
111
fn multiply( self , rhs: & Self ) -> Self { self * rhs}
149
112
}
150
113
} ;
151
114
}
152
115
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
+
159
123
160
124
pub use self :: present:: Present ;
161
125
mod present {
@@ -189,6 +153,7 @@ mod tuples {
189
153
190
154
use super :: { Semigroup , Monoid , Abelian , Multiply } ;
191
155
156
+ /// Implementations for tuples. The two arguments must have the same length.
192
157
macro_rules! tuple_implementation {
193
158
( ( $( $name: ident) * ) , ( $( $name2: ident) * ) ) => (
194
159
impl <$( $name: Semigroup ) ,* > Semigroup for ( $( $name, ) * ) {
0 commit comments