123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- use core::ops::{Add, Sub, Mul, Div, Rem, Shl, Shr};
- /// Performs addition that returns `None` instead of wrapping around on
- /// overflow.
- pub trait CheckedAdd: Sized + Add<Self, Output=Self> {
- /// Adds two numbers, checking for overflow. If overflow happens, `None` is
- /// returned.
- fn checked_add(&self, v: &Self) -> Option<Self>;
- }
- macro_rules! checked_impl {
- ($trait_name:ident, $method:ident, $t:ty) => {
- impl $trait_name for $t {
- #[inline]
- fn $method(&self, v: &$t) -> Option<$t> {
- <$t>::$method(*self, *v)
- }
- }
- }
- }
- checked_impl!(CheckedAdd, checked_add, u8);
- checked_impl!(CheckedAdd, checked_add, u16);
- checked_impl!(CheckedAdd, checked_add, u32);
- checked_impl!(CheckedAdd, checked_add, u64);
- checked_impl!(CheckedAdd, checked_add, usize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedAdd, checked_add, u128);
- checked_impl!(CheckedAdd, checked_add, i8);
- checked_impl!(CheckedAdd, checked_add, i16);
- checked_impl!(CheckedAdd, checked_add, i32);
- checked_impl!(CheckedAdd, checked_add, i64);
- checked_impl!(CheckedAdd, checked_add, isize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedAdd, checked_add, i128);
- /// Performs subtraction that returns `None` instead of wrapping around on underflow.
- pub trait CheckedSub: Sized + Sub<Self, Output=Self> {
- /// Subtracts two numbers, checking for underflow. If underflow happens,
- /// `None` is returned.
- fn checked_sub(&self, v: &Self) -> Option<Self>;
- }
- checked_impl!(CheckedSub, checked_sub, u8);
- checked_impl!(CheckedSub, checked_sub, u16);
- checked_impl!(CheckedSub, checked_sub, u32);
- checked_impl!(CheckedSub, checked_sub, u64);
- checked_impl!(CheckedSub, checked_sub, usize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedSub, checked_sub, u128);
- checked_impl!(CheckedSub, checked_sub, i8);
- checked_impl!(CheckedSub, checked_sub, i16);
- checked_impl!(CheckedSub, checked_sub, i32);
- checked_impl!(CheckedSub, checked_sub, i64);
- checked_impl!(CheckedSub, checked_sub, isize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedSub, checked_sub, i128);
- /// Performs multiplication that returns `None` instead of wrapping around on underflow or
- /// overflow.
- pub trait CheckedMul: Sized + Mul<Self, Output=Self> {
- /// Multiplies two numbers, checking for underflow or overflow. If underflow
- /// or overflow happens, `None` is returned.
- fn checked_mul(&self, v: &Self) -> Option<Self>;
- }
- checked_impl!(CheckedMul, checked_mul, u8);
- checked_impl!(CheckedMul, checked_mul, u16);
- checked_impl!(CheckedMul, checked_mul, u32);
- checked_impl!(CheckedMul, checked_mul, u64);
- checked_impl!(CheckedMul, checked_mul, usize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedMul, checked_mul, u128);
- checked_impl!(CheckedMul, checked_mul, i8);
- checked_impl!(CheckedMul, checked_mul, i16);
- checked_impl!(CheckedMul, checked_mul, i32);
- checked_impl!(CheckedMul, checked_mul, i64);
- checked_impl!(CheckedMul, checked_mul, isize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedMul, checked_mul, i128);
- /// Performs division that returns `None` instead of panicking on division by zero and instead of
- /// wrapping around on underflow and overflow.
- pub trait CheckedDiv: Sized + Div<Self, Output=Self> {
- /// Divides two numbers, checking for underflow, overflow and division by
- /// zero. If any of that happens, `None` is returned.
- fn checked_div(&self, v: &Self) -> Option<Self>;
- }
- checked_impl!(CheckedDiv, checked_div, u8);
- checked_impl!(CheckedDiv, checked_div, u16);
- checked_impl!(CheckedDiv, checked_div, u32);
- checked_impl!(CheckedDiv, checked_div, u64);
- checked_impl!(CheckedDiv, checked_div, usize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedDiv, checked_div, u128);
- checked_impl!(CheckedDiv, checked_div, i8);
- checked_impl!(CheckedDiv, checked_div, i16);
- checked_impl!(CheckedDiv, checked_div, i32);
- checked_impl!(CheckedDiv, checked_div, i64);
- checked_impl!(CheckedDiv, checked_div, isize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedDiv, checked_div, i128);
- /// Performs an integral remainder that returns `None` instead of panicking on division by zero and
- /// instead of wrapping around on underflow and overflow.
- pub trait CheckedRem: Sized + Rem<Self, Output = Self> {
- /// Finds the remainder of dividing two numbers, checking for underflow, overflow and division
- /// by zero. If any of that happens, `None` is returned.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_traits::CheckedRem;
- /// use std::i32::MIN;
- ///
- /// assert_eq!(CheckedRem::checked_rem(&10, &7), Some(3));
- /// assert_eq!(CheckedRem::checked_rem(&10, &-7), Some(3));
- /// assert_eq!(CheckedRem::checked_rem(&-10, &7), Some(-3));
- /// assert_eq!(CheckedRem::checked_rem(&-10, &-7), Some(-3));
- ///
- /// assert_eq!(CheckedRem::checked_rem(&10, &0), None);
- ///
- /// assert_eq!(CheckedRem::checked_rem(&MIN, &1), Some(0));
- /// assert_eq!(CheckedRem::checked_rem(&MIN, &-1), None);
- /// ```
- fn checked_rem(&self, v: &Self) -> Option<Self>;
- }
- checked_impl!(CheckedRem, checked_rem, u8);
- checked_impl!(CheckedRem, checked_rem, u16);
- checked_impl!(CheckedRem, checked_rem, u32);
- checked_impl!(CheckedRem, checked_rem, u64);
- checked_impl!(CheckedRem, checked_rem, usize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedRem, checked_rem, u128);
- checked_impl!(CheckedRem, checked_rem, i8);
- checked_impl!(CheckedRem, checked_rem, i16);
- checked_impl!(CheckedRem, checked_rem, i32);
- checked_impl!(CheckedRem, checked_rem, i64);
- checked_impl!(CheckedRem, checked_rem, isize);
- #[cfg(feature = "i128")]
- checked_impl!(CheckedRem, checked_rem, i128);
- macro_rules! checked_impl_unary {
- ($trait_name:ident, $method:ident, $t:ty) => {
- impl $trait_name for $t {
- #[inline]
- fn $method(&self) -> Option<$t> {
- <$t>::$method(*self)
- }
- }
- }
- }
- /// Performs negation that returns `None` if the result can't be represented.
- pub trait CheckedNeg: Sized {
- /// Negates a number, returning `None` for results that can't be represented, like signed `MIN`
- /// values that can't be positive, or non-zero unsigned values that can't be negative.
- ///
- /// # Examples
- ///
- /// ```
- /// use num_traits::CheckedNeg;
- /// use std::i32::MIN;
- ///
- /// assert_eq!(CheckedNeg::checked_neg(&1_i32), Some(-1));
- /// assert_eq!(CheckedNeg::checked_neg(&-1_i32), Some(1));
- /// assert_eq!(CheckedNeg::checked_neg(&MIN), None);
- ///
- /// assert_eq!(CheckedNeg::checked_neg(&0_u32), Some(0));
- /// assert_eq!(CheckedNeg::checked_neg(&1_u32), None);
- /// ```
- fn checked_neg(&self) -> Option<Self>;
- }
- checked_impl_unary!(CheckedNeg, checked_neg, u8);
- checked_impl_unary!(CheckedNeg, checked_neg, u16);
- checked_impl_unary!(CheckedNeg, checked_neg, u32);
- checked_impl_unary!(CheckedNeg, checked_neg, u64);
- checked_impl_unary!(CheckedNeg, checked_neg, usize);
- #[cfg(feature = "i128")]
- checked_impl_unary!(CheckedNeg, checked_neg, u128);
- checked_impl_unary!(CheckedNeg, checked_neg, i8);
- checked_impl_unary!(CheckedNeg, checked_neg, i16);
- checked_impl_unary!(CheckedNeg, checked_neg, i32);
- checked_impl_unary!(CheckedNeg, checked_neg, i64);
- checked_impl_unary!(CheckedNeg, checked_neg, isize);
- #[cfg(feature = "i128")]
- checked_impl_unary!(CheckedNeg, checked_neg, i128);
- /// Performs a left shift that returns `None` on overflow.
- pub trait CheckedShl: Sized + Shl<u32, Output=Self> {
- /// Shifts a number to the left, checking for overflow. If overflow happens,
- /// `None` is returned.
- ///
- /// ```
- /// use num_traits::CheckedShl;
- ///
- /// let x: u16 = 0x0001;
- ///
- /// assert_eq!(CheckedShl::checked_shl(&x, 0), Some(0x0001));
- /// assert_eq!(CheckedShl::checked_shl(&x, 1), Some(0x0002));
- /// assert_eq!(CheckedShl::checked_shl(&x, 15), Some(0x8000));
- /// assert_eq!(CheckedShl::checked_shl(&x, 16), None);
- /// ```
- fn checked_shl(&self, rhs: u32) -> Option<Self>;
- }
- macro_rules! checked_shift_impl {
- ($trait_name:ident, $method:ident, $t:ty) => {
- impl $trait_name for $t {
- #[inline]
- fn $method(&self, rhs: u32) -> Option<$t> {
- <$t>::$method(*self, rhs)
- }
- }
- }
- }
- checked_shift_impl!(CheckedShl, checked_shl, u8);
- checked_shift_impl!(CheckedShl, checked_shl, u16);
- checked_shift_impl!(CheckedShl, checked_shl, u32);
- checked_shift_impl!(CheckedShl, checked_shl, u64);
- checked_shift_impl!(CheckedShl, checked_shl, usize);
- #[cfg(feature = "i128")]
- checked_shift_impl!(CheckedShl, checked_shl, u128);
- checked_shift_impl!(CheckedShl, checked_shl, i8);
- checked_shift_impl!(CheckedShl, checked_shl, i16);
- checked_shift_impl!(CheckedShl, checked_shl, i32);
- checked_shift_impl!(CheckedShl, checked_shl, i64);
- checked_shift_impl!(CheckedShl, checked_shl, isize);
- #[cfg(feature = "i128")]
- checked_shift_impl!(CheckedShl, checked_shl, i128);
- /// Performs a right shift that returns `None` on overflow.
- pub trait CheckedShr: Sized + Shr<u32, Output=Self> {
- /// Shifts a number to the left, checking for overflow. If overflow happens,
- /// `None` is returned.
- ///
- /// ```
- /// use num_traits::CheckedShr;
- ///
- /// let x: u16 = 0x8000;
- ///
- /// assert_eq!(CheckedShr::checked_shr(&x, 0), Some(0x8000));
- /// assert_eq!(CheckedShr::checked_shr(&x, 1), Some(0x4000));
- /// assert_eq!(CheckedShr::checked_shr(&x, 15), Some(0x0001));
- /// assert_eq!(CheckedShr::checked_shr(&x, 16), None);
- /// ```
- fn checked_shr(&self, rhs: u32) -> Option<Self>;
- }
- checked_shift_impl!(CheckedShr, checked_shr, u8);
- checked_shift_impl!(CheckedShr, checked_shr, u16);
- checked_shift_impl!(CheckedShr, checked_shr, u32);
- checked_shift_impl!(CheckedShr, checked_shr, u64);
- checked_shift_impl!(CheckedShr, checked_shr, usize);
- #[cfg(feature = "i128")]
- checked_shift_impl!(CheckedShr, checked_shr, u128);
- checked_shift_impl!(CheckedShr, checked_shr, i8);
- checked_shift_impl!(CheckedShr, checked_shr, i16);
- checked_shift_impl!(CheckedShr, checked_shr, i32);
- checked_shift_impl!(CheckedShr, checked_shr, i64);
- checked_shift_impl!(CheckedShr, checked_shr, isize);
- #[cfg(feature = "i128")]
- checked_shift_impl!(CheckedShr, checked_shr, i128);
|