1#![allow(unused, non_camel_case_types)]
10
11macro_rules! upcasted_op {
36 (
37 add_err($lhs:expr, $rhs:expr) $ba:ty => $up:ty) => {
40 if $crate::cif!(diff($ba, $up)) {
41 #[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
42 {
43 $lhs + $rhs
44 }
45 #[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
46 unsafe {
48 $lhs.unchecked_add($rhs)
49 }
50 } else {
51 if let Some(sum) = $lhs.checked_add($rhs) {
52 sum
53 } else {
54 return Err($crate::NumError::Overflow(None));
55 }
56 }
57 };
58 (mul_err($lhs:expr, $rhs:expr) $ba:ty => $up:ty) => {
59 if $crate::cif!(diff($ba, $up)) {
60 #[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
61 {
62 $lhs * $rhs
63 }
64 #[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
65 unsafe {
67 $lhs.unchecked_mul($rhs)
68 }
69 } else {
70 if let Some(product) = $lhs.checked_mul($rhs) {
71 product
72 } else {
73 return Err($crate::NumError::Overflow(None));
74 }
75 }
76 };
77 (
78 reduced_add_err($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
83 if $crate::cif!(diff($ba, $up)) {
84 #[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
85 {
86 $lhs + $rhs
87 }
88 #[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
89 unsafe {
91 $lhs.unchecked_add($rhs)
92 }
93 } else {
94 if let Some(sum) = ($lhs % $modulus).checked_add($rhs % $modulus) {
96 sum
97 } else {
98 return Err($crate::NumError::Overflow(None));
99 }
100 }
101 };
102 (
103 reduced_add($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
105 if $crate::cif!(diff($ba, $up)) {
106 #[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
107 {
108 $lhs + $rhs
109 }
110 #[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
111 unsafe {
113 $lhs.unchecked_add($rhs)
114 }
115 } else {
116 ($lhs % $modulus) + ($rhs % $modulus)
118 }
119 };
120 (reduced_mul_err($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
121 if $crate::cif!(diff($ba, $up)) {
122 #[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
123 {
124 $lhs * $rhs
125 }
126 #[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
127 unsafe {
129 $lhs.unchecked_mul($rhs)
130 }
131 } else {
132 if let Some(product) = ($lhs % $modulus).checked_mul($rhs % $modulus) {
134 product
135 } else {
136 return Err($crate::NumError::Overflow(None));
137 }
138 }
139 };
140 (reduced_mul($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
141 if $crate::cif!(diff($ba, $up)) {
142 #[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
143 {
144 $lhs * $rhs
145 }
146 #[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
147 unsafe {
149 $lhs.unchecked_mul($rhs)
150 }
151 } else {
152 ($lhs % $modulus) + ($rhs % $modulus)
154 }
155 };
156}
157pub(crate) use upcasted_op;
158
159macro_rules! impl_ops {
170 ($W:ident: $($T:ty : $cap:literal ),+) => { $(
171 $crate::num::impl_ops![@common $W($T:$cap)];
172 $crate::num::impl_ops![@neg $W($T:$cap)];
173 )+ };
174 ($W:ident: (no_neg) $($T:ty : $cap:literal),+) => { $(
175 $crate::num::impl_ops![@common $W($T:$cap)];
176 )+ };
177
178 (@common $W:ident($T:ty : $cap:literal)) => {
179 $crate::num::impl_ops![@op $W($T:$cap), Add, add];
180 $crate::num::impl_ops![@op $W($T:$cap), Sub, sub];
181 $crate::num::impl_ops![@op $W($T:$cap), Mul, mul];
182 $crate::num::impl_ops![@op $W($T:$cap), Div, div];
183 $crate::num::impl_ops![@op $W($T:$cap), Rem, rem];
184 $crate::num::impl_ops![@op_assign $W($T:$cap), AddAssign, add_assign];
185 $crate::num::impl_ops![@op_assign $W($T:$cap), SubAssign, sub_assign];
186 $crate::num::impl_ops![@op_assign $W($T:$cap), MulAssign, mul_assign];
187 $crate::num::impl_ops![@op_assign $W($T:$cap), DivAssign, div_assign];
188 $crate::num::impl_ops![@op_assign $W($T:$cap), RemAssign, rem_assign];
189 };
190 (@neg $W:ident($T:ty : $cap:literal)) => {
191 #[cfg(feature = $cap )]
192 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
193 impl core::ops::Neg for $W<$T> {
194 type Output = $W<$T>;
195 fn neg(self) -> $W<$T> { $W(self.0.neg()) }
196 }
197 };
198
199 (
200 @op $W:ident($T:ty : $cap:literal), $trait:ident, $fn:ident) => {
205 #[cfg(feature = $cap )]
207 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
208 impl core::ops::$trait for $W<$T> {
209 $crate::num::impl_ops![@op_body $W($T), $fn, $W<$T>, 0];
210 }
211 #[cfg(feature = $cap )]
212 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
213 impl<'s> core::ops::$trait<$W<$T>> for &'s $W<$T> {
214 $crate::num::impl_ops![@op_body $W($T), $fn, $W<$T>, 0];
215 }
216 #[cfg(feature = $cap )]
217 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
218 impl<'o> core::ops::$trait<&'o $W<$T>> for $W<$T> {
219 $crate::num::impl_ops![@op_body $W($T), $fn, &'o $W<$T>, 0];
220 }
221 #[cfg(feature = $cap )]
222 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
223 impl<'s, 'o> core::ops::$trait<&'o $W<$T>> for &'s $W<$T> {
224 $crate::num::impl_ops![@op_body $W($T), $fn, &'o $W<$T>, 0];
225 }
226 #[cfg(feature = $cap )]
228 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
229 impl core::ops::$trait<$T> for $W<$T> {
230 $crate::num::impl_ops![@op_body $W($T), $fn, $T];
231 }
232 #[cfg(feature = $cap )]
233 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
234 impl<'s> core::ops::$trait<$T> for &'s $W<$T> {
235 $crate::num::impl_ops![@op_body $W($T), $fn, $T];
236 }
237 #[cfg(feature = $cap )]
238 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
239 impl<'o> core::ops::$trait<&'o $T> for $W<$T> {
240 $crate::num::impl_ops![@op_body $W($T), $fn, &'o $T];
241 }
242 #[cfg(feature = $cap )]
243 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
244 impl<'s, 'o> core::ops::$trait<&'o $T> for &'s $W<$T> {
245 $crate::num::impl_ops![@op_body $W($T), $fn, &'o $T];
246 }
247 };
248 (@op_body $W:ident($T:ty), $fn:ident, $other:ty $(, $other_field:tt)?) => {
249 type Output = $W<$T>;
250 fn $fn(self, other: $other) -> $W<$T> { $W(self.0.$fn(other$(. $other_field)?)) }
251 };
252
253 (@op_assign $W:ident($T:ty : $cap:literal), $trait:ident, $fn:ident) => { $crate::paste! {
254 #[cfg(feature = $cap )]
256 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
257 impl core::ops::$trait for $W<$T> {
258 fn $fn(&mut self, other: $W<$T>) { self.0.$fn(other.0); }
259 }
260 #[cfg(feature = $cap )]
261 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
262 impl<'o> core::ops::$trait<&'o $W<$T>> for $W<$T> {
263 fn $fn(&mut self, other: &'o $W<$T>) { self.0.$fn(other.0); }
264 }
265 #[cfg(feature = $cap )]
267 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
268 impl core::ops::$trait<$T> for $W<$T> {
269 fn $fn(&mut self, other: $T) { self.0.$fn(other); }
270 }
271 #[cfg(feature = $cap )]
272 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
273 impl<'o> core::ops::$trait<&'o $T> for $W<$T> {
274 fn $fn(&mut self, other: &'o $T) { self.0.$fn(other); }
275 }
276 }};
277}
278pub(crate) use impl_ops;