add const_* methods

This commit is contained in:
Trevor Spiteri 2021-04-07 13:33:55 +02:00
parent 1dc6125a4b
commit 856ea398a9
3 changed files with 478 additions and 0 deletions

View File

@ -96,8 +96,28 @@ 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 were added to all fixed-point numbers:
* [`const_neg`][f-cne-1-8] (only for signed types)
* [`const_add`][f-ca-1-8], [`const_sub`][f-cs-1-8],
[`const_rem`][f-cr-1-8]
* [`const_mul_int`][f-cmi-1-8], [`const_div_int`][f-cdi-1-8]
* [`const_shl`][f-cshl-1-8], [`const_shr`][f-cshr-1-8]
* [`const_not`][f-cno-1-8], [`const_bitand`][f-cba-1-8],
[`const_bitor`][f-cbo-1-8], [`const_bitxor`][f-cbx-1-8]
* Many methods were marked with the `must_use` attribute.
[f-ca-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_add
[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.const_div_int
[f-cmi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_mul_int
[f-cne-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_neg
[f-cno-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-cs-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_sub
[f-cshl-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_shl
[f-cshr-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_shr
[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-sdei-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.saturating_div_euclid_int

View File

@ -21,8 +21,28 @@ 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 were added to all fixed-point numbers:
* [`const_neg`][f-cne-1-8] (only for signed types)
* [`const_add`][f-ca-1-8], [`const_sub`][f-cs-1-8],
[`const_rem`][f-cr-1-8]
* [`const_mul_int`][f-cmi-1-8], [`const_div_int`][f-cdi-1-8]
* [`const_shl`][f-cshl-1-8], [`const_shr`][f-cshr-1-8]
* [`const_not`][f-cno-1-8], [`const_bitand`][f-cba-1-8],
[`const_bitor`][f-cbo-1-8], [`const_bitxor`][f-cbx-1-8]
* Many methods were marked with the `must_use` attribute.
[f-ca-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_add
[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.const_div_int
[f-cmi-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_mul_int
[f-cne-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_neg
[f-cno-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-cs-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_sub
[f-cshl-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_shl
[f-cshr-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.const_shr
[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-sdei-1-8]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.saturating_div_euclid_int

View File

@ -961,6 +961,444 @@ assert_eq!(Fix::from_num(3).mean(Fix::from_num(4)), Fix::from_num(3.5));
}
}
if_signed! {
$Signedness;
comment! {
"Negation. Usable in constant context.
This is equivalent to the `-` unary operator and
<code>[Neg][core::ops::Neg]::[neg][core::ops::Neg::neg]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `-` unary operator and the
[`Neg`][core::ops::Neg] trait are usable in constant context.
# Panics
When debug assertions are enabled, this method panics if the result
overflows. Overflow can only occur when negating the minimum value.
When debug assertions are not enabled, the wrapped value can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use
[`wrapping_neg`][Self::wrapping_neg] instead.
# Examples
```rust
use fixed::{const_fixed_from_int, types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const_fixed_from_int! {
const FIVE: Fix = 5;
}
const NEG_FIVE: Fix = FIVE.const_neg();
assert_eq!(NEG_FIVE, -FIVE);
```
";
#[inline]
pub const fn const_neg(self) -> $Fixed<Frac> {
Self::from_bits(-self.to_bits())
}
}
}
comment! {
"Addition. Usable in constant context.
This is equivalent to the `+` operator and
<code>[Add][core::ops::Add]::[add][core::ops::Add::add]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `+` operator and the
[`Add`][core::ops::Add] trait are usable in constant context.
# Panics
When debug assertions are enabled, this method panics if the result
overflows. When debug assertions are not enabled, the wrapped value
can be returned, but it is not considered a breaking change if in the
future it panics; if wrapping is required use
[`wrapping_add`][Self::wrapping_add] instead.
# Examples
```rust
use fixed::{const_fixed_from_int, types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const_fixed_from_int! {
const TWO: Fix = 2;
const THREE: Fix = 3;
}
const FIVE: Fix = TWO.const_add(THREE);
assert_eq!(FIVE, TWO + THREE);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_add(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() + rhs.to_bits())
}
}
comment! {
"Subtraction. Usable in constant context.
This is equivalent to the `-` operator and
<code>[Sub][core::ops::Sub]::[sub][core::ops::Sub::sub]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `-` operator and the
[`Sub`][core::ops::Sub] trait are usable in constant context.
# Panics
When debug assertions are enabled, this method panics if the result
overflows. When debug assertions are not enabled, the wrapped value
can be returned, but it is not considered a breaking change if in the
future it panics; if wrapping is required use
[`wrapping_sub`][Self::wrapping_sub] instead.
# Examples
```rust
use fixed::{const_fixed_from_int, types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const_fixed_from_int! {
const TWO: Fix = 2;
const FIVE: Fix = 5;
}
const THREE: Fix = FIVE.const_sub(TWO);
assert_eq!(THREE, FIVE - TWO);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_sub(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() - rhs.to_bits())
}
}
comment! {
"Remainder. Usable in constant context.
This is equivalent to the `%` operator and
<code>[Rem][core::ops::Rem]::[rem][core::ops::Rem::rem]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `%` operator and the
[`Rem`][core::ops::Rem] trait are usable in constant context.
# Panics
Panics if the divisor is zero.
# Examples
```rust
use fixed::{const_fixed_from_int, types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const_fixed_from_int! {
const THREE: Fix = 3;
const FIVE: Fix = 5;
}
const TWO: Fix = FIVE.const_rem(THREE);
assert_eq!(TWO, FIVE % THREE);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_rem(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
let rhs_bits = rhs.to_bits();
if_signed! {
$Signedness;
if rhs_bits == -1 {
return Self::ZERO;
}
}
Self::from_bits(self.to_bits() % rhs_bits)
}
}
comment! {
"Multiplication by an integer. Usable in constant context.
This is equivalent to the `*` operator and
<code>[Mul][core::ops::Mul]::[mul][core::ops::Mul::mul]</code> with an
integer as the second operand, but can also be used in constant
context. Unless required in constant context, use the operator or
trait instead.
# Planned deprecation
This method will be deprecated when the `*` operator and the
[`Mul`][core::ops::Mul] trait are usable in constant context.
# Panics
When debug assertions are enabled, this method panics if the result
overflows. When debug assertions are not enabled, the wrapped value
can be returned, but it is not considered a breaking change if in the
future it panics; if wrapping is required use
[`wrapping_mul_int`][Self::wrapping_mul_int] instead.
# Examples
```rust
use fixed::{const_fixed_from_int, types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const_fixed_from_int! {
const THREE: Fix = 3;
}
const SIX: Fix = THREE.const_mul_int(2);
assert_eq!(SIX, THREE * 2);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_mul_int(self, rhs: $Inner) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() * rhs)
}
}
comment! {
"Division by an integer. Usable in constant context.
This is equivalent to the `/` operator and
<code>[Div][core::ops::Div]::[div][core::ops::Div::div]</code> with an
integer as the second operand, but can also be used in constant
context. Unless required in constant context, use the operator or
trait instead.
# Planned deprecation
This method will be deprecated when the `/` operator and the
[`Div`][core::ops::Div] trait are usable in constant context.
# Panics
Panics if the divisor is zero",
if_signed_else_empty_str!($Signedness, " or if the division results in overflow"),
".
# Examples
```rust
use fixed::{const_fixed_from_int, types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const_fixed_from_int! {
const SIX: Fix = 6;
}
const ONE_AND_HALF: Fix = SIX.const_div_int(4);
assert_eq!(ONE_AND_HALF, SIX / 4);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_div_int(self, rhs: $Inner) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() / rhs)
}
}
comment! {
"Shift left. Usable in constant context.
This is equivalent to the `<<` operator and
<code>[Shl][core::ops::Shl]::[shl][core::ops::Shl::shl]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `<<` operator and the
[`Shl`][core::ops::Shl] trait are usable in constant context.
# Panics
When debug assertions are enabled, this method panics if `rhs`  ", $s_nbits, ".
When debug assertions are not enabled, the wrapped value can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use
[`wrapping_shl`][Self::wrapping_shl] instead.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const C: Fix = Fix::from_bits(0x3E).const_shl(4);
assert_eq!(C, Fix::from_bits(0x3E) << 4);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_shl(self, rhs: u32) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() << rhs)
}
}
comment! {
"Shift right. Usable in constant context.
This is equivalent to the `>>` operator and
<code>[Shr][core::ops::Shr]::[shr][core::ops::Shr::shr]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `>>` operator and the
[`Shr`][core::ops::Shr] trait are usable in constant context.
# Panics
When debug assertions are enabled, this method panics if `rhs`  ", $s_nbits, ".
When debug assertions are not enabled, the wrapped value can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use
[`wrapping_shr`][Self::wrapping_shr] instead.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const C: Fix = Fix::from_bits(0x3E).const_shr(4);
assert_eq!(C, Fix::from_bits(0x3E) >> 4);
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_shr(self, rhs: u32) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() >> rhs)
}
}
comment! {
"Bitwise NOT. Usable in constant context.
This is equivalent to the `!` operator and
<code>[Not][core::ops::Not]::[not][core::ops::Not::not]</code>, but
can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `!` operator and the
[`Not`][core::ops::Not] trait are usable in constant context.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const C: Fix = Fix::from_bits(0x3E).const_not();
assert_eq!(C, !Fix::from_bits(0x3E));
```
";
#[inline]
pub const fn const_not(self) -> $Fixed<Frac> {
Self::from_bits(!self.to_bits())
}
}
comment! {
"Bitwise AND. Usable in constant context.
This is equivalent to the `&` operator and
<code>[BitAnd][core::ops::BitAnd]::[bitand][core::ops::BitAnd::bitand]</code>,
but can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `&` operator and the
[`BitAnd`][core::ops::BitAnd] trait are usable in constant context.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const C: Fix = Fix::from_bits(0x3E).const_bitand(Fix::from_bits(0x55));
assert_eq!(C, Fix::from_bits(0x3E) & Fix::from_bits(0x55));
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_bitand(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() & rhs.to_bits())
}
}
comment! {
"Bitwise OR. Usable in constant context.
This is equivalent to the `|` operator and
<code>[BitOr][core::ops::BitOr]::[bitor][core::ops::BitOr::bitor]</code>,
but can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `|` operator and the
[`BitOr`][core::ops::BitOr] trait are usable in constant context.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const C: Fix = Fix::from_bits(0x3E).const_bitor(Fix::from_bits(0x55));
assert_eq!(C, Fix::from_bits(0x3E) | Fix::from_bits(0x55));
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_bitor(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() | rhs.to_bits())
}
}
comment! {
"Bitwise XOR. Usable in constant context.
This is equivalent to the `^` operator and
<code>[BitXor][core::ops::BitXor]::[bitxor][core::ops::BitXor::bitxor]</code>,
but can also be used in constant context. Unless required in constant
context, use the operator or trait instead.
# Planned deprecation
This method will be deprecated when the `^` operator and the
[`BitXor`][core::ops::BitXor] trait are usable in constant context.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
const C: Fix = Fix::from_bits(0x3E).const_bitxor(Fix::from_bits(0x55));
assert_eq!(C, Fix::from_bits(0x3E) ^ Fix::from_bits(0x55));
```
";
#[inline]
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn const_bitxor(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
Self::from_bits(self.to_bits() ^ rhs.to_bits())
}
}
comment! {
"Checked negation. Returns the negated value, or [`None`] on overflow.