1use super::BitUint;
8
9macro_rules! impl_ops {
10 ($T:ty) => {
11 impl<const N: u32> BitUint<$T, N> {
12 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 6>::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 = BitUint::<", stringify!($T), ", 6>::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 = BitUint::<", stringify!($T), ", 6>::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 = BitUint::<", stringify!($T), ", 6>::new(42).unwrap();")]
94 #[must_use]
99 #[inline]
100 pub const fn checked_div(self, rhs: $T) -> Option<Self> {
101 if let Some(result) = self.get().checked_div(rhs) {
102 Self::new(result)
103 } else {
104 None
105 }
106 }
107
108 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 6>::new(42).unwrap();")]
118 #[must_use]
123 #[inline]
124 pub const fn checked_div_euclid(self, rhs: $T) -> Option<Self> {
125 if let Some(result) = self.get().checked_div_euclid(rhs) {
126 Self::new(result)
127 } else {
128 None
129 }
130 }
131
132 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 3>::new(5).unwrap();")]
142 #[must_use]
147 #[inline]
148 pub const fn checked_rem(self, rhs: $T) -> Option<Self> {
149 if let Some(result) = self.get().checked_rem(rhs) {
150 Self::new(result)
151 } else {
152 None
153 }
154 }
155
156 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 3>::new(5).unwrap();")]
166 #[must_use]
171 #[inline]
172 pub const fn checked_rem_euclid(self, rhs: $T) -> Option<Self> {
173 if let Some(result) = self.get().checked_rem_euclid(rhs) {
174 Self::new(result)
175 } else {
176 None
177 }
178 }
179
180 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 3>::new(5).unwrap();")]
192 #[must_use]
196 #[inline]
197 pub const fn checked_ilog(self, base: $T) -> Option<u32> {
198 self.get().checked_ilog(base)
199 }
200
201 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 2>::new(2).unwrap();")]
211 #[must_use]
215 #[inline]
216 pub const fn checked_ilog2(self) -> Option<u32> {
217 self.get().checked_ilog2()
218 }
219
220 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 4>::new(10).unwrap();")]
230 #[must_use]
234 #[inline]
235 pub const fn checked_ilog10(self) -> Option<u32> {
236 self.get().checked_ilog10()
237 }
238
239 #[doc = concat!(" BitUint::<", stringify!($T), ", 1>::MIN.checked_neg().map(BitUint::get),")]
252 #[doc = concat!("assert!(BitUint::<", stringify!($T), ", 1>::MAX.checked_neg().is_none());")]
255 #[must_use]
257 #[inline]
258 pub const fn checked_neg(self) -> Option<Self> {
259 if let Some(result) = self.get().checked_neg() {
260 Self::new(result)
261 } else {
262 None
263 }
264 }
265
266 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 5>::new(0x01).unwrap();")]
277 #[doc = concat!("let m = BitUint::<", stringify!($T), ", 5>::new(0x10).unwrap();")]
278 #[doc = concat!("assert_eq!(m.checked_shl(", stringify!($T), "::BITS - 1).map(BitUint::get), Some(0x00));")]
282 #[must_use]
284 #[inline]
285 pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
286 if let Some(result) = self.get().checked_shl(rhs) {
287 Self::new(result)
288 } else {
289 None
290 }
291 }
292
293 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 5>::new(0x10).unwrap();")]
304 #[must_use]
309 #[inline]
310 pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
311 if let Some(result) = self.get().checked_shr(rhs) {
312 Self::new(result)
313 } else {
314 None
315 }
316 }
317
318 #[doc = concat!("let n = BitUint::<", stringify!($T), ", 6>::new(2).unwrap();")]
328 #[doc = concat!("assert!(BitUint::<", stringify!($T), ", 6>::MAX.checked_pow(2).is_none());")]
331 #[must_use]
333 #[inline]
334 pub const fn checked_pow(self, exp: u32) -> Option<Self> {
335 if let Some(result) = self.get().checked_pow(exp) {
336 Self::new(result)
337 } else {
338 None
339 }
340 }
341 }
342 };
343}
344impl_ops!(u8);
345impl_ops!(u16);
346impl_ops!(u32);
347impl_ops!(u64);
348impl_ops!(u128);
349impl_ops!(usize);
350
351#[cfg(test)]
352mod tests {
353 use super::super::BitU8;
354
355 #[test]
356 fn checked_add() {
357 let n = BitU8::<6>::new(42).unwrap();
358
359 assert_eq!(n.checked_add(21).map(BitU8::get), Some(63));
360 assert!(n.checked_add(22).is_none());
361 }
362
363 #[test]
364 const fn checked_add_is_const_fn() {
365 const _: Option<BitU8<6>> = BitU8::<6>::MAX.checked_add(1);
366 }
367
368 #[test]
369 fn checked_sub() {
370 let n = BitU8::<6>::new(42).unwrap();
371
372 assert_eq!(n.checked_sub(42).map(BitU8::get), Some(0));
373 assert!(n.checked_sub(43).is_none());
374 }
375
376 #[test]
377 const fn checked_sub_is_const_fn() {
378 const _: Option<BitU8<6>> = BitU8::<6>::MIN.checked_sub(1);
379 }
380
381 #[test]
382 fn checked_mul() {
383 let n = BitU8::<6>::new(21).unwrap();
384
385 assert_eq!(n.checked_mul(2).map(BitU8::get), Some(42));
386 assert!(n.checked_mul(4).is_none());
387 }
388
389 #[test]
390 const fn checked_mul_is_const_fn() {
391 const _: Option<BitU8<6>> = BitU8::<6>::MAX.checked_mul(2);
392 }
393
394 #[test]
395 fn checked_div() {
396 let n = BitU8::<6>::new(42).unwrap();
397
398 assert_eq!(n.checked_div(2).map(BitU8::get), Some(21));
399 assert!(n.checked_div(0).is_none());
400 }
401
402 #[test]
403 const fn checked_div_is_const_fn() {
404 const _: Option<BitU8<6>> = BitU8::<6>::MAX.checked_div(0);
405 }
406
407 #[test]
408 fn checked_div_euclid() {
409 let n = BitU8::<6>::new(42).unwrap();
410
411 assert_eq!(n.checked_div_euclid(2).map(BitU8::get), Some(21));
412 assert!(n.checked_div_euclid(0).is_none());
413 }
414
415 #[test]
416 const fn checked_div_euclid_is_const_fn() {
417 const _: Option<BitU8<6>> = BitU8::<6>::MAX.checked_div_euclid(0);
418 }
419
420 #[test]
421 fn checked_rem() {
422 let n = BitU8::<3>::new(5).unwrap();
423
424 assert_eq!(n.checked_rem(2).map(BitU8::get), Some(1));
425 assert!(n.checked_rem(0).is_none());
426 }
427
428 #[test]
429 const fn checked_rem_is_const_fn() {
430 const _: Option<BitU8<3>> = BitU8::<3>::MAX.checked_rem(0);
431 }
432
433 #[test]
434 fn checked_rem_euclid() {
435 let n = BitU8::<3>::new(5).unwrap();
436
437 assert_eq!(n.checked_rem_euclid(2).map(BitU8::get), Some(1));
438 assert!(n.checked_rem_euclid(0).is_none());
439 }
440
441 #[test]
442 const fn checked_rem_euclid_is_const_fn() {
443 const _: Option<BitU8<3>> = BitU8::<3>::MAX.checked_rem_euclid(0);
444 }
445
446 #[test]
447 fn checked_ilog() {
448 let n = BitU8::<3>::new(5).unwrap();
449
450 assert_eq!(n.checked_ilog(5), Some(1));
451 assert!(n.checked_ilog(1).is_none());
452 assert!(BitU8::<3>::MIN.checked_ilog(5).is_none());
453 }
454
455 #[test]
456 const fn checked_ilog_is_const_fn() {
457 const _: Option<u32> = BitU8::<3>::MIN.checked_ilog(5);
458 }
459
460 #[test]
461 fn checked_ilog2() {
462 let n = BitU8::<2>::new(2).unwrap();
463
464 assert_eq!(n.checked_ilog2(), Some(1));
465 assert!(BitU8::<2>::MIN.checked_ilog2().is_none());
466 }
467
468 #[test]
469 const fn checked_ilog2_is_const_fn() {
470 const _: Option<u32> = BitU8::<2>::MIN.checked_ilog2();
471 }
472
473 #[test]
474 fn checked_ilog10() {
475 let n = BitU8::<4>::new(10).unwrap();
476
477 assert_eq!(n.checked_ilog10(), Some(1));
478 assert!(BitU8::<4>::MIN.checked_ilog10().is_none());
479 }
480
481 #[test]
482 const fn checked_ilog10_is_const_fn() {
483 const _: Option<u32> = BitU8::<4>::MIN.checked_ilog10();
484 }
485
486 #[test]
487 fn checked_neg() {
488 assert_eq!(BitU8::<1>::MIN.checked_neg().map(BitU8::get), Some(0));
489 assert!(BitU8::<1>::MAX.checked_neg().is_none());
490 }
491
492 #[test]
493 const fn checked_neg_is_const_fn() {
494 const _: Option<BitU8<1>> = BitU8::<1>::MAX.checked_neg();
495 }
496
497 #[test]
498 fn checked_shl() {
499 let n = BitU8::<5>::new(0x01).unwrap();
500 let m = BitU8::<5>::new(0x10).unwrap();
501
502 assert_eq!(n.checked_shl(4).map(BitU8::get), Some(0x10));
503 assert!(m.checked_shl(129).is_none());
504 assert_eq!(m.checked_shl(u8::BITS - 1).map(BitU8::get), Some(0x00));
505 }
506
507 #[test]
508 const fn checked_shl_is_const_fn() {
509 const _: Option<BitU8<5>> = BitU8::<5>::MIN.checked_shl(129);
510 }
511
512 #[test]
513 fn checked_shr() {
514 let n = BitU8::<5>::new(0x10).unwrap();
515
516 assert_eq!(n.checked_shr(4).map(BitU8::get), Some(0x01));
517 assert!(n.checked_shr(129).is_none());
518 }
519
520 #[test]
521 const fn checked_shr_is_const_fn() {
522 const _: Option<BitU8<5>> = BitU8::<5>::MIN.checked_shr(129);
523 }
524
525 #[test]
526 fn checked_pow() {
527 let n = BitU8::<6>::new(2).unwrap();
528
529 assert_eq!(n.checked_pow(5).map(BitU8::get), Some(32));
530 assert!(BitU8::<6>::MAX.checked_pow(2).is_none());
531 }
532
533 #[test]
534 const fn checked_pow_is_const_fn() {
535 const _: Option<BitU8<6>> = BitU8::<6>::MAX.checked_pow(2);
536 }
537}