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