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]
|
#[test]
|
||||||
fn checked_ops() {
|
fn checked_ops() {
|
||||||
use opt_ops::CheckedError;
|
|
||||||
|
|
||||||
assert_eq!(CT_1.checked_add(CT_1), Some(CT_2));
|
assert_eq!(CT_1.checked_add(CT_1), Some(CT_2));
|
||||||
|
|
||||||
assert_eq!(CT_1.opt_checked_add(CT_1), Ok(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!(ClockTime::MAX.checked_add(CT_1).is_none());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ClockTime::MAX.opt_checked_add(Some(CT_1)),
|
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));
|
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!(CT_1.checked_sub(CT_2).is_none());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(CT_1).opt_checked_sub(CT_2),
|
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"]
|
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn wrapping_add(self, rhs: Self) -> Self {
|
pub fn wrapping_add(self, rhs: Self) -> Self {
|
||||||
self.overflowing_add(rhs).0
|
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"]
|
#[must_use = "this returns the result of the operation, without modifying the original"]
|
||||||
#[inline]
|
#[inline]
|
||||||
// FIXME Can't use `map` in a `const fn` as of rustc 1.53.0-beta.2
|
// 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 {
|
impl OptionCheckedAdd for $name {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn opt_checked_add(
|
fn opt_checked_add(
|
||||||
self,
|
self,
|
||||||
rhs: Self,
|
rhs: Self,
|
||||||
) -> Result<Option<Self::Output>, opt_ops::CheckedError> {
|
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||||
self.checked_add(rhs)
|
self.checked_add(rhs)
|
||||||
.ok_or(opt_ops::CheckedError::Overflow)
|
.ok_or(opt_ops::Error::Overflow)
|
||||||
.map(Some)
|
.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 {
|
impl OptionCheckedSub for $name {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn opt_checked_sub(
|
fn opt_checked_sub(
|
||||||
self,
|
self,
|
||||||
rhs: Self,
|
rhs: Self,
|
||||||
) -> Result<Option<Self::Output>, opt_ops::CheckedError> {
|
) -> Result<Option<Self::Output>, opt_ops::Error> {
|
||||||
self.checked_sub(rhs)
|
self.checked_sub(rhs)
|
||||||
.ok_or(opt_ops::CheckedError::Overflow)
|
.ok_or(opt_ops::Error::Overflow)
|
||||||
.map(Some)
|
.map(Some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue