1use crate::errors::option_expect;
2use crate::ExpType;
3use crate::{doc, errors};
4
5macro_rules! wrapping {
6 ($BUint: ident, $BInt: ident, $Digit: ident) => {
7 #[doc = doc::wrapping::impl_desc!()]
8 impl<const N: usize> $BUint<N> {
9 #[doc = doc::wrapping::wrapping_add!(U)]
10 #[must_use = doc::must_use_op!()]
11 #[inline]
12 pub const fn wrapping_add(self, rhs: Self) -> Self {
13 self.overflowing_add(rhs).0
14 }
15
16 #[doc = doc::wrapping::wrapping_add_signed!(U)]
17 #[must_use = doc::must_use_op!()]
18 #[inline]
19 pub const fn wrapping_add_signed(self, rhs: $BInt<N>) -> Self {
20 self.overflowing_add_signed(rhs).0
21 }
22
23 #[doc = doc::wrapping::wrapping_sub!(U)]
24 #[must_use = doc::must_use_op!()]
25 #[inline]
26 pub const fn wrapping_sub(self, rhs: Self) -> Self {
27 self.overflowing_sub(rhs).0
28 }
29
30 #[doc = doc::wrapping::wrapping_mul!(U)]
31 #[must_use = doc::must_use_op!()]
32 #[inline]
33 pub const fn wrapping_mul(self, rhs: Self) -> Self {
34 self.overflowing_mul(rhs).0
35 }
36
37 #[doc = doc::wrapping::wrapping_div!(U)]
38 #[must_use = doc::must_use_op!()]
39 #[inline]
40 pub const fn wrapping_div(self, rhs: Self) -> Self {
41 option_expect!(self.checked_div(rhs), errors::err_msg!(errors::div_by_zero_message!()))
42 }
43
44 #[doc = doc::wrapping::wrapping_div_euclid!(U)]
45 #[must_use = doc::must_use_op!()]
46 #[inline]
47 pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
48 self.wrapping_div(rhs)
49 }
50
51 #[doc = doc::wrapping::wrapping_rem!(U)]
52 #[must_use = doc::must_use_op!()]
53 #[inline]
54 pub const fn wrapping_rem(self, rhs: Self) -> Self {
55 option_expect!(self.checked_rem(rhs), errors::err_msg!(errors::rem_by_zero_message!()))
56 }
57
58 #[doc = doc::wrapping::wrapping_rem_euclid!(U)]
59 #[must_use = doc::must_use_op!()]
60 #[inline]
61 pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
62 self.wrapping_rem(rhs)
63 }
64
65 #[doc = doc::wrapping::wrapping_neg!(U)]
66 #[must_use = doc::must_use_op!()]
67 #[inline]
68 pub const fn wrapping_neg(self) -> Self {
69 self.overflowing_neg().0
70 }
71
72 #[doc = doc::wrapping::wrapping_shl!(U)]
73 #[must_use = doc::must_use_op!()]
74 #[inline]
75 pub const fn wrapping_shl(self, rhs: ExpType) -> Self {
76 self.overflowing_shl(rhs).0
77 }
78
79 #[doc = doc::wrapping::wrapping_shr!(U)]
80 #[must_use = doc::must_use_op!()]
81 #[inline]
82 pub const fn wrapping_shr(self, rhs: ExpType) -> Self {
83 self.overflowing_shr(rhs).0
84 }
85
86 #[doc = doc::wrapping::wrapping_pow!(U)]
87 #[must_use = doc::must_use_op!()]
88 #[inline]
89 pub const fn wrapping_pow(mut self, mut pow: ExpType) -> Self {
90 if pow == 0 {
92 return Self::ONE;
93 }
94 let mut y = Self::ONE;
95 while pow > 1 {
96 if pow & 1 == 1 {
97 y = self.wrapping_mul(y);
98 }
99 self = self.wrapping_mul(self);
100 pow >>= 1;
101 }
102 self.wrapping_mul(y)
103 }
104
105 #[doc = doc::wrapping::wrapping_next_power_of_two!(U 256)]
106 #[must_use = doc::must_use_op!()]
107 #[inline]
108 pub const fn wrapping_next_power_of_two(self) -> Self {
109 match self.checked_next_power_of_two() {
110 Some(int) => int,
111 None => Self::ZERO,
112 }
113 }
114 }
115 };
116}
117
118#[cfg(test)]
119crate::test::all_digit_tests! {
120 use crate::test::{test_bignum, types::{utest, itest}};
121
122 #[test]
123 #[should_panic(expected = "attempt to divide by zero")]
124 fn div_by_zero_panic() {
125 let a = UTEST::MAX;
126 let b = UTEST::ZERO;
127 let _ = a.wrapping_div(b);
128 }
129
130 #[test]
131 #[should_panic(expected = "attempt to calculate the remainder with a divisor of zero")]
132 fn rem_by_zero_panic() {
133 let a = UTEST::MAX;
134 let b = UTEST::ZERO;
135 let _ = a.wrapping_rem(b);
136 }
137
138 test_bignum! {
139 function: <utest>::wrapping_add(a: utest, b: utest)
140 }
141 test_bignum! {
142 function: <utest>::wrapping_add_signed(a: utest, b: itest)
143 }
144 test_bignum! {
145 function: <utest>::wrapping_sub(a: utest, b: utest)
146 }
147 test_bignum! {
148 function: <utest>::wrapping_mul(a: utest, b: utest)
149 }
150 test_bignum! {
151 function: <utest>::wrapping_div(a: utest, b: utest),
152 skip: b == 0
153 }
154 test_bignum! {
155 function: <utest>::wrapping_div_euclid(a: utest, b: utest),
156 skip: b == 0
157 }
158 test_bignum! {
159 function: <utest>::wrapping_rem(a: utest, b: utest),
160 skip: b == 0
161 }
162 test_bignum! {
163 function: <utest>::wrapping_rem_euclid(a: utest, b: utest),
164 skip: b == 0
165 }
166 test_bignum! {
167 function: <utest>::wrapping_neg(a: utest)
168 }
169 test_bignum! {
170 function: <utest>::wrapping_shl(a: utest, b: u16)
171 }
172 test_bignum! {
173 function: <utest>::wrapping_shr(a: utest, b: u16)
174 }
175 test_bignum! {
176 function: <utest>::wrapping_pow(a: utest, b: u16)
177 }
178 test_bignum! {
179 function: <utest>::wrapping_next_power_of_two(a: utest),
180 cases: [
181 (utest::MAX)
182 ]
183 }
184}
185
186crate::macro_impl!(wrapping);