int.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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 zeros in the binary representation
  78. /// of `self`.
  79. ///
  80. /// # Examples
  81. ///
  82. /// ```
  83. /// use num_traits::PrimInt;
  84. ///
  85. /// let n = 0b0101000u16;
  86. ///
  87. /// assert_eq!(n.leading_zeros(), 10);
  88. /// ```
  89. fn leading_zeros(self) -> u32;
  90. /// Returns the number of trailing zeros in the binary representation
  91. /// of `self`.
  92. ///
  93. /// # Examples
  94. ///
  95. /// ```
  96. /// use num_traits::PrimInt;
  97. ///
  98. /// let n = 0b0101000u16;
  99. ///
  100. /// assert_eq!(n.trailing_zeros(), 3);
  101. /// ```
  102. fn trailing_zeros(self) -> u32;
  103. /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
  104. /// the truncated bits to the end of the resulting integer.
  105. ///
  106. /// # Examples
  107. ///
  108. /// ```
  109. /// use num_traits::PrimInt;
  110. ///
  111. /// let n = 0x0123456789ABCDEFu64;
  112. /// let m = 0x3456789ABCDEF012u64;
  113. ///
  114. /// assert_eq!(n.rotate_left(12), m);
  115. /// ```
  116. fn rotate_left(self, n: u32) -> Self;
  117. /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
  118. /// the truncated bits to the beginning of the resulting integer.
  119. ///
  120. /// # Examples
  121. ///
  122. /// ```
  123. /// use num_traits::PrimInt;
  124. ///
  125. /// let n = 0x0123456789ABCDEFu64;
  126. /// let m = 0xDEF0123456789ABCu64;
  127. ///
  128. /// assert_eq!(n.rotate_right(12), m);
  129. /// ```
  130. fn rotate_right(self, n: u32) -> Self;
  131. /// Shifts the bits to the left by a specified amount amount, `n`, filling
  132. /// zeros in the least significant bits.
  133. ///
  134. /// This is bitwise equivalent to signed `Shl`.
  135. ///
  136. /// # Examples
  137. ///
  138. /// ```
  139. /// use num_traits::PrimInt;
  140. ///
  141. /// let n = 0x0123456789ABCDEFu64;
  142. /// let m = 0x3456789ABCDEF000u64;
  143. ///
  144. /// assert_eq!(n.signed_shl(12), m);
  145. /// ```
  146. fn signed_shl(self, n: u32) -> Self;
  147. /// Shifts the bits to the right by a specified amount amount, `n`, copying
  148. /// the "sign bit" in the most significant bits even for unsigned types.
  149. ///
  150. /// This is bitwise equivalent to signed `Shr`.
  151. ///
  152. /// # Examples
  153. ///
  154. /// ```
  155. /// use num_traits::PrimInt;
  156. ///
  157. /// let n = 0xFEDCBA9876543210u64;
  158. /// let m = 0xFFFFEDCBA9876543u64;
  159. ///
  160. /// assert_eq!(n.signed_shr(12), m);
  161. /// ```
  162. fn signed_shr(self, n: u32) -> Self;
  163. /// Shifts the bits to the left by a specified amount amount, `n`, filling
  164. /// zeros in the least significant bits.
  165. ///
  166. /// This is bitwise equivalent to unsigned `Shl`.
  167. ///
  168. /// # Examples
  169. ///
  170. /// ```
  171. /// use num_traits::PrimInt;
  172. ///
  173. /// let n = 0x0123456789ABCDEFi64;
  174. /// let m = 0x3456789ABCDEF000i64;
  175. ///
  176. /// assert_eq!(n.unsigned_shl(12), m);
  177. /// ```
  178. fn unsigned_shl(self, n: u32) -> Self;
  179. /// Shifts the bits to the right by a specified amount amount, `n`, filling
  180. /// zeros in the most significant bits.
  181. ///
  182. /// This is bitwise equivalent to unsigned `Shr`.
  183. ///
  184. /// # Examples
  185. ///
  186. /// ```
  187. /// use num_traits::PrimInt;
  188. ///
  189. /// let n = -8i8; // 0b11111000
  190. /// let m = 62i8; // 0b00111110
  191. ///
  192. /// assert_eq!(n.unsigned_shr(2), m);
  193. /// ```
  194. fn unsigned_shr(self, n: u32) -> Self;
  195. /// Reverses the byte order of the integer.
  196. ///
  197. /// # Examples
  198. ///
  199. /// ```
  200. /// use num_traits::PrimInt;
  201. ///
  202. /// let n = 0x0123456789ABCDEFu64;
  203. /// let m = 0xEFCDAB8967452301u64;
  204. ///
  205. /// assert_eq!(n.swap_bytes(), m);
  206. /// ```
  207. fn swap_bytes(self) -> Self;
  208. /// Convert an integer from big endian to the target's endianness.
  209. ///
  210. /// On big endian this is a no-op. On little endian the bytes are swapped.
  211. ///
  212. /// # Examples
  213. ///
  214. /// ```
  215. /// use num_traits::PrimInt;
  216. ///
  217. /// let n = 0x0123456789ABCDEFu64;
  218. ///
  219. /// if cfg!(target_endian = "big") {
  220. /// assert_eq!(u64::from_be(n), n)
  221. /// } else {
  222. /// assert_eq!(u64::from_be(n), n.swap_bytes())
  223. /// }
  224. /// ```
  225. fn from_be(x: Self) -> Self;
  226. /// Convert an integer from little endian to the target's endianness.
  227. ///
  228. /// On little endian this is a no-op. On big endian the bytes are swapped.
  229. ///
  230. /// # Examples
  231. ///
  232. /// ```
  233. /// use num_traits::PrimInt;
  234. ///
  235. /// let n = 0x0123456789ABCDEFu64;
  236. ///
  237. /// if cfg!(target_endian = "little") {
  238. /// assert_eq!(u64::from_le(n), n)
  239. /// } else {
  240. /// assert_eq!(u64::from_le(n), n.swap_bytes())
  241. /// }
  242. /// ```
  243. fn from_le(x: Self) -> Self;
  244. /// Convert `self` to big endian from the target's endianness.
  245. ///
  246. /// On big endian this is a no-op. On little endian the bytes are swapped.
  247. ///
  248. /// # Examples
  249. ///
  250. /// ```
  251. /// use num_traits::PrimInt;
  252. ///
  253. /// let n = 0x0123456789ABCDEFu64;
  254. ///
  255. /// if cfg!(target_endian = "big") {
  256. /// assert_eq!(n.to_be(), n)
  257. /// } else {
  258. /// assert_eq!(n.to_be(), n.swap_bytes())
  259. /// }
  260. /// ```
  261. fn to_be(self) -> Self;
  262. /// Convert `self` to little endian from the target's endianness.
  263. ///
  264. /// On little endian this is a no-op. On big endian the bytes are swapped.
  265. ///
  266. /// # Examples
  267. ///
  268. /// ```
  269. /// use num_traits::PrimInt;
  270. ///
  271. /// let n = 0x0123456789ABCDEFu64;
  272. ///
  273. /// if cfg!(target_endian = "little") {
  274. /// assert_eq!(n.to_le(), n)
  275. /// } else {
  276. /// assert_eq!(n.to_le(), n.swap_bytes())
  277. /// }
  278. /// ```
  279. fn to_le(self) -> Self;
  280. /// Raises self to the power of `exp`, using exponentiation by squaring.
  281. ///
  282. /// # Examples
  283. ///
  284. /// ```
  285. /// use num_traits::PrimInt;
  286. ///
  287. /// assert_eq!(2i32.pow(4), 16);
  288. /// ```
  289. fn pow(self, exp: u32) -> Self;
  290. }
  291. macro_rules! prim_int_impl {
  292. ($T:ty, $S:ty, $U:ty) => {
  293. impl PrimInt for $T {
  294. #[inline]
  295. fn count_ones(self) -> u32 {
  296. <$T>::count_ones(self)
  297. }
  298. #[inline]
  299. fn count_zeros(self) -> u32 {
  300. <$T>::count_zeros(self)
  301. }
  302. #[inline]
  303. fn leading_zeros(self) -> u32 {
  304. <$T>::leading_zeros(self)
  305. }
  306. #[inline]
  307. fn trailing_zeros(self) -> u32 {
  308. <$T>::trailing_zeros(self)
  309. }
  310. #[inline]
  311. fn rotate_left(self, n: u32) -> Self {
  312. <$T>::rotate_left(self, n)
  313. }
  314. #[inline]
  315. fn rotate_right(self, n: u32) -> Self {
  316. <$T>::rotate_right(self, n)
  317. }
  318. #[inline]
  319. fn signed_shl(self, n: u32) -> Self {
  320. ((self as $S) << n) as $T
  321. }
  322. #[inline]
  323. fn signed_shr(self, n: u32) -> Self {
  324. ((self as $S) >> n) as $T
  325. }
  326. #[inline]
  327. fn unsigned_shl(self, n: u32) -> Self {
  328. ((self as $U) << n) as $T
  329. }
  330. #[inline]
  331. fn unsigned_shr(self, n: u32) -> Self {
  332. ((self as $U) >> n) as $T
  333. }
  334. #[inline]
  335. fn swap_bytes(self) -> Self {
  336. <$T>::swap_bytes(self)
  337. }
  338. #[inline]
  339. fn from_be(x: Self) -> Self {
  340. <$T>::from_be(x)
  341. }
  342. #[inline]
  343. fn from_le(x: Self) -> Self {
  344. <$T>::from_le(x)
  345. }
  346. #[inline]
  347. fn to_be(self) -> Self {
  348. <$T>::to_be(self)
  349. }
  350. #[inline]
  351. fn to_le(self) -> Self {
  352. <$T>::to_le(self)
  353. }
  354. #[inline]
  355. fn pow(self, exp: u32) -> Self {
  356. <$T>::pow(self, exp)
  357. }
  358. }
  359. };
  360. }
  361. // prim_int_impl!(type, signed, unsigned);
  362. prim_int_impl!(u8, i8, u8);
  363. prim_int_impl!(u16, i16, u16);
  364. prim_int_impl!(u32, i32, u32);
  365. prim_int_impl!(u64, i64, u64);
  366. #[cfg(has_i128)]
  367. prim_int_impl!(u128, i128, u128);
  368. prim_int_impl!(usize, isize, usize);
  369. prim_int_impl!(i8, i8, u8);
  370. prim_int_impl!(i16, i16, u16);
  371. prim_int_impl!(i32, i32, u32);
  372. prim_int_impl!(i64, i64, u64);
  373. #[cfg(has_i128)]
  374. prim_int_impl!(i128, i128, u128);
  375. prim_int_impl!(isize, isize, usize);