Skip to main content

bnum/buint/
saturating.rs

1use crate::doc;
2use crate::ExpType;
3
4macro_rules! saturating {
5    ($BUint: ident, $BInt: ident, $Digit: ident) => {
6        #[doc = doc::saturating::impl_desc!()]
7        impl<const N: usize> $BUint<N> {
8            #[inline]
9            const fn saturate_up((int, overflow): ($BUint<N>, bool)) -> $BUint<N> {
10                if overflow {
11                    $BUint::MAX
12                } else {
13                    int
14                }
15            }
16
17            #[inline]
18            const fn saturate_down((int, overflow): ($BUint<N>, bool)) -> $BUint<N> {
19                if overflow {
20                    $BUint::MIN
21                } else {
22                    int
23                }
24            }
25
26            #[doc = doc::saturating::saturating_add!(U)]
27            #[must_use = doc::must_use_op!()]
28            #[inline]
29            pub const fn saturating_add(self, rhs: Self) -> Self {
30                Self::saturate_up(self.overflowing_add(rhs))
31            }
32
33            #[doc = doc::saturating::saturating_add_signed!(U)]
34            #[must_use = doc::must_use_op!()]
35            #[inline]
36            pub const fn saturating_add_signed(self, rhs: $BInt<N>) -> Self {
37                if rhs.is_negative() {
38                    Self::saturate_down(self.overflowing_add_signed(rhs))
39                } else {
40                    Self::saturate_up(self.overflowing_add_signed(rhs))
41                }
42            }
43
44            #[doc = doc::saturating::saturating_sub!(U)]
45            #[must_use = doc::must_use_op!()]
46            #[inline]
47            pub const fn saturating_sub(self, rhs: Self) -> Self {
48                Self::saturate_down(self.overflowing_sub(rhs))
49            }
50
51            #[doc = doc::saturating::saturating_mul!(U)]
52            #[must_use = doc::must_use_op!()]
53            #[inline]
54            pub const fn saturating_mul(self, rhs: Self) -> Self {
55                Self::saturate_up(self.overflowing_mul(rhs))
56            }
57
58            #[doc = doc::saturating::saturating_div!(U)]
59            #[must_use = doc::must_use_op!()]
60            #[inline]
61            pub const fn saturating_div(self, rhs: Self) -> Self {
62                self.div_euclid(rhs)
63            }
64
65            #[doc = doc::saturating::saturating_pow!(U)]
66            #[must_use = doc::must_use_op!()]
67            #[inline]
68            pub const fn saturating_pow(self, exp: ExpType) -> Self {
69                Self::saturate_up(self.overflowing_pow(exp))
70            }
71        }
72    };
73}
74
75#[cfg(test)]
76crate::test::all_digit_tests! {
77    use crate::test::test_bignum;
78    use crate::test::types::*;
79
80    test_bignum! {
81        function: <utest>::saturating_add(a: utest, b: utest)
82    }
83    test_bignum! {
84        function: <utest>::saturating_add_signed(a: utest, b: itest)
85    }
86    test_bignum! {
87        function: <utest>::saturating_sub(a: utest, b: utest)
88    }
89    test_bignum! {
90        function: <utest>::saturating_mul(a: utest, b: utest)
91    }
92    test_bignum! {
93        function: <utest>::saturating_div(a: utest, b: utest),
94        skip: b == 0
95    }
96    test_bignum! {
97        function: <utest>::saturating_pow(a: utest, b: u16)
98    }
99}
100
101crate::macro_impl!(saturating);