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