From f74de249c8617e680704fcd9714086b808374951 Mon Sep 17 00:00:00 2001 From: LEXUGE Date: Fri, 13 Apr 2018 16:04:56 +0800 Subject: [PATCH 1/4] remove formats --- src/ops/checked.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/ops/checked.rs b/src/ops/checked.rs index 020f649..e232be7 100644 --- a/src/ops/checked.rs +++ b/src/ops/checked.rs @@ -1,4 +1,4 @@ -use core::ops::{Add, Sub, Mul, Div, Shl, Shr}; +use core::ops::{Add, Sub, Mul, Div, Rem, Shl, Shr}; /// Performs addition that returns `None` instead of wrapping around on /// overflow. @@ -90,6 +90,51 @@ checked_impl!(CheckedDiv, checked_div, i32); checked_impl!(CheckedDiv, checked_div, i64); checked_impl!(CheckedDiv, checked_div, isize); +// CheckedRem +pub trait CheckedRem: Sized + Rem { + fn checked_rem(&self, v: &Self) -> Option; +} + +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); + +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); + +// CheckedNeg +macro_rules! checked_impl_one_para { + ($trait_name:ident, $method:ident, $t:ty) => { + impl $trait_name for $t { + #[inline] + fn $method(&self) -> Option<$t> { + <$t>::$method(*self) + } + } + } +} + +pub trait CheckedNeg: Sized { + fn checked_neg(&self) -> Option; +} + +checked_impl_one_para!(CheckedNeg, checked_neg, u8); +checked_impl_one_para!(CheckedNeg, checked_neg, u16); +checked_impl_one_para!(CheckedNeg, checked_neg, u32); +checked_impl_one_para!(CheckedNeg, checked_neg, u64); +checked_impl_one_para!(CheckedNeg, checked_neg, usize); + +checked_impl_one_para!(CheckedNeg, checked_neg, i8); +checked_impl_one_para!(CheckedNeg, checked_neg, i16); +checked_impl_one_para!(CheckedNeg, checked_neg, i32); +checked_impl_one_para!(CheckedNeg, checked_neg, i64); +checked_impl_one_para!(CheckedNeg, checked_neg, isize); + /// Performs a left shift that returns `None` on overflow. pub trait CheckedShl: Sized + Shl { /// Shifts a number to the left, checking for overflow. If overflow happens, From 5fb3724b69a6a4968f8c3c5df6fa824eeb0d213e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 13 Apr 2018 14:13:42 -0700 Subject: [PATCH 2/4] rename checked_impl_one_param to checked_impl_unary --- src/ops/checked.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/ops/checked.rs b/src/ops/checked.rs index e232be7..3e578d0 100644 --- a/src/ops/checked.rs +++ b/src/ops/checked.rs @@ -107,8 +107,7 @@ checked_impl!(CheckedRem, checked_rem, i32); checked_impl!(CheckedRem, checked_rem, i64); checked_impl!(CheckedRem, checked_rem, isize); -// CheckedNeg -macro_rules! checked_impl_one_para { +macro_rules! checked_impl_unary { ($trait_name:ident, $method:ident, $t:ty) => { impl $trait_name for $t { #[inline] @@ -123,17 +122,17 @@ pub trait CheckedNeg: Sized { fn checked_neg(&self) -> Option; } -checked_impl_one_para!(CheckedNeg, checked_neg, u8); -checked_impl_one_para!(CheckedNeg, checked_neg, u16); -checked_impl_one_para!(CheckedNeg, checked_neg, u32); -checked_impl_one_para!(CheckedNeg, checked_neg, u64); -checked_impl_one_para!(CheckedNeg, checked_neg, usize); +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); -checked_impl_one_para!(CheckedNeg, checked_neg, i8); -checked_impl_one_para!(CheckedNeg, checked_neg, i16); -checked_impl_one_para!(CheckedNeg, checked_neg, i32); -checked_impl_one_para!(CheckedNeg, checked_neg, i64); -checked_impl_one_para!(CheckedNeg, checked_neg, isize); +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); /// Performs a left shift that returns `None` on overflow. pub trait CheckedShl: Sized + Shl { From b1c4074cc4fe52c9831989e5c7f85a10ed72a3a8 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 13 Apr 2018 14:14:22 -0700 Subject: [PATCH 3/4] Document CheckedRem and CheckedNeg --- src/ops/checked.rs | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ops/checked.rs b/src/ops/checked.rs index 3e578d0..530bbcd 100644 --- a/src/ops/checked.rs +++ b/src/ops/checked.rs @@ -90,8 +90,28 @@ checked_impl!(CheckedDiv, checked_div, i32); checked_impl!(CheckedDiv, checked_div, i64); checked_impl!(CheckedDiv, checked_div, isize); -// CheckedRem +/// 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 { + /// 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; } @@ -118,7 +138,24 @@ macro_rules! checked_impl_unary { } } +/// Performs negation that returns `None` if the result can't be represented. pub trait CheckedNeg: Sized { + /// Negates a number, returning `None` for results taht 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; } From aa21fba9fcf78461936896341431b10ea0b03b0b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 13 Apr 2018 14:14:49 -0700 Subject: [PATCH 4/4] re-export CheckedRem and CheckedNeg at the root --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3e1c80c..53d3af6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,8 @@ pub use float::FloatConst; // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`. pub use identities::{Zero, One, zero, one}; pub use ops::inv::Inv; -pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr}; +pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, + CheckedRem, CheckedNeg, CheckedShl, CheckedShr}; pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub}; pub use ops::saturating::Saturating; pub use sign::{Signed, Unsigned, abs, abs_sub, signum};