1macro_rules! forward_ref_val_binop {
20 (impl $imp:ident for $res:ty, $method:ident) => {
21 impl<'a> $imp<$res> for &'a $res {
22 type Output = $res;
23
24 #[inline]
25 fn $method(self, other: $res) -> $res {
26 $imp::$method(self, &other)
28 }
29 }
30 };
31}
32
33macro_rules! forward_val_assignop {
59 (impl $imp:ident for $res:ty, $method:ident) => {
60 impl $imp<$res> for $res {
61 #[inline]
62 fn $method(&mut self, other: $res) {
63 $imp::$method(self, &other)
65 }
66 }
67 };
68}
69
70macro_rules! impl_div_for_uint_primitive {
71 ($res:ty) => {
73 impl<'a> Div<$res> for &'a BigDecimal {
74 type Output = BigDecimal;
75
76 #[inline]
77 fn div(self, den: $res) -> Self::Output {
78 if den == 1 {
79 self.clone()
80 } else if den == 2 {
81 self.half()
82 } else {
83 self / BigDecimal::from(den)
84 }
85 }
86 }
87
88 impl<'a> Div<&'a BigDecimal> for $res {
89 type Output = BigDecimal;
90
91 #[inline(always)]
92 fn div(self, den: &'a BigDecimal) -> Self::Output {
93 BigDecimal::from(self) / den
94 }
95 }
96
97 impl Div<BigDecimal> for $res {
98 type Output = BigDecimal;
99
100 #[inline(always)]
101 fn div(self, den: BigDecimal) -> Self::Output {
102 BigDecimal::from(self) / den
103 }
104 }
105 };
106}
107
108macro_rules! impl_div_for_int_primitive {
109 ($res:ty) => {
111 impl<'a> Div<$res> for BigDecimal {
112 type Output = BigDecimal;
113
114 #[inline(always)]
115 fn div(self, den: $res) -> Self::Output {
116 if den < 0 {
117 -Div::div(self, -den)
118 } else if den == 1 {
119 self
120 } else if den == 2 {
121 self.half()
122 } else {
123 self / BigDecimal::from(den)
124 }
125 }
126 }
127
128 impl<'a> Div<$res> for &'a BigDecimal {
129 type Output = BigDecimal;
130
131 #[inline(always)]
132 fn div(self, den: $res) -> Self::Output {
133 if den < 0 {
134 -Div::div(self, -den)
135 } else if den == 1 {
136 self.clone()
137 } else if den == 2 {
138 self.half()
139 } else {
140 self / BigDecimal::from(den)
141 }
142 }
143 }
144
145 impl<'a> Div<&'a BigDecimal> for $res {
146 type Output = BigDecimal;
147
148 #[inline(always)]
149 fn div(self, den: &'a BigDecimal) -> Self::Output {
150 match (self < 0, den.is_negative()) {
151 (true, true) => -self / -den,
152 (true, false) => (-self / den).neg(),
153 (false, true) => (-self / den.abs()),
154 (false, false) => BigDecimal::from(self) / den,
155 }
156 }
157 }
158
159 impl Div<BigDecimal> for $res {
160 type Output = BigDecimal;
161
162 #[inline(always)]
163 fn div(self, den: BigDecimal) -> Self::Output {
164 match (self < 0, den.is_negative()) {
165 (true, true) => -self / -den,
166 (true, false) => (-self / den).neg(),
167 (false, true) => (-self / den.abs()),
168 (false, false) => BigDecimal::from(self) / den,
169 }
170 }
171 }
172 };
173}
174
175macro_rules! impl_div_for_float_primitive {
176 ($res:ty) => {
178 impl<'a> Div<$res> for &'a BigDecimal {
179 type Output = BigDecimal;
180
181 #[inline]
182 #[allow(clippy::float_cmp)]
183 fn div(self, den: $res) -> Self::Output {
184 if den.is_nan() {
185 BigDecimal::zero()
186 } else if den == 1.0 {
187 self.clone()
188 } else if den == 0.5 {
189 self.double()
190 } else if den == 2.0 {
191 self.half()
192 } else if den == -1.0 {
193 -self
194 } else if den < 0.0 && self.is_positive() {
195 -(self / -den)
196 } else {
197 self / BigDecimal::try_from(den).unwrap()
199 }
200 }
201 }
202
203 impl<'a> Div<&'a BigDecimal> for $res {
204 type Output = BigDecimal;
205 #[inline(always)]
206 fn div(self, den: &'a BigDecimal) -> Self::Output {
207 if self.is_nan() {
208 BigDecimal::zero()
209 } else {
210 BigDecimal::try_from(self).unwrap() / den
211 }
212 }
213 }
214
215 impl Div<BigDecimal> for $res {
216 type Output = BigDecimal;
217 #[inline(always)]
218 fn div(self, den: BigDecimal) -> Self::Output {
219 if self.is_nan() {
220 BigDecimal::zero()
221 } else {
222 BigDecimal::try_from(self).unwrap() / den
223 }
224 }
225 }
226 };
227}
228
229macro_rules! forward_primitive_types {
230 (floats => $macro_name:ident) => {
231 $macro_name!(f32);
232 $macro_name!(f64);
233 };
234 (ints => $macro_name:ident) => {
235 $macro_name!(i8);
236 $macro_name!(i16);
237 $macro_name!(i32);
238 $macro_name!(i64);
239 };
240 (uints => $macro_name:ident) => {
241 $macro_name!(u8);
242 $macro_name!(u16);
243 $macro_name!(u32);
244 $macro_name!(u64);
245 };
246}
247
248macro_rules! impl_div_for_primitives {
249 () => {
250 forward_primitive_types!(floats => impl_div_for_float_primitive);
251 forward_primitive_types!(ints => impl_div_for_int_primitive);
252 forward_primitive_types!(uints => impl_div_for_uint_primitive);
253 };
254}