1
1
use core:: ops:: { Div , Rem } ;
2
- pub trait DivEuclid : Sized + Div < Self , Output = Self > {
2
+
3
+ pub trait Euclid : Sized + Div < Self , Output = Self > + Rem < Self , Output = Self > {
3
4
/// Calculates Euclidean division, the matching method for `rem_euclid`.
4
5
///
5
6
/// This computes the integer `n` such that
@@ -10,18 +11,17 @@ pub trait DivEuclid: Sized + Div<Self, Output = Self> {
10
11
/// # Examples
11
12
///
12
13
/// ```
13
- /// use num_traits::DivEuclid ;
14
+ /// use num_traits::Euclid ;
14
15
///
15
16
/// let a: i32 = 7;
16
17
/// let b: i32 = 4;
17
- /// assert_eq!(DivEuclid ::div_euclid(a,b), 1); // 7 > 4 * 1
18
- /// assert_eq!(DivEuclid ::div_euclid(-a,b), -2); // -7 >= 4 * -2
19
- /// assert_eq!(DivEuclid ::div_euclid(a,-b), -1); // 7 >= -4 * -1
20
- /// assert_eq!(DivEuclid ::div_euclid(-a,-b), 2); // -7 >= -4 * 2
18
+ /// assert_eq!(Euclid ::div_euclid(a, b), 1); // 7 > 4 * 1
19
+ /// assert_eq!(Euclid ::div_euclid(-a, b), -2); // -7 >= 4 * -2
20
+ /// assert_eq!(Euclid ::div_euclid(a, -b), -1); // 7 >= -4 * -1
21
+ /// assert_eq!(Euclid ::div_euclid(-a, -b), 2); // -7 >= -4 * 2
21
22
/// ```
22
23
fn div_euclid ( self , v : Self ) -> Self ;
23
- }
24
- pub trait RemEuclid : Sized + Rem < Self , Output = Self > {
24
+
25
25
/// Calculates the least nonnegative remainder of `self (mod v)`.
26
26
///
27
27
/// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
@@ -36,20 +36,20 @@ pub trait RemEuclid: Sized + Rem<Self, Output = Self> {
36
36
/// # Examples
37
37
///
38
38
/// ```
39
- /// use num_traits::RemEuclid ;
39
+ /// use num_traits::Euclid ;
40
40
///
41
41
/// let a: i32 = 7;
42
42
/// let b: i32 = 4;
43
- /// assert_eq!(RemEuclid ::rem_euclid(a,b), 3);
44
- /// assert_eq!(RemEuclid ::rem_euclid(-a,b), 1);
45
- /// assert_eq!(RemEuclid ::rem_euclid(a,-b), 3);
46
- /// assert_eq!(RemEuclid ::rem_euclid(-a,-b), 1);
43
+ /// assert_eq!(Euclid ::rem_euclid(a, b), 3);
44
+ /// assert_eq!(Euclid ::rem_euclid(-a, b), 1);
45
+ /// assert_eq!(Euclid ::rem_euclid(a, -b), 3);
46
+ /// assert_eq!(Euclid ::rem_euclid(-a, -b), 1);
47
47
/// ```
48
48
fn rem_euclid ( self , v : Self ) -> Self ;
49
49
}
50
- macro_rules! div_euclid_int_impl {
51
- ( $trait_name : ident for $ ( $t: ty) * ) => { $(
52
- impl $trait_name for $t {
50
+ macro_rules! euclid_int_impl {
51
+ ( $( $t: ty) * ) => { $(
52
+ impl Euclid for $t {
53
53
#[ inline]
54
54
fn div_euclid( self , v: $t) -> Self {
55
55
let q = self / v;
@@ -58,22 +58,7 @@ macro_rules! div_euclid_int_impl {
58
58
}
59
59
q
60
60
}
61
- }
62
- ) * }
63
- }
64
- macro_rules! div_euclid_uint_impl {
65
- ( $trait_name: ident for $( $t: ty) * ) => { $(
66
- impl $trait_name for $t {
67
- #[ inline]
68
- fn div_euclid( self , v: $t) -> Self {
69
- self / v
70
- }
71
- }
72
- ) * }
73
- }
74
- macro_rules! rem_euclid_int_impl {
75
- ( $trait_name: ident for $( $t: ty) * ) => { $(
76
- impl $trait_name for $t {
61
+
77
62
#[ inline]
78
63
fn rem_euclid( self , v: $t) -> Self {
79
64
let r = self % v;
@@ -90,152 +75,131 @@ macro_rules! rem_euclid_int_impl {
90
75
}
91
76
) * }
92
77
}
93
- macro_rules! rem_euclid_uint_impl {
94
- ( $trait_name: ident for $( $t: ty) * ) => { $(
95
- impl $trait_name for $t {
78
+ macro_rules! euclid_uint_impl {
79
+ ( $( $t: ty) * ) => { $(
80
+ impl Euclid for $t {
81
+ #[ inline]
82
+ fn div_euclid( self , v: $t) -> Self {
83
+ self / v
84
+ }
85
+
96
86
#[ inline]
97
87
fn rem_euclid( self , v: $t) -> Self {
98
88
self % v
99
89
}
100
90
}
101
91
) * }
102
92
}
103
- div_euclid_int_impl ! ( DivEuclid for i8 i16 i32 i64 ) ;
104
- div_euclid_uint_impl ! ( DivEuclid for isize usize u8 u16 u32 u64 ) ;
105
- rem_euclid_int_impl ! ( RemEuclid for i8 i16 i32 i64 ) ;
106
- rem_euclid_uint_impl ! ( RemEuclid for isize usize u8 u16 u32 u64 ) ;
107
- #[ cfg( has_i128) ]
108
- div_euclid_int_impl ! ( DivEuclid for i128 ) ;
93
+ euclid_int_impl ! ( isize i8 i16 i32 i64 ) ;
94
+ euclid_uint_impl ! ( usize u8 u16 u32 u64 ) ;
109
95
#[ cfg( has_i128) ]
110
- div_euclid_uint_impl ! ( DivEuclid for u128 ) ;
96
+ euclid_int_impl ! ( i128 ) ;
111
97
#[ cfg( has_i128) ]
112
- rem_euclid_int_impl ! ( RemEuclid for i128 ) ;
113
- #[ cfg( has_i128) ]
114
- rem_euclid_uint_impl ! ( RemEuclid for u128 ) ;
98
+ euclid_uint_impl ! ( u128 ) ;
115
99
116
- # [ cfg ( any ( feature = "std" , feature = "libm" ) ) ]
117
- impl DivEuclid for f32 {
100
+ impl Euclid for f32 {
101
+ # [ inline ]
118
102
fn div_euclid ( self , v : f32 ) -> f32 {
119
- let q = <f32 as :: Float >:: trunc ( self / v) ;
103
+ let q = <f32 as :: FloatCore >:: trunc ( self / v) ;
120
104
if self % v < 0.0 {
121
105
return if v > 0.0 { q - 1.0 } else { q + 1.0 } ;
122
106
}
123
107
q
124
108
}
125
- }
126
109
127
- #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
128
- impl RemEuclid for f32 {
110
+ #[ inline]
129
111
fn rem_euclid ( self , v : f32 ) -> f32 {
130
112
let r = self % v;
131
113
if r < 0.0 {
132
- r + <f32 as :: Float >:: abs ( v)
114
+ r + <f32 as :: FloatCore >:: abs ( v)
133
115
} else {
134
116
r
135
117
}
136
118
}
137
119
}
138
120
139
- # [ cfg ( any ( feature = "std" , feature = "libm" ) ) ]
140
- impl DivEuclid for f64 {
121
+ impl Euclid for f64 {
122
+ # [ inline ]
141
123
fn div_euclid ( self , v : f64 ) -> f64 {
142
- let q = <f64 as :: Float >:: trunc ( self / v) ;
124
+ let q = <f64 as :: FloatCore >:: trunc ( self / v) ;
143
125
if self % v < 0.0 {
144
126
return if v > 0.0 { q - 1.0 } else { q + 1.0 } ;
145
127
}
146
128
q
147
129
}
148
- }
149
- #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
150
- impl RemEuclid for f64 {
130
+
131
+ #[ inline]
151
132
fn rem_euclid ( self , v : f64 ) -> f64 {
152
133
let r = self % v;
153
134
if r < 0.0 {
154
- r + <f64 as :: Float >:: abs ( v)
135
+ r + <f64 as :: FloatCore >:: abs ( v)
155
136
} else {
156
137
r
157
138
}
158
139
}
159
140
}
160
141
161
- pub trait CheckedDivEuclid : DivEuclid {
142
+ pub trait CheckedEuclid : Euclid {
162
143
/// Performs euclid division that returns `None` instead of panicking on division by zero
163
144
/// and instead of wrapping around on underflow and overflow.
164
145
fn checked_div_euclid ( self , v : Self ) -> Option < Self > ;
165
- }
166
- pub trait CheckedRemEuclid : RemEuclid {
146
+
167
147
/// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
168
148
/// division by zero. If any of that happens, `None` is returned.
169
149
fn checked_rem_euclid ( self , v : Self ) -> Option < Self > ;
170
150
}
171
- macro_rules! checked_div_euclid_int_impl {
172
- ( $trait_name : ident for $ ( $t: ty) * ) => { $(
173
- impl $trait_name for $t {
151
+ macro_rules! checked_euclid_int_impl {
152
+ ( $( $t: ty) * ) => { $(
153
+ impl CheckedEuclid for $t {
174
154
#[ inline]
175
155
fn checked_div_euclid( self , v: $t) -> Option <$t> {
176
156
if v == 0 || ( self == Self :: min_value( ) && v == -1 ) {
177
157
None
178
158
} else {
179
- Some ( DivEuclid :: div_euclid( self , v) )
159
+ Some ( Euclid :: div_euclid( self , v) )
180
160
}
181
161
}
182
- }
183
- ) * }
184
- }
185
- macro_rules! checked_div_euclid_uint_impl {
186
- ( $trait_name: ident for $( $t: ty) * ) => { $(
187
- impl $trait_name for $t {
162
+
188
163
#[ inline]
189
- fn checked_div_euclid ( self , v: $t) -> Option <$t> {
190
- if v == 0 {
164
+ fn checked_rem_euclid ( self , v: $t) -> Option <$t> {
165
+ if v == 0 || ( self == Self :: min_value ( ) && v == - 1 ) {
191
166
None
192
167
} else {
193
- Some ( DivEuclid :: div_euclid ( self , v) )
168
+ Some ( Euclid :: rem_euclid ( self , v) )
194
169
}
195
170
}
196
171
}
197
172
) * }
198
173
}
199
- macro_rules! checked_rem_euclid_int_impl {
200
- ( $trait_name : ident for $ ( $t: ty) * ) => { $(
201
- impl $trait_name for $t {
174
+ macro_rules! checked_euclid_uint_impl {
175
+ ( $( $t: ty) * ) => { $(
176
+ impl CheckedEuclid for $t {
202
177
#[ inline]
203
- fn checked_rem_euclid ( self , v: $t) -> Option <$t> {
204
- if v == 0 || ( self == Self :: min_value ( ) && v == - 1 ) {
178
+ fn checked_div_euclid ( self , v: $t) -> Option <$t> {
179
+ if v == 0 {
205
180
None
206
181
} else {
207
- Some ( RemEuclid :: rem_euclid ( self , v) )
182
+ Some ( Euclid :: div_euclid ( self , v) )
208
183
}
209
184
}
210
- }
211
- ) * }
212
- }
213
- macro_rules! checked_rem_euclid_uint_impl {
214
- ( $trait_name: ident for $( $t: ty) * ) => { $(
215
- impl $trait_name for $t {
185
+
216
186
#[ inline]
217
187
fn checked_rem_euclid( self , v: $t) -> Option <$t> {
218
188
if v == 0 {
219
189
None
220
190
} else {
221
- Some ( RemEuclid :: rem_euclid( self , v) )
191
+ Some ( Euclid :: rem_euclid( self , v) )
222
192
}
223
193
}
224
194
}
225
195
) * }
226
196
}
227
- checked_div_euclid_int_impl ! ( CheckedDivEuclid for i8 i16 i32 i64 ) ;
228
- checked_div_euclid_uint_impl ! ( CheckedDivEuclid for isize usize u8 u16 u32 u64 ) ;
229
- checked_rem_euclid_int_impl ! ( CheckedRemEuclid for i8 i16 i32 i64 ) ;
230
- checked_rem_euclid_uint_impl ! ( CheckedRemEuclid for isize usize u8 u16 u32 u64 ) ;
231
- #[ cfg( has_i128) ]
232
- checked_div_euclid_int_impl ! ( CheckedDivEuclid for i128 ) ;
233
- #[ cfg( has_i128) ]
234
- checked_div_euclid_uint_impl ! ( CheckedDivEuclid for u128 ) ;
197
+ checked_euclid_int_impl ! ( isize i8 i16 i32 i64 ) ;
198
+ checked_euclid_uint_impl ! ( usize u8 u16 u32 u64 ) ;
235
199
#[ cfg( has_i128) ]
236
- checked_rem_euclid_int_impl ! ( CheckedRemEuclid for i128 ) ;
200
+ checked_euclid_int_impl ! ( i128 ) ;
237
201
#[ cfg( has_i128) ]
238
- checked_rem_euclid_uint_impl ! ( CheckedRemEuclid for u128 ) ;
202
+ checked_euclid_uint_impl ! ( u128 ) ;
239
203
240
204
#[ cfg( test) ]
241
205
mod tests {
@@ -249,8 +213,8 @@ mod tests {
249
213
{
250
214
let x: $t = 10 ;
251
215
let y: $t = 3 ;
252
- assert_eq!( DivEuclid :: div_euclid( x, y) , 3 ) ;
253
- assert_eq!( RemEuclid :: rem_euclid( x, y) , 1 ) ;
216
+ assert_eq!( Euclid :: div_euclid( x, y) , 3 ) ;
217
+ assert_eq!( Euclid :: rem_euclid( x, y) , 1 ) ;
254
218
}
255
219
) +
256
220
} ;
@@ -267,13 +231,13 @@ mod tests {
267
231
{
268
232
let x: $t = 10 ;
269
233
let y: $t = -3 ;
270
- assert_eq!( DivEuclid :: div_euclid( x, y) , -3 ) ;
271
- assert_eq!( DivEuclid :: div_euclid( -x, y) , 4 ) ;
272
- assert_eq!( RemEuclid :: rem_euclid( x, y) , 1 ) ;
273
- assert_eq!( RemEuclid :: rem_euclid( -x, y) , 2 ) ;
234
+ assert_eq!( Euclid :: div_euclid( x, y) , -3 ) ;
235
+ assert_eq!( Euclid :: div_euclid( -x, y) , 4 ) ;
236
+ assert_eq!( Euclid :: rem_euclid( x, y) , 1 ) ;
237
+ assert_eq!( Euclid :: rem_euclid( -x, y) , 2 ) ;
274
238
let x: $t = $t:: min_value( ) +1 ;
275
239
let y: $t = -1 ;
276
- assert_eq!( DivEuclid :: div_euclid( x, y) , $t:: max_value( ) ) ;
240
+ assert_eq!( Euclid :: div_euclid( x, y) , $t:: max_value( ) ) ;
277
241
}
278
242
) +
279
243
} ;
@@ -283,22 +247,21 @@ mod tests {
283
247
}
284
248
285
249
#[ test]
286
- #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
287
250
fn euclid_float ( ) {
288
251
macro_rules! test_euclid {
289
252
( $( $t: ident) +) => {
290
253
$(
291
254
{
292
255
let x: $t = 12.1 ;
293
256
let y: $t = 3.2 ;
294
- assert!( DivEuclid :: div_euclid( x, y) * y+RemEuclid :: rem_euclid( x, y) -x
295
- <=46.4 * <$t as :: Float >:: epsilon( ) ) ;
296
- assert!( DivEuclid :: div_euclid( x, -y) * -y+RemEuclid :: rem_euclid( x, -y) -x
297
- <= 46.4 * <$t as :: Float >:: epsilon( ) ) ;
298
- assert!( DivEuclid :: div_euclid( -x, y) * y+RemEuclid :: rem_euclid( -x, y) -( -x)
299
- <= 46.4 * <$t as :: Float >:: epsilon( ) ) ;
300
- assert!( DivEuclid :: div_euclid( -x, -y) * -y+RemEuclid :: rem_euclid( -x, -y) -( -x)
301
- <= 46.4 * <$t as :: Float >:: epsilon( ) ) ;
257
+ assert!( Euclid :: div_euclid( x, y) * y+Euclid :: rem_euclid( x, y) -x
258
+ <=46.4 * <$t as :: FloatCore >:: epsilon( ) ) ;
259
+ assert!( Euclid :: div_euclid( x, -y) * -y+Euclid :: rem_euclid( x, -y) -x
260
+ <= 46.4 * <$t as :: FloatCore >:: epsilon( ) ) ;
261
+ assert!( Euclid :: div_euclid( -x, y) * y+Euclid :: rem_euclid( -x, y) -( -x)
262
+ <= 46.4 * <$t as :: FloatCore >:: epsilon( ) ) ;
263
+ assert!( Euclid :: div_euclid( -x, -y) * -y+Euclid :: rem_euclid( -x, -y) -( -x)
264
+ <= 46.4 * <$t as :: FloatCore >:: epsilon( ) ) ;
302
265
}
303
266
) +
304
267
} ;
@@ -313,10 +276,10 @@ mod tests {
313
276
( $( $t: ident) +) => {
314
277
$(
315
278
{
316
- assert_eq!( CheckedDivEuclid :: checked_div_euclid( $t:: min_value( ) , -1 ) , None ) ;
317
- assert_eq!( CheckedRemEuclid :: checked_rem_euclid( $t:: min_value( ) , -1 ) , None ) ;
318
- assert_eq!( CheckedDivEuclid :: checked_div_euclid( 1 , 0 ) , None ) ;
319
- assert_eq!( CheckedRemEuclid :: checked_rem_euclid( 1 , 0 ) , None ) ;
279
+ assert_eq!( CheckedEuclid :: checked_div_euclid( $t:: min_value( ) , -1 ) , None ) ;
280
+ assert_eq!( CheckedEuclid :: checked_rem_euclid( $t:: min_value( ) , -1 ) , None ) ;
281
+ assert_eq!( CheckedEuclid :: checked_div_euclid( 1 , 0 ) , None ) ;
282
+ assert_eq!( CheckedEuclid :: checked_rem_euclid( 1 , 0 ) , None ) ;
320
283
}
321
284
) +
322
285
} ;
0 commit comments