123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- use core::num::Wrapping;
- use core::ops::{Add, Mul};
- /// Defines an additive identity element for `Self`.
- ///
- /// # Laws
- ///
- /// ```{.text}
- /// a + 0 = a ∀ a ∈ Self
- /// 0 + a = a ∀ a ∈ Self
- /// ```
- pub trait Zero: Sized + Add<Self, Output = Self> {
- /// Returns the additive identity element of `Self`, `0`.
- /// # Purity
- ///
- /// This function should return the same result at all times regardless of
- /// external mutable state, for example values stored in TLS or in
- /// `static mut`s.
- // This cannot be an associated constant, because of bignums.
- fn zero() -> Self;
- /// Sets `self` to the additive identity element of `Self`, `0`.
- fn set_zero(&mut self) {
- *self = Zero::zero();
- }
- /// Returns `true` if `self` is equal to the additive identity.
- fn is_zero(&self) -> bool;
- }
- macro_rules! zero_impl {
- ($t:ty, $v:expr) => {
- impl Zero for $t {
- #[inline]
- fn zero() -> $t {
- $v
- }
- #[inline]
- fn is_zero(&self) -> bool {
- *self == $v
- }
- }
- };
- }
- zero_impl!(usize, 0);
- zero_impl!(u8, 0);
- zero_impl!(u16, 0);
- zero_impl!(u32, 0);
- zero_impl!(u64, 0);
- #[cfg(has_i128)]
- zero_impl!(u128, 0);
- zero_impl!(isize, 0);
- zero_impl!(i8, 0);
- zero_impl!(i16, 0);
- zero_impl!(i32, 0);
- zero_impl!(i64, 0);
- #[cfg(has_i128)]
- zero_impl!(i128, 0);
- zero_impl!(f32, 0.0);
- zero_impl!(f64, 0.0);
- impl<T: Zero> Zero for Wrapping<T>
- where
- Wrapping<T>: Add<Output = Wrapping<T>>,
- {
- fn is_zero(&self) -> bool {
- self.0.is_zero()
- }
- fn set_zero(&mut self) {
- self.0.set_zero();
- }
- fn zero() -> Self {
- Wrapping(T::zero())
- }
- }
- /// Defines a multiplicative identity element for `Self`.
- ///
- /// # Laws
- ///
- /// ```{.text}
- /// a * 1 = a ∀ a ∈ Self
- /// 1 * a = a ∀ a ∈ Self
- /// ```
- pub trait One: Sized + Mul<Self, Output = Self> {
- /// Returns the multiplicative identity element of `Self`, `1`.
- ///
- /// # Purity
- ///
- /// This function should return the same result at all times regardless of
- /// external mutable state, for example values stored in TLS or in
- /// `static mut`s.
- // This cannot be an associated constant, because of bignums.
- fn one() -> Self;
- /// Sets `self` to the multiplicative identity element of `Self`, `1`.
- fn set_one(&mut self) {
- *self = One::one();
- }
- /// Returns `true` if `self` is equal to the multiplicative identity.
- ///
- /// For performance reasons, it's best to implement this manually.
- /// After a semver bump, this method will be required, and the
- /// `where Self: PartialEq` bound will be removed.
- #[inline]
- fn is_one(&self) -> bool
- where
- Self: PartialEq,
- {
- *self == Self::one()
- }
- }
- macro_rules! one_impl {
- ($t:ty, $v:expr) => {
- impl One for $t {
- #[inline]
- fn one() -> $t {
- $v
- }
- #[inline]
- fn is_one(&self) -> bool {
- *self == $v
- }
- }
- };
- }
- one_impl!(usize, 1);
- one_impl!(u8, 1);
- one_impl!(u16, 1);
- one_impl!(u32, 1);
- one_impl!(u64, 1);
- #[cfg(has_i128)]
- one_impl!(u128, 1);
- one_impl!(isize, 1);
- one_impl!(i8, 1);
- one_impl!(i16, 1);
- one_impl!(i32, 1);
- one_impl!(i64, 1);
- #[cfg(has_i128)]
- one_impl!(i128, 1);
- one_impl!(f32, 1.0);
- one_impl!(f64, 1.0);
- impl<T: One> One for Wrapping<T>
- where
- Wrapping<T>: Mul<Output = Wrapping<T>>,
- {
- fn set_one(&mut self) {
- self.0.set_one();
- }
- fn one() -> Self {
- Wrapping(T::one())
- }
- }
- // Some helper functions provided for backwards compatibility.
- /// Returns the additive identity, `0`.
- #[inline(always)]
- pub fn zero<T: Zero>() -> T {
- Zero::zero()
- }
- /// Returns the multiplicative identity, `1`.
- #[inline(always)]
- pub fn one<T: One>() -> T {
- One::one()
- }
- #[test]
- fn wrapping_identities() {
- macro_rules! test_wrapping_identities {
- ($($t:ty)+) => {
- $(
- assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
- assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
- assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
- assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
- )+
- };
- }
- test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
- }
- #[test]
- fn wrapping_is_zero() {
- fn require_zero<T: Zero>(_: &T) {}
- require_zero(&Wrapping(42));
- }
- #[test]
- fn wrapping_is_one() {
- fn require_one<T: One>(_: &T) {}
- require_one(&Wrapping(42));
- }
|