mod.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. use core::ops;
  2. macro_rules! hty {
  3. ($ty:ty) => {
  4. <$ty as LargeInt>::HighHalf
  5. }
  6. }
  7. macro_rules! os_ty {
  8. ($ty:ty) => {
  9. <$ty as Int>::OtherSign
  10. }
  11. }
  12. pub mod mul;
  13. pub mod sdiv;
  14. pub mod shift;
  15. pub mod udiv;
  16. /// Trait for some basic operations on integers
  17. pub trait Int:
  18. Copy +
  19. PartialEq +
  20. PartialOrd +
  21. ops::AddAssign +
  22. ops::Add<Output = Self> +
  23. ops::Sub<Output = Self> +
  24. ops::Div<Output = Self> +
  25. ops::Shl<u32, Output = Self> +
  26. ops::Shr<u32, Output = Self> +
  27. ops::BitOr<Output = Self> +
  28. ops::BitXor<Output = Self> +
  29. ops::BitAnd<Output = Self> +
  30. ops::BitAndAssign +
  31. ops::Not<Output = Self> +
  32. {
  33. /// Type with the same width but other signedness
  34. type OtherSign: Int;
  35. /// Unsigned version of Self
  36. type UnsignedInt: Int;
  37. /// Returns the bitwidth of the int type
  38. fn bits() -> u32;
  39. fn zero() -> Self;
  40. fn one() -> Self;
  41. /// Extracts the sign from self and returns a tuple.
  42. ///
  43. /// # Examples
  44. ///
  45. /// ```rust,ignore
  46. /// let i = -25_i32;
  47. /// let (sign, u) = i.extract_sign();
  48. /// assert_eq!(sign, true);
  49. /// assert_eq!(u, 25_u32);
  50. /// ```
  51. fn extract_sign(self) -> (bool, Self::UnsignedInt);
  52. /// Convert to a signed representation
  53. fn unsigned(self) -> Self::UnsignedInt;
  54. // copied from primitive integers, but put in a trait
  55. fn max_value() -> Self;
  56. fn min_value() -> Self;
  57. fn wrapping_add(self, other: Self) -> Self;
  58. fn wrapping_mul(self, other: Self) -> Self;
  59. }
  60. macro_rules! int_impl {
  61. ($ity:ty, $uty:ty, $bits:expr) => {
  62. impl Int for $uty {
  63. type OtherSign = $ity;
  64. type UnsignedInt = $uty;
  65. fn zero() -> Self {
  66. 0
  67. }
  68. fn one() -> Self {
  69. 1
  70. }
  71. fn bits() -> u32 {
  72. $bits
  73. }
  74. fn extract_sign(self) -> (bool, $uty) {
  75. (false, self)
  76. }
  77. fn unsigned(self) -> $uty {
  78. self
  79. }
  80. fn max_value() -> Self {
  81. <Self>::max_value()
  82. }
  83. fn min_value() -> Self {
  84. <Self>::min_value()
  85. }
  86. fn wrapping_add(self, other: Self) -> Self {
  87. <Self>::wrapping_add(self, other)
  88. }
  89. fn wrapping_mul(self, other: Self) -> Self {
  90. <Self>::wrapping_mul(self, other)
  91. }
  92. }
  93. impl Int for $ity {
  94. type OtherSign = $uty;
  95. type UnsignedInt = $uty;
  96. fn bits() -> u32 {
  97. $bits
  98. }
  99. fn zero() -> Self {
  100. 0
  101. }
  102. fn one() -> Self {
  103. 1
  104. }
  105. fn extract_sign(self) -> (bool, $uty) {
  106. if self < 0 {
  107. (true, (!(self as $uty)).wrapping_add(1))
  108. } else {
  109. (false, self as $uty)
  110. }
  111. }
  112. fn unsigned(self) -> $uty {
  113. self as $uty
  114. }
  115. fn max_value() -> Self {
  116. <Self>::max_value()
  117. }
  118. fn min_value() -> Self {
  119. <Self>::min_value()
  120. }
  121. fn wrapping_add(self, other: Self) -> Self {
  122. <Self>::wrapping_add(self, other)
  123. }
  124. fn wrapping_mul(self, other: Self) -> Self {
  125. <Self>::wrapping_mul(self, other)
  126. }
  127. }
  128. }
  129. }
  130. int_impl!(i32, u32, 32);
  131. int_impl!(i64, u64, 64);
  132. int_impl!(i128, u128, 128);
  133. /// Trait to convert an integer to/from smaller parts
  134. pub trait LargeInt: Int {
  135. type LowHalf: Int;
  136. type HighHalf: Int;
  137. fn low(self) -> Self::LowHalf;
  138. fn low_as_high(low: Self::LowHalf) -> Self::HighHalf;
  139. fn high(self) -> Self::HighHalf;
  140. fn high_as_low(low: Self::HighHalf) -> Self::LowHalf;
  141. fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
  142. }
  143. macro_rules! large_int {
  144. ($ty:ty, $tylow:ty, $tyhigh:ty, $halfbits:expr) => {
  145. impl LargeInt for $ty {
  146. type LowHalf = $tylow;
  147. type HighHalf = $tyhigh;
  148. fn low(self) -> $tylow {
  149. self as $tylow
  150. }
  151. fn low_as_high(low: $tylow) -> $tyhigh {
  152. low as $tyhigh
  153. }
  154. fn high(self) -> $tyhigh {
  155. (self >> $halfbits) as $tyhigh
  156. }
  157. fn high_as_low(high: $tyhigh) -> $tylow {
  158. high as $tylow
  159. }
  160. fn from_parts(low: $tylow, high: $tyhigh) -> $ty {
  161. low as $ty | ((high as $ty) << $halfbits)
  162. }
  163. }
  164. }
  165. }
  166. large_int!(u64, u32, u32, 32);
  167. large_int!(i64, u32, i32, 32);
  168. large_int!(u128, u64, u64, 64);
  169. large_int!(i128, u64, i64, 64);