1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | macro_rules! impl_trait_op_same( |
4 | ($typ:ty, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident) => { |
5 | impl std::ops::$op for $typ { |
6 | type Output = Self; |
7 | #[inline] |
8 | fn $op_name(self, rhs: $typ) -> Self { |
9 | Self(self.0.$op_name(rhs.0)) |
10 | } |
11 | } |
12 | |
13 | impl std::ops::$op_assign for $typ { |
14 | #[inline] |
15 | fn $op_assign_name(&mut self, rhs: $typ) { |
16 | self.0.$op_assign_name(rhs.0) |
17 | } |
18 | } |
19 | }; |
20 | ); |
21 | |
22 | macro_rules! impl_non_trait_op_same( |
23 | ($typ:ty, $inner:ty) => { |
24 | impl $typ { |
25 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
26 | #[inline] |
27 | pub const fn checked_add(self, rhs: Self) -> Option<Self> { |
28 | match self.0.checked_add(rhs.0) { |
29 | Some(res) if res <= Self::MAX.0 => Some(Self(res)), |
30 | _ => None, |
31 | } |
32 | } |
33 | |
34 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
35 | #[inline] |
36 | pub const fn saturating_add(self, rhs: Self) -> Self { |
37 | let res = self.0.saturating_add(rhs.0); |
38 | if res < Self::MAX.0 { |
39 | Self(res) |
40 | } else { |
41 | Self::MAX |
42 | } |
43 | } |
44 | |
45 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
46 | #[inline] |
47 | pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { |
48 | let self_u128 = self.0 as u128; |
49 | let rhs_128 = rhs.0 as u128; |
50 | let res_u128 = self_u128 + rhs_128; |
51 | if res_u128 <= Self::MAX.0 as u128 { |
52 | (Self(<$inner>::try_from(res_u128).unwrap()), false) |
53 | } else { |
54 | (Self(<$inner>::try_from((res_u128 - Self::MAX.0 as u128 - 1) as u64).unwrap()), true) |
55 | } |
56 | } |
57 | |
58 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
59 | #[inline] |
60 | pub fn wrapping_add(self, rhs: Self) -> Self { |
61 | self.overflowing_add(rhs).0 |
62 | } |
63 | |
64 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
65 | #[inline] |
66 | // FIXME Can't use `map` in a `const fn` as of rustc 1.53.0-beta.2 |
67 | #[allow(clippy::manual_map)] |
68 | pub const fn checked_sub(self, rhs: Self) -> Option<Self> { |
69 | match self.0.checked_sub(rhs.0) { |
70 | Some(res) => Some(Self(res)), |
71 | None => None, |
72 | } |
73 | } |
74 | |
75 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
76 | #[inline] |
77 | pub const fn saturating_sub(self, rhs: Self) -> Self { |
78 | Self(self.0.saturating_sub(rhs.0)) |
79 | } |
80 | |
81 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
82 | #[inline] |
83 | pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) { |
84 | if self.0 >= rhs.0 { |
85 | (Self(self.0 - rhs.0), false) |
86 | } else { |
87 | (Self(Self::MAX.0 - rhs.0 + self.0 + 1), true) |
88 | } |
89 | } |
90 | |
91 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
92 | #[inline] |
93 | pub const fn wrapping_sub(self, rhs: Self) -> Self { |
94 | self.overflowing_sub(rhs).0 |
95 | } |
96 | |
97 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
98 | #[inline] |
99 | pub fn absdiff(self, rhs: Self) -> Self { |
100 | if self > rhs { |
101 | self - rhs |
102 | } else { |
103 | rhs - self |
104 | } |
105 | } |
106 | |
107 | } |
108 | }; |
109 | ); |
110 | |
111 | macro_rules! impl_trait_op_inner_type( |
112 | ($typ:ty, $inner:ty, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident) => { |
113 | impl std::ops::$op<$inner> for $typ { |
114 | type Output = Self; |
115 | #[inline] |
116 | fn $op_name(self, rhs: $inner) -> Self { |
117 | Self(self.0.$op_name(rhs)) |
118 | } |
119 | } |
120 | |
121 | impl std::ops::$op_assign<$inner> for $typ { |
122 | #[inline] |
123 | fn $op_assign_name(&mut self, rhs: $inner) { |
124 | self.0.$op_assign_name(rhs) |
125 | } |
126 | } |
127 | }; |
128 | ); |
129 | |
130 | macro_rules! impl_non_trait_op_inner_type( |
131 | ($typ:ty, $inner:ty) => { |
132 | impl $typ { |
133 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
134 | #[inline] |
135 | pub const fn checked_div(self, rhs: $inner) -> Option<Self> { |
136 | match self.0.checked_div(rhs) { |
137 | Some(val) => Some(Self(val)), |
138 | None => None, |
139 | } |
140 | } |
141 | |
142 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
143 | #[inline] |
144 | pub const fn saturating_div(self, rhs: $inner) -> Self { |
145 | Self(self.0.saturating_div(rhs)) |
146 | } |
147 | |
148 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
149 | #[inline] |
150 | pub const fn checked_mul(self, rhs: $inner) -> Option<Self> { |
151 | match self.0.checked_mul(rhs) { |
152 | Some(res) if res <= Self::MAX.0 => Some(Self(res)), |
153 | _ => None, |
154 | } |
155 | } |
156 | |
157 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
158 | #[inline] |
159 | pub const fn saturating_mul(self, rhs: $inner) -> Self { |
160 | let res = self.0.saturating_mul(rhs); |
161 | if res < Self::MAX.0 { |
162 | Self(res) |
163 | } else { |
164 | Self::MAX |
165 | } |
166 | } |
167 | |
168 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
169 | #[inline] |
170 | pub fn overflowing_mul(self, rhs: $inner) -> (Self, bool) { |
171 | let self_u128 = self.0 as u128; |
172 | let rhs_128 = rhs as u128; |
173 | let res_u128 = self_u128 * rhs_128; |
174 | if res_u128 <= Self::MAX.0 as u128 { |
175 | (Self(<$inner>::try_from(res_u128).unwrap()), false) |
176 | } else { |
177 | (Self(<$inner>::try_from((res_u128 - Self::MAX.0 as u128 - 1) as u64).unwrap()), true) |
178 | } |
179 | } |
180 | |
181 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
182 | #[inline] |
183 | pub fn wrapping_mul(self, rhs: $inner) -> Self { |
184 | self.overflowing_mul(rhs).0 |
185 | } |
186 | |
187 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
188 | #[inline] |
189 | pub const fn checked_rem(self, rhs: $inner) -> Option<Self> { |
190 | match self.0.checked_rem(rhs) { |
191 | Some(val) => Some(Self(val)), |
192 | None => None, |
193 | } |
194 | } |
195 | } |
196 | }; |
197 | ); |
198 | |
199 | macro_rules! impl_unsigned_int_into_signed( |
200 | ($typ:ty) => { |
201 | impl crate::format::SignedIntrinsic for $typ {} |
202 | |
203 | impl crate::format::UnsignedIntoSigned for $typ { |
204 | type Signed = crate::Signed<$typ>; |
205 | |
206 | #[inline] |
207 | fn into_positive(self) -> Self::Signed { |
208 | crate::Signed::Positive(self) |
209 | } |
210 | |
211 | #[inline] |
212 | fn into_negative(self) -> Self::Signed { |
213 | crate::Signed::Negative(self) |
214 | } |
215 | } |
216 | |
217 | impl crate::format::UnsignedIntoSigned for Option<$typ> { |
218 | type Signed = Option<crate::Signed<$typ>>; |
219 | |
220 | #[inline] |
221 | fn into_positive(self) -> Self::Signed { |
222 | Some(self?.into_positive()) |
223 | } |
224 | |
225 | #[inline] |
226 | fn into_negative(self) -> Self::Signed { |
227 | Some(self?.into_negative()) |
228 | } |
229 | } |
230 | |
231 | impl From<$typ> for crate::Signed<$typ> { |
232 | #[inline] |
233 | fn from(v: $typ) -> crate::Signed<$typ> { |
234 | crate::Signed::Positive(v) |
235 | } |
236 | } |
237 | }; |
238 | |
239 | ($typ:ty, $inner:ty) => { |
240 | impl_unsigned_int_into_signed!($typ); |
241 | |
242 | impl crate::Signed<$typ> { |
243 | // rustdoc-stripper-ignore-next |
244 | /// Returns a `Signed` containing the inner type of `self`. |
245 | #[inline] |
246 | pub fn into_inner_signed(self) -> crate::Signed<$inner> { |
247 | use crate::Signed::*; |
248 | match self { |
249 | Positive(new_type) => Positive(*new_type), |
250 | Negative(new_type) => Negative(*new_type), |
251 | } |
252 | } |
253 | } |
254 | }; |
255 | ); |
256 | |
257 | macro_rules! impl_common_ops_for_newtype_uint( |
258 | ($typ:ty, $inner:ty) => { |
259 | impl_common_ops_for_newtype_uint!($typ, $inner, one: 1); |
260 | }; |
261 | |
262 | ($typ:ty, $inner:ty, one: $one:expr$(,)?) => { |
263 | impl $typ { |
264 | pub const ZERO: Self = Self(0); |
265 | pub const NONE: Option<Self> = None; |
266 | // rustdoc-stripper-ignore-next |
267 | /// The unitary value. |
268 | pub const ONE: Self = Self($one); |
269 | |
270 | pub const MAX_SIGNED: crate::Signed::<$typ> = crate::Signed::Positive(Self::MAX); |
271 | pub const MIN_SIGNED: crate::Signed::<$typ> = crate::Signed::Negative(Self::MAX); |
272 | |
273 | #[inline] |
274 | pub const fn is_zero(self) -> bool { |
275 | self.0 == Self::ZERO.0 |
276 | } |
277 | } |
278 | |
279 | impl std::ops::Deref for $typ { |
280 | type Target = $inner; |
281 | |
282 | #[inline] |
283 | fn deref(&self) -> &$inner { |
284 | &self.0 |
285 | } |
286 | } |
287 | |
288 | impl AsRef<$inner> for $typ { |
289 | #[inline] |
290 | fn as_ref(&self) -> &$inner { |
291 | &self.0 |
292 | } |
293 | } |
294 | |
295 | impl From<$typ> for $inner { |
296 | fn from(v: $typ) -> $inner { |
297 | v.0 |
298 | } |
299 | } |
300 | |
301 | impl_trait_op_same!($typ, Add, add, AddAssign, add_assign); |
302 | impl_trait_op_same!($typ, Sub, sub, SubAssign, sub_assign); |
303 | impl std::ops::Div for $typ { |
304 | type Output = $inner; |
305 | #[inline] |
306 | fn div(self, rhs: $typ) -> $inner { |
307 | self.0.div(rhs.0) |
308 | } |
309 | } |
310 | impl std::ops::Rem for $typ { |
311 | type Output = Self; |
312 | #[inline] |
313 | fn rem(self, rhs: Self) -> Self { |
314 | Self(self.0.rem(rhs.0)) |
315 | } |
316 | } |
317 | |
318 | impl_non_trait_op_same!($typ, $inner); |
319 | |
320 | impl_trait_op_inner_type!($typ, $inner, Mul, mul, MulAssign, mul_assign); |
321 | impl std::ops::Mul<$typ> for $inner { |
322 | type Output = $typ; |
323 | #[inline] |
324 | fn mul(self, rhs: $typ) -> $typ { |
325 | rhs.mul(self) |
326 | } |
327 | } |
328 | |
329 | impl_trait_op_inner_type!($typ, $inner, Div, div, DivAssign, div_assign); |
330 | impl_trait_op_inner_type!($typ, $inner, Rem, rem, RemAssign, rem_assign); |
331 | |
332 | impl_non_trait_op_inner_type!($typ, $inner); |
333 | |
334 | impl_unsigned_int_into_signed!($typ, $inner); |
335 | |
336 | impl_signed_ops!($typ, $inner, <$typ>::ZERO); |
337 | |
338 | impl muldiv::MulDiv<$inner> for $typ { |
339 | type Output = Self; |
340 | |
341 | #[inline] |
342 | fn mul_div_floor(self, num: $inner, denom: $inner) -> Option<Self> { |
343 | self.0 |
344 | .mul_div_floor(num, denom) |
345 | .map(Self) |
346 | } |
347 | |
348 | #[inline] |
349 | fn mul_div_round(self, num: $inner, denom: $inner) -> Option<Self> { |
350 | self.0 |
351 | .mul_div_round(num, denom) |
352 | .map(Self) |
353 | } |
354 | |
355 | #[inline] |
356 | fn mul_div_ceil(self, num: $inner, denom: $inner) -> Option<Self> { |
357 | self.0 |
358 | .mul_div_ceil(num, denom) |
359 | .map(Self) |
360 | } |
361 | } |
362 | |
363 | impl opt_ops::OptionOperations for $typ {} |
364 | |
365 | impl opt_ops::OptionCheckedAdd for $typ { |
366 | type Output = Self; |
367 | #[inline] |
368 | fn opt_checked_add( |
369 | self, |
370 | rhs: Self, |
371 | ) -> Result<Option<Self>, opt_ops::Error> { |
372 | self.checked_add(rhs) |
373 | .ok_or(opt_ops::Error::Overflow) |
374 | .map(Some) |
375 | } |
376 | } |
377 | |
378 | impl opt_ops::OptionSaturatingAdd for $typ { |
379 | type Output = Self; |
380 | #[inline] |
381 | fn opt_saturating_add(self, rhs: Self) -> Option<Self> { |
382 | Some(self.saturating_add(rhs)) |
383 | } |
384 | } |
385 | |
386 | impl opt_ops::OptionOverflowingAdd for $typ { |
387 | type Output = Self; |
388 | #[inline] |
389 | fn opt_overflowing_add(self, rhs: Self) -> Option<(Self, bool)> { |
390 | let res = self.overflowing_add(rhs); |
391 | Some((res.0, res.1)) |
392 | } |
393 | } |
394 | |
395 | impl opt_ops::OptionWrappingAdd for $typ { |
396 | type Output = Self; |
397 | #[inline] |
398 | fn opt_wrapping_add(self, rhs: Self) -> Option<Self> { |
399 | Some(self.wrapping_add(rhs)) |
400 | } |
401 | } |
402 | |
403 | impl opt_ops::OptionCheckedDiv<$inner> for $typ { |
404 | type Output = Self; |
405 | #[inline] |
406 | fn opt_checked_div(self, rhs: $inner) -> Result<Option<Self>, opt_ops::Error> { |
407 | if rhs == 0 { |
408 | return Err(opt_ops::Error::DivisionByZero); |
409 | } |
410 | self |
411 | .checked_div(rhs) |
412 | .ok_or(opt_ops::Error::Overflow) |
413 | .map(Some) |
414 | } |
415 | } |
416 | |
417 | impl opt_ops::OptionCheckedDiv for $typ { |
418 | type Output = $inner; |
419 | #[inline] |
420 | fn opt_checked_div(self, rhs: Self) -> Result<Option<$inner>, opt_ops::Error> { |
421 | if rhs.0 == 0 { |
422 | return Err(opt_ops::Error::DivisionByZero); |
423 | } |
424 | self.0 |
425 | .checked_div(rhs.0) |
426 | .ok_or(opt_ops::Error::Overflow) |
427 | .map(Some) |
428 | } |
429 | } |
430 | |
431 | impl opt_ops::OptionCheckedMul<$inner> for $typ { |
432 | type Output = Self; |
433 | #[inline] |
434 | fn opt_checked_mul( |
435 | self, |
436 | rhs: $inner, |
437 | ) -> Result<Option<Self>, opt_ops::Error> { |
438 | self.checked_mul(rhs) |
439 | .ok_or(opt_ops::Error::Overflow) |
440 | .map(Some) |
441 | } |
442 | } |
443 | |
444 | impl opt_ops::OptionCheckedMul<$typ> for $inner { |
445 | type Output = $typ; |
446 | #[inline] |
447 | fn opt_checked_mul( |
448 | self, |
449 | rhs: $typ, |
450 | ) -> Result<Option<$typ>, opt_ops::Error> { |
451 | rhs.checked_mul(self) |
452 | .ok_or(opt_ops::Error::Overflow) |
453 | .map(Some) |
454 | } |
455 | } |
456 | |
457 | impl opt_ops::OptionSaturatingMul<$inner> for $typ { |
458 | type Output = Self; |
459 | #[inline] |
460 | fn opt_saturating_mul(self, rhs: $inner) -> Option<Self> { |
461 | Some(self.saturating_mul(rhs)) |
462 | } |
463 | } |
464 | |
465 | impl opt_ops::OptionSaturatingMul<$typ> for $inner { |
466 | type Output = $typ; |
467 | #[inline] |
468 | fn opt_saturating_mul(self, rhs: $typ) -> Option<$typ> { |
469 | Some(rhs.saturating_mul(self)) |
470 | } |
471 | } |
472 | |
473 | impl opt_ops::OptionOverflowingMul<$inner> for $typ { |
474 | type Output = Self; |
475 | #[inline] |
476 | fn opt_overflowing_mul(self, rhs: $inner) -> Option<(Self, bool)> { |
477 | let res = self.overflowing_mul(rhs); |
478 | Some((res.0, res.1)) |
479 | } |
480 | } |
481 | |
482 | impl opt_ops::OptionOverflowingMul<$typ> for $inner { |
483 | type Output = $typ; |
484 | #[inline] |
485 | fn opt_overflowing_mul(self, rhs: $typ) -> Option<($typ, bool)> { |
486 | let res = rhs.overflowing_mul(self); |
487 | Some((res.0, res.1)) |
488 | } |
489 | } |
490 | |
491 | impl opt_ops::OptionWrappingMul<$inner> for $typ { |
492 | type Output = Self; |
493 | #[inline] |
494 | fn opt_wrapping_mul(self, rhs: $inner) -> Option<Self> { |
495 | Some(self.wrapping_mul(rhs)) |
496 | } |
497 | } |
498 | |
499 | impl opt_ops::OptionWrappingMul<$typ> for $inner { |
500 | type Output = $typ; |
501 | #[inline] |
502 | fn opt_wrapping_mul(self, rhs: $typ) -> Option<$typ> { |
503 | Some(rhs.wrapping_mul(self)) |
504 | } |
505 | } |
506 | |
507 | impl opt_ops::OptionCheckedRem<$inner> for $typ { |
508 | type Output = Self; |
509 | #[inline] |
510 | fn opt_checked_rem(self, rhs: $inner) -> Result<Option<Self>, opt_ops::Error> { |
511 | if rhs == 0 { |
512 | return Err(opt_ops::Error::DivisionByZero); |
513 | } |
514 | self.checked_rem(rhs) |
515 | .ok_or(opt_ops::Error::Overflow) |
516 | .map(Some) |
517 | } |
518 | } |
519 | |
520 | impl opt_ops::OptionCheckedRem for $typ { |
521 | type Output = Self; |
522 | #[inline] |
523 | fn opt_checked_rem(self, rhs: Self) -> Result<Option<Self>, opt_ops::Error> { |
524 | if rhs.0 == 0 { |
525 | return Err(opt_ops::Error::DivisionByZero); |
526 | } |
527 | self.checked_rem(rhs.0) |
528 | .ok_or(opt_ops::Error::Overflow) |
529 | .map(Some) |
530 | } |
531 | } |
532 | |
533 | impl opt_ops::OptionCheckedSub for $typ { |
534 | type Output = Self; |
535 | #[inline] |
536 | fn opt_checked_sub( |
537 | self, |
538 | rhs: Self, |
539 | ) -> Result<Option<Self>, opt_ops::Error> { |
540 | self.checked_sub(rhs) |
541 | .ok_or(opt_ops::Error::Overflow) |
542 | .map(Some) |
543 | } |
544 | } |
545 | |
546 | impl opt_ops::OptionSaturatingSub for $typ { |
547 | type Output = Self; |
548 | #[inline] |
549 | fn opt_saturating_sub(self, rhs: Self) -> Option<Self> { |
550 | Some(self.saturating_sub(rhs)) |
551 | } |
552 | } |
553 | |
554 | impl opt_ops::OptionOverflowingSub for $typ { |
555 | type Output = Self; |
556 | #[inline] |
557 | fn opt_overflowing_sub(self, rhs: Self) -> Option<(Self, bool)> { |
558 | let res = self.overflowing_sub(rhs); |
559 | Some((res.0, res.1)) |
560 | } |
561 | } |
562 | |
563 | impl opt_ops::OptionWrappingSub for $typ { |
564 | type Output = Self; |
565 | #[inline] |
566 | fn opt_wrapping_sub(self, rhs: Self) -> Option<Self> { |
567 | Some(self.wrapping_sub(rhs)) |
568 | } |
569 | } |
570 | }; |
571 | ); |
572 | |
573 | macro_rules! impl_signed_ops( |
574 | (u64) => { |
575 | impl_signed_ops!(u64, u64, 0); |
576 | }; |
577 | |
578 | (u32) => { |
579 | impl_signed_ops!(u32, u32, 0); |
580 | }; |
581 | |
582 | (usize) => { |
583 | impl_signed_ops!(usize, usize, 0); |
584 | }; |
585 | |
586 | ($typ:ty, $inner:ty, $zero:expr) => { |
587 | impl crate::Signed<$typ> { |
588 | // rustdoc-stripper-ignore-next |
589 | /// Returns the signum for this `Signed`. |
590 | /// |
591 | /// Returns: |
592 | /// |
593 | /// - `0` if the number is zero. |
594 | /// - `1` if the value must be considered as positive. |
595 | /// - `-1` if the value must be considered as negative. |
596 | #[inline] |
597 | pub fn signum(self) -> i32 { |
598 | use crate::Signed::*; |
599 | match self { |
600 | Positive(val) | Negative(val) if val == $zero => 0i32, |
601 | Positive(_) => 1i32, |
602 | Negative(_) => -1i32, |
603 | } |
604 | } |
605 | |
606 | // rustdoc-stripper-ignore-next |
607 | /// Returns the checked subtraction `self - other`. |
608 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
609 | #[inline] |
610 | pub fn checked_sub(self, other: Self) -> Option<Self> { |
611 | use crate::Signed::*; |
612 | match (self, other) { |
613 | (Positive(a), Positive(b)) if a >= b => Some(Positive(a - b)), |
614 | (Positive(a), Positive(b)) => Some(Negative(b - a)), |
615 | (Negative(a), Negative(b)) if a >= b => Some(Negative(a - b)), |
616 | (Negative(a), Negative(b)) => Some(Positive(b - a)), |
617 | (Positive(a), Negative(b)) => a.checked_add(b).map(Positive), |
618 | (Negative(a), Positive(b)) => a.checked_add(b).map(Negative), |
619 | } |
620 | } |
621 | |
622 | // rustdoc-stripper-ignore-next |
623 | /// Returns the checked subtraction `self - other`. |
624 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
625 | #[inline] |
626 | pub fn checked_sub_unsigned(self, other: $typ) -> Option<Self> { |
627 | self.checked_sub(crate::Signed::Positive(other)) |
628 | } |
629 | |
630 | // rustdoc-stripper-ignore-next |
631 | /// Returns the checked addition `self + other`. |
632 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
633 | #[inline] |
634 | pub fn checked_add(self, other: Self) -> Option<Self> { |
635 | use crate::Signed::*; |
636 | match (self, other) { |
637 | (Positive(a), Positive(b)) => a.checked_add(b).map(Positive), |
638 | (Negative(a), Negative(b)) => a.checked_add(b).map(Negative), |
639 | (Positive(_), Negative(_)) => self.checked_sub(-other), |
640 | (Negative(_), Positive(_)) => Some(-((-self).checked_sub(other)?)) |
641 | } |
642 | } |
643 | |
644 | // rustdoc-stripper-ignore-next |
645 | /// Returns the checked addition `self + other`. |
646 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
647 | #[inline] |
648 | pub fn checked_add_unsigned(self, other: $typ) -> Option<Self> { |
649 | self.checked_add(crate::Signed::Positive(other)) |
650 | } |
651 | |
652 | // rustdoc-stripper-ignore-next |
653 | /// Returns the saturating subtraction `self - other`. |
654 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
655 | #[inline] |
656 | pub fn saturating_sub(self, other: Self) -> Self { |
657 | use crate::Signed::*; |
658 | match (self, other) { |
659 | (Positive(a), Positive(b)) if a >= b => Positive(a - b), |
660 | (Positive(a), Positive(b)) => Negative(b - a), |
661 | (Negative(a), Negative(b)) if a >= b => Negative(a - b), |
662 | (Negative(a), Negative(b)) => Positive(b - a), |
663 | (Positive(a), Negative(b)) => Positive(a.saturating_add(b)), |
664 | (Negative(a), Positive(b)) => Negative(a.saturating_add(b)), |
665 | } |
666 | } |
667 | |
668 | // rustdoc-stripper-ignore-next |
669 | /// Returns the saturating subtraction `self - other`. |
670 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
671 | #[inline] |
672 | pub fn saturating_sub_unsigned(self, other: $typ) -> Self { |
673 | self.saturating_sub(crate::Signed::Positive(other)) |
674 | } |
675 | |
676 | // rustdoc-stripper-ignore-next |
677 | /// Returns the saturating addition `self + other`. |
678 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
679 | #[inline] |
680 | pub fn saturating_add(self, other: Self) -> Self { |
681 | use crate::Signed::*; |
682 | match (self, other) { |
683 | (Positive(a), Positive(b)) => Positive(a.saturating_add(b)), |
684 | (Negative(a), Negative(b)) => Negative(a.saturating_add(b)), |
685 | (Positive(_), Negative(_)) => self.saturating_sub(-other), |
686 | (Negative(_), Positive(_)) => -((-self).saturating_sub(other)), |
687 | } |
688 | } |
689 | |
690 | // rustdoc-stripper-ignore-next |
691 | /// Returns the saturating addition `self + other`. |
692 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
693 | #[inline] |
694 | pub fn saturating_add_unsigned(self, other: $typ) -> Self { |
695 | self.saturating_add(crate::Signed::Positive(other)) |
696 | } |
697 | } |
698 | |
699 | impl std::ops::Add for crate::Signed<$typ> { |
700 | type Output = Self; |
701 | #[inline] |
702 | fn add(self, other: Self) -> Self { |
703 | self.checked_add(other).expect("Overflowing addition" ) |
704 | } |
705 | } |
706 | |
707 | impl std::ops::AddAssign for crate::Signed<$typ> { |
708 | #[inline] |
709 | fn add_assign(&mut self, other: Self) { |
710 | *self = self.checked_add(other).expect("Overflowing addition" ) |
711 | } |
712 | } |
713 | |
714 | impl std::ops::Sub for crate::Signed<$typ> { |
715 | type Output = Self; |
716 | #[inline] |
717 | fn sub(self, other: Self) -> Self { |
718 | self.checked_sub(other).expect("Overflowing subtraction" ) |
719 | } |
720 | } |
721 | |
722 | impl std::ops::SubAssign for crate::Signed<$typ> { |
723 | #[inline] |
724 | fn sub_assign(&mut self, other: Self) { |
725 | *self = self.checked_sub(other).expect("Overflowing subtraction" ) |
726 | } |
727 | } |
728 | |
729 | impl std::ops::Add<$typ> for crate::Signed<$typ> { |
730 | type Output = Self; |
731 | #[inline] |
732 | fn add(self, other: $typ) -> Self { |
733 | self.checked_add(crate::Signed::Positive(other)).expect("Overflowing addition" ) |
734 | } |
735 | } |
736 | |
737 | impl std::ops::AddAssign<$typ> for crate::Signed<$typ> { |
738 | #[inline] |
739 | fn add_assign(&mut self, other: $typ) { |
740 | *self = self.checked_add(crate::Signed::Positive(other)).expect("Overflowing addition" ) |
741 | } |
742 | } |
743 | |
744 | impl std::ops::Sub<$typ> for crate::Signed<$typ> { |
745 | type Output = Self; |
746 | |
747 | #[inline] |
748 | fn sub(self, other: $typ) -> Self { |
749 | self.checked_sub(crate::Signed::Positive(other)).expect("Overflowing subtraction" ) |
750 | } |
751 | } |
752 | |
753 | impl std::ops::SubAssign<$typ> for crate::Signed<$typ> { |
754 | #[inline] |
755 | fn sub_assign(&mut self, other: $typ) { |
756 | *self = self.checked_sub(crate::Signed::Positive(other)).expect("Overflowing subtraction" ) |
757 | } |
758 | } |
759 | |
760 | impl std::ops::Add<crate::Signed<$typ>> for $typ { |
761 | type Output = crate::Signed<$typ>; |
762 | #[inline] |
763 | fn add(self, other: crate::Signed<$typ>) -> crate::Signed<$typ> { |
764 | crate::Signed::Positive(self).checked_add(other).expect("Overflowing addition" ) |
765 | } |
766 | } |
767 | |
768 | impl std::ops::Sub<crate::Signed<$typ>> for $typ { |
769 | type Output = crate::Signed<$typ>; |
770 | #[inline] |
771 | fn sub(self, other: crate::Signed<$typ>) -> crate::Signed<$typ> { |
772 | crate::Signed::Positive(self).checked_sub(other).expect("Overflowing subtraction" ) |
773 | } |
774 | } |
775 | |
776 | impl std::cmp::PartialOrd for crate::Signed<$typ> { |
777 | #[inline] |
778 | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { |
779 | Some(self.cmp(other)) |
780 | } |
781 | } |
782 | |
783 | impl std::cmp::PartialEq<$typ> for crate::Signed<$typ> { |
784 | #[inline] |
785 | fn eq(&self, other: &$typ) -> bool { |
786 | self.eq(&crate::Signed::Positive(*other)) |
787 | } |
788 | } |
789 | |
790 | impl std::cmp::PartialEq<crate::Signed<$typ>> for $typ { |
791 | #[inline] |
792 | fn eq(&self, other: &crate::Signed<$typ>) -> bool { |
793 | crate::Signed::Positive(*self).eq(other) |
794 | } |
795 | } |
796 | |
797 | impl std::cmp::PartialOrd<$typ> for crate::Signed<$typ> { |
798 | #[inline] |
799 | fn partial_cmp(&self, other: &$typ) -> Option<std::cmp::Ordering> { |
800 | Some(self.cmp(&crate::Signed::Positive(*other))) |
801 | } |
802 | } |
803 | |
804 | impl std::cmp::PartialOrd<crate::Signed<$typ>> for $typ { |
805 | #[inline] |
806 | fn partial_cmp(&self, other: &crate::Signed<$typ>) -> Option<std::cmp::Ordering> { |
807 | Some(crate::Signed::Positive(*self).cmp(other)) |
808 | } |
809 | } |
810 | |
811 | impl std::cmp::Ord for crate::Signed<$typ> { |
812 | #[inline] |
813 | fn cmp(&self, other: &Self) -> std::cmp::Ordering { |
814 | use crate::Signed::*; |
815 | match (self, other) { |
816 | (Positive(a), Positive(b)) => a.cmp(b), |
817 | (Negative(a), Negative(b)) => b.cmp(a), |
818 | (Positive(_), Negative(_)) => std::cmp::Ordering::Greater, |
819 | (Negative(_), Positive(_)) => std::cmp::Ordering::Less, |
820 | } |
821 | } |
822 | } |
823 | |
824 | impl opt_ops::OptionOperations for crate::Signed<$typ> {} |
825 | |
826 | impl opt_ops::OptionCheckedAdd for crate::Signed<$typ> { |
827 | type Output = Self; |
828 | #[inline] |
829 | fn opt_checked_add( |
830 | self, |
831 | rhs: Self, |
832 | ) -> Result<Option<Self>, opt_ops::Error> { |
833 | self.checked_add(rhs) |
834 | .ok_or(opt_ops::Error::Overflow) |
835 | .map(Some) |
836 | } |
837 | } |
838 | |
839 | impl opt_ops::OptionSaturatingAdd for crate::Signed<$typ> { |
840 | type Output = Self; |
841 | #[inline] |
842 | fn opt_saturating_add(self, rhs: Self) -> Option<Self> { |
843 | Some(self.saturating_add(rhs)) |
844 | } |
845 | } |
846 | |
847 | impl opt_ops::OptionCheckedSub for crate::Signed<$typ> { |
848 | type Output = Self; |
849 | #[inline] |
850 | fn opt_checked_sub( |
851 | self, |
852 | rhs: Self, |
853 | ) -> Result<Option<Self>, opt_ops::Error> { |
854 | self.checked_sub(rhs) |
855 | .ok_or(opt_ops::Error::Overflow) |
856 | .map(Some) |
857 | } |
858 | } |
859 | |
860 | impl opt_ops::OptionSaturatingSub for crate::Signed<$typ> { |
861 | type Output = Self; |
862 | #[inline] |
863 | fn opt_saturating_sub(self, rhs: Self) -> Option<Self> { |
864 | Some(self.saturating_sub(rhs)) |
865 | } |
866 | } |
867 | |
868 | impl opt_ops::OptionCheckedAdd<$typ> for crate::Signed<$typ> { |
869 | type Output = Self; |
870 | #[inline] |
871 | fn opt_checked_add( |
872 | self, |
873 | rhs: $typ, |
874 | ) -> Result<Option<Self>, opt_ops::Error> { |
875 | self.opt_checked_add(crate::Signed::Positive(rhs)) |
876 | } |
877 | } |
878 | |
879 | impl opt_ops::OptionSaturatingAdd<$typ> for crate::Signed<$typ> { |
880 | type Output = Self; |
881 | #[inline] |
882 | fn opt_saturating_add(self, rhs: $typ) -> Option<Self> { |
883 | self.opt_saturating_add(crate::Signed::Positive(rhs)) |
884 | } |
885 | } |
886 | |
887 | impl opt_ops::OptionCheckedSub<$typ> for crate::Signed<$typ> { |
888 | type Output = Self; |
889 | #[inline] |
890 | fn opt_checked_sub( |
891 | self, |
892 | rhs: $typ, |
893 | ) -> Result<Option<Self>, opt_ops::Error> { |
894 | self.opt_checked_sub(crate::Signed::Positive(rhs)) |
895 | } |
896 | } |
897 | |
898 | impl opt_ops::OptionSaturatingSub<$typ> for crate::Signed<$typ> { |
899 | type Output = Self; |
900 | #[inline] |
901 | fn opt_saturating_sub(self, rhs: $typ) -> Option<Self> { |
902 | self.opt_saturating_sub(crate::Signed::Positive(rhs)) |
903 | } |
904 | } |
905 | |
906 | impl opt_ops::OptionCheckedAdd<crate::Signed<$typ>> for $typ { |
907 | type Output = crate::Signed<$typ>; |
908 | #[inline] |
909 | fn opt_checked_add( |
910 | self, |
911 | rhs: crate::Signed<$typ>, |
912 | ) -> Result<Option<Self::Output>, opt_ops::Error> { |
913 | crate::Signed::Positive(self).opt_checked_add(rhs) |
914 | } |
915 | } |
916 | |
917 | impl opt_ops::OptionSaturatingAdd<crate::Signed<$typ>> for $typ { |
918 | type Output = crate::Signed<$typ>; |
919 | #[inline] |
920 | fn opt_saturating_add( |
921 | self, |
922 | rhs: crate::Signed<$typ> |
923 | ) -> Option<Self::Output> { |
924 | crate::Signed::Positive(self).opt_saturating_add(rhs) |
925 | } |
926 | } |
927 | |
928 | impl opt_ops::OptionCheckedSub<crate::Signed<$typ>> for $typ { |
929 | type Output = crate::Signed<$typ>; |
930 | #[inline] |
931 | fn opt_checked_sub( |
932 | self, |
933 | rhs: crate::Signed<$typ>, |
934 | ) -> Result<Option<Self::Output>, opt_ops::Error> { |
935 | crate::Signed::Positive(self).opt_checked_sub(rhs) |
936 | } |
937 | } |
938 | |
939 | impl opt_ops::OptionSaturatingSub<crate::Signed<$typ>> for $typ { |
940 | type Output = crate::Signed<$typ>; |
941 | #[inline] |
942 | fn opt_saturating_sub( |
943 | self, |
944 | rhs: crate::Signed<$typ> |
945 | ) -> Option<Self::Output> { |
946 | crate::Signed::Positive(self).opt_saturating_sub(rhs) |
947 | } |
948 | } |
949 | }; |
950 | ); |
951 | |
952 | macro_rules! impl_signed_div_mul( |
953 | (u64) => { |
954 | impl_signed_div_mul!(u64, u64, i64, |val: u64| val); |
955 | impl_signed_extra_div_mul!(u64, i64); |
956 | impl_signed_div_mul_trait!(u64, u64, i64, |val: u64| val); |
957 | }; |
958 | |
959 | (usize) => { |
960 | impl_signed_div_mul!(usize, usize, isize, |val: usize| val); |
961 | impl_signed_extra_div_mul!(usize, isize); |
962 | // `MulDiv` not available for usize |
963 | }; |
964 | |
965 | (u32) => { |
966 | impl_signed_div_mul!(u32, u32, i32, |val: u32| val); |
967 | impl_signed_extra_div_mul!(u32, i32); |
968 | impl_signed_div_mul_trait!(u32, u32, i32, |val: u32| val); |
969 | }; |
970 | |
971 | ($newtyp:ty, u64) => { |
972 | impl_signed_div_mul!($newtyp, u64, i64, |val: $newtyp| *val); |
973 | impl_signed_extra_div_mul!($newtyp, u64, i64); |
974 | impl_signed_div_mul_trait!($newtyp, u64, i64, |val: $newtyp| *val); |
975 | }; |
976 | |
977 | ($newtyp:ty, u32) => { |
978 | impl_signed_div_mul!($newtyp, u32, i32, |val: $newtyp| *val); |
979 | impl_signed_extra_div_mul!($newtyp, u32, i32); |
980 | impl_signed_div_mul_trait!($newtyp, u32, i32, |val: $newtyp| *val); |
981 | }; |
982 | |
983 | ($typ:ty, $inner:ty, $signed_rhs:ty, $into_inner:expr) => { |
984 | impl crate::Signed<$typ> { |
985 | #[allow(dead_code)] |
986 | #[inline] |
987 | fn signed_from_inner(val: $inner, sign: $signed_rhs) -> Option<crate::Signed<$typ>> { |
988 | skip_assert_initialized!(); |
989 | if sign.is_positive() { |
990 | Self::positive_from_inner(val) |
991 | } else { |
992 | Self::negative_from_inner(val) |
993 | } |
994 | } |
995 | |
996 | #[inline] |
997 | fn positive_from_inner(val: $inner) -> Option<Self> { |
998 | skip_assert_initialized!(); |
999 | <$typ>::try_from(val).ok().map(crate::Signed::Positive) |
1000 | } |
1001 | |
1002 | #[inline] |
1003 | fn negative_from_inner(val: $inner) -> Option<Self> { |
1004 | skip_assert_initialized!(); |
1005 | <$typ>::try_from(val).ok().map(crate::Signed::Negative) |
1006 | } |
1007 | |
1008 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1009 | #[inline] |
1010 | pub fn checked_div(self, rhs:$signed_rhs) -> Option<Self> { |
1011 | use crate::Signed::*; |
1012 | match self { |
1013 | Positive(lhs) => { |
1014 | if rhs.is_positive() { |
1015 | lhs.checked_div(rhs as $inner).map(Positive) |
1016 | } else { |
1017 | lhs.checked_div(-rhs as $inner).map(Negative) |
1018 | } |
1019 | } |
1020 | Negative(lhs) => { |
1021 | if rhs.is_positive() { |
1022 | lhs.checked_div(rhs as $inner).map(Negative) |
1023 | } else { |
1024 | lhs.checked_div(-rhs as $inner).map(Positive) |
1025 | } |
1026 | } |
1027 | } |
1028 | } |
1029 | |
1030 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1031 | #[inline] |
1032 | pub fn checked_div_unsigned(self, rhs:$inner) -> Option<Self> { |
1033 | use crate::Signed::*; |
1034 | match self { |
1035 | Positive(lhs) => lhs.checked_div(rhs).map(Positive), |
1036 | Negative(lhs) => lhs.checked_div(rhs).map(Negative), |
1037 | } |
1038 | } |
1039 | |
1040 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1041 | #[inline] |
1042 | pub fn checked_rem(self, rhs:$signed_rhs) -> Option<Self> { |
1043 | use crate::Signed::*; |
1044 | match self { |
1045 | Positive(lhs) => { |
1046 | if rhs.is_positive() { |
1047 | lhs.checked_rem(rhs as $inner).map(Positive) |
1048 | } else { |
1049 | lhs.checked_rem(-rhs as $inner).map(Positive) |
1050 | } |
1051 | } |
1052 | Negative(lhs) => { |
1053 | if rhs.is_positive() { |
1054 | lhs.checked_rem(rhs as $inner).map(Negative) |
1055 | } else { |
1056 | lhs.checked_rem(-rhs as $inner).map(Negative) |
1057 | } |
1058 | } |
1059 | } |
1060 | } |
1061 | |
1062 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1063 | #[inline] |
1064 | pub fn checked_rem_unsigned(self, rhs:$inner) -> Option<Self> { |
1065 | use crate::Signed::*; |
1066 | match self { |
1067 | Positive(lhs) => lhs.checked_rem(rhs).map(Positive), |
1068 | Negative(lhs) => lhs.checked_rem(rhs).map(Negative), |
1069 | } |
1070 | } |
1071 | |
1072 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1073 | #[inline] |
1074 | pub fn checked_mul(self, rhs:$signed_rhs) -> Option<Self> { |
1075 | use crate::Signed::*; |
1076 | match self { |
1077 | Positive(lhs) => { |
1078 | if rhs.is_positive() { |
1079 | lhs.checked_mul(rhs as $inner).map(Positive) |
1080 | } else { |
1081 | lhs.checked_mul(-rhs as $inner).map(Negative) |
1082 | } |
1083 | } |
1084 | Negative(lhs) => { |
1085 | if rhs.is_positive() { |
1086 | lhs.checked_mul(rhs as $inner).map(Negative) |
1087 | } else { |
1088 | lhs.checked_mul(-rhs as $inner).map(Positive) |
1089 | } |
1090 | } |
1091 | } |
1092 | } |
1093 | |
1094 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1095 | #[inline] |
1096 | pub fn checked_mul_unsigned(self, rhs:$inner) -> Option<Self> { |
1097 | use crate::Signed::*; |
1098 | match self { |
1099 | Positive(lhs) => lhs.checked_mul(rhs).map(Positive), |
1100 | Negative(lhs) => lhs.checked_mul(rhs).map(Negative), |
1101 | } |
1102 | } |
1103 | |
1104 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1105 | #[inline] |
1106 | pub fn saturating_mul(self, rhs:$signed_rhs) -> Self { |
1107 | use crate::Signed::*; |
1108 | match self { |
1109 | Positive(lhs) => { |
1110 | if rhs.is_positive() { |
1111 | Positive(lhs.saturating_mul(rhs as $inner)) |
1112 | } else { |
1113 | Negative(lhs.saturating_mul(-rhs as $inner)) |
1114 | } |
1115 | } |
1116 | Negative(lhs) => { |
1117 | if rhs.is_positive() { |
1118 | Negative(lhs.saturating_mul(rhs as $inner)) |
1119 | } else { |
1120 | Positive(lhs.saturating_mul(-rhs as $inner)) |
1121 | } |
1122 | } |
1123 | } |
1124 | } |
1125 | |
1126 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
1127 | #[inline] |
1128 | pub fn saturating_mul_unsigned(self, rhs:$inner) -> Self { |
1129 | use crate::Signed::*; |
1130 | match self { |
1131 | Positive(lhs) => Positive(lhs.saturating_mul(rhs)), |
1132 | Negative(lhs) => Negative(lhs.saturating_mul(rhs)), |
1133 | } |
1134 | } |
1135 | } |
1136 | |
1137 | impl std::ops::Div<$signed_rhs> for crate::Signed<$typ> { |
1138 | type Output = Self; |
1139 | #[inline] |
1140 | fn div(self, rhs: $signed_rhs) -> Self { |
1141 | self.checked_div(rhs).expect("division overflowed" ) |
1142 | } |
1143 | } |
1144 | |
1145 | impl std::ops::DivAssign<$signed_rhs> for crate::Signed<$typ> { |
1146 | #[inline] |
1147 | fn div_assign(&mut self, rhs: $signed_rhs) { |
1148 | *self = std::ops::Div::div(*self, rhs); |
1149 | } |
1150 | } |
1151 | |
1152 | impl std::ops::Div<$inner> for crate::Signed<$typ> { |
1153 | type Output = Self; |
1154 | #[inline] |
1155 | fn div(self, rhs: $inner) -> Self { |
1156 | self.checked_div_unsigned(rhs).expect("division overflowed" ) |
1157 | } |
1158 | } |
1159 | |
1160 | impl std::ops::DivAssign<$inner> for crate::Signed<$typ> { |
1161 | #[inline] |
1162 | fn div_assign(&mut self, rhs: $inner) { |
1163 | *self = std::ops::Div::div(*self, rhs); |
1164 | } |
1165 | } |
1166 | |
1167 | impl std::ops::Rem<$signed_rhs> for crate::Signed<$typ> { |
1168 | type Output = Self; |
1169 | #[inline] |
1170 | fn rem(self, rhs: $signed_rhs) -> Self { |
1171 | self.checked_rem(rhs).expect("division overflowed" ) |
1172 | } |
1173 | } |
1174 | |
1175 | impl std::ops::RemAssign<$signed_rhs> for crate::Signed<$typ> { |
1176 | #[inline] |
1177 | fn rem_assign(&mut self, rhs: $signed_rhs) { |
1178 | *self = std::ops::Rem::rem(*self, rhs); |
1179 | } |
1180 | } |
1181 | |
1182 | impl std::ops::Rem<$inner> for crate::Signed<$typ> { |
1183 | type Output = Self; |
1184 | #[inline] |
1185 | fn rem(self, rhs: $inner) -> Self { |
1186 | self.checked_rem_unsigned(rhs).expect("division overflowed" ) |
1187 | } |
1188 | } |
1189 | |
1190 | impl std::ops::RemAssign<$inner> for crate::Signed<$typ> { |
1191 | #[inline] |
1192 | fn rem_assign(&mut self, rhs: $inner) { |
1193 | *self = std::ops::Rem::rem(*self, rhs); |
1194 | } |
1195 | } |
1196 | |
1197 | impl std::ops::Mul<$signed_rhs> for crate::Signed<$typ> { |
1198 | type Output = Self; |
1199 | #[inline] |
1200 | fn mul(self, rhs: $signed_rhs) -> Self { |
1201 | self.checked_mul(rhs).expect("multiplication overflowed" ) |
1202 | } |
1203 | } |
1204 | |
1205 | impl std::ops::MulAssign<$signed_rhs> for crate::Signed<$typ> { |
1206 | #[inline] |
1207 | fn mul_assign(&mut self, rhs: $signed_rhs) { |
1208 | *self = std::ops::Mul::mul(*self, rhs); |
1209 | } |
1210 | } |
1211 | |
1212 | impl std::ops::Mul<$inner> for crate::Signed<$typ> { |
1213 | type Output = Self; |
1214 | #[inline] |
1215 | fn mul(self, rhs: $inner) -> Self { |
1216 | self.checked_mul_unsigned(rhs).expect("multiplication overflowed" ) |
1217 | } |
1218 | } |
1219 | |
1220 | impl std::ops::MulAssign<$inner> for crate::Signed<$typ> { |
1221 | #[inline] |
1222 | fn mul_assign(&mut self, rhs: $inner) { |
1223 | *self = std::ops::Mul::mul(*self, rhs); |
1224 | } |
1225 | } |
1226 | |
1227 | impl opt_ops::OptionCheckedDiv<$signed_rhs> for crate::Signed<$typ> { |
1228 | type Output = Self; |
1229 | #[inline] |
1230 | fn opt_checked_div(self, rhs: $signed_rhs) -> Result<Option<Self>, opt_ops::Error> { |
1231 | if rhs == 0 { |
1232 | return Err(opt_ops::Error::DivisionByZero); |
1233 | } |
1234 | self.checked_div(rhs) |
1235 | .ok_or(opt_ops::Error::Overflow) |
1236 | .map(Some) |
1237 | } |
1238 | } |
1239 | |
1240 | impl opt_ops::OptionCheckedMul<$signed_rhs> for crate::Signed<$typ> { |
1241 | type Output = Self; |
1242 | #[inline] |
1243 | fn opt_checked_mul(self, rhs: $signed_rhs) -> Result<Option<Self>, opt_ops::Error> { |
1244 | self.checked_mul(rhs) |
1245 | .ok_or(opt_ops::Error::Overflow) |
1246 | .map(Some) |
1247 | } |
1248 | } |
1249 | |
1250 | impl opt_ops::OptionSaturatingMul<$signed_rhs> for crate::Signed<$typ> { |
1251 | type Output = Self; |
1252 | #[inline] |
1253 | fn opt_saturating_mul(self, rhs: $signed_rhs) -> Option<Self> { |
1254 | Some(self.saturating_mul(rhs)) |
1255 | } |
1256 | } |
1257 | |
1258 | impl opt_ops::OptionCheckedRem<$signed_rhs> for crate::Signed<$typ> { |
1259 | type Output = Self; |
1260 | #[inline] |
1261 | fn opt_checked_rem(self, rhs: $signed_rhs) -> Result<Option<Self>, opt_ops::Error> { |
1262 | if rhs == 0 { |
1263 | return Err(opt_ops::Error::DivisionByZero); |
1264 | } |
1265 | self.checked_rem(rhs) |
1266 | .ok_or(opt_ops::Error::Overflow) |
1267 | .map(Some) |
1268 | } |
1269 | } |
1270 | |
1271 | impl opt_ops::OptionCheckedDiv<$inner> for crate::Signed<$typ> { |
1272 | type Output = Self; |
1273 | #[inline] |
1274 | fn opt_checked_div(self, rhs: $inner) -> Result<Option<Self>, opt_ops::Error> { |
1275 | if rhs == 0 { |
1276 | return Err(opt_ops::Error::DivisionByZero); |
1277 | } |
1278 | self.checked_div_unsigned(rhs) |
1279 | .ok_or(opt_ops::Error::Overflow) |
1280 | .map(Some) |
1281 | } |
1282 | } |
1283 | |
1284 | impl opt_ops::OptionCheckedMul<$inner> for crate::Signed<$typ> { |
1285 | type Output = Self; |
1286 | #[inline] |
1287 | fn opt_checked_mul(self, rhs: $inner) -> Result<Option<Self>, opt_ops::Error> { |
1288 | self.checked_mul_unsigned(rhs) |
1289 | .ok_or(opt_ops::Error::Overflow) |
1290 | .map(Some) |
1291 | } |
1292 | } |
1293 | |
1294 | impl opt_ops::OptionSaturatingMul<$inner> for crate::Signed<$typ> { |
1295 | type Output = Self; |
1296 | #[inline] |
1297 | fn opt_saturating_mul(self, rhs: $inner) -> Option<Self> { |
1298 | Some(self.saturating_mul_unsigned(rhs)) |
1299 | } |
1300 | } |
1301 | |
1302 | impl opt_ops::OptionCheckedRem<$inner> for crate::Signed<$typ> { |
1303 | type Output = Self; |
1304 | #[inline] |
1305 | fn opt_checked_rem(self, rhs: $inner) -> Result<Option<Self>, opt_ops::Error> { |
1306 | if rhs == 0 { |
1307 | return Err(opt_ops::Error::DivisionByZero); |
1308 | } |
1309 | self.checked_rem_unsigned(rhs) |
1310 | .ok_or(opt_ops::Error::Overflow) |
1311 | .map(Some) |
1312 | } |
1313 | } |
1314 | }; |
1315 | ); |
1316 | |
1317 | macro_rules! impl_signed_extra_div_mul( |
1318 | ($typ:ty, $signed:ty) => { |
1319 | impl std::ops::Div for crate::Signed<$typ> { |
1320 | type Output = Self; |
1321 | #[inline] |
1322 | fn div(self, rhs: Self) -> Self { |
1323 | match rhs { |
1324 | crate::Signed::Positive(rhs) => self.div(rhs), |
1325 | crate::Signed::Negative(rhs) => std::ops::Neg::neg(self.div(rhs)), |
1326 | } |
1327 | } |
1328 | } |
1329 | |
1330 | impl std::ops::Rem for crate::Signed<$typ> { |
1331 | type Output = Self; |
1332 | #[inline] |
1333 | fn rem(self, rhs: Self) -> Self { |
1334 | self.rem(rhs.abs()) |
1335 | } |
1336 | } |
1337 | |
1338 | impl opt_ops::OptionCheckedDiv for crate::Signed<$typ> { |
1339 | type Output = Self; |
1340 | #[inline] |
1341 | fn opt_checked_div(self, rhs: Self) -> Result<Option<Self>, opt_ops::Error> { |
1342 | match rhs { |
1343 | crate::Signed::Positive(rhs) => self.opt_checked_div(rhs), |
1344 | crate::Signed::Negative(rhs) => { |
1345 | self.opt_checked_div(rhs) |
1346 | .map(|res| res.map(std::ops::Neg::neg)) |
1347 | } |
1348 | } |
1349 | } |
1350 | } |
1351 | |
1352 | impl opt_ops::OptionCheckedRem for crate::Signed<$typ> { |
1353 | type Output = Self; |
1354 | #[inline] |
1355 | fn opt_checked_rem(self, rhs: Self) -> Result<Option<Self>, opt_ops::Error> { |
1356 | self.opt_checked_rem(rhs.abs()) |
1357 | } |
1358 | } |
1359 | }; |
1360 | ($newtyp:ty, $inner:ty, $signed_inner:ty) => { |
1361 | impl std::ops::Div for crate::Signed<$newtyp> { |
1362 | type Output = crate::Signed<$inner>; |
1363 | #[inline] |
1364 | fn div(self, rhs: Self) -> Self::Output { |
1365 | self.into_inner_signed().div(rhs.into_inner_signed()) |
1366 | } |
1367 | } |
1368 | |
1369 | impl std::ops::Rem for crate::Signed<$newtyp> { |
1370 | type Output = Self; |
1371 | #[inline] |
1372 | fn rem(self, rhs: Self) -> Self { |
1373 | self.rem(rhs.abs().0) |
1374 | } |
1375 | } |
1376 | |
1377 | impl std::ops::Mul<crate::Signed<$newtyp>> for $inner { |
1378 | type Output = crate::Signed<$newtyp>; |
1379 | #[inline] |
1380 | fn mul(self, rhs: crate::Signed<$newtyp>) -> Self::Output { |
1381 | rhs.mul(self) |
1382 | } |
1383 | } |
1384 | |
1385 | impl std::ops::Mul<crate::Signed<$newtyp>> for $signed_inner { |
1386 | type Output = crate::Signed<$newtyp>; |
1387 | #[inline] |
1388 | fn mul(self, rhs: crate::Signed<$newtyp>) -> Self::Output { |
1389 | rhs.mul(self) |
1390 | } |
1391 | } |
1392 | |
1393 | impl opt_ops::OptionCheckedDiv for crate::Signed<$newtyp> { |
1394 | type Output = crate::Signed<$inner>; |
1395 | #[inline] |
1396 | fn opt_checked_div(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> { |
1397 | self.into_inner_signed().opt_checked_div(rhs.into_inner_signed()) |
1398 | } |
1399 | } |
1400 | |
1401 | impl opt_ops::OptionCheckedRem for crate::Signed<$newtyp> { |
1402 | type Output = crate::Signed<$inner>; |
1403 | #[inline] |
1404 | fn opt_checked_rem(self, rhs: Self) -> Result<Option<Self::Output>, opt_ops::Error> { |
1405 | self.into_inner_signed().opt_checked_rem(rhs.abs().0) |
1406 | } |
1407 | } |
1408 | |
1409 | impl opt_ops::OptionCheckedMul<crate::Signed<$newtyp>> for $signed_inner { |
1410 | type Output = crate::Signed<$newtyp>; |
1411 | #[inline] |
1412 | fn opt_checked_mul(self, rhs: crate::Signed<$newtyp>) -> Result<Option<Self::Output>, opt_ops::Error> { |
1413 | rhs.opt_checked_mul(self) |
1414 | } |
1415 | } |
1416 | |
1417 | impl opt_ops::OptionSaturatingMul<crate::Signed<$newtyp>> for $signed_inner { |
1418 | type Output = crate::Signed<$newtyp>; |
1419 | #[inline] |
1420 | fn opt_saturating_mul(self, rhs: crate::Signed<$newtyp>) -> Option<Self::Output> { |
1421 | rhs.opt_saturating_mul(self) |
1422 | } |
1423 | } |
1424 | |
1425 | impl opt_ops::OptionCheckedMul<crate::Signed<$newtyp>> for $inner { |
1426 | type Output = crate::Signed<$newtyp>; |
1427 | #[inline] |
1428 | fn opt_checked_mul(self, rhs: crate::Signed<$newtyp>) -> Result<Option<Self::Output>, opt_ops::Error> { |
1429 | rhs.opt_checked_mul(self) |
1430 | } |
1431 | } |
1432 | |
1433 | impl opt_ops::OptionSaturatingMul<crate::Signed<$newtyp>> for $inner { |
1434 | type Output = crate::Signed<$newtyp>; |
1435 | #[inline] |
1436 | fn opt_saturating_mul(self, rhs: crate::Signed<$newtyp>) -> Option<Self::Output> { |
1437 | rhs.opt_saturating_mul(self) |
1438 | } |
1439 | } |
1440 | }; |
1441 | ); |
1442 | |
1443 | macro_rules! impl_signed_div_mul_trait( |
1444 | ($typ:ty, $inner:ty, $signed_rhs:ty, $into_inner:expr) => { |
1445 | #[allow(clippy::redundant_closure_call)] |
1446 | impl muldiv::MulDiv<$signed_rhs> for crate::Signed<$typ> { |
1447 | type Output = Self; |
1448 | |
1449 | #[inline] |
1450 | fn mul_div_floor(self, num: $signed_rhs, denom: $signed_rhs) -> Option<Self> { |
1451 | use crate::Signed::*; |
1452 | match self { |
1453 | Positive(lhs) => { |
1454 | $into_inner(lhs) |
1455 | .mul_div_floor(num.unsigned_abs(), denom.unsigned_abs()) |
1456 | .and_then(|val| Self::signed_from_inner(val, num.signum() * denom.signum())) |
1457 | } |
1458 | Negative(lhs) => { |
1459 | $into_inner(lhs) |
1460 | .mul_div_floor(num.unsigned_abs(), denom.unsigned_abs()) |
1461 | .and_then(|val| Self::signed_from_inner(val, -num.signum() * denom.signum())) |
1462 | } |
1463 | } |
1464 | } |
1465 | |
1466 | #[inline] |
1467 | fn mul_div_round(self, num: $signed_rhs, denom: $signed_rhs) -> Option<Self> { |
1468 | use crate::Signed::*; |
1469 | match self { |
1470 | Positive(lhs) => { |
1471 | $into_inner(lhs) |
1472 | .mul_div_round(num.unsigned_abs(), denom.unsigned_abs()) |
1473 | .and_then(|val| Self::signed_from_inner(val, num.signum() * denom.signum())) |
1474 | } |
1475 | Negative(lhs) => { |
1476 | $into_inner(lhs) |
1477 | .mul_div_round(num.unsigned_abs(), denom.unsigned_abs()) |
1478 | .and_then(|val| Self::signed_from_inner(val, -num.signum() * denom.signum())) |
1479 | } |
1480 | } |
1481 | } |
1482 | |
1483 | #[inline] |
1484 | fn mul_div_ceil(self, num: $signed_rhs, denom: $signed_rhs) -> Option<Self> { |
1485 | use crate::Signed::*; |
1486 | match self { |
1487 | Positive(lhs) => { |
1488 | $into_inner(lhs) |
1489 | .mul_div_ceil(num.unsigned_abs(), denom.unsigned_abs()) |
1490 | .and_then(|val| Self::signed_from_inner(val, num.signum() * denom.signum())) |
1491 | } |
1492 | Negative(lhs) => { |
1493 | $into_inner(lhs) |
1494 | .mul_div_ceil(num.unsigned_abs(), denom.unsigned_abs()) |
1495 | .and_then(|val| Self::signed_from_inner(val, -num.signum() * denom.signum())) |
1496 | } |
1497 | } |
1498 | } |
1499 | } |
1500 | |
1501 | #[allow(clippy::redundant_closure_call)] |
1502 | impl muldiv::MulDiv<$inner> for crate::Signed<$typ> { |
1503 | type Output = Self; |
1504 | |
1505 | #[inline] |
1506 | fn mul_div_floor(self, num: $inner, denom: $inner) -> Option<Self> { |
1507 | use crate::Signed::*; |
1508 | match self { |
1509 | Positive(lhs) => { |
1510 | $into_inner(lhs) |
1511 | .mul_div_floor(num, denom) |
1512 | .and_then(Self::positive_from_inner) |
1513 | } |
1514 | Negative(lhs) => { |
1515 | $into_inner(lhs) |
1516 | .mul_div_floor(num, denom) |
1517 | .and_then(Self::negative_from_inner) |
1518 | } |
1519 | } |
1520 | } |
1521 | |
1522 | #[inline] |
1523 | fn mul_div_round(self, num: $inner, denom: $inner) -> Option<Self> { |
1524 | use crate::Signed::*; |
1525 | match self { |
1526 | Positive(lhs) => { |
1527 | $into_inner(lhs) |
1528 | .mul_div_round(num, denom) |
1529 | .and_then(Self::positive_from_inner) |
1530 | } |
1531 | Negative(lhs) => { |
1532 | $into_inner(lhs) |
1533 | .mul_div_round(num, denom) |
1534 | .and_then(Self::negative_from_inner) |
1535 | } |
1536 | } |
1537 | } |
1538 | |
1539 | #[inline] |
1540 | fn mul_div_ceil(self, num: $inner, denom: $inner) -> Option<Self> { |
1541 | use crate::Signed::*; |
1542 | match self { |
1543 | Positive(lhs) => { |
1544 | $into_inner(lhs) |
1545 | .mul_div_ceil(num, denom) |
1546 | .and_then(Self::positive_from_inner) |
1547 | } |
1548 | Negative(lhs) => { |
1549 | $into_inner(lhs) |
1550 | .mul_div_ceil(num, denom) |
1551 | .and_then(Self::negative_from_inner) |
1552 | } |
1553 | } |
1554 | } |
1555 | } |
1556 | }; |
1557 | ); |
1558 | |
1559 | macro_rules! impl_format_value_traits( |
1560 | ($typ:ty, $format:ident, $format_value:ident, $inner:ty) => { |
1561 | impl FormattedValue for Option<$typ> { |
1562 | type FullRange = Self; |
1563 | |
1564 | #[inline] |
1565 | fn default_format() -> Format { |
1566 | Format::$format |
1567 | } |
1568 | |
1569 | #[inline] |
1570 | fn format(&self) -> Format { |
1571 | Format::$format |
1572 | } |
1573 | |
1574 | #[inline] |
1575 | fn is_some(&self) -> bool { |
1576 | Option::is_some(self) |
1577 | } |
1578 | |
1579 | #[inline] |
1580 | unsafe fn into_raw_value(self) -> i64 { |
1581 | IntoGlib::into_glib(self) as i64 |
1582 | } |
1583 | } |
1584 | |
1585 | impl FormattedValueFullRange for Option<$typ> { |
1586 | #[inline] |
1587 | unsafe fn from_raw(format: Format, value: i64) -> Self { |
1588 | debug_assert_eq!(format, Format::$format); |
1589 | FromGlib::from_glib(value as u64) |
1590 | } |
1591 | } |
1592 | |
1593 | impl FormattedValueNoneBuilder for Option<$typ> { |
1594 | #[inline] |
1595 | fn none() -> Option<$typ> { |
1596 | None |
1597 | } |
1598 | } |
1599 | |
1600 | impl From<Option<$typ>> for GenericFormattedValue { |
1601 | #[inline] |
1602 | fn from(v: Option<$typ>) -> Self { |
1603 | skip_assert_initialized!(); |
1604 | Self::$format_value(v) |
1605 | } |
1606 | } |
1607 | |
1608 | impl From<$typ> for GenericFormattedValue { |
1609 | #[inline] |
1610 | fn from(v: $typ) -> Self { |
1611 | skip_assert_initialized!(); |
1612 | Self::$format_value(Some(v)) |
1613 | } |
1614 | } |
1615 | |
1616 | impl FormattedValue for $typ { |
1617 | type FullRange = Option<$typ>; |
1618 | |
1619 | #[inline] |
1620 | fn default_format() -> Format { |
1621 | Format::$format |
1622 | } |
1623 | |
1624 | #[inline] |
1625 | fn format(&self) -> Format { |
1626 | Format::$format |
1627 | } |
1628 | |
1629 | #[inline] |
1630 | fn is_some(&self) -> bool { |
1631 | true |
1632 | } |
1633 | |
1634 | #[inline] |
1635 | unsafe fn into_raw_value(self) -> i64 { |
1636 | IntoGlib::into_glib(self) as i64 |
1637 | } |
1638 | } |
1639 | |
1640 | impl SpecificFormattedValue for Option<$typ> {} |
1641 | impl SpecificFormattedValueFullRange for Option<$typ> {} |
1642 | impl SpecificFormattedValue for $typ {} |
1643 | impl FormattedValueIntrinsic for $typ {} |
1644 | impl SpecificFormattedValueIntrinsic for $typ {} |
1645 | |
1646 | impl TryFrom<GenericFormattedValue> for Option<$typ> { |
1647 | type Error = FormattedValueError; |
1648 | #[inline] |
1649 | fn try_from(v: GenericFormattedValue) -> Result<Self, Self::Error> { |
1650 | skip_assert_initialized!(); |
1651 | if let GenericFormattedValue::$format_value(v) = v { |
1652 | Ok(v) |
1653 | } else { |
1654 | Err(FormattedValueError(v.format())) |
1655 | } |
1656 | } |
1657 | } |
1658 | |
1659 | impl TryFrom<$inner> for $typ { |
1660 | type Error = GlibNoneError; |
1661 | #[inline] |
1662 | fn try_from(v: $inner) -> Result<Self, GlibNoneError> { |
1663 | skip_assert_initialized!(); |
1664 | unsafe { Self::try_from_glib(v as i64) } |
1665 | } |
1666 | } |
1667 | |
1668 | impl TryFromGlib<i64> for $typ { |
1669 | type Error = GlibNoneError; |
1670 | #[inline] |
1671 | unsafe fn try_from_glib(val: i64) -> Result<Self, GlibNoneError> { |
1672 | skip_assert_initialized!(); |
1673 | <$typ as TryFromGlib<u64>>::try_from_glib(val as u64) |
1674 | } |
1675 | } |
1676 | }; |
1677 | ); |
1678 | |
1679 | macro_rules! option_glib_newtype_from_to { |
1680 | ($typ:ident, $none_value:expr) => { |
1681 | #[doc(hidden)] |
1682 | impl IntoGlib for $typ { |
1683 | type GlibType = u64; |
1684 | #[inline] |
1685 | fn into_glib(self) -> u64 { |
1686 | assert_ne!( |
1687 | self.0, $none_value, |
1688 | concat!( |
1689 | "attempt to build a `None` glib variant" , |
1690 | "from a non-`Option` type " , |
1691 | stringify!($typ), |
1692 | ), |
1693 | ); |
1694 | self.0 |
1695 | } |
1696 | } |
1697 | |
1698 | #[doc(hidden)] |
1699 | impl OptionIntoGlib for $typ { |
1700 | const GLIB_NONE: u64 = $none_value; |
1701 | } |
1702 | |
1703 | #[doc(hidden)] |
1704 | impl TryFromGlib<u64> for $typ { |
1705 | type Error = GlibNoneError; |
1706 | #[inline] |
1707 | unsafe fn try_from_glib(val: u64) -> Result<Self, GlibNoneError> { |
1708 | skip_assert_initialized!(); |
1709 | if val == $none_value { |
1710 | return Err(GlibNoneError); |
1711 | } |
1712 | |
1713 | Ok($typ(val)) |
1714 | } |
1715 | } |
1716 | }; |
1717 | } |
1718 | |
1719 | // FIXME we could automatically build `$displayable_option_name` |
1720 | // if `concat_idents!` was stable. |
1721 | // See: https://doc.rust-lang.org/std/macro.concat_idents.html |
1722 | macro_rules! glib_newtype_display { |
1723 | ($typ:ty) => { |
1724 | impl std::fmt::Display for $typ { |
1725 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
1726 | std::fmt::Display::fmt(&self.0, f) |
1727 | } |
1728 | } |
1729 | |
1730 | impl crate::utils::Displayable for $typ { |
1731 | type DisplayImpl = Self; |
1732 | fn display(self) -> Self { |
1733 | self |
1734 | } |
1735 | } |
1736 | }; |
1737 | |
1738 | ($typ:ty, Format::$format:ident) => { |
1739 | impl std::fmt::Display for $typ { |
1740 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
1741 | std::fmt::Display::fmt(&self.0, f)?; |
1742 | std::fmt::Write::write_char(f, ' ' )?; |
1743 | std::fmt::Display::fmt(&Format::$format, f) |
1744 | } |
1745 | } |
1746 | |
1747 | impl crate::utils::Displayable for $typ { |
1748 | type DisplayImpl = Self; |
1749 | fn display(self) -> Self { |
1750 | self |
1751 | } |
1752 | } |
1753 | }; |
1754 | |
1755 | ($typ:ty, $displayable_option_name:ident) => { |
1756 | glib_newtype_display!($typ); |
1757 | |
1758 | pub struct $displayable_option_name(Option<$typ>); |
1759 | |
1760 | impl std::fmt::Display for $displayable_option_name { |
1761 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
1762 | if let Some(val) = self.0.as_ref() { |
1763 | std::fmt::Display::fmt(val, f) |
1764 | } else { |
1765 | f.write_str("undef." ) |
1766 | } |
1767 | } |
1768 | } |
1769 | |
1770 | impl crate::utils::Displayable for Option<$typ> { |
1771 | type DisplayImpl = $displayable_option_name; |
1772 | fn display(self) -> Self::DisplayImpl { |
1773 | $displayable_option_name(self) |
1774 | } |
1775 | } |
1776 | }; |
1777 | |
1778 | ($typ:ty, $displayable_option_name:ident, Format::$format:ident) => { |
1779 | glib_newtype_display!($typ, Format::$format); |
1780 | |
1781 | pub struct $displayable_option_name(Option<$typ>); |
1782 | |
1783 | impl std::fmt::Display for $displayable_option_name { |
1784 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
1785 | if let Some(val) = self.0.as_ref() { |
1786 | std::fmt::Display::fmt(val, f) |
1787 | } else { |
1788 | write!(f, "undef. {}" , Format::$format) |
1789 | } |
1790 | } |
1791 | } |
1792 | |
1793 | impl crate::utils::Displayable for Option<$typ> { |
1794 | type DisplayImpl = $displayable_option_name; |
1795 | fn display(self) -> Self::DisplayImpl { |
1796 | $displayable_option_name(self) |
1797 | } |
1798 | } |
1799 | }; |
1800 | } |
1801 | |
1802 | macro_rules! impl_signed_int_into_signed( |
1803 | (u64) => { |
1804 | impl_signed_int_into_signed!(u64, u64, i64, |val: u64| val); |
1805 | }; |
1806 | |
1807 | (usize) => { |
1808 | impl_signed_int_into_signed!(usize, usize, isize, |val: usize| val); |
1809 | }; |
1810 | |
1811 | (u32) => { |
1812 | impl_signed_int_into_signed!(u32, u32, i32, |val: u32| val); |
1813 | }; |
1814 | |
1815 | ($newtyp:ty, u64) => { |
1816 | impl_signed_int_into_signed!($newtyp, u64, i64, |val: $newtyp| *val); |
1817 | }; |
1818 | |
1819 | ($newtyp:ty, u32) => { |
1820 | impl_signed_int_into_signed!($newtyp, u32, i32, |val: $newtyp| *val); |
1821 | }; |
1822 | |
1823 | ($typ:ty, $inner:ty, $signed:ty, $into_inner:expr) => { |
1824 | #[allow(clippy::redundant_closure_call)] |
1825 | impl TryFrom<crate::Signed<$typ>> for $signed { |
1826 | type Error = std::num::TryFromIntError; |
1827 | |
1828 | #[inline] |
1829 | fn try_from(value: crate::Signed<$typ>) -> Result<$signed, Self::Error> { |
1830 | assert_eq!(::std::mem::size_of::<$inner>(), ::std::mem::size_of::<$signed>()); |
1831 | |
1832 | match value { |
1833 | crate::Signed::Positive(value) => <$signed>::try_from($into_inner(value)), |
1834 | crate::Signed::Negative(value) => { |
1835 | let inner = $into_inner(value); |
1836 | // `$signed::MIN.abs()` can't be represented as an `$signed` |
1837 | if inner == (<$inner>::MAX >> 1) + 1 { |
1838 | Ok(<$signed>::MIN) |
1839 | } else { |
1840 | Ok(-<$signed>::try_from(inner)?) |
1841 | } |
1842 | }, |
1843 | } |
1844 | } |
1845 | } |
1846 | |
1847 | impl From<$signed> for crate::Signed<$typ> { |
1848 | #[inline] |
1849 | fn from(value: $signed) -> crate::Signed<$typ> { |
1850 | let abs = value.unsigned_abs(); |
1851 | if value.signum() >= 0 { |
1852 | Self::positive_from_inner(abs).unwrap() |
1853 | } else { |
1854 | Self::negative_from_inner(abs).unwrap() |
1855 | } |
1856 | } |
1857 | } |
1858 | }; |
1859 | ); |
1860 | |