checked.rs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. use core::ops::{Add, Sub, Mul, Div};
  2. /// Performs addition that returns `None` instead of wrapping around on
  3. /// overflow.
  4. pub trait CheckedAdd: Sized + Add<Self, Output=Self> {
  5. /// Adds two numbers, checking for overflow. If overflow happens, `None` is
  6. /// returned.
  7. fn checked_add(&self, v: &Self) -> Option<Self>;
  8. }
  9. macro_rules! checked_impl {
  10. ($trait_name:ident, $method:ident, $t:ty) => {
  11. impl $trait_name for $t {
  12. #[inline]
  13. fn $method(&self, v: &$t) -> Option<$t> {
  14. <$t>::$method(*self, *v)
  15. }
  16. }
  17. }
  18. }
  19. checked_impl!(CheckedAdd, checked_add, u8);
  20. checked_impl!(CheckedAdd, checked_add, u16);
  21. checked_impl!(CheckedAdd, checked_add, u32);
  22. checked_impl!(CheckedAdd, checked_add, u64);
  23. checked_impl!(CheckedAdd, checked_add, usize);
  24. checked_impl!(CheckedAdd, checked_add, i8);
  25. checked_impl!(CheckedAdd, checked_add, i16);
  26. checked_impl!(CheckedAdd, checked_add, i32);
  27. checked_impl!(CheckedAdd, checked_add, i64);
  28. checked_impl!(CheckedAdd, checked_add, isize);
  29. /// Performs subtraction that returns `None` instead of wrapping around on underflow.
  30. pub trait CheckedSub: Sized + Sub<Self, Output=Self> {
  31. /// Subtracts two numbers, checking for underflow. If underflow happens,
  32. /// `None` is returned.
  33. fn checked_sub(&self, v: &Self) -> Option<Self>;
  34. }
  35. checked_impl!(CheckedSub, checked_sub, u8);
  36. checked_impl!(CheckedSub, checked_sub, u16);
  37. checked_impl!(CheckedSub, checked_sub, u32);
  38. checked_impl!(CheckedSub, checked_sub, u64);
  39. checked_impl!(CheckedSub, checked_sub, usize);
  40. checked_impl!(CheckedSub, checked_sub, i8);
  41. checked_impl!(CheckedSub, checked_sub, i16);
  42. checked_impl!(CheckedSub, checked_sub, i32);
  43. checked_impl!(CheckedSub, checked_sub, i64);
  44. checked_impl!(CheckedSub, checked_sub, isize);
  45. /// Performs multiplication that returns `None` instead of wrapping around on underflow or
  46. /// overflow.
  47. pub trait CheckedMul: Sized + Mul<Self, Output=Self> {
  48. /// Multiplies two numbers, checking for underflow or overflow. If underflow
  49. /// or overflow happens, `None` is returned.
  50. fn checked_mul(&self, v: &Self) -> Option<Self>;
  51. }
  52. checked_impl!(CheckedMul, checked_mul, u8);
  53. checked_impl!(CheckedMul, checked_mul, u16);
  54. checked_impl!(CheckedMul, checked_mul, u32);
  55. checked_impl!(CheckedMul, checked_mul, u64);
  56. checked_impl!(CheckedMul, checked_mul, usize);
  57. checked_impl!(CheckedMul, checked_mul, i8);
  58. checked_impl!(CheckedMul, checked_mul, i16);
  59. checked_impl!(CheckedMul, checked_mul, i32);
  60. checked_impl!(CheckedMul, checked_mul, i64);
  61. checked_impl!(CheckedMul, checked_mul, isize);
  62. /// Performs division that returns `None` instead of panicking on division by zero and instead of
  63. /// wrapping around on underflow and overflow.
  64. pub trait CheckedDiv: Sized + Div<Self, Output=Self> {
  65. /// Divides two numbers, checking for underflow, overflow and division by
  66. /// zero. If any of that happens, `None` is returned.
  67. fn checked_div(&self, v: &Self) -> Option<Self>;
  68. }
  69. checked_impl!(CheckedDiv, checked_div, u8);
  70. checked_impl!(CheckedDiv, checked_div, u16);
  71. checked_impl!(CheckedDiv, checked_div, u32);
  72. checked_impl!(CheckedDiv, checked_div, u64);
  73. checked_impl!(CheckedDiv, checked_div, usize);
  74. checked_impl!(CheckedDiv, checked_div, i8);
  75. checked_impl!(CheckedDiv, checked_div, i16);
  76. checked_impl!(CheckedDiv, checked_div, i32);
  77. checked_impl!(CheckedDiv, checked_div, i64);
  78. checked_impl!(CheckedDiv, checked_div, isize);