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 fn div(self, den: $res) -> Self::Output {
183 if den.is_nan() {
184 BigDecimal::zero()
185 } else if den == 1.0 {
186 self.clone()
187 } else if den == 0.5 {
188 self.double()
189 } else if den == 2.0 {
190 self.half()
191 } else if den == -1.0 {
192 -self
193 } else if den < 0.0 && self.is_positive() {
194 -(self / -den)
195 } else {
196 self / BigDecimal::try_from(den).unwrap()
198 }
199 }
200 }
201
202 impl<'a> Div<&'a BigDecimal> for $res {
203 type Output = BigDecimal;
204 #[inline(always)]
205 fn div(self, den: &'a BigDecimal) -> Self::Output {
206 if self.is_nan() {
207 BigDecimal::zero()
208 } else {
209 BigDecimal::try_from(self).unwrap() / den
210 }
211 }
212 }
213
214 impl Div<BigDecimal> for $res {
215 type Output = BigDecimal;
216 #[inline(always)]
217 fn div(self, den: BigDecimal) -> Self::Output {
218 if self.is_nan() {
219 BigDecimal::zero()
220 } else {
221 BigDecimal::try_from(self).unwrap() / den
222 }
223 }
224 }
225 };
226}
227
228macro_rules! forward_primitive_types {
229 (floats => $macro_name:ident) => {
230 $macro_name!(f32);
231 $macro_name!(f64);
232 };
233 (ints => $macro_name:ident) => {
234 $macro_name!(i8);
235 $macro_name!(i16);
236 $macro_name!(i32);
237 $macro_name!(i64);
238 };
239 (uints => $macro_name:ident) => {
240 $macro_name!(u8);
241 $macro_name!(u16);
242 $macro_name!(u32);
243 $macro_name!(u64);
244 };
245}
246
247macro_rules! impl_div_for_primitives {
248 () => {
249 forward_primitive_types!(floats => impl_div_for_float_primitive);
250 forward_primitive_types!(ints => impl_div_for_int_primitive);
251 forward_primitive_types!(uints => impl_div_for_uint_primitive);
252 };
253}