int.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
  2. use bounds::Bounded;
  3. use ops::checked::*;
  4. use ops::saturating::Saturating;
  5. use {Num, NumCast};
  6. /// Generic trait for primitive integers.
  7. ///
  8. /// The `PrimInt` trait is an abstraction over the builtin primitive integer types (e.g., `u8`,
  9. /// `u32`, `isize`, `i128`, ...). It inherits the basic numeric traits and extends them with
  10. /// bitwise operators and non-wrapping arithmetic.
  11. ///
  12. /// The trait explicitly inherits `Copy`, `Eq`, `Ord`, and `Sized`. The intention is that all
  13. /// types implementing this trait behave like primitive types that are passed by value by default
  14. /// and behave like builtin integers. Furthermore, the types are expected to expose the integer
  15. /// value in binary representation and support bitwise operators. The standard bitwise operations
  16. /// (e.g., bitwise-and, bitwise-or, right-shift, left-shift) are inherited and the trait extends
  17. /// these with introspective queries (e.g., `PrimInt::count_ones()`, `PrimInt::leading_zeros()`),
  18. /// bitwise combinators (e.g., `PrimInt::rotate_left()`), and endianness converters (e.g.,
  19. /// `PrimInt::to_be()`).
  20. ///
  21. /// All `PrimInt` types are expected to be fixed-width binary integers. The width can be queried
  22. /// via `T::zero().count_zeros()`. The trait currently lacks a way to query the width at
  23. /// compile-time.
  24. ///
  25. /// While a default implementation for all builtin primitive integers is provided, the trait is in
  26. /// no way restricted to these. Other integer types that fulfil the requirements are free to
  27. /// implement the trait was well.
  28. ///
  29. /// This trait and many of the method names originate in the unstable `core::num::Int` trait from
  30. /// the rust standard library. The original trait was never stabilized and thus removed from the
  31. /// standard library.
  32. pub trait PrimInt:
  33. Sized
  34. + Copy
  35. + Num
  36. + NumCast
  37. + Bounded
  38. + PartialOrd
  39. + Ord
  40. + Eq
  41. + Not<Output = Self>
  42. + BitAnd<Output = Self>
  43. + BitOr<Output = Self>
  44. + BitXor<Output = Self>
  45. + Shl<usize, Output = Self>
  46. + Shr<usize, Output = Self>
  47. + CheckedAdd<Output = Self>
  48. + CheckedSub<Output = Self>
  49. + CheckedMul<Output = Self>
  50. + CheckedDiv<Output = Self>
  51. + Saturating
  52. {
  53. /// Returns the number of ones in the binary representation of `self`.
  54. ///
  55. /// # Examples
  56. ///
  57. /// ```
  58. /// use num_traits::PrimInt;
  59. ///
  60. /// let n = 0b01001100u8;
  61. ///
  62. /// assert_eq!(n.count_ones(), 3);
  63. /// ```
  64. fn count_ones(self) -> u32;
  65. /// Returns the number of zeros in the binary representation of `self`.
  66. ///
  67. /// # Examples
  68. ///
  69. /// ```
  70. /// use num_traits::PrimInt;
  71. ///
  72. /// let n = 0b01001100u8;
  73. ///
  74. /// assert_eq!(n.count_zeros(), 5);
  75. /// ```
  76. fn count_zeros(self) -> u32;
  77. /// Returns the number of leading ones in the binary representation
  78. /// of `self`.
  79. ///
  80. /// # Examples
  81. ///
  82. /// ```
  83. /// use num_traits::PrimInt;
  84. ///
  85. /// let n = 0xF00Du16;
  86. ///
  87. /// assert_eq!(n.leading_ones(), 4);
  88. /// ```
  89. fn leading_ones(self) -> u32 {
  90. (!self).leading_zeros()
  91. }
  92. /// Returns the number of leading zeros in the binary representation
  93. /// of `self`.
  94. ///
  95. /// # Examples
  96. ///
  97. /// ```
  98. /// use num_traits::PrimInt;
  99. ///
  100. /// let n = 0b0101000u16;
  101. ///
  102. /// assert_eq!(n.leading_zeros(), 10);
  103. /// ```
  104. fn leading_zeros(self) -> u32;
  105. /// Returns the number of trailing ones in the binary representation
  106. /// of `self`.
  107. ///
  108. /// # Examples
  109. ///
  110. /// ```
  111. /// use num_traits::PrimInt;
  112. ///
  113. /// let n = 0xBEEFu16;
  114. ///
  115. /// assert_eq!(n.trailing_ones(), 4);
  116. /// ```
  117. fn trailing_ones(self) -> u32 {
  118. (!self).trailing_zeros()
  119. }
  120. /// Returns the number of trailing zeros in the binary representation
  121. /// of `self`.
  122. ///
  123. /// # Examples
  124. ///
  125. /// ```
  126. /// use num_traits::PrimInt;
  127. ///
  128. /// let n = 0b0101000u16;
  129. ///
  130. /// assert_eq!(n.trailing_zeros(), 3);
  131. /// ```
  132. fn trailing_zeros(self) -> u32;
  133. /// Shifts the bits to the left by a specified amount, `n`, wrapping
  134. /// the truncated bits to the end of the resulting integer.
  135. ///
  136. /// # Examples
  137. ///
  138. /// ```
  139. /// use num_traits::PrimInt;
  140. ///
  141. /// let n = 0x0123456789ABCDEFu64;
  142. /// let m = 0x3456789ABCDEF012u64;
  143. ///
  144. /// assert_eq!(n.rotate_left(12), m);
  145. /// ```
  146. fn rotate_left(self, n: u32) -> Self;
  147. /// Shifts the bits to the right by a specified amount, `n`, wrapping
  148. /// the truncated bits to the beginning of the resulting integer.
  149. ///
  150. /// # Examples
  151. ///
  152. /// ```
  153. /// use num_traits::PrimInt;
  154. ///
  155. /// let n = 0x0123456789ABCDEFu64;
  156. /// let m = 0xDEF0123456789ABCu64;
  157. ///
  158. /// assert_eq!(n.rotate_right(12), m);
  159. /// ```
  160. fn rotate_right(self, n: u32) -> Self;
  161. /// Shifts the bits to the left by a specified amount, `n`, filling
  162. /// zeros in the least significant bits.
  163. ///
  164. /// This is bitwise equivalent to signed `Shl`.
  165. ///
  166. /// # Examples
  167. ///
  168. /// ```
  169. /// use num_traits::PrimInt;
  170. ///
  171. /// let n = 0x0123456789ABCDEFu64;
  172. /// let m = 0x3456789ABCDEF000u64;
  173. ///
  174. /// assert_eq!(n.signed_shl(12), m);
  175. /// ```
  176. fn signed_shl(self, n: u32) -> Self;
  177. /// Shifts the bits to the right by a specified amount, `n`, copying
  178. /// the "sign bit" in the most significant bits even for unsigned types.
  179. ///
  180. /// This is bitwise equivalent to signed `Shr`.
  181. ///
  182. /// # Examples
  183. ///
  184. /// ```
  185. /// use num_traits::PrimInt;
  186. ///
  187. /// let n = 0xFEDCBA9876543210u64;
  188. /// let m = 0xFFFFEDCBA9876543u64;
  189. ///
  190. /// assert_eq!(n.signed_shr(12), m);
  191. /// ```
  192. fn signed_shr(self, n: u32) -> Self;
  193. /// Shifts the bits to the left by a specified amount, `n`, filling
  194. /// zeros in the least significant bits.
  195. ///
  196. /// This is bitwise equivalent to unsigned `Shl`.
  197. ///
  198. /// # Examples
  199. ///
  200. /// ```
  201. /// use num_traits::PrimInt;
  202. ///
  203. /// let n = 0x0123456789ABCDEFi64;
  204. /// let m = 0x3456789ABCDEF000i64;
  205. ///
  206. /// assert_eq!(n.unsigned_shl(12), m);
  207. /// ```
  208. fn unsigned_shl(self, n: u32) -> Self;
  209. /// Shifts the bits to the right by a specified amount, `n`, filling
  210. /// zeros in the most significant bits.
  211. ///
  212. /// This is bitwise equivalent to unsigned `Shr`.
  213. ///
  214. /// # Examples
  215. ///
  216. /// ```
  217. /// use num_traits::PrimInt;
  218. ///
  219. /// let n = -8i8; // 0b11111000
  220. /// let m = 62i8; // 0b00111110
  221. ///
  222. /// assert_eq!(n.unsigned_shr(2), m);
  223. /// ```
  224. fn unsigned_shr(self, n: u32) -> Self;
  225. /// Reverses the byte order of the integer.
  226. ///
  227. /// # Examples
  228. ///
  229. /// ```
  230. /// use num_traits::PrimInt;
  231. ///
  232. /// let n = 0x0123456789ABCDEFu64;
  233. /// let m = 0xEFCDAB8967452301u64;
  234. ///
  235. /// assert_eq!(n.swap_bytes(), m);
  236. /// ```
  237. fn swap_bytes(self) -> Self;
  238. /// Reverses the order of bits in the integer.
  239. ///
  240. /// The least significant bit becomes the most significant bit, second least-significant bit
  241. /// becomes second most-significant bit, etc.
  242. ///
  243. /// # Examples
  244. ///
  245. /// ```
  246. /// use num_traits::PrimInt;
  247. ///
  248. /// let n = 0x12345678u32;
  249. /// let m = 0x1e6a2c48u32;
  250. ///
  251. /// assert_eq!(n.reverse_bits(), m);
  252. /// assert_eq!(0u32.reverse_bits(), 0);
  253. /// ```
  254. fn reverse_bits(self) -> Self {
  255. reverse_bits_fallback(self)
  256. }
  257. /// Convert an integer from big endian to the target's endianness.
  258. ///
  259. /// On big endian this is a no-op. On little endian the bytes are swapped.
  260. ///
  261. /// # Examples
  262. ///
  263. /// ```
  264. /// use num_traits::PrimInt;
  265. ///
  266. /// let n = 0x0123456789ABCDEFu64;
  267. ///
  268. /// if cfg!(target_endian = "big") {
  269. /// assert_eq!(u64::from_be(n), n)
  270. /// } else {
  271. /// assert_eq!(u64::from_be(n), n.swap_bytes())
  272. /// }
  273. /// ```
  274. fn from_be(x: Self) -> Self;
  275. /// Convert an integer from little endian to the target's endianness.
  276. ///
  277. /// On little endian this is a no-op. On big endian the bytes are swapped.
  278. ///
  279. /// # Examples
  280. ///
  281. /// ```
  282. /// use num_traits::PrimInt;
  283. ///
  284. /// let n = 0x0123456789ABCDEFu64;
  285. ///
  286. /// if cfg!(target_endian = "little") {
  287. /// assert_eq!(u64::from_le(n), n)
  288. /// } else {
  289. /// assert_eq!(u64::from_le(n), n.swap_bytes())
  290. /// }
  291. /// ```
  292. fn from_le(x: Self) -> Self;
  293. /// Convert `self` to big endian from the target's endianness.
  294. ///
  295. /// On big endian this is a no-op. On little endian the bytes are swapped.
  296. ///
  297. /// # Examples
  298. ///
  299. /// ```
  300. /// use num_traits::PrimInt;
  301. ///
  302. /// let n = 0x0123456789ABCDEFu64;
  303. ///
  304. /// if cfg!(target_endian = "big") {
  305. /// assert_eq!(n.to_be(), n)
  306. /// } else {
  307. /// assert_eq!(n.to_be(), n.swap_bytes())
  308. /// }
  309. /// ```
  310. fn to_be(self) -> Self;
  311. /// Convert `self` to little endian from the target's endianness.
  312. ///
  313. /// On little endian this is a no-op. On big endian the bytes are swapped.
  314. ///
  315. /// # Examples
  316. ///
  317. /// ```
  318. /// use num_traits::PrimInt;
  319. ///
  320. /// let n = 0x0123456789ABCDEFu64;
  321. ///
  322. /// if cfg!(target_endian = "little") {
  323. /// assert_eq!(n.to_le(), n)
  324. /// } else {
  325. /// assert_eq!(n.to_le(), n.swap_bytes())
  326. /// }
  327. /// ```
  328. fn to_le(self) -> Self;
  329. /// Raises self to the power of `exp`, using exponentiation by squaring.
  330. ///
  331. /// # Examples
  332. ///
  333. /// ```
  334. /// use num_traits::PrimInt;
  335. ///
  336. /// assert_eq!(2i32.pow(4), 16);
  337. /// ```
  338. fn pow(self, exp: u32) -> Self;
  339. }
  340. fn one_per_byte<P: PrimInt>() -> P {
  341. // i8, u8: return 0x01
  342. // i16, u16: return 0x0101 = (0x01 << 8) | 0x01
  343. // i32, u32: return 0x01010101 = (0x0101 << 16) | 0x0101
  344. // ...
  345. let mut ret = P::one();
  346. let mut shift = 8;
  347. let mut b = ret.count_zeros() >> 3;
  348. while b != 0 {
  349. ret = (ret << shift) | ret;
  350. shift <<= 1;
  351. b >>= 1;
  352. }
  353. ret
  354. }
  355. fn reverse_bits_fallback<P: PrimInt>(i: P) -> P {
  356. let rep_01: P = one_per_byte();
  357. let rep_03 = (rep_01 << 1) | rep_01;
  358. let rep_05 = (rep_01 << 2) | rep_01;
  359. let rep_0f = (rep_03 << 2) | rep_03;
  360. let rep_33 = (rep_03 << 4) | rep_03;
  361. let rep_55 = (rep_05 << 4) | rep_05;
  362. // code above only used to determine rep_0f, rep_33, rep_55;
  363. // optimizer should be able to do it in compile time
  364. let mut ret = i.swap_bytes();
  365. ret = ((ret & rep_0f) << 4) | ((ret >> 4) & rep_0f);
  366. ret = ((ret & rep_33) << 2) | ((ret >> 2) & rep_33);
  367. ret = ((ret & rep_55) << 1) | ((ret >> 1) & rep_55);
  368. ret
  369. }
  370. macro_rules! prim_int_impl {
  371. ($T:ty, $S:ty, $U:ty) => {
  372. impl PrimInt for $T {
  373. #[inline]
  374. fn count_ones(self) -> u32 {
  375. <$T>::count_ones(self)
  376. }
  377. #[inline]
  378. fn count_zeros(self) -> u32 {
  379. <$T>::count_zeros(self)
  380. }
  381. #[cfg(has_leading_trailing_ones)]
  382. #[inline]
  383. fn leading_ones(self) -> u32 {
  384. <$T>::leading_ones(self)
  385. }
  386. #[inline]
  387. fn leading_zeros(self) -> u32 {
  388. <$T>::leading_zeros(self)
  389. }
  390. #[cfg(has_leading_trailing_ones)]
  391. #[inline]
  392. fn trailing_ones(self) -> u32 {
  393. <$T>::trailing_ones(self)
  394. }
  395. #[inline]
  396. fn trailing_zeros(self) -> u32 {
  397. <$T>::trailing_zeros(self)
  398. }
  399. #[inline]
  400. fn rotate_left(self, n: u32) -> Self {
  401. <$T>::rotate_left(self, n)
  402. }
  403. #[inline]
  404. fn rotate_right(self, n: u32) -> Self {
  405. <$T>::rotate_right(self, n)
  406. }
  407. #[inline]
  408. fn signed_shl(self, n: u32) -> Self {
  409. ((self as $S) << n) as $T
  410. }
  411. #[inline]
  412. fn signed_shr(self, n: u32) -> Self {
  413. ((self as $S) >> n) as $T
  414. }
  415. #[inline]
  416. fn unsigned_shl(self, n: u32) -> Self {
  417. ((self as $U) << n) as $T
  418. }
  419. #[inline]
  420. fn unsigned_shr(self, n: u32) -> Self {
  421. ((self as $U) >> n) as $T
  422. }
  423. #[inline]
  424. fn swap_bytes(self) -> Self {
  425. <$T>::swap_bytes(self)
  426. }
  427. #[cfg(has_reverse_bits)]
  428. #[inline]
  429. fn reverse_bits(self) -> Self {
  430. <$T>::reverse_bits(self)
  431. }
  432. #[inline]
  433. fn from_be(x: Self) -> Self {
  434. <$T>::from_be(x)
  435. }
  436. #[inline]
  437. fn from_le(x: Self) -> Self {
  438. <$T>::from_le(x)
  439. }
  440. #[inline]
  441. fn to_be(self) -> Self {
  442. <$T>::to_be(self)
  443. }
  444. #[inline]
  445. fn to_le(self) -> Self {
  446. <$T>::to_le(self)
  447. }
  448. #[inline]
  449. fn pow(self, exp: u32) -> Self {
  450. <$T>::pow(self, exp)
  451. }
  452. }
  453. };
  454. }
  455. // prim_int_impl!(type, signed, unsigned);
  456. prim_int_impl!(u8, i8, u8);
  457. prim_int_impl!(u16, i16, u16);
  458. prim_int_impl!(u32, i32, u32);
  459. prim_int_impl!(u64, i64, u64);
  460. #[cfg(has_i128)]
  461. prim_int_impl!(u128, i128, u128);
  462. prim_int_impl!(usize, isize, usize);
  463. prim_int_impl!(i8, i8, u8);
  464. prim_int_impl!(i16, i16, u16);
  465. prim_int_impl!(i32, i32, u32);
  466. prim_int_impl!(i64, i64, u64);
  467. #[cfg(has_i128)]
  468. prim_int_impl!(i128, i128, u128);
  469. prim_int_impl!(isize, isize, usize);
  470. #[cfg(test)]
  471. mod tests {
  472. use int::PrimInt;
  473. #[test]
  474. pub fn reverse_bits() {
  475. use core::{i16, i32, i64, i8};
  476. assert_eq!(
  477. PrimInt::reverse_bits(0x0123_4567_89ab_cdefu64),
  478. 0xf7b3_d591_e6a2_c480
  479. );
  480. assert_eq!(PrimInt::reverse_bits(0i8), 0);
  481. assert_eq!(PrimInt::reverse_bits(-1i8), -1);
  482. assert_eq!(PrimInt::reverse_bits(1i8), i8::MIN);
  483. assert_eq!(PrimInt::reverse_bits(i8::MIN), 1);
  484. assert_eq!(PrimInt::reverse_bits(-2i8), i8::MAX);
  485. assert_eq!(PrimInt::reverse_bits(i8::MAX), -2);
  486. assert_eq!(PrimInt::reverse_bits(0i16), 0);
  487. assert_eq!(PrimInt::reverse_bits(-1i16), -1);
  488. assert_eq!(PrimInt::reverse_bits(1i16), i16::MIN);
  489. assert_eq!(PrimInt::reverse_bits(i16::MIN), 1);
  490. assert_eq!(PrimInt::reverse_bits(-2i16), i16::MAX);
  491. assert_eq!(PrimInt::reverse_bits(i16::MAX), -2);
  492. assert_eq!(PrimInt::reverse_bits(0i32), 0);
  493. assert_eq!(PrimInt::reverse_bits(-1i32), -1);
  494. assert_eq!(PrimInt::reverse_bits(1i32), i32::MIN);
  495. assert_eq!(PrimInt::reverse_bits(i32::MIN), 1);
  496. assert_eq!(PrimInt::reverse_bits(-2i32), i32::MAX);
  497. assert_eq!(PrimInt::reverse_bits(i32::MAX), -2);
  498. assert_eq!(PrimInt::reverse_bits(0i64), 0);
  499. assert_eq!(PrimInt::reverse_bits(-1i64), -1);
  500. assert_eq!(PrimInt::reverse_bits(1i64), i64::MIN);
  501. assert_eq!(PrimInt::reverse_bits(i64::MIN), 1);
  502. assert_eq!(PrimInt::reverse_bits(-2i64), i64::MAX);
  503. assert_eq!(PrimInt::reverse_bits(i64::MAX), -2);
  504. }
  505. #[test]
  506. #[cfg(has_i128)]
  507. pub fn reverse_bits_i128() {
  508. use core::i128;
  509. assert_eq!(PrimInt::reverse_bits(0i128), 0);
  510. assert_eq!(PrimInt::reverse_bits(-1i128), -1);
  511. assert_eq!(PrimInt::reverse_bits(1i128), i128::MIN);
  512. assert_eq!(PrimInt::reverse_bits(i128::MIN), 1);
  513. assert_eq!(PrimInt::reverse_bits(-2i128), i128::MAX);
  514. assert_eq!(PrimInt::reverse_bits(i128::MAX), -2);
  515. }
  516. }