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