reweb3_num/bint/
checked.rs1macro_rules! checked_ilog {
2 ($method: ident $(, $base: ident: $ty: ty)?) => {
3 #[doc = doc::checked::$method!(I)]
4 #[must_use = doc::must_use_op!()]
5 #[inline]
6 pub const fn $method(self $(, $base: $ty)?) -> Option<ExpType> {
7 if self.is_negative() {
8 None
9 } else {
10 self.bits.$method($($base)?)
11 }
12 }
13 }
14}
15
16use crate::doc;
17use crate::int::checked::tuple_to_option;
18use crate::ExpType;
19
20macro_rules! checked {
21 ($BUint: ident, $BInt: ident, $Digit: ident) => {
22 #[doc = doc::checked::impl_desc!()]
23 impl<const N: usize> $BInt<N> {
24 #[doc = doc::checked::checked_add!(I)]
25 #[must_use = doc::must_use_op!()]
26 #[inline]
27 pub const fn checked_add(self, rhs: Self) -> Option<Self> {
28 tuple_to_option(self.overflowing_add(rhs))
29 }
30
31 #[doc = doc::checked::checked_add_unsigned!(I)]
32 #[must_use = doc::must_use_op!()]
33 #[inline]
34 pub const fn checked_add_unsigned(self, rhs: $BUint<N>) -> Option<Self> {
35 tuple_to_option(self.overflowing_add_unsigned(rhs))
36 }
37
38 #[doc = doc::checked::checked_sub!(I)]
39 #[must_use = doc::must_use_op!()]
40 #[inline]
41 pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
42 tuple_to_option(self.overflowing_sub(rhs))
43 }
44
45 #[doc = doc::checked::checked_sub_unsigned!(I)]
46 #[must_use = doc::must_use_op!()]
47 #[inline]
48 pub const fn checked_sub_unsigned(self, rhs: $BUint<N>) -> Option<Self> {
49 tuple_to_option(self.overflowing_sub_unsigned(rhs))
50 }
51
52 #[doc = doc::checked::checked_mul!(I)]
53 #[must_use = doc::must_use_op!()]
54 #[inline]
55 pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
56 tuple_to_option(self.overflowing_mul(rhs))
57 }
58
59 #[doc = doc::checked::checked_div!(I)]
60 #[must_use = doc::must_use_op!()]
61 #[inline]
62 pub const fn checked_div(self, rhs: Self) -> Option<Self> {
63 if rhs.is_zero() {
64 None
65 } else {
66 tuple_to_option(self.overflowing_div(rhs))
67 }
68 }
69
70 #[doc = doc::checked::checked_div_euclid!(I)]
71 #[must_use = doc::must_use_op!()]
72 #[inline]
73 pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
74 if rhs.is_zero() {
75 None
76 } else {
77 tuple_to_option(self.overflowing_div_euclid(rhs))
78 }
79 }
80
81 #[doc = doc::checked::checked_rem!(I)]
82 #[must_use = doc::must_use_op!()]
83 #[inline]
84 pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
85 if rhs.is_zero() {
86 None
87 } else {
88 tuple_to_option(self.overflowing_rem(rhs))
89 }
90 }
91
92 #[doc = doc::checked::checked_rem_euclid!(I)]
93 #[must_use = doc::must_use_op!()]
94 #[inline]
95 pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
96 if rhs.is_zero() {
97 None
98 } else {
99 tuple_to_option(self.overflowing_rem_euclid(rhs))
100 }
101 }
102
103 #[doc = doc::checked::checked_neg!(I)]
104 #[must_use = doc::must_use_op!()]
105 #[inline]
106 pub const fn checked_neg(self) -> Option<Self> {
107 tuple_to_option(self.overflowing_neg())
108 }
109
110 #[doc = doc::checked::checked_shl!(I)]
111 #[must_use = doc::must_use_op!()]
112 #[inline]
113 pub const fn checked_shl(self, rhs: ExpType) -> Option<Self> {
114 tuple_to_option(self.overflowing_shl(rhs))
115 }
116
117 #[doc = doc::checked::checked_shr!(I)]
118 #[must_use = doc::must_use_op!()]
119 #[inline]
120 pub const fn checked_shr(self, rhs: ExpType) -> Option<Self> {
121 tuple_to_option(self.overflowing_shr(rhs))
122 }
123
124 #[doc = doc::checked::checked_abs!(I)]
125 #[must_use = doc::must_use_op!()]
126 #[inline]
127 pub const fn checked_abs(self) -> Option<Self> {
128 tuple_to_option(self.overflowing_abs())
129 }
130
131 #[doc = doc::checked::checked_pow!(I)]
132 #[must_use = doc::must_use_op!()]
133 #[inline]
134 pub const fn checked_pow(self, pow: ExpType) -> Option<Self> {
135 match self.unsigned_abs().checked_pow(pow) {
136 Some(u) => {
137 let out = Self::from_bits(u);
138 let neg = self.is_negative();
139 if !neg || pow & 1 == 0 {
140 if out.is_negative() {
141 None
142 } else {
143 Some(out)
144 }
145 } else {
146 let out = out.wrapping_neg();
147 if !out.is_negative() {
148 None
149 } else {
150 Some(out)
151 }
152 }
153 }
154 None => None,
155 }
156 }
157
158 #[doc = doc::checked::checked_next_multiple_of!(I)]
159 #[must_use = doc::must_use_op!()]
160 #[inline]
161 pub const fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
162 if rhs.is_zero() {
163 return None;
164 }
165 let rem = self.wrapping_rem_euclid(rhs);
166 if rem.is_zero() {
167 return Some(self);
168 }
169 if rem.is_negative() == rhs.is_negative() {
170 self.checked_add(rhs.wrapping_sub(rem))
171 } else {
172 self.checked_sub(rem)
173 }
174 }
175
176 #[doc = doc::checked::checked_ilog!(I)]
177 #[must_use = doc::must_use_op!()]
178 #[inline]
179 pub const fn checked_ilog(self, base: Self) -> Option<ExpType> {
180 if base.is_negative() || self.is_negative() {
181 None
182 } else {
183 self.to_bits().checked_ilog(base.to_bits())
184 }
185 }
186
187 checked_ilog!(checked_ilog2);
188 checked_ilog!(checked_ilog10);
189 }
190 };
191}
192
193crate::macro_impl!(checked);