1use super::*;
17
18impl<E: Environment, I: IntegerType> Neg for Integer<E, I> {
19 type Output = Integer<E, I>;
20
21 #[inline]
23 fn neg(self) -> Self::Output {
24 match I::is_signed() {
25 true => match self.integer.checked_neg() {
26 Some(integer) => Integer::new(integer),
27 None => E::halt(format!("Integer negation failed on: {}", self.integer)),
28 },
29 false => E::halt("Negation of unsigned integers is not supported."),
30 }
31 }
32}
33
34impl<E: Environment, I: IntegerType> AbsChecked for Integer<E, I> {
35 type Output = Integer<E, I>;
36
37 #[inline]
39 fn abs_checked(self) -> Self::Output {
40 match I::is_signed() {
41 true => match self.integer.checked_abs() {
42 Some(integer) => Integer::new(integer),
43 None => E::halt(format!("Integer absolute value failed on: {}", self.integer)),
44 },
45 false => self,
46 }
47 }
48}
49
50impl<E: Environment, I: IntegerType> AbsWrapped for Integer<E, I> {
51 type Output = Integer<E, I>;
52
53 #[inline]
55 fn abs_wrapped(self) -> Self::Output {
56 match I::is_signed() {
57 true => Integer::new(self.integer.wrapping_abs()),
58 false => self,
59 }
60 }
61}
62
63impl<E: Environment, I: IntegerType> Add<Integer<E, I>> for Integer<E, I> {
64 type Output = Integer<E, I>;
65
66 #[inline]
68 fn add(self, other: Integer<E, I>) -> Self::Output {
69 match self.integer.checked_add(&other.integer) {
70 Some(integer) => Integer::new(integer),
71 None => E::halt(format!("Integer addition failed on: {self} and {other}")),
72 }
73 }
74}
75
76impl<E: Environment, I: IntegerType> Add<&Integer<E, I>> for Integer<E, I> {
77 type Output = Integer<E, I>;
78
79 #[inline]
81 fn add(self, other: &Integer<E, I>) -> Self::Output {
82 match self.integer.checked_add(&other.integer) {
83 Some(integer) => Integer::new(integer),
84 None => E::halt(format!("Integer addition failed on: {self} and {other}")),
85 }
86 }
87}
88
89impl<E: Environment, I: IntegerType> AddWrapped<Integer<E, I>> for Integer<E, I> {
90 type Output = Integer<E, I>;
91
92 #[inline]
94 fn add_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
95 Integer::new(self.integer.wrapping_add(&other.integer))
96 }
97}
98
99impl<E: Environment, I: IntegerType> AddAssign<Integer<E, I>> for Integer<E, I> {
100 #[inline]
102 fn add_assign(&mut self, other: Integer<E, I>) {
103 match self.integer.checked_add(&other.integer) {
104 Some(integer) => self.integer = integer,
105 None => E::halt(format!("Integer addition failed on: {self} and {other}")),
106 }
107 }
108}
109
110impl<E: Environment, I: IntegerType> AddAssign<&Integer<E, I>> for Integer<E, I> {
111 #[inline]
113 fn add_assign(&mut self, other: &Integer<E, I>) {
114 match self.integer.checked_add(&other.integer) {
115 Some(integer) => self.integer = integer,
116 None => E::halt(format!("Integer addition failed on: {self} and {other}")),
117 }
118 }
119}
120
121impl<E: Environment, I: IntegerType> Sub<Integer<E, I>> for Integer<E, I> {
122 type Output = Integer<E, I>;
123
124 #[inline]
126 fn sub(self, other: Integer<E, I>) -> Self::Output {
127 match self.integer.checked_sub(&other.integer) {
128 Some(integer) => Integer::new(integer),
129 None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
130 }
131 }
132}
133
134impl<E: Environment, I: IntegerType> Sub<&Integer<E, I>> for Integer<E, I> {
135 type Output = Integer<E, I>;
136
137 #[inline]
139 fn sub(self, other: &Integer<E, I>) -> Self::Output {
140 match self.integer.checked_sub(&other.integer) {
141 Some(integer) => Integer::new(integer),
142 None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
143 }
144 }
145}
146
147impl<E: Environment, I: IntegerType> SubWrapped<Integer<E, I>> for Integer<E, I> {
148 type Output = Integer<E, I>;
149
150 #[inline]
152 fn sub_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
153 Integer::new(self.integer.wrapping_sub(&other.integer))
154 }
155}
156
157impl<E: Environment, I: IntegerType> SubAssign<Integer<E, I>> for Integer<E, I> {
158 #[inline]
160 fn sub_assign(&mut self, other: Integer<E, I>) {
161 match self.integer.checked_sub(&other.integer) {
162 Some(integer) => self.integer = integer,
163 None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
164 }
165 }
166}
167
168impl<E: Environment, I: IntegerType> SubAssign<&Integer<E, I>> for Integer<E, I> {
169 #[inline]
171 fn sub_assign(&mut self, other: &Integer<E, I>) {
172 match self.integer.checked_sub(&other.integer) {
173 Some(integer) => self.integer = integer,
174 None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
175 }
176 }
177}
178
179impl<E: Environment, I: IntegerType> Mul<Integer<E, I>> for Integer<E, I> {
180 type Output = Integer<E, I>;
181
182 #[inline]
184 fn mul(self, other: Integer<E, I>) -> Self::Output {
185 match self.integer.checked_mul(&other.integer) {
186 Some(integer) => Integer::new(integer),
187 None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
188 }
189 }
190}
191
192impl<E: Environment, I: IntegerType> Mul<&Integer<E, I>> for Integer<E, I> {
193 type Output = Integer<E, I>;
194
195 #[inline]
197 fn mul(self, other: &Integer<E, I>) -> Self::Output {
198 match self.integer.checked_mul(&other.integer) {
199 Some(integer) => Integer::new(integer),
200 None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
201 }
202 }
203}
204
205impl<E: Environment, I: IntegerType> MulWrapped<Integer<E, I>> for Integer<E, I> {
206 type Output = Integer<E, I>;
207
208 #[inline]
210 fn mul_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
211 Integer::new(self.integer.wrapping_mul(&other.integer))
212 }
213}
214
215impl<E: Environment, I: IntegerType> MulAssign<Integer<E, I>> for Integer<E, I> {
216 #[inline]
218 fn mul_assign(&mut self, other: Integer<E, I>) {
219 match self.integer.checked_mul(&other.integer) {
220 Some(integer) => self.integer = integer,
221 None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
222 }
223 }
224}
225
226impl<E: Environment, I: IntegerType> MulAssign<&Integer<E, I>> for Integer<E, I> {
227 #[inline]
229 fn mul_assign(&mut self, other: &Integer<E, I>) {
230 match self.integer.checked_mul(&other.integer) {
231 Some(integer) => self.integer = integer,
232 None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
233 }
234 }
235}
236
237impl<E: Environment, I: IntegerType> Div<Integer<E, I>> for Integer<E, I> {
238 type Output = Integer<E, I>;
239
240 #[inline]
242 fn div(self, other: Integer<E, I>) -> Self::Output {
243 match self.integer.checked_div(&other.integer) {
244 Some(integer) => Integer::new(integer),
245 None => E::halt(format!("Integer division failed on: {self} and {other}")),
246 }
247 }
248}
249
250impl<E: Environment, I: IntegerType> Div<&Integer<E, I>> for Integer<E, I> {
251 type Output = Integer<E, I>;
252
253 #[inline]
255 fn div(self, other: &Integer<E, I>) -> Self::Output {
256 match self.integer.checked_div(&other.integer) {
257 Some(integer) => Integer::new(integer),
258 None => E::halt(format!("Integer division failed on: {self} and {other}")),
259 }
260 }
261}
262
263impl<E: Environment, I: IntegerType> DivWrapped<Integer<E, I>> for Integer<E, I> {
264 type Output = Integer<E, I>;
265
266 #[inline]
268 fn div_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
269 match other.is_zero() {
270 true => E::halt(format!("Integer division by zero: {self} / {other}")),
271 false => Integer::new(self.integer.wrapping_div(&other.integer)),
272 }
273 }
274}
275
276impl<E: Environment, I: IntegerType> DivAssign<Integer<E, I>> for Integer<E, I> {
277 #[inline]
279 fn div_assign(&mut self, other: Integer<E, I>) {
280 match self.integer.checked_div(&other.integer) {
281 Some(integer) => self.integer = integer,
282 None => E::halt(format!("Integer division failed on: {self} and {other}")),
283 }
284 }
285}
286
287impl<E: Environment, I: IntegerType> DivAssign<&Integer<E, I>> for Integer<E, I> {
288 #[inline]
290 fn div_assign(&mut self, other: &Integer<E, I>) {
291 match self.integer.checked_div(&other.integer) {
292 Some(integer) => self.integer = integer,
293 None => E::halt(format!("Integer division failed on: {self} and {other}")),
294 }
295 }
296}
297
298impl<E: Environment, I: IntegerType> Modulo<Integer<E, I>> for Integer<E, I> {
299 type Output = Integer<E, I>;
300
301 #[inline]
303 fn modulo(&self, other: &Integer<E, I>) -> Self {
304 match I::is_signed() {
305 true => E::halt("Taking the modulus of signed integers is not supported"),
306 false => match other.is_zero() {
307 true => E::halt(format!("Integer modulus by zero: {self} % {other}")),
308 false => Integer::new(self.integer.modulo(&other.integer)),
309 },
310 }
311 }
312}
313
314impl<E: Environment, I: IntegerType> Rem<Integer<E, I>> for Integer<E, I> {
315 type Output = Integer<E, I>;
316
317 #[inline]
319 fn rem(self, other: Integer<E, I>) -> Self {
320 match self.integer.checked_rem(&other.integer) {
321 Some(integer) => Integer::new(integer),
322 None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
323 }
324 }
325}
326
327impl<E: Environment, I: IntegerType> Rem<&Integer<E, I>> for Integer<E, I> {
328 type Output = Integer<E, I>;
329
330 #[inline]
332 fn rem(self, other: &Integer<E, I>) -> Self {
333 match self.integer.checked_rem(&other.integer) {
334 Some(integer) => Integer::new(integer),
335 None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
336 }
337 }
338}
339
340impl<E: Environment, I: IntegerType> RemWrapped<Integer<E, I>> for Integer<E, I> {
341 type Output = Integer<E, I>;
342
343 #[inline]
345 fn rem_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
346 match other.is_zero() {
347 true => E::halt(format!("Integer remainder by zero: {self} % {other}")),
348 false => Integer::new(self.integer.wrapping_rem(&other.integer)),
349 }
350 }
351}
352
353impl<E: Environment, I: IntegerType> RemAssign<Integer<E, I>> for Integer<E, I> {
354 #[inline]
356 fn rem_assign(&mut self, other: Integer<E, I>) {
357 match self.integer.checked_rem(&other.integer) {
358 Some(integer) => self.integer = integer,
359 None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
360 }
361 }
362}
363
364impl<E: Environment, I: IntegerType> RemAssign<&Integer<E, I>> for Integer<E, I> {
365 #[inline]
367 fn rem_assign(&mut self, other: &Integer<E, I>) {
368 match self.integer.checked_rem(&other.integer) {
369 Some(integer) => self.integer = integer,
370 None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
371 }
372 }
373}
374
375impl<E: Environment, I: IntegerType, M: Magnitude> Pow<Integer<E, M>> for Integer<E, I> {
376 type Output = Integer<E, I>;
377
378 #[inline]
380 fn pow(self, other: Integer<E, M>) -> Self::Output {
381 match self.integer.checked_pow(&other.integer.to_u32().unwrap()) {
382 Some(integer) => Integer::new(integer),
384 None => E::halt(format!("Integer power failed on: {self} and {other}")),
385 }
386 }
387}
388
389impl<E: Environment, I: IntegerType, M: Magnitude> Pow<&Integer<E, M>> for Integer<E, I> {
390 type Output = Integer<E, I>;
391
392 #[inline]
394 fn pow(self, other: &Integer<E, M>) -> Self::Output {
395 match self.integer.checked_pow(&other.integer.to_u32().unwrap()) {
396 Some(integer) => Integer::new(integer),
398 None => E::halt(format!("Integer power failed on: {self} and {other}")),
399 }
400 }
401}
402
403impl<E: Environment, I: IntegerType, M: Magnitude> PowWrapped<Integer<E, M>> for Integer<E, I> {
404 type Output = Integer<E, I>;
405
406 #[inline]
408 fn pow_wrapped(&self, other: &Integer<E, M>) -> Self::Output {
409 Integer::new(self.integer.wrapping_pow(&other.integer.to_u32().unwrap()))
410 }
411}
412
413impl<E: Environment, I: IntegerType> Square for Integer<E, I> {
414 type Output = Integer<E, I>;
415
416 #[inline]
418 fn square(&self) -> Self::Output {
419 match self.integer.checked_mul(&self.integer) {
420 Some(integer) => Integer::new(integer),
421 None => E::halt(format!("Integer square failed on: {}", self.integer)),
422 }
423 }
424}