identities.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. use core::num::Wrapping;
  2. use core::ops::{Add, Mul};
  3. /// Defines an additive identity element for `Self`.
  4. ///
  5. /// # Laws
  6. ///
  7. /// ```{.text}
  8. /// a + 0 = a ∀ a ∈ Self
  9. /// 0 + a = a ∀ a ∈ Self
  10. /// ```
  11. pub trait Zero: Sized + Add<Self, Output = Self> {
  12. /// Returns the additive identity element of `Self`, `0`.
  13. /// # Purity
  14. ///
  15. /// This function should return the same result at all times regardless of
  16. /// external mutable state, for example values stored in TLS or in
  17. /// `static mut`s.
  18. // This cannot be an associated constant, because of bignums.
  19. fn zero() -> Self;
  20. /// Sets `self` to the additive identity element of `Self`, `0`.
  21. fn set_zero(&mut self) {
  22. *self = Zero::zero();
  23. }
  24. /// Returns `true` if `self` is equal to the additive identity.
  25. fn is_zero(&self) -> bool;
  26. }
  27. macro_rules! zero_impl {
  28. ($t:ty, $v:expr) => {
  29. impl Zero for $t {
  30. #[inline]
  31. fn zero() -> $t {
  32. $v
  33. }
  34. #[inline]
  35. fn is_zero(&self) -> bool {
  36. *self == $v
  37. }
  38. }
  39. };
  40. }
  41. zero_impl!(usize, 0);
  42. zero_impl!(u8, 0);
  43. zero_impl!(u16, 0);
  44. zero_impl!(u32, 0);
  45. zero_impl!(u64, 0);
  46. #[cfg(has_i128)]
  47. zero_impl!(u128, 0);
  48. zero_impl!(isize, 0);
  49. zero_impl!(i8, 0);
  50. zero_impl!(i16, 0);
  51. zero_impl!(i32, 0);
  52. zero_impl!(i64, 0);
  53. #[cfg(has_i128)]
  54. zero_impl!(i128, 0);
  55. zero_impl!(f32, 0.0);
  56. zero_impl!(f64, 0.0);
  57. impl<T: Zero> Zero for Wrapping<T>
  58. where
  59. Wrapping<T>: Add<Output = Wrapping<T>>,
  60. {
  61. fn is_zero(&self) -> bool {
  62. self.0.is_zero()
  63. }
  64. fn set_zero(&mut self) {
  65. self.0.set_zero();
  66. }
  67. fn zero() -> Self {
  68. Wrapping(T::zero())
  69. }
  70. }
  71. /// Defines a multiplicative identity element for `Self`.
  72. ///
  73. /// # Laws
  74. ///
  75. /// ```{.text}
  76. /// a * 1 = a ∀ a ∈ Self
  77. /// 1 * a = a ∀ a ∈ Self
  78. /// ```
  79. pub trait One: Sized + Mul<Self, Output = Self> {
  80. /// Returns the multiplicative identity element of `Self`, `1`.
  81. ///
  82. /// # Purity
  83. ///
  84. /// This function should return the same result at all times regardless of
  85. /// external mutable state, for example values stored in TLS or in
  86. /// `static mut`s.
  87. // This cannot be an associated constant, because of bignums.
  88. fn one() -> Self;
  89. /// Sets `self` to the multiplicative identity element of `Self`, `1`.
  90. fn set_one(&mut self) {
  91. *self = One::one();
  92. }
  93. /// Returns `true` if `self` is equal to the multiplicative identity.
  94. ///
  95. /// For performance reasons, it's best to implement this manually.
  96. /// After a semver bump, this method will be required, and the
  97. /// `where Self: PartialEq` bound will be removed.
  98. #[inline]
  99. fn is_one(&self) -> bool
  100. where
  101. Self: PartialEq,
  102. {
  103. *self == Self::one()
  104. }
  105. }
  106. macro_rules! one_impl {
  107. ($t:ty, $v:expr) => {
  108. impl One for $t {
  109. #[inline]
  110. fn one() -> $t {
  111. $v
  112. }
  113. #[inline]
  114. fn is_one(&self) -> bool {
  115. *self == $v
  116. }
  117. }
  118. };
  119. }
  120. one_impl!(usize, 1);
  121. one_impl!(u8, 1);
  122. one_impl!(u16, 1);
  123. one_impl!(u32, 1);
  124. one_impl!(u64, 1);
  125. #[cfg(has_i128)]
  126. one_impl!(u128, 1);
  127. one_impl!(isize, 1);
  128. one_impl!(i8, 1);
  129. one_impl!(i16, 1);
  130. one_impl!(i32, 1);
  131. one_impl!(i64, 1);
  132. #[cfg(has_i128)]
  133. one_impl!(i128, 1);
  134. one_impl!(f32, 1.0);
  135. one_impl!(f64, 1.0);
  136. impl<T: One> One for Wrapping<T>
  137. where
  138. Wrapping<T>: Mul<Output = Wrapping<T>>,
  139. {
  140. fn set_one(&mut self) {
  141. self.0.set_one();
  142. }
  143. fn one() -> Self {
  144. Wrapping(T::one())
  145. }
  146. }
  147. // Some helper functions provided for backwards compatibility.
  148. /// Returns the additive identity, `0`.
  149. #[inline(always)]
  150. pub fn zero<T: Zero>() -> T {
  151. Zero::zero()
  152. }
  153. /// Returns the multiplicative identity, `1`.
  154. #[inline(always)]
  155. pub fn one<T: One>() -> T {
  156. One::one()
  157. }
  158. #[test]
  159. fn wrapping_identities() {
  160. macro_rules! test_wrapping_identities {
  161. ($($t:ty)+) => {
  162. $(
  163. assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
  164. assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
  165. assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
  166. assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
  167. )+
  168. };
  169. }
  170. test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
  171. }
  172. #[test]
  173. fn wrapping_is_zero() {
  174. fn require_zero<T: Zero>(_: &T) {}
  175. require_zero(&Wrapping(42));
  176. }
  177. #[test]
  178. fn wrapping_is_one() {
  179. fn require_one<T: One>(_: &T) {}
  180. require_one(&Wrapping(42));
  181. }