int.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. use std::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
  2. use {Num, NumCast};
  3. use bounds::Bounded;
  4. use ops::checked::*;
  5. use ops::saturating::Saturating;
  6. pub trait PrimInt
  7. : Sized
  8. + Copy
  9. + Num + NumCast
  10. + Bounded
  11. + PartialOrd + Ord + Eq
  12. + Not<Output=Self>
  13. + BitAnd<Output=Self>
  14. + BitOr<Output=Self>
  15. + BitXor<Output=Self>
  16. + Shl<usize, Output=Self>
  17. + Shr<usize, Output=Self>
  18. + CheckedAdd<Output=Self>
  19. + CheckedSub<Output=Self>
  20. + CheckedMul<Output=Self>
  21. + CheckedDiv<Output=Self>
  22. + Saturating
  23. {
  24. /// Returns the number of ones in the binary representation of `self`.
  25. ///
  26. /// # Examples
  27. ///
  28. /// ```
  29. /// use num_traits::PrimInt;
  30. ///
  31. /// let n = 0b01001100u8;
  32. ///
  33. /// assert_eq!(n.count_ones(), 3);
  34. /// ```
  35. fn count_ones(self) -> u32;
  36. /// Returns the number of zeros in the binary representation of `self`.
  37. ///
  38. /// # Examples
  39. ///
  40. /// ```
  41. /// use num_traits::PrimInt;
  42. ///
  43. /// let n = 0b01001100u8;
  44. ///
  45. /// assert_eq!(n.count_zeros(), 5);
  46. /// ```
  47. fn count_zeros(self) -> u32;
  48. /// Returns the number of leading zeros in the binary representation
  49. /// of `self`.
  50. ///
  51. /// # Examples
  52. ///
  53. /// ```
  54. /// use num_traits::PrimInt;
  55. ///
  56. /// let n = 0b0101000u16;
  57. ///
  58. /// assert_eq!(n.leading_zeros(), 10);
  59. /// ```
  60. fn leading_zeros(self) -> u32;
  61. /// Returns the number of trailing zeros in the binary representation
  62. /// of `self`.
  63. ///
  64. /// # Examples
  65. ///
  66. /// ```
  67. /// use num_traits::PrimInt;
  68. ///
  69. /// let n = 0b0101000u16;
  70. ///
  71. /// assert_eq!(n.trailing_zeros(), 3);
  72. /// ```
  73. fn trailing_zeros(self) -> u32;
  74. /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
  75. /// the truncated bits to the end of the resulting integer.
  76. ///
  77. /// # Examples
  78. ///
  79. /// ```
  80. /// use num_traits::PrimInt;
  81. ///
  82. /// let n = 0x0123456789ABCDEFu64;
  83. /// let m = 0x3456789ABCDEF012u64;
  84. ///
  85. /// assert_eq!(n.rotate_left(12), m);
  86. /// ```
  87. fn rotate_left(self, n: u32) -> Self;
  88. /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
  89. /// the truncated bits to the beginning of the resulting integer.
  90. ///
  91. /// # Examples
  92. ///
  93. /// ```
  94. /// use num_traits::PrimInt;
  95. ///
  96. /// let n = 0x0123456789ABCDEFu64;
  97. /// let m = 0xDEF0123456789ABCu64;
  98. ///
  99. /// assert_eq!(n.rotate_right(12), m);
  100. /// ```
  101. fn rotate_right(self, n: u32) -> Self;
  102. /// Shifts the bits to the left by a specified amount amount, `n`, filling
  103. /// zeros in the least significant bits.
  104. ///
  105. /// This is bitwise equivalent to signed `Shl`.
  106. ///
  107. /// # Examples
  108. ///
  109. /// ```
  110. /// use num_traits::PrimInt;
  111. ///
  112. /// let n = 0x0123456789ABCDEFu64;
  113. /// let m = 0x3456789ABCDEF000u64;
  114. ///
  115. /// assert_eq!(n.signed_shl(12), m);
  116. /// ```
  117. fn signed_shl(self, n: u32) -> Self;
  118. /// Shifts the bits to the right by a specified amount amount, `n`, copying
  119. /// the "sign bit" in the most significant bits even for unsigned types.
  120. ///
  121. /// This is bitwise equivalent to signed `Shr`.
  122. ///
  123. /// # Examples
  124. ///
  125. /// ```
  126. /// use num_traits::PrimInt;
  127. ///
  128. /// let n = 0xFEDCBA9876543210u64;
  129. /// let m = 0xFFFFEDCBA9876543u64;
  130. ///
  131. /// assert_eq!(n.signed_shr(12), m);
  132. /// ```
  133. fn signed_shr(self, n: u32) -> Self;
  134. /// Shifts the bits to the left by a specified amount amount, `n`, filling
  135. /// zeros in the least significant bits.
  136. ///
  137. /// This is bitwise equivalent to unsigned `Shl`.
  138. ///
  139. /// # Examples
  140. ///
  141. /// ```
  142. /// use num_traits::PrimInt;
  143. ///
  144. /// let n = 0x0123456789ABCDEFi64;
  145. /// let m = 0x3456789ABCDEF000i64;
  146. ///
  147. /// assert_eq!(n.unsigned_shl(12), m);
  148. /// ```
  149. fn unsigned_shl(self, n: u32) -> Self;
  150. /// Shifts the bits to the right by a specified amount amount, `n`, filling
  151. /// zeros in the most significant bits.
  152. ///
  153. /// This is bitwise equivalent to unsigned `Shr`.
  154. ///
  155. /// # Examples
  156. ///
  157. /// ```
  158. /// use num_traits::PrimInt;
  159. ///
  160. /// let n = 0xFEDCBA9876543210i64;
  161. /// let m = 0x000FEDCBA9876543i64;
  162. ///
  163. /// assert_eq!(n.unsigned_shr(12), m);
  164. /// ```
  165. fn unsigned_shr(self, n: u32) -> Self;
  166. /// Reverses the byte order of the integer.
  167. ///
  168. /// # Examples
  169. ///
  170. /// ```
  171. /// use num_traits::PrimInt;
  172. ///
  173. /// let n = 0x0123456789ABCDEFu64;
  174. /// let m = 0xEFCDAB8967452301u64;
  175. ///
  176. /// assert_eq!(n.swap_bytes(), m);
  177. /// ```
  178. fn swap_bytes(self) -> Self;
  179. /// Convert an integer from big endian to the target's endianness.
  180. ///
  181. /// On big endian this is a no-op. On little endian the bytes are swapped.
  182. ///
  183. /// # Examples
  184. ///
  185. /// ```
  186. /// use num_traits::PrimInt;
  187. ///
  188. /// let n = 0x0123456789ABCDEFu64;
  189. ///
  190. /// if cfg!(target_endian = "big") {
  191. /// assert_eq!(u64::from_be(n), n)
  192. /// } else {
  193. /// assert_eq!(u64::from_be(n), n.swap_bytes())
  194. /// }
  195. /// ```
  196. fn from_be(x: Self) -> Self;
  197. /// Convert an integer from little endian to the target's endianness.
  198. ///
  199. /// On little endian this is a no-op. On big endian the bytes are swapped.
  200. ///
  201. /// # Examples
  202. ///
  203. /// ```
  204. /// use num_traits::PrimInt;
  205. ///
  206. /// let n = 0x0123456789ABCDEFu64;
  207. ///
  208. /// if cfg!(target_endian = "little") {
  209. /// assert_eq!(u64::from_le(n), n)
  210. /// } else {
  211. /// assert_eq!(u64::from_le(n), n.swap_bytes())
  212. /// }
  213. /// ```
  214. fn from_le(x: Self) -> Self;
  215. /// Convert `self` to big endian from the target's endianness.
  216. ///
  217. /// On big endian this is a no-op. On little endian the bytes are swapped.
  218. ///
  219. /// # Examples
  220. ///
  221. /// ```
  222. /// use num_traits::PrimInt;
  223. ///
  224. /// let n = 0x0123456789ABCDEFu64;
  225. ///
  226. /// if cfg!(target_endian = "big") {
  227. /// assert_eq!(n.to_be(), n)
  228. /// } else {
  229. /// assert_eq!(n.to_be(), n.swap_bytes())
  230. /// }
  231. /// ```
  232. fn to_be(self) -> Self;
  233. /// Convert `self` to little endian from the target's endianness.
  234. ///
  235. /// On little endian this is a no-op. On big endian the bytes are swapped.
  236. ///
  237. /// # Examples
  238. ///
  239. /// ```
  240. /// use num_traits::PrimInt;
  241. ///
  242. /// let n = 0x0123456789ABCDEFu64;
  243. ///
  244. /// if cfg!(target_endian = "little") {
  245. /// assert_eq!(n.to_le(), n)
  246. /// } else {
  247. /// assert_eq!(n.to_le(), n.swap_bytes())
  248. /// }
  249. /// ```
  250. fn to_le(self) -> Self;
  251. /// Raises self to the power of `exp`, using exponentiation by squaring.
  252. ///
  253. /// # Examples
  254. ///
  255. /// ```
  256. /// use num_traits::PrimInt;
  257. ///
  258. /// assert_eq!(2i32.pow(4), 16);
  259. /// ```
  260. fn pow(self, mut exp: u32) -> Self;
  261. }
  262. macro_rules! prim_int_impl {
  263. ($T:ty, $S:ty, $U:ty) => (
  264. impl PrimInt for $T {
  265. fn count_ones(self) -> u32 {
  266. <$T>::count_ones(self)
  267. }
  268. fn count_zeros(self) -> u32 {
  269. <$T>::count_zeros(self)
  270. }
  271. fn leading_zeros(self) -> u32 {
  272. <$T>::leading_zeros(self)
  273. }
  274. fn trailing_zeros(self) -> u32 {
  275. <$T>::trailing_zeros(self)
  276. }
  277. fn rotate_left(self, n: u32) -> Self {
  278. <$T>::rotate_left(self, n)
  279. }
  280. fn rotate_right(self, n: u32) -> Self {
  281. <$T>::rotate_right(self, n)
  282. }
  283. fn signed_shl(self, n: u32) -> Self {
  284. ((self as $S) << n) as $T
  285. }
  286. fn signed_shr(self, n: u32) -> Self {
  287. ((self as $S) >> n) as $T
  288. }
  289. fn unsigned_shl(self, n: u32) -> Self {
  290. ((self as $U) << n) as $T
  291. }
  292. fn unsigned_shr(self, n: u32) -> Self {
  293. ((self as $U) >> n) as $T
  294. }
  295. fn swap_bytes(self) -> Self {
  296. <$T>::swap_bytes(self)
  297. }
  298. fn from_be(x: Self) -> Self {
  299. <$T>::from_be(x)
  300. }
  301. fn from_le(x: Self) -> Self {
  302. <$T>::from_le(x)
  303. }
  304. fn to_be(self) -> Self {
  305. <$T>::to_be(self)
  306. }
  307. fn to_le(self) -> Self {
  308. <$T>::to_le(self)
  309. }
  310. fn pow(self, exp: u32) -> Self {
  311. <$T>::pow(self, exp)
  312. }
  313. }
  314. )
  315. }
  316. // prim_int_impl!(type, signed, unsigned);
  317. prim_int_impl!(u8, i8, u8);
  318. prim_int_impl!(u16, i16, u16);
  319. prim_int_impl!(u32, i32, u32);
  320. prim_int_impl!(u64, i64, u64);
  321. prim_int_impl!(usize, isize, usize);
  322. prim_int_impl!(i8, i8, u8);
  323. prim_int_impl!(i16, i16, u16);
  324. prim_int_impl!(i32, i32, u32);
  325. prim_int_impl!(i64, i64, u64);
  326. prim_int_impl!(isize, isize, usize);