constify no_frac div and rem functions

This commit is contained in:
Trevor Spiteri 2021-04-07 18:19:43 +02:00
parent 672646d814
commit e6ed2775e9
3 changed files with 97 additions and 23 deletions

View File

@ -96,8 +96,14 @@ The conversions supported cover the following cases.
* [`unwrapped_rem`][f-ur-1-8],
[`unwrapped_rem_euclid`][f-ure-1-8]
* [`unwrapped_rem_int`][f-uri-1-8]
* The following methods are now `const` functions:
* [`checked_rem`][f-chr-1-8]
* [`rem_euclid`][f-re-1-8], [`checked_rem_euclid`][f-cre-1-8]
* [`checked_div_int`][f-cdi-1-8],
[`wrapping_div_int`][f-wdi-1-8],
[`overflowing_div_int`][f-odi-1-8]
* The following methods were added to all fixed-point numbers:
* [`const_rem`][f-cr-1-8]
* [`const_rem`][f-cor-1-8]
* [`const_not`][f-cn-1-8]
* [`const_bitand`][f-cba-1-8], [`const_bitor`][f-cbo-1-8],
[`const_bitxor`][f-cbx-1-8]
@ -106,15 +112,21 @@ The conversions supported cover the following cases.
[f-cba-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_bitand
[f-cbo-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_bitor
[f-cbx-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_bitxor
[f-cdi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.checked_div_int
[f-chr-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.checked_rem
[f-cn-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_not
[f-cr-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_rem
[f-cor-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_rem
[f-cre-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.checked_rem_euclid
[f-d-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.DELTA
[f-o-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.ONE
[f-odi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.overflowing_div_int
[f-re-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.rem_euclid
[f-sdei-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.saturating_div_euclid_int
[f-srei-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.saturating_rem_euclid_int
[f-ur-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.unwrapped_rem
[f-ure-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.unwrapped_rem_euclid
[f-uri-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.unwrapped_rem_int
[f-wdi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.wrapping_div_int
[f-z-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.ZERO
[tf-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html
[u-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.Unwrapped.html

View File

@ -21,8 +21,14 @@ Version 1.8.0 (unreleased)
* [`unwrapped_rem`][f-ur-1-8],
[`unwrapped_rem_euclid`][f-ure-1-8]
* [`unwrapped_rem_int`][f-uri-1-8]
* The following methods are now `const` functions:
* [`checked_rem`][f-chr-1-8]
* [`rem_euclid`][f-re-1-8], [`checked_rem_euclid`][f-cre-1-8]
* [`checked_div_int`][f-cdi-1-8],
[`wrapping_div_int`][f-wdi-1-8],
[`overflowing_div_int`][f-odi-1-8]
* The following methods were added to all fixed-point numbers:
* [`const_rem`][f-cr-1-8]
* [`const_rem`][f-cor-1-8]
* [`const_not`][f-cn-1-8]
* [`const_bitand`][f-cba-1-8], [`const_bitor`][f-cbo-1-8],
[`const_bitxor`][f-cbx-1-8]
@ -31,15 +37,21 @@ Version 1.8.0 (unreleased)
[f-cba-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_bitand
[f-cbo-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_bitor
[f-cbx-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_bitxor
[f-cdi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.checked_div_int
[f-chr-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.checked_rem
[f-cn-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_not
[f-cr-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_rem
[f-cor-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_rem
[f-cre-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.checked_rem_euclid
[f-d-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.DELTA
[f-o-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.ONE
[f-odi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.overflowing_div_int
[f-re-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.rem_euclid
[f-sdei-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.saturating_div_euclid_int
[f-srei-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.saturating_rem_euclid_int
[f-ur-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.unwrapped_rem
[f-ure-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.unwrapped_rem_euclid
[f-uri-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.unwrapped_rem_int
[f-wdi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.wrapping_div_int
[f-z-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.ZERO
[tf-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html
[u-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.Unwrapped.html

View File

@ -811,7 +811,7 @@ assert_eq!(Fix::from_num(7.5).rem_euclid(Fix::from_num(2)), Fix::from_num(1.5));
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub fn rem_euclid(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
pub const fn rem_euclid(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
let rhs_bits = rhs.to_bits();
if_signed! {
$Signedness;
@ -819,7 +819,22 @@ assert_eq!(Fix::from_num(7.5).rem_euclid(Fix::from_num(2)), Fix::from_num(1.5));
return Self::ZERO;
}
}
Self::from_bits(self.to_bits().rem_euclid(rhs_bits))
// TODO: replace when rustc 1.52.0 is required
// Self::from_bits(self.to_bits().rem_euclid(rhs_bits))
let bits = self.to_bits() % rhs_bits;
if_signed! {
$Signedness;
let bits = if bits < 0 {
if rhs_bits < 0 {
bits - rhs_bits
} else {
bits + rhs_bits
}
} else {
bits
};
}
Self::from_bits(bits)
}
}
@ -1215,7 +1230,7 @@ assert_eq!(Fix::from_num(1.5).checked_rem(Fix::ZERO), None);
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub fn checked_rem(self, rhs: $Fixed<Frac>) -> Option<$Fixed<Frac>> {
pub const fn checked_rem(self, rhs: $Fixed<Frac>) -> Option<$Fixed<Frac>> {
let rhs_bits = rhs.to_bits();
if_signed! {
$Signedness;
@ -1223,9 +1238,15 @@ assert_eq!(Fix::from_num(1.5).checked_rem(Fix::ZERO), None);
return Some(Self::ZERO);
}
}
match self.to_bits().checked_rem(rhs_bits) {
None => None,
Some(bits) => Some(Self::from_bits(bits)),
// TODO: replace when rustc 1.52.0 is required
// match self.to_bits().checked_rem(rhs_bits) {
// None => None,
// Some(bits) => Some(Self::from_bits(bits)),
// }
if rhs_bits == 0 {
None
} else {
Some(Self::from_bits(self.to_bits() % rhs_bits))
}
}
}
@ -1335,11 +1356,23 @@ assert_eq!(Fix::ONE.checked_div_int(0), None);
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub fn checked_div_int(self, rhs: $Inner) -> Option<$Fixed<Frac>> {
match self.to_bits().checked_div(rhs) {
None => None,
Some(bits) => Some(Self::from_bits(bits)),
pub const fn checked_div_int(self, rhs: $Inner) -> Option<$Fixed<Frac>> {
// TODO: replace when rustc 1.52.0 is required
// match self.to_bits().checked_div(rhs) {
// None => None,
// Some(bits) => Some(Self::from_bits(bits)),
// }
if rhs == 0 {
return None;
}
let self_bits = self.to_bits();
if_signed! {
$Signedness;
if self_bits == Self::MIN.to_bits() && rhs == -1 {
return None;
}
}
Some(Self::from_bits(self_bits / rhs))
}
}
@ -1365,7 +1398,7 @@ assert_eq!(num.checked_rem_euclid(Fix::ZERO), None);
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub fn checked_rem_euclid(self, rhs: $Fixed<Frac>) -> Option<$Fixed<Frac>> {
pub const fn checked_rem_euclid(self, rhs: $Fixed<Frac>) -> Option<$Fixed<Frac>> {
let rhs_bits = rhs.to_bits();
if_signed! {
$Signedness;
@ -1373,9 +1406,15 @@ assert_eq!(num.checked_rem_euclid(Fix::ZERO), None);
return Some(Self::ZERO);
}
}
match self.to_bits().checked_rem_euclid(rhs_bits) {
None => None,
Some(bits) => Some(Self::from_bits(bits)),
// TODO: replace when rustc 1.52.0 is required
// match self.to_bits().checked_rem_euclid(rhs_bits) {
// None => None,
// Some(bits) => Some(Self::from_bits(bits)),
// }
if rhs_bits == 0 {
None
} else {
Some(self.rem_euclid(rhs))
}
}
}
@ -1886,8 +1925,10 @@ assert_eq!(Fix::from_num(3).wrapping_div_int(2), one_point_5);
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub fn wrapping_div_int(self, rhs: $Inner) -> $Fixed<Frac> {
Self::from_bits(self.to_bits().wrapping_div(rhs))
pub const fn wrapping_div_int(self, rhs: $Inner) -> $Fixed<Frac> {
// TODO: replace when rustc 1.52.0 is required
// Self::from_bits(self.to_bits().wrapping_div(rhs))
self.overflowing_div_int(rhs).0
}
}
@ -2660,9 +2701,18 @@ assert_eq!(Fix::from_num(3).overflowing_div_int(2), (one_point_5, false));
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub fn overflowing_div_int(self, rhs: $Inner) -> ($Fixed<Frac>, bool) {
let (ans, o) = self.to_bits().overflowing_div(rhs);
(Self::from_bits(ans), o)
pub const fn overflowing_div_int(self, rhs: $Inner) -> ($Fixed<Frac>, bool) {
// TODO: replace when rustc 1.52.0 is required
// let (ans, o) = self.to_bits().overflowing_div(rhs);
// (Self::from_bits(ans), o)
let self_bits = self.to_bits();
if_signed! {
$Signedness;
if self_bits == Self::MIN.to_bits() && rhs == -1 {
return (self, true);
}
}
(Self::from_bits(self_bits / rhs), false)
}
}