1 macro_rules! int_module {
2     ($T:ident, $T_i:ident) => {
3         #[cfg(test)]
4         mod tests {
5             use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
6             use core::$T_i::*;
7 
8             use crate::num;
9 
10             #[test]
11             fn test_overflows() {
12                 assert!(MAX > 0);
13                 assert!(MIN <= 0);
14                 assert_eq!(MIN + MAX + 1, 0);
15             }
16 
17             #[test]
18             fn test_num() {
19                 num::test_num(10 as $T, 2 as $T);
20             }
21 
22             #[test]
23             fn test_rem_euclid() {
24                 assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
25             }
26 
27             #[test]
28             pub fn test_abs() {
29                 assert_eq!((1 as $T).abs(), 1 as $T);
30                 assert_eq!((0 as $T).abs(), 0 as $T);
31                 assert_eq!((-1 as $T).abs(), 1 as $T);
32             }
33 
34             #[test]
35             fn test_signum() {
36                 assert_eq!((1 as $T).signum(), 1 as $T);
37                 assert_eq!((0 as $T).signum(), 0 as $T);
38                 assert_eq!((-0 as $T).signum(), 0 as $T);
39                 assert_eq!((-1 as $T).signum(), -1 as $T);
40             }
41 
42             #[test]
43             fn test_is_positive() {
44                 assert!((1 as $T).is_positive());
45                 assert!(!(0 as $T).is_positive());
46                 assert!(!(-0 as $T).is_positive());
47                 assert!(!(-1 as $T).is_positive());
48             }
49 
50             #[test]
51             fn test_is_negative() {
52                 assert!(!(1 as $T).is_negative());
53                 assert!(!(0 as $T).is_negative());
54                 assert!(!(-0 as $T).is_negative());
55                 assert!((-1 as $T).is_negative());
56             }
57 
58             #[test]
59             fn test_bitwise_operators() {
60                 assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
61                 assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
62                 assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
63                 assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
64                 assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
65                 assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
66             }
67 
68             const A: $T = 0b0101100;
69             const B: $T = 0b0100001;
70             const C: $T = 0b1111001;
71 
72             const _0: $T = 0;
73             const _1: $T = !0;
74 
75             #[test]
76             fn test_count_ones() {
77                 assert_eq!(A.count_ones(), 3);
78                 assert_eq!(B.count_ones(), 2);
79                 assert_eq!(C.count_ones(), 5);
80             }
81 
82             #[test]
83             fn test_count_zeros() {
84                 assert_eq!(A.count_zeros(), $T::BITS - 3);
85                 assert_eq!(B.count_zeros(), $T::BITS - 2);
86                 assert_eq!(C.count_zeros(), $T::BITS - 5);
87             }
88 
89             #[test]
90             fn test_leading_trailing_ones() {
91                 let a: $T = 0b0101_1111;
92                 assert_eq!(a.trailing_ones(), 5);
93                 assert_eq!((!a).leading_ones(), $T::BITS - 7);
94 
95                 assert_eq!(a.reverse_bits().leading_ones(), 5);
96 
97                 assert_eq!(_1.leading_ones(), $T::BITS);
98                 assert_eq!(_1.trailing_ones(), $T::BITS);
99 
100                 assert_eq!((_1 << 1).trailing_ones(), 0);
101                 assert_eq!(MAX.leading_ones(), 0);
102 
103                 assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1);
104                 assert_eq!(MAX.trailing_ones(), $T::BITS - 1);
105 
106                 assert_eq!(_0.leading_ones(), 0);
107                 assert_eq!(_0.trailing_ones(), 0);
108 
109                 let x: $T = 0b0010_1100;
110                 assert_eq!(x.leading_ones(), 0);
111                 assert_eq!(x.trailing_ones(), 0);
112             }
113 
114             #[test]
115             fn test_rotate() {
116                 assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
117                 assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
118                 assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
119 
120                 // Rotating these should make no difference
121                 //
122                 // We test using 124 bits because to ensure that overlong bit shifts do
123                 // not cause undefined behaviour. See #10183.
124                 assert_eq!(_0.rotate_left(124), _0);
125                 assert_eq!(_1.rotate_left(124), _1);
126                 assert_eq!(_0.rotate_right(124), _0);
127                 assert_eq!(_1.rotate_right(124), _1);
128 
129                 // Rotating by 0 should have no effect
130                 assert_eq!(A.rotate_left(0), A);
131                 assert_eq!(B.rotate_left(0), B);
132                 assert_eq!(C.rotate_left(0), C);
133                 // Rotating by a multiple of word size should also have no effect
134                 assert_eq!(A.rotate_left(128), A);
135                 assert_eq!(B.rotate_left(128), B);
136                 assert_eq!(C.rotate_left(128), C);
137             }
138 
139             #[test]
140             fn test_swap_bytes() {
141                 assert_eq!(A.swap_bytes().swap_bytes(), A);
142                 assert_eq!(B.swap_bytes().swap_bytes(), B);
143                 assert_eq!(C.swap_bytes().swap_bytes(), C);
144 
145                 // Swapping these should make no difference
146                 assert_eq!(_0.swap_bytes(), _0);
147                 assert_eq!(_1.swap_bytes(), _1);
148             }
149 
150             #[test]
151             fn test_le() {
152                 assert_eq!($T::from_le(A.to_le()), A);
153                 assert_eq!($T::from_le(B.to_le()), B);
154                 assert_eq!($T::from_le(C.to_le()), C);
155                 assert_eq!($T::from_le(_0), _0);
156                 assert_eq!($T::from_le(_1), _1);
157                 assert_eq!(_0.to_le(), _0);
158                 assert_eq!(_1.to_le(), _1);
159             }
160 
161             #[test]
162             fn test_be() {
163                 assert_eq!($T::from_be(A.to_be()), A);
164                 assert_eq!($T::from_be(B.to_be()), B);
165                 assert_eq!($T::from_be(C.to_be()), C);
166                 assert_eq!($T::from_be(_0), _0);
167                 assert_eq!($T::from_be(_1), _1);
168                 assert_eq!(_0.to_be(), _0);
169                 assert_eq!(_1.to_be(), _1);
170             }
171 
172             #[test]
173             fn test_signed_checked_div() {
174                 assert_eq!((10 as $T).checked_div(2), Some(5));
175                 assert_eq!((5 as $T).checked_div(0), None);
176                 assert_eq!(isize::MIN.checked_div(-1), None);
177             }
178 
179             #[test]
180             fn test_saturating_abs() {
181                 assert_eq!((0 as $T).saturating_abs(), 0);
182                 assert_eq!((123 as $T).saturating_abs(), 123);
183                 assert_eq!((-123 as $T).saturating_abs(), 123);
184                 assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
185                 assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
186                 assert_eq!(MAX.saturating_abs(), MAX);
187                 assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
188                 assert_eq!((MIN + 1).saturating_abs(), MAX);
189                 assert_eq!(MIN.saturating_abs(), MAX);
190             }
191 
192             #[test]
193             fn test_saturating_neg() {
194                 assert_eq!((0 as $T).saturating_neg(), 0);
195                 assert_eq!((123 as $T).saturating_neg(), -123);
196                 assert_eq!((-123 as $T).saturating_neg(), 123);
197                 assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
198                 assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
199                 assert_eq!(MAX.saturating_neg(), MIN + 1);
200                 assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
201                 assert_eq!((MIN + 1).saturating_neg(), MAX);
202                 assert_eq!(MIN.saturating_neg(), MAX);
203             }
204 
205             #[test]
206             fn test_from_str() {
207                 fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
208                     std::str::FromStr::from_str(t).ok()
209                 }
210                 assert_eq!(from_str::<$T>("0"), Some(0 as $T));
211                 assert_eq!(from_str::<$T>("3"), Some(3 as $T));
212                 assert_eq!(from_str::<$T>("10"), Some(10 as $T));
213                 assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
214                 assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
215 
216                 assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
217                 assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
218                 assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
219                 assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
220                 assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
221 
222                 assert_eq!(from_str::<$T>(""), None);
223                 assert_eq!(from_str::<$T>(" "), None);
224                 assert_eq!(from_str::<$T>("x"), None);
225             }
226 
227             #[test]
228             fn test_from_str_radix() {
229                 assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
230                 assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
231                 assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
232                 assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
233                 assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
234                 assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
235                 assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
236                 assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
237 
238                 assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
239                 assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
240                 assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
241                 assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
242                 assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
243                 assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
244                 assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
245                 assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
246 
247                 assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
248                 assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
249             }
250 
251             #[test]
252             fn test_pow() {
253                 let mut r = 2 as $T;
254                 assert_eq!(r.pow(2), 4 as $T);
255                 assert_eq!(r.pow(0), 1 as $T);
256                 assert_eq!(r.wrapping_pow(2), 4 as $T);
257                 assert_eq!(r.wrapping_pow(0), 1 as $T);
258                 assert_eq!(r.checked_pow(2), Some(4 as $T));
259                 assert_eq!(r.checked_pow(0), Some(1 as $T));
260                 assert_eq!(r.overflowing_pow(2), (4 as $T, false));
261                 assert_eq!(r.overflowing_pow(0), (1 as $T, false));
262                 assert_eq!(r.saturating_pow(2), 4 as $T);
263                 assert_eq!(r.saturating_pow(0), 1 as $T);
264 
265                 r = MAX;
266                 // use `^` to represent .pow() with no overflow.
267                 // if itest::MAX == 2^j-1, then itest is a `j` bit int,
268                 // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
269                 // thussaturating_pow the overflowing result is exactly 1.
270                 assert_eq!(r.wrapping_pow(2), 1 as $T);
271                 assert_eq!(r.checked_pow(2), None);
272                 assert_eq!(r.overflowing_pow(2), (1 as $T, true));
273                 assert_eq!(r.saturating_pow(2), MAX);
274                 //test for negative exponent.
275                 r = -2 as $T;
276                 assert_eq!(r.pow(2), 4 as $T);
277                 assert_eq!(r.pow(3), -8 as $T);
278                 assert_eq!(r.pow(0), 1 as $T);
279                 assert_eq!(r.wrapping_pow(2), 4 as $T);
280                 assert_eq!(r.wrapping_pow(3), -8 as $T);
281                 assert_eq!(r.wrapping_pow(0), 1 as $T);
282                 assert_eq!(r.checked_pow(2), Some(4 as $T));
283                 assert_eq!(r.checked_pow(3), Some(-8 as $T));
284                 assert_eq!(r.checked_pow(0), Some(1 as $T));
285                 assert_eq!(r.overflowing_pow(2), (4 as $T, false));
286                 assert_eq!(r.overflowing_pow(3), (-8 as $T, false));
287                 assert_eq!(r.overflowing_pow(0), (1 as $T, false));
288                 assert_eq!(r.saturating_pow(2), 4 as $T);
289                 assert_eq!(r.saturating_pow(3), -8 as $T);
290                 assert_eq!(r.saturating_pow(0), 1 as $T);
291             }
292 
293             #[test]
294             fn test_div_floor() {
295                 let a: $T = 8;
296                 let b = 3;
297                 assert_eq!(a.unstable_div_floor(b), 2);
298                 assert_eq!(a.unstable_div_floor(-b), -3);
299                 assert_eq!((-a).unstable_div_floor(b), -3);
300                 assert_eq!((-a).unstable_div_floor(-b), 2);
301             }
302 
303             #[test]
304             fn test_div_ceil() {
305                 let a: $T = 8;
306                 let b = 3;
307                 assert_eq!(a.unstable_div_ceil(b), 3);
308                 assert_eq!(a.unstable_div_ceil(-b), -2);
309                 assert_eq!((-a).unstable_div_ceil(b), -2);
310                 assert_eq!((-a).unstable_div_ceil(-b), 3);
311             }
312 
313             #[test]
314             fn test_next_multiple_of() {
315                 assert_eq!((16 as $T).unstable_next_multiple_of(8), 16);
316                 assert_eq!((23 as $T).unstable_next_multiple_of(8), 24);
317                 assert_eq!((16 as $T).unstable_next_multiple_of(-8), 16);
318                 assert_eq!((23 as $T).unstable_next_multiple_of(-8), 16);
319                 assert_eq!((-16 as $T).unstable_next_multiple_of(8), -16);
320                 assert_eq!((-23 as $T).unstable_next_multiple_of(8), -16);
321                 assert_eq!((-16 as $T).unstable_next_multiple_of(-8), -16);
322                 assert_eq!((-23 as $T).unstable_next_multiple_of(-8), -24);
323                 assert_eq!(MIN.unstable_next_multiple_of(-1), MIN);
324             }
325 
326             #[test]
327             fn test_checked_next_multiple_of() {
328                 assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16));
329                 assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24));
330                 assert_eq!((16 as $T).checked_next_multiple_of(-8), Some(16));
331                 assert_eq!((23 as $T).checked_next_multiple_of(-8), Some(16));
332                 assert_eq!((-16 as $T).checked_next_multiple_of(8), Some(-16));
333                 assert_eq!((-23 as $T).checked_next_multiple_of(8), Some(-16));
334                 assert_eq!((-16 as $T).checked_next_multiple_of(-8), Some(-16));
335                 assert_eq!((-23 as $T).checked_next_multiple_of(-8), Some(-24));
336                 assert_eq!((1 as $T).checked_next_multiple_of(0), None);
337                 assert_eq!(MAX.checked_next_multiple_of(2), None);
338                 assert_eq!(MIN.checked_next_multiple_of(-3), None);
339                 assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN));
340             }
341         }
342     };
343 }
344