1use std::cmp::Ordering;
5use std::fmt;
6use std::ops::{Add, AddAssign, Mul, Neg};
7
8use crate::{Sign, Signed, Negateable};
9
10#[derive(Copy, Clone)]
18pub struct Zero;
19
20impl num_traits::Zero for Zero {
21 fn zero() -> Self {
22 Self
23 }
24
25 fn is_zero(&self) -> bool {
26 true
27 }
28}
29
30impl Default for Zero {
31 fn default() -> Self {
32 Zero
33 }
34}
35
36impl Add for Zero {
37 type Output = Self;
38
39 fn add(self, _: Self) -> Self::Output {
40 Self
41 }
42}
43
44impl Mul for Zero {
45 type Output = Self;
46
47 fn mul(self, _: Self) -> Self::Output {
48 Self
49 }
50}
51
52impl Eq for Zero {}
53
54impl PartialEq for Zero {
55 fn eq(&self, _: &Self) -> bool {
56 true
57 }
58}
59
60impl PartialOrd for Zero {
61 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
62 Some(Ordering::Equal)
63 }
64}
65
66impl Ord for Zero {
67 fn cmp(&self, _: &Self) -> Ordering {
68 Ordering::Equal
69 }
70}
71
72impl Signed for Zero {
73 fn signum(&self) -> Sign {
74 Sign::Zero
75 }
76}
77
78impl Negateable for Zero {
79 #[inline]
80 fn negate(&mut self) {
81 }
82}
83
84impl Neg for Zero {
85 type Output = Self;
86
87 fn neg(self) -> Self::Output {
88 self
89 }
90}
91
92impl fmt::Debug for Zero {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 <Self as fmt::Display>::fmt(self, f)
95 }
96}
97
98impl fmt::Display for Zero {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 f.write_str("0")
101 }
102}
103
104macro_rules! define_ops {
105 ($primitive:ident) => {
106 impl From<Zero> for $primitive {
107 fn from(_: Zero) -> Self {
108 0
109 }
110 }
111
112 impl From<&Zero> for $primitive {
113 fn from(_: &Zero) -> Self {
114 0
115 }
116 }
117
118 impl Add<Zero> for $primitive {
119 type Output = Self;
120
121 fn add(self, _: Zero) -> Self::Output {
122 self
123 }
124 }
125
126 impl Add<&Zero> for $primitive {
127 type Output = Self;
128
129 fn add(self, _: &Zero) -> Self::Output {
130 self
131 }
132 }
133
134 impl AddAssign<&Zero> for $primitive {
135 fn add_assign(&mut self, _: &Zero) {
136 }
137 }
138
139 impl Mul<Zero> for $primitive {
140 type Output = Self;
141
142 fn mul(self, _: Zero) -> Self::Output {
143 0
144 }
145 }
146
147 impl Mul<&Zero> for $primitive {
148 type Output = Self;
149
150 fn mul(self, _: &Zero) -> Self::Output {
151 0
152 }
153 }
154
155 impl Mul<&Zero> for &$primitive {
156 type Output = $primitive;
157
158 fn mul(self, _: &Zero) -> Self::Output {
159 0
160 }
161 }
162 }
163}
164
165define_ops!(i8);
166define_ops!(i16);
167define_ops!(i32);
168define_ops!(i64);
169define_ops!(i128);
170define_ops!(u8);
171define_ops!(u16);
172define_ops!(u32);
173define_ops!(u64);
174define_ops!(u128);
175
176#[cfg(test)]
177mod test {
178 use crate::{Abs, Sign, Signed, Zero};
179
180 #[test]
181 fn test() {
182 assert_eq!(Zero, num_traits::Zero::zero());
183 assert!(num_traits::Zero::is_zero(&Zero));
184 assert_eq!(Zero + Zero, Zero);
185 assert_eq!(Zero * Zero, Zero);
186 assert_eq!(Zero.abs(), Zero);
187 assert_eq!(Zero.signum(), Sign::Zero);
188 }
189
190 #[test]
191 fn test_integer() {
192 assert_eq!(1 + Zero, 1);
193 assert_eq!(-1 + Zero, -1);
194 assert_eq!(894 * Zero, 0);
195 assert_eq!(-894 * &Zero, 0);
196 assert_eq!(0_u8 * &Zero, 0);
197 }
198}