forked from mirrors/gstreamer-rs
Impl Option*{Div,Mul,Rem}
Use the inner type for Rhs, as implemented for Duration. These operations make sense without providing a "unit".
This commit is contained in:
parent
f83b385487
commit
4bbd201377
2 changed files with 123 additions and 11 deletions
|
@ -426,8 +426,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn checked_ops() {
|
||||
use opt_ops::CheckedError;
|
||||
|
||||
assert_eq!(CT_1.checked_add(CT_1), Some(CT_2));
|
||||
|
||||
assert_eq!(CT_1.opt_checked_add(CT_1), Ok(Some(CT_2)));
|
||||
|
@ -439,7 +437,7 @@ mod tests {
|
|||
assert!(ClockTime::MAX.checked_add(CT_1).is_none());
|
||||
assert_eq!(
|
||||
ClockTime::MAX.opt_checked_add(Some(CT_1)),
|
||||
Err(CheckedError::Overflow)
|
||||
Err(opt_ops::Error::Overflow)
|
||||
);
|
||||
|
||||
assert_eq!(CT_2.checked_sub(CT_1), Some(CT_1));
|
||||
|
@ -454,7 +452,7 @@ mod tests {
|
|||
assert!(CT_1.checked_sub(CT_2).is_none());
|
||||
assert_eq!(
|
||||
Some(CT_1).opt_checked_sub(CT_2),
|
||||
Err(CheckedError::Overflow)
|
||||
Err(opt_ops::Error::Overflow)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,14 +111,69 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME add overflowing_add
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub fn wrapping_add(self, rhs: Self) -> Self {
|
||||
self.overflowing_add(rhs).0
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_div(self, rhs: $inner_type) -> Option<Self> {
|
||||
match self.0.checked_div(rhs) {
|
||||
Some(val) => Some(Self(val)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_mul(self, rhs: $inner_type) -> Option<Self> {
|
||||
match self.0.checked_mul(rhs) {
|
||||
Some(res) if res <= Self::MAX.0 => Some(Self(res)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn saturating_mul(self, rhs: $inner_type) -> Self {
|
||||
let res = self.0.saturating_mul(rhs);
|
||||
if res < Self::MAX.0 {
|
||||
Self(res)
|
||||
} else {
|
||||
Self::MAX
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub fn overflowing_mul(self, rhs: $inner_type) -> (Self, bool) {
|
||||
let self_u128 = self.0 as u128;
|
||||
let rhs_128 = rhs as u128;
|
||||
let res_u128 = self_u128 * rhs_128;
|
||||
if res_u128 <= Self::MAX.0 as u128 {
|
||||
(Self(<$inner_type>::try_from(res_u128).unwrap()), false)
|
||||
} else {
|
||||
(Self(<$inner_type>::try_from((res_u128 - Self::MAX.0 as u128 - 1) as u64).unwrap()), true)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub fn wrapping_mul(self, rhs: $inner_type) -> Self {
|
||||
self.overflowing_mul(rhs).0
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
pub const fn checked_rem(self, rhs: $inner_type) -> Option<Self> {
|
||||
match self.0.checked_rem(rhs) {
|
||||
Some(val) => Some(Self(val)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||
#[inline]
|
||||
// FIXME Can't use `map` in a `const fn` as of rustc 1.53.0-beta.2
|
||||
|
@ -189,13 +244,12 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
|
||||
impl OptionCheckedAdd for $name {
|
||||
type Output = Self;
|
||||
|
||||
fn opt_checked_add(
|
||||
self,
|
||||
rhs: Self,
|
||||
) -> Result<Option<Self::Output>, opt_ops::CheckedError> {
|
||||
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
self.checked_add(rhs)
|
||||
.ok_or(opt_ops::CheckedError::Overflow)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
@ -222,14 +276,74 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
|||
}
|
||||
}
|
||||
|
||||
impl OptionCheckedDiv<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_checked_div(self, rhs: $inner_type) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
if rhs == 0 {
|
||||
return Err(opt_ops::Error::DivisionByZero);
|
||||
}
|
||||
self.0
|
||||
.checked_div(rhs)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(|val| Some(Self(val)))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionCheckedMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_checked_mul(
|
||||
self,
|
||||
rhs: $inner_type,
|
||||
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
self.checked_mul(rhs)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionSaturatingMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_saturating_mul(self, rhs: $inner_type) -> Option<Self::Output> {
|
||||
Some(self.saturating_mul(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionOverflowingMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_overflowing_mul(self, rhs: $inner_type) -> Option<(Self::Output, bool)> {
|
||||
let res = self.overflowing_mul(rhs);
|
||||
Some((res.0, res.1))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionWrappingMul<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_wrapping_mul(self, rhs: $inner_type) -> Option<Self::Output> {
|
||||
Some(self.wrapping_mul(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionCheckedRem<$inner_type> for $name {
|
||||
type Output = Self;
|
||||
fn opt_checked_rem(self, rhs: $inner_type) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
if rhs == 0 {
|
||||
return Err(opt_ops::Error::DivisionByZero);
|
||||
}
|
||||
self.0
|
||||
.checked_rem(rhs)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(|val| Some(Self(val)))
|
||||
}
|
||||
}
|
||||
|
||||
impl OptionCheckedSub for $name {
|
||||
type Output = Self;
|
||||
fn opt_checked_sub(
|
||||
self,
|
||||
rhs: Self,
|
||||
) -> Result<Option<Self::Output>, opt_ops::CheckedError> {
|
||||
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||
self.checked_sub(rhs)
|
||||
.ok_or(opt_ops::CheckedError::Overflow)
|
||||
.ok_or(opt_ops::Error::Overflow)
|
||||
.map(Some)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue