gstreamer/format/
macros.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3macro_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
22macro_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
111macro_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
130macro_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
199macro_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
257macro_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
573macro_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
952macro_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
1317macro_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
1443macro_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
1559macro_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
1679macro_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
1722macro_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
1802macro_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);