1use super::BitInt;
8
9macro_rules! impl_ops {
10 ($T:ty) => {
11 impl<const N: u32> BitInt<$T, N> {
12 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 7>::new(42).unwrap();")]
22 #[must_use]
27 #[inline]
28 pub const fn checked_add(self, rhs: $T) -> Option<Self> {
29 if let Some(result) = self.get().checked_add(rhs) {
30 Self::new(result)
31 } else {
32 None
33 }
34 }
35
36 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 7>::new(-42).unwrap();")]
46 #[must_use]
51 #[inline]
52 pub const fn checked_sub(self, rhs: $T) -> Option<Self> {
53 if let Some(result) = self.get().checked_sub(rhs) {
54 Self::new(result)
55 } else {
56 None
57 }
58 }
59
60 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 7>::new(21).unwrap();")]
70 #[must_use]
75 #[inline]
76 pub const fn checked_mul(self, rhs: $T) -> Option<Self> {
77 if let Some(result) = self.get().checked_mul(rhs) {
78 Self::new(result)
79 } else {
80 None
81 }
82 }
83
84 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 7>::new(42).unwrap();")]
94 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 7>::MIN.checked_div(-1), None);")]
98 #[must_use]
100 #[inline]
101 pub const fn checked_div(self, rhs: $T) -> Option<Self> {
102 if let Some(result) = self.get().checked_div(rhs) {
103 Self::new(result)
104 } else {
105 None
106 }
107 }
108
109 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 7>::new(42).unwrap();")]
119 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 7>::MIN.checked_div_euclid(-1), None);")]
123 #[must_use]
125 #[inline]
126 pub const fn checked_div_euclid(self, rhs: $T) -> Option<Self> {
127 if let Some(result) = self.get().checked_div_euclid(rhs) {
128 Self::new(result)
129 } else {
130 None
131 }
132 }
133
134 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 4>::new(5).unwrap();")]
144 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 4>::MIN.checked_rem(-1), None);")]
148 #[must_use]
150 #[inline]
151 pub const fn checked_rem(self, rhs: $T) -> Option<Self> {
152 match self.get().checked_rem(rhs) {
153 Some(result) if self.checked_div(rhs).is_some() => Self::new(result),
154 _ => None,
155 }
156 }
157
158 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 4>::new(5).unwrap();")]
168 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 4>::MIN.checked_rem_euclid(-1), None);")]
172 #[must_use]
174 #[inline]
175 pub const fn checked_rem_euclid(self, rhs: $T) -> Option<Self> {
176 match self.get().checked_rem_euclid(rhs) {
177 Some(result) if self.checked_div_euclid(rhs).is_some() => Self::new(result),
178 _ => None,
179 }
180 }
181
182 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 4>::new(5).unwrap();")]
194 #[must_use]
198 #[inline]
199 pub const fn checked_ilog(self, base: $T) -> Option<u32> {
200 self.get().checked_ilog(base)
201 }
202
203 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 3>::new(2).unwrap();")]
213 #[must_use]
217 #[inline]
218 pub const fn checked_ilog2(self) -> Option<u32> {
219 self.get().checked_ilog2()
220 }
221
222 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 5>::new(10).unwrap();")]
232 #[must_use]
236 #[inline]
237 pub const fn checked_ilog10(self) -> Option<u32> {
238 self.get().checked_ilog10()
239 }
240
241 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 4>::new(5).unwrap();")]
251 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 4>::MIN.checked_neg(), None);")]
254 #[must_use]
256 #[inline]
257 pub const fn checked_neg(self) -> Option<Self> {
258 if let Some(result) = self.get().checked_neg() {
259 Self::new(result)
260 } else {
261 None
262 }
263 }
264
265 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 6>::new(0x01).unwrap();")]
276 #[doc = concat!("let m = BitInt::<", stringify!($T), ", 6>::new(0x10).unwrap();")]
277 #[doc = concat!("assert_eq!(m.checked_shl(", stringify!($T), "::BITS - 1).map(BitInt::get), Some(0x00));")]
281 #[must_use]
283 #[inline]
284 pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
285 if let Some(result) = self.get().checked_shl(rhs) {
286 Self::new(result)
287 } else {
288 None
289 }
290 }
291
292 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 6>::new(0x10).unwrap();")]
303 #[must_use]
308 #[inline]
309 pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
310 if let Some(result) = self.get().checked_shr(rhs) {
311 Self::new(result)
312 } else {
313 None
314 }
315 }
316
317 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 4>::new(-5).unwrap();")]
327 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 4>::MIN.checked_abs(), None);")]
330 #[must_use]
332 #[inline]
333 pub const fn checked_abs(self) -> Option<Self> {
334 if let Some(result) = self.get().checked_abs() {
335 Self::new(result)
336 } else {
337 None
338 }
339 }
340
341 #[doc = concat!("let n = BitInt::<", stringify!($T), ", 8>::new(8).unwrap();")]
351 #[doc = concat!("assert_eq!(BitInt::<", stringify!($T), ", 8>::MAX.checked_pow(2), None);")]
354 #[must_use]
356 #[inline]
357 pub const fn checked_pow(self, exp: u32) -> Option<Self> {
358 if let Some(result) = self.get().checked_pow(exp) {
359 Self::new(result)
360 } else {
361 None
362 }
363 }
364 }
365 };
366}
367impl_ops!(i8);
368impl_ops!(i16);
369impl_ops!(i32);
370impl_ops!(i64);
371impl_ops!(i128);
372impl_ops!(isize);
373
374#[cfg(test)]
375mod tests {
376 use super::super::BitI8;
377
378 #[test]
379 fn checked_add() {
380 let n = BitI8::<7>::new(42).unwrap();
381
382 assert_eq!(n.checked_add(21).map(BitI8::get), Some(63));
383 assert!(n.checked_add(22).is_none());
384 }
385
386 #[test]
387 const fn checked_add_is_const_fn() {
388 const _: Option<BitI8<7>> = BitI8::<7>::MAX.checked_add(1);
389 }
390
391 #[test]
392 fn checked_sub() {
393 let n = BitI8::<7>::new(-42).unwrap();
394
395 assert_eq!(n.checked_sub(22).map(BitI8::get), Some(-64));
396 assert!(n.checked_sub(23).is_none());
397 }
398
399 #[test]
400 const fn checked_sub_is_const_fn() {
401 const _: Option<BitI8<7>> = BitI8::<7>::MIN.checked_sub(1);
402 }
403
404 #[test]
405 fn checked_mul() {
406 let n = BitI8::<7>::new(21).unwrap();
407
408 assert_eq!(n.checked_mul(2).map(BitI8::get), Some(42));
409 assert!(n.checked_mul(4).is_none());
410 }
411
412 #[test]
413 const fn checked_mul_is_const_fn() {
414 const _: Option<BitI8<7>> = BitI8::<7>::MAX.checked_mul(2);
415 }
416
417 #[test]
418 fn checked_div() {
419 let n = BitI8::<7>::new(42).unwrap();
420
421 assert_eq!(n.checked_div(2).map(BitI8::get), Some(21));
422 assert!(n.checked_div(0).is_none());
423 assert!(BitI8::<7>::MIN.checked_div(-1).is_none());
424 }
425
426 #[test]
427 const fn checked_div_is_const_fn() {
428 const _: Option<BitI8<7>> = BitI8::<7>::MAX.checked_div(0);
429 }
430
431 #[test]
432 fn checked_div_euclid() {
433 let n = BitI8::<7>::new(42).unwrap();
434
435 assert_eq!(n.checked_div_euclid(2).map(BitI8::get), Some(21));
436 assert!(n.checked_div_euclid(0).is_none());
437 assert!(BitI8::<7>::MIN.checked_div_euclid(-1).is_none());
438 }
439
440 #[test]
441 const fn checked_div_euclid_is_const_fn() {
442 const _: Option<BitI8<7>> = BitI8::<7>::MAX.checked_div_euclid(0);
443 }
444
445 #[test]
446 fn checked_rem() {
447 let n = BitI8::<4>::new(5).unwrap();
448
449 assert_eq!(n.checked_rem(2).map(BitI8::get), Some(1));
450 assert!(n.checked_rem(0).is_none());
451 assert!(BitI8::<4>::MIN.checked_rem(-1).is_none());
452 }
453
454 #[test]
455 const fn checked_rem_is_const_fn() {
456 const _: Option<BitI8<4>> = BitI8::<4>::MAX.checked_rem(0);
457 }
458
459 #[test]
460 fn checked_rem_euclid() {
461 let n = BitI8::<4>::new(5).unwrap();
462
463 assert_eq!(n.checked_rem_euclid(2).map(BitI8::get), Some(1));
464 assert!(n.checked_rem_euclid(0).is_none());
465 assert!(BitI8::<4>::MIN.checked_rem_euclid(-1).is_none());
466 }
467
468 #[test]
469 const fn checked_rem_euclid_is_const_fn() {
470 const _: Option<BitI8<4>> = BitI8::<4>::MAX.checked_rem_euclid(0);
471 }
472
473 #[test]
474 fn checked_ilog() {
475 let n = BitI8::<4>::new(5).unwrap();
476
477 assert_eq!(n.checked_ilog(5), Some(1));
478 assert!(n.checked_ilog(1).is_none());
479 assert!(BitI8::<4>::MIN.checked_ilog(5).is_none());
480 }
481
482 #[test]
483 const fn checked_ilog_is_const_fn() {
484 const _: Option<u32> = BitI8::<4>::MIN.checked_ilog(5);
485 }
486
487 #[test]
488 fn checked_ilog2() {
489 let n = BitI8::<3>::new(2).unwrap();
490
491 assert_eq!(n.checked_ilog2(), Some(1));
492 assert!(BitI8::<3>::MIN.checked_ilog2().is_none());
493 }
494
495 #[test]
496 const fn checked_ilog2_is_const_fn() {
497 const _: Option<u32> = BitI8::<3>::MIN.checked_ilog2();
498 }
499
500 #[test]
501 fn checked_ilog10() {
502 let n = BitI8::<5>::new(10).unwrap();
503
504 assert_eq!(n.checked_ilog10(), Some(1));
505 assert!(BitI8::<5>::MIN.checked_ilog10().is_none());
506 }
507
508 #[test]
509 const fn checked_ilog10_is_const_fn() {
510 const _: Option<u32> = BitI8::<5>::MIN.checked_ilog10();
511 }
512
513 #[test]
514 fn checked_neg() {
515 let n = BitI8::<4>::new(5).unwrap();
516
517 assert_eq!(n.checked_neg().map(BitI8::get), Some(-5));
518 assert!(BitI8::<4>::MIN.checked_neg().is_none());
519 }
520
521 #[test]
522 const fn checked_neg_is_const_fn() {
523 const _: Option<BitI8<4>> = BitI8::<4>::MIN.checked_neg();
524 }
525
526 #[test]
527 fn checked_shl() {
528 let n = BitI8::<6>::new(0x01).unwrap();
529 let m = BitI8::<6>::new(0x10).unwrap();
530
531 assert_eq!(n.checked_shl(4).map(BitI8::get), Some(0x10));
532 assert!(n.checked_shl(129).is_none());
533 assert_eq!(m.checked_shl(i8::BITS - 1).map(BitI8::get), Some(0x00));
534 }
535
536 #[test]
537 const fn checked_shl_is_const_fn() {
538 const _: Option<BitI8<6>> = BitI8::<6>::MIN.checked_shl(129);
539 }
540
541 #[test]
542 fn checked_shr() {
543 let n = BitI8::<6>::new(0x10).unwrap();
544
545 assert_eq!(n.checked_shr(4).map(BitI8::get), Some(0x01));
546 assert!(n.checked_shr(128).is_none());
547 }
548
549 #[test]
550 const fn checked_shr_is_const_fn() {
551 const _: Option<BitI8<6>> = BitI8::<6>::MIN.checked_shr(128);
552 }
553
554 #[test]
555 fn checked_abs() {
556 let n = BitI8::<4>::new(-5).unwrap();
557
558 assert_eq!(n.checked_abs().map(BitI8::get), Some(5));
559 assert!(BitI8::<4>::MIN.checked_abs().is_none());
560 }
561
562 #[test]
563 const fn checked_abs_is_const_fn() {
564 const _: Option<BitI8<4>> = BitI8::<4>::MIN.checked_abs();
565 }
566
567 #[test]
568 fn checked_pow() {
569 let n = BitI8::<8>::new(8).unwrap();
570
571 assert_eq!(n.checked_pow(2).map(BitI8::get), Some(64));
572 assert!(BitI8::<8>::MAX.checked_pow(2).is_none());
573 }
574
575 #[test]
576 const fn checked_pow_is_const_fn() {
577 const _: Option<BitI8<8>> = BitI8::<8>::MAX.checked_pow(2);
578 }
579}