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