use crate::{
helpers::{Sealed, Widest},
types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8, Unsigned},
F128Bits, FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32,
FixedU64, FixedU8, ParseFixedError,
};
#[cfg(feature = "arbitrary")]
use arbitrary::Arbitrary;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use bytemuck::{self, Pod, TransparentWrapper};
use core::{
fmt::{Binary, Debug, Display, LowerHex, Octal, UpperHex},
hash::Hash,
iter::{Product, Sum},
mem,
num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
NonZeroU32, NonZeroU64, NonZeroU8,
},
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
SubAssign,
},
str::FromStr,
};
use half::{bf16, f16};
#[cfg(feature = "num-traits")]
use num_traits::{
bounds::Bounded,
cast::{FromPrimitive, ToPrimitive},
float::FloatConst,
identities::Zero,
ops::{
checked::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr,
CheckedSub,
},
inv::Inv,
overflowing::{OverflowingAdd, OverflowingMul, OverflowingSub},
saturating::{SaturatingAdd, SaturatingMul, SaturatingSub},
wrapping::{WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub},
},
};
#[cfg(feature = "serde")]
use serde::{de::Deserialize, ser::Serialize};
macro_rules! comment_features {
($comment:expr) => {
#[cfg(all(
not(feature = "arbitrary"),
not(feature = "borsh"),
not(feature = "num-traits"),
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed {}
}
#[cfg(all(
not(feature = "arbitrary"),
not(feature = "borsh"),
not(feature = "num-traits"),
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(
not(feature = "arbitrary"),
not(feature = "borsh"),
feature = "num-traits",
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
{
}
}
#[cfg(all(
not(feature = "arbitrary"),
not(feature = "borsh"),
feature = "num-traits",
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(
not(feature = "arbitrary"),
feature = "borsh",
not(feature = "num-traits"),
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: BorshSerialize + BorshDeserialize,
{}
}
#[cfg(all(
not(feature = "arbitrary"),
feature = "borsh",
not(feature = "num-traits"),
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: BorshSerialize + BorshDeserialize,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(
not(feature = "arbitrary"),
feature = "borsh",
feature = "num-traits",
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: BorshSerialize + BorshDeserialize,
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
{
}
}
#[cfg(all(
not(feature = "arbitrary"),
feature = "borsh",
feature = "num-traits",
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: BorshSerialize + BorshDeserialize,
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(
feature = "arbitrary",
not(feature = "borsh"),
not(feature = "num-traits"),
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
{
}
}
#[cfg(all(
feature = "arbitrary",
not(feature = "borsh"),
not(feature = "num-traits"),
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: Serialize + for<'de> Deserialize<'de>
{
}
}
#[cfg(all(
feature = "arbitrary",
not(feature = "borsh"),
feature = "num-traits",
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
{
}
}
#[cfg(all(
feature = "arbitrary",
not(feature = "borsh"),
feature = "num-traits",
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(
feature = "arbitrary",
feature = "borsh",
not(feature = "num-traits"),
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: BorshSerialize + BorshDeserialize,
{
}
}
#[cfg(all(
feature = "arbitrary",
feature = "borsh",
not(feature = "num-traits"),
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: BorshSerialize + BorshDeserialize,
Self: Serialize + for<'de> Deserialize<'de>
{
}
}
#[cfg(all(
feature = "arbitrary",
feature = "borsh",
feature = "num-traits",
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: BorshSerialize + BorshDeserialize,
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
{
}
}
#[cfg(all(
feature = "arbitrary",
feature = "borsh",
feature = "num-traits",
feature = "serde"
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Sealed
where
Self: for<'a> Arbitrary<'a>,
Self: BorshSerialize + BorshDeserialize,
Self: Zero + Bounded + Inv,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
};
}
comment_features! {
r#"This trait is used to provide supertraits to the [`Fixed`] trait
depending on the crate’s [optional features], and should not be used directly.
1. If the `arbitrary` feature is enabled, [`Arbitrary`] is a supertrait of
[`Fixed`].
2. If the `borsh` experimental feature is enabled, [`BorshSerialize`] and
[`BorshDeserialize`] are supertraits of [`Fixed`].
3. If the `num-traits` experimental feature is enabled, the following
are supertraits of [`Fixed`]:
* [`Zero`]
* [`Bounded`]
* [`Inv`]
* [`CheckedAdd`], [`CheckedSub`], [`CheckedNeg`],
[`CheckedMul`], [`CheckedDiv`], [`CheckedRem`],
[`CheckedShl`], [`CheckedShr`]
* [`SaturatingAdd`], [`SaturatingSub`], [`SaturatingMul`]
* [`WrappingAdd`], [`WrappingSub`], [`WrappingNeg`],
[`WrappingMul`], [`WrappingShl`], [`WrappingShr`]
* [`OverflowingAdd`], [`OverflowingSub`], [`OverflowingMul`]
* [`ToPrimitive`], [`FromPrimitive`]
* [`FloatConst`]
The following are *not* supertraits of [`Fixed`], even though they
are implemented for fixed-point numbers where applicable:
* [`One`] because not all fixed-point numbers can represent the
value 1
* [`Num`] because it has [`One`] as a supertrait
* [`MulAdd`], [`MulAddAssign`] because
<code>[MulAdd][`MulAdd`]::[mul\_add][`mul_add`]</code>
conflicts with
<code>[Fixed]::[mul\_add][Fixed::mul_add]</code>
Similarly, [`Signed`] and [`Unsigned`] are *not* supertraits of
[`FixedSigned`] and [`FixedUnsigned`] because they have [`Num`] as
a supertrait.
4. If the `serde` feature is enabled, [`Serialize`] and
[`Deserialize`] are supertraits of [`Fixed`].
[`MulAddAssign`]: num_traits::ops::mul_add::MulAddAssign
[`MulAdd`]: num_traits::ops::mul_add::MulAdd
[`Num`]: num_traits::Num
[`One`]: num_traits::identities::One
[`Signed`]: num_traits::sign::Signed
[`Unsigned`]: num_traits::sign::Unsigned
[`mul_add`]: num_traits::ops::mul_add::MulAdd::mul_add
[optional features]: crate#optional-features
"#
}
pub trait Fixed
where
Self: Default + Hash + Ord,
Self: Pod + TransparentWrapper<<Self as Fixed>::Bits>,
Self: Debug + Display + Binary + Octal + LowerHex + UpperHex,
Self: FromStr<Err = ParseFixedError>,
Self: FromFixed + ToFixed,
Self: Add<Output = Self> + AddAssign,
Self: Sub<Output = Self> + SubAssign,
Self: Mul<Output = Self> + MulAssign,
Self: Div<Output = Self> + DivAssign,
Self: Rem<Output = Self> + RemAssign,
Self: Mul<<Self as Fixed>::Bits, Output = Self> + MulAssign<<Self as Fixed>::Bits>,
Self: Div<<Self as Fixed>::Bits, Output = Self> + DivAssign<<Self as Fixed>::Bits>,
Self: Rem<<Self as Fixed>::Bits, Output = Self> + RemAssign<<Self as Fixed>::Bits>,
Self: Rem<<Self as Fixed>::NonZeroBits, Output = Self>,
Self: RemAssign<<Self as Fixed>::NonZeroBits>,
Self: Not<Output = Self>,
Self: BitAnd<Output = Self> + BitAndAssign,
Self: BitOr<Output = Self> + BitOrAssign,
Self: BitXor<Output = Self> + BitXorAssign,
Self: Shl<u32, Output = Self> + ShlAssign<u32>,
Self: Shr<u32, Output = Self> + ShrAssign<u32>,
Self: Sum + Product,
Self: PartialOrd<i8> + PartialOrd<i16> + PartialOrd<i32>,
Self: PartialOrd<i64> + PartialOrd<i128> + PartialOrd<isize>,
Self: PartialOrd<u8> + PartialOrd<u16> + PartialOrd<u32>,
Self: PartialOrd<u64> + PartialOrd<u128> + PartialOrd<usize>,
Self: PartialOrd<f16> + PartialOrd<bf16>,
Self: PartialOrd<f32> + PartialOrd<f64>,
Self: PartialOrd<F128Bits>,
Self: FixedOptionalFeatures,
Self: Sealed,
{
type Bits;
type NonZeroBits;
type Bytes;
type Frac: Unsigned;
type Signed: FixedSigned;
type Unsigned: FixedUnsigned;
#[inline]
fn get_signed(&self) -> Option<&Self::Signed> {
if Self::IS_SIGNED {
Some(bytemuck::cast_ref(self))
} else {
None
}
}
#[inline]
fn get_unsigned(&self) -> Option<&Self::Unsigned> {
if Self::IS_SIGNED {
None
} else {
Some(bytemuck::cast_ref(self))
}
}
#[inline]
fn get_signed_mut(&mut self) -> Option<&mut Self::Signed> {
if Self::IS_SIGNED {
Some(bytemuck::cast_mut(self))
} else {
None
}
}
#[inline]
fn get_unsigned_mut(&mut self) -> Option<&mut Self::Unsigned> {
if Self::IS_SIGNED {
None
} else {
Some(bytemuck::cast_mut(self))
}
}
const ZERO: Self;
const DELTA: Self;
const MIN: Self;
const MAX: Self;
const IS_SIGNED: bool;
const INT_NBITS: u32;
const FRAC_NBITS: u32;
fn from_bits(bits: Self::Bits) -> Self;
fn to_bits(self) -> Self::Bits;
fn from_be(fixed: Self) -> Self;
fn from_le(fixed: Self) -> Self;
fn to_be(self) -> Self;
fn to_le(self) -> Self;
fn swap_bytes(self) -> Self;
fn from_be_bytes(bytes: Self::Bytes) -> Self;
fn from_le_bytes(bytes: Self::Bytes) -> Self;
fn from_ne_bytes(bytes: Self::Bytes) -> Self;
fn to_be_bytes(self) -> Self::Bytes;
fn to_le_bytes(self) -> Self::Bytes;
fn to_ne_bytes(self) -> Self::Bytes;
fn from_num<Src: ToFixed>(src: Src) -> Self;
fn to_num<Dst: FromFixed>(self) -> Dst;
fn checked_from_num<Src: ToFixed>(src: Src) -> Option<Self>;
fn checked_to_num<Dst: FromFixed>(self) -> Option<Dst>;
fn saturating_from_num<Src: ToFixed>(src: Src) -> Self;
fn saturating_to_num<Dst: FromFixed>(self) -> Dst;
fn wrapping_from_num<Src: ToFixed>(src: Src) -> Self;
fn wrapping_to_num<Dst: FromFixed>(self) -> Dst;
#[track_caller]
fn unwrapped_from_num<Src: ToFixed>(src: Src) -> Self;
#[track_caller]
fn unwrapped_to_num<Dst: FromFixed>(self) -> Dst;
fn overflowing_from_num<Src: ToFixed>(src: Src) -> (Self, bool);
fn overflowing_to_num<Dst: FromFixed>(self) -> (Dst, bool);
fn from_str_binary(src: &str) -> Result<Self, ParseFixedError>;
fn from_str_octal(src: &str) -> Result<Self, ParseFixedError>;
fn from_str_hex(src: &str) -> Result<Self, ParseFixedError>;
fn saturating_from_str(src: &str) -> Result<Self, ParseFixedError>;
fn saturating_from_str_binary(src: &str) -> Result<Self, ParseFixedError>;
fn saturating_from_str_octal(src: &str) -> Result<Self, ParseFixedError>;
fn saturating_from_str_hex(src: &str) -> Result<Self, ParseFixedError>;
fn wrapping_from_str(src: &str) -> Result<Self, ParseFixedError>;
fn wrapping_from_str_binary(src: &str) -> Result<Self, ParseFixedError>;
fn wrapping_from_str_octal(src: &str) -> Result<Self, ParseFixedError>;
fn wrapping_from_str_hex(src: &str) -> Result<Self, ParseFixedError>;
fn overflowing_from_str(src: &str) -> Result<(Self, bool), ParseFixedError>;
fn overflowing_from_str_binary(src: &str) -> Result<(Self, bool), ParseFixedError>;
fn overflowing_from_str_octal(src: &str) -> Result<(Self, bool), ParseFixedError>;
fn overflowing_from_str_hex(src: &str) -> Result<(Self, bool), ParseFixedError>;
fn int(self) -> Self;
fn frac(self) -> Self;
fn round_to_zero(self) -> Self;
fn ceil(self) -> Self;
fn floor(self) -> Self;
fn round(self) -> Self;
fn round_ties_to_even(self) -> Self;
fn checked_ceil(self) -> Option<Self>;
fn checked_floor(self) -> Option<Self>;
fn checked_round(self) -> Option<Self>;
fn checked_round_ties_to_even(self) -> Option<Self>;
fn saturating_ceil(self) -> Self;
fn saturating_floor(self) -> Self;
fn saturating_round(self) -> Self;
fn saturating_round_ties_to_even(self) -> Self;
fn wrapping_ceil(self) -> Self;
fn wrapping_floor(self) -> Self;
fn wrapping_round(self) -> Self;
fn wrapping_round_ties_to_even(self) -> Self;
#[track_caller]
fn unwrapped_ceil(self) -> Self;
#[track_caller]
fn unwrapped_floor(self) -> Self;
#[track_caller]
fn unwrapped_round(self) -> Self;
#[track_caller]
fn unwrapped_round_ties_to_even(self) -> Self;
fn overflowing_ceil(self) -> (Self, bool);
fn overflowing_floor(self) -> (Self, bool);
fn overflowing_round(self) -> (Self, bool);
fn overflowing_round_ties_to_even(self) -> (Self, bool);
fn count_ones(self) -> u32;
fn count_zeros(self) -> u32;
fn leading_ones(self) -> u32;
fn leading_zeros(self) -> u32;
fn trailing_ones(self) -> u32;
fn trailing_zeros(self) -> u32;
fn int_log2(self) -> i32;
fn int_log10(self) -> i32;
fn checked_int_log2(self) -> Option<i32>;
fn checked_int_log10(self) -> Option<i32>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn reverse_bits(self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn rotate_left(self, n: u32) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn rotate_right(self, n: u32) -> Self;
fn is_zero(self) -> bool;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn dist(self, other: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn mean(self, other: Self) -> Self;
fn recip(self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn mul_add(self, mul: Self, add: Self) -> Self;
fn mul_acc(&mut self, a: Self, b: Self);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn div_euclid(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn rem_euclid(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn div_euclid_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn rem_euclid_int(self, rhs: Self::Bits) -> Self;
fn lerp(self, start: Self, end: Self) -> Self;
fn inv_lerp(self, start: Self, end: Self) -> Self;
fn checked_neg(self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_add(self, rhs: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_sub(self, rhs: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_mul(self, rhs: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_div(self, rhs: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_rem(self, rhs: Self) -> Option<Self>;
fn checked_recip(self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_mul_add(self, mul: Self, add: Self) -> Option<Self>;
#[must_use = "this `Option` may be a `None` variant indicating overflow, which should be handled"]
fn checked_mul_acc(&mut self, a: Self, b: Self) -> Option<()>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_mul_int(self, rhs: Self::Bits) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_div_int(self, rhs: Self::Bits) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_rem_int(self, rhs: Self::Bits) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_div_euclid_int(self, rhs: Self::Bits) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_rem_euclid_int(self, rhs: Self::Bits) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_shl(self, rhs: u32) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_shr(self, rhs: u32) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_dist(self, other: Self) -> Option<Self>;
fn checked_lerp(self, start: Self, end: Self) -> Option<Self>;
fn checked_inv_lerp(self, start: Self, end: Self) -> Option<Self>;
fn saturating_neg(self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_add(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_sub(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_mul(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div(self, rhs: Self) -> Self;
fn saturating_recip(self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_mul_add(self, mul: Self, add: Self) -> Self;
fn saturating_mul_acc(&mut self, a: Self, b: Self);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div_euclid(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_mul_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div_euclid_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_rem_euclid_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_dist(self, other: Self) -> Self;
fn saturating_lerp(self, start: Self, end: Self) -> Self;
fn saturating_inv_lerp(self, start: Self, end: Self) -> Self;
fn wrapping_neg(self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_add(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_sub(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_mul(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div(self, rhs: Self) -> Self;
fn wrapping_recip(self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_mul_add(self, mul: Self, add: Self) -> Self;
fn wrapping_mul_acc(&mut self, a: Self, b: Self);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div_euclid(self, rhs: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_mul_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div_euclid_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_rem_euclid_int(self, rhs: Self::Bits) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_shl(self, rhs: u32) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_shr(self, rhs: u32) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_dist(self, other: Self) -> Self;
fn wrapping_lerp(self, start: Self, end: Self) -> Self;
fn wrapping_inv_lerp(self, start: Self, end: Self) -> Self;
#[track_caller]
fn unwrapped_neg(self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_add(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_sub(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_mul(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_div(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_rem(self, rhs: Self) -> Self;
#[track_caller]
fn unwrapped_recip(self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_mul_add(self, mul: Self, add: Self) -> Self;
#[track_caller]
fn unwrapped_mul_acc(&mut self, a: Self, b: Self);
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_div_euclid(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_rem_euclid(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_mul_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_div_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_rem_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_div_euclid_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_rem_euclid_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_shl(self, rhs: u32) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_shr(self, rhs: u32) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_dist(self, other: Self) -> Self;
fn unwrapped_lerp(self, start: Self, end: Self) -> Self;
fn unwrapped_inv_lerp(self, start: Self, end: Self) -> Self;
fn overflowing_neg(self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_add(self, rhs: Self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_sub(self, rhs: Self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_mul(self, rhs: Self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div(self, rhs: Self) -> (Self, bool);
fn overflowing_recip(self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_mul_add(self, mul: Self, add: Self) -> (Self, bool);
#[must_use = "this returns whether overflow occurs; use `wrapping_mul_acc` if the flag is not needed"]
fn overflowing_mul_acc(&mut self, a: Self, b: Self) -> bool;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div_int(self, rhs: Self::Bits) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div_euclid_int(self, rhs: Self::Bits) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_rem_euclid_int(self, rhs: Self::Bits) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_shl(self, rhs: u32) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_shr(self, rhs: u32) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_dist(self, other: Self) -> (Self, bool);
fn overflowing_lerp(self, start: Self, end: Self) -> (Self, bool);
fn overflowing_inv_lerp(self, start: Self, end: Self) -> (Self, bool);
}
pub trait FixedSigned: Fixed
where
Self: Neg<Output = Self>,
{
fn signed_bits(self) -> u32;
fn is_positive(self) -> bool;
fn is_negative(self) -> bool;
fn abs(self) -> Self;
fn unsigned_abs(self) -> Self::Unsigned;
fn unsigned_dist(self, other: Self) -> Self::Unsigned;
fn signum(self) -> Self;
fn checked_abs(self) -> Option<Self>;
fn checked_signum(self) -> Option<Self>;
fn saturating_abs(self) -> Self;
fn saturating_signum(self) -> Self;
fn wrapping_abs(self) -> Self;
fn wrapping_signum(self) -> Self;
#[track_caller]
fn unwrapped_abs(self) -> Self;
#[track_caller]
fn unwrapped_signum(self) -> Self;
fn overflowing_abs(self) -> (Self, bool);
fn overflowing_signum(self) -> (Self, bool);
}
pub trait FixedUnsigned: Fixed
where
Self: Div<<Self as Fixed>::NonZeroBits, Output = Self>,
Self: DivAssign<<Self as Fixed>::NonZeroBits>,
{
fn significant_bits(self) -> u32;
fn is_power_of_two(self) -> bool;
fn highest_one(self) -> Self;
fn next_power_of_two(self) -> Self;
fn checked_next_power_of_two(self) -> Option<Self>;
fn wrapping_next_power_of_two(self) -> Self;
#[track_caller]
fn unwrapped_next_power_of_two(self) -> Self;
}
pub trait LosslessTryFrom<Src>: Sized {
fn lossless_try_from(src: Src) -> Option<Self>;
}
pub trait LosslessTryInto<Dst> {
fn lossless_try_into(self) -> Option<Dst>;
}
impl<Src, Dst> LosslessTryInto<Dst> for Src
where
Dst: LosslessTryFrom<Src>,
{
fn lossless_try_into(self) -> Option<Dst> {
Dst::lossless_try_from(self)
}
}
pub trait LossyFrom<Src> {
fn lossy_from(src: Src) -> Self;
}
pub trait LossyInto<Dst> {
fn lossy_into(self) -> Dst;
}
impl<Src, Dst> LossyInto<Dst> for Src
where
Dst: LossyFrom<Src>,
{
fn lossy_into(self) -> Dst {
Dst::lossy_from(self)
}
}
pub trait FromFixed {
fn from_fixed<F: Fixed>(src: F) -> Self;
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self>
where
Self: Sized;
fn saturating_from_fixed<F: Fixed>(src: F) -> Self;
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self;
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool)
where
Self: Sized;
#[inline]
#[track_caller]
fn unwrapped_from_fixed<F: Fixed>(src: F) -> Self
where
Self: Sized,
{
match Self::overflowing_from_fixed(src) {
(val, false) => val,
(_, true) => panic!("overflow"),
}
}
}
pub trait ToFixed {
fn to_fixed<F: Fixed>(self) -> F;
fn checked_to_fixed<F: Fixed>(self) -> Option<F>;
fn saturating_to_fixed<F: Fixed>(self) -> F;
fn wrapping_to_fixed<F: Fixed>(self) -> F;
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool);
#[inline]
#[track_caller]
fn unwrapped_to_fixed<F: Fixed>(self) -> F
where
Self: Sized,
{
match self.overflowing_to_fixed() {
(val, false) => val,
(_, true) => panic!("overflow"),
}
}
}
pub trait FixedEquiv {
type Equiv: Fixed;
fn to_fixed_equiv(self) -> Self::Equiv;
fn as_fixed_equiv(&self) -> &Self::Equiv;
fn as_fixed_equiv_mut(&mut self) -> &mut Self::Equiv;
fn from_fixed_equiv(f: Self::Equiv) -> Self;
fn ref_from_fixed_equiv(f: &Self::Equiv) -> &Self;
fn mut_from_fixed_equiv(f: &mut Self::Equiv) -> &mut Self;
}
macro_rules! trait_delegate {
(fn $method:ident($($param:ident: $Param:ty),*) -> $Ret:ty) => {
#[inline]
fn $method($($param: $Param),*) -> $Ret {
Self::$method($($param),*)
}
};
(fn $method:ident(self $(, $param:ident: $Param:ty)*) -> $Ret:ty) => {
#[inline]
fn $method(self $(, $param: $Param)*) -> $Ret {
self.$method($($param),*)
}
};
(fn $method:ident(&mut self $(, $param:ident: $Param:ty)*) $(-> $Ret:ty)*) => {
#[inline]
fn $method(&mut self $(, $param: $Param)*) $(-> $Ret)* {
self.$method($($param),*)
}
};
(fn $method:ident<$Gen:ident: $Trait:ident>($($param:ident: $Param:ty),*) -> $Ret:ty) => {
#[inline]
fn $method<$Gen: $Trait>($($param: $Param),*) -> $Ret {
Self::$method($($param),*)
}
};
(fn $method:ident<$Gen:ident: $Trait:ident>(self $(, $param:ident: $Param:ty)*) -> $Ret:ty) => {
#[inline]
fn $method<$Gen: $Trait>(self $(, $param: $Param)*) -> $Ret {
self.$method($($param),*)
}
};
}
macro_rules! impl_fixed {
(
$Fixed:ident, $IFixed:ident, $UFixed:ident, $LeEqU:ident, $Bits:ident, $NonZeroBits:ident,
$Signedness:tt
) => {
impl<Frac: $LeEqU> FixedOptionalFeatures for $Fixed<Frac> {}
impl<Frac: $LeEqU> Fixed for $Fixed<Frac> {
type Bits = $Bits;
type NonZeroBits = $NonZeroBits;
type Bytes = [u8; mem::size_of::<$Bits>()];
type Frac = Frac;
type Signed = $IFixed<Frac>;
type Unsigned = $UFixed<Frac>;
const ZERO: Self = Self::ZERO;
const DELTA: Self = Self::DELTA;
const MIN: Self = Self::MIN;
const MAX: Self = Self::MAX;
const IS_SIGNED: bool = Self::IS_SIGNED;
const INT_NBITS: u32 = Self::INT_NBITS;
const FRAC_NBITS: u32 = Self::FRAC_NBITS;
trait_delegate! { fn from_bits(bits: Self::Bits) -> Self }
trait_delegate! { fn to_bits(self) -> Self::Bits }
trait_delegate! { fn from_be(fixed: Self) -> Self }
trait_delegate! { fn from_le(fixed: Self) -> Self }
trait_delegate! { fn to_be(self) -> Self }
trait_delegate! { fn to_le(self) -> Self }
trait_delegate! { fn swap_bytes(self) -> Self }
trait_delegate! { fn from_be_bytes(bits: Self::Bytes) -> Self }
trait_delegate! { fn from_le_bytes(bits: Self::Bytes) -> Self }
trait_delegate! { fn from_ne_bytes(bits: Self::Bytes) -> Self }
trait_delegate! { fn to_be_bytes(self) -> Self::Bytes }
trait_delegate! { fn to_le_bytes(self) -> Self::Bytes }
trait_delegate! { fn to_ne_bytes(self) -> Self::Bytes }
trait_delegate! { fn from_num<Src: ToFixed>(src: Src) -> Self }
trait_delegate! { fn to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn checked_from_num<Src: ToFixed>(val: Src) -> Option<Self> }
trait_delegate! { fn checked_to_num<Dst: FromFixed>(self) -> Option<Dst> }
trait_delegate! { fn saturating_from_num<Src: ToFixed>(val: Src) -> Self }
trait_delegate! { fn saturating_to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn wrapping_from_num<Src: ToFixed>(val: Src) -> Self }
trait_delegate! { fn wrapping_to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn unwrapped_from_num<Src: ToFixed>(val: Src) -> Self }
trait_delegate! { fn unwrapped_to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn overflowing_from_num<Src: ToFixed>(val: Src) -> (Self, bool) }
trait_delegate! { fn overflowing_to_num<Dst: FromFixed>(self) -> (Dst, bool) }
trait_delegate! { fn from_str_binary(src: &str) -> Result<Self, ParseFixedError> }
trait_delegate! { fn from_str_octal(src: &str) -> Result<Self, ParseFixedError> }
trait_delegate! { fn from_str_hex(src: &str) -> Result<Self, ParseFixedError> }
trait_delegate! {
fn saturating_from_str(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn saturating_from_str_binary(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn saturating_from_str_octal(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn saturating_from_str_hex(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str_binary(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str_octal(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str_hex(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str_binary(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str_octal(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str_hex(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! { fn int(self) -> Self }
trait_delegate! { fn frac(self) -> Self }
trait_delegate! { fn ceil(self) -> Self }
trait_delegate! { fn floor(self) -> Self }
trait_delegate! { fn round_to_zero(self) -> Self }
trait_delegate! { fn round(self) -> Self }
trait_delegate! { fn round_ties_to_even(self) -> Self }
trait_delegate! { fn checked_ceil(self) -> Option<Self> }
trait_delegate! { fn checked_floor(self) -> Option<Self> }
trait_delegate! { fn checked_round(self) -> Option<Self> }
trait_delegate! { fn checked_round_ties_to_even(self) -> Option<Self> }
trait_delegate! { fn saturating_ceil(self) -> Self }
trait_delegate! { fn saturating_floor(self) -> Self }
trait_delegate! { fn saturating_round(self) -> Self }
trait_delegate! { fn saturating_round_ties_to_even(self) -> Self }
trait_delegate! { fn wrapping_ceil(self) -> Self }
trait_delegate! { fn wrapping_floor(self) -> Self }
trait_delegate! { fn wrapping_round(self) -> Self }
trait_delegate! { fn wrapping_round_ties_to_even(self) -> Self }
trait_delegate! { fn unwrapped_ceil(self) -> Self }
trait_delegate! { fn unwrapped_floor(self) -> Self }
trait_delegate! { fn unwrapped_round(self) -> Self }
trait_delegate! { fn unwrapped_round_ties_to_even(self) -> Self }
trait_delegate! { fn overflowing_ceil(self) -> (Self, bool) }
trait_delegate! { fn overflowing_floor(self) -> (Self, bool) }
trait_delegate! { fn overflowing_round(self) -> (Self, bool) }
trait_delegate! { fn overflowing_round_ties_to_even(self) -> (Self, bool) }
trait_delegate! { fn count_ones(self) -> u32 }
trait_delegate! { fn count_zeros(self) -> u32 }
trait_delegate! { fn leading_ones(self) -> u32 }
trait_delegate! { fn leading_zeros(self) -> u32 }
trait_delegate! { fn trailing_ones(self) -> u32 }
trait_delegate! { fn trailing_zeros(self) -> u32 }
trait_delegate! { fn int_log2(self) -> i32 }
trait_delegate! { fn int_log10(self) -> i32 }
trait_delegate! { fn checked_int_log2(self) -> Option<i32> }
trait_delegate! { fn checked_int_log10(self) -> Option<i32> }
trait_delegate! { fn reverse_bits(self) -> Self }
trait_delegate! { fn rotate_left(self, n: u32) -> Self }
trait_delegate! { fn rotate_right(self, n: u32) -> Self }
trait_delegate! { fn is_zero(self) -> bool }
trait_delegate! { fn dist(self, other: Self) -> Self }
trait_delegate! { fn mean(self, other: Self) -> Self }
trait_delegate! { fn recip(self) -> Self }
trait_delegate! { fn mul_add(self, mul: Self, add: Self) -> Self }
trait_delegate! { fn mul_acc(&mut self, a: Self, b: Self) }
trait_delegate! { fn div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn rem_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn checked_neg(self) -> Option<Self> }
trait_delegate! { fn checked_add(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_sub(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_mul(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_div(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_rem(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_recip(self) -> Option<Self> }
trait_delegate! { fn checked_mul_add(self, mul: Self, add: Self) -> Option<Self> }
trait_delegate! { fn checked_mul_acc(&mut self, a: Self, b: Self) -> Option<()> }
trait_delegate! { fn checked_div_euclid(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_rem_euclid(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_mul_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_div_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_rem_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_div_euclid_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_rem_euclid_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_shl(self, rhs: u32) -> Option<Self> }
trait_delegate! { fn checked_shr(self, rhs: u32) -> Option<Self> }
trait_delegate! { fn checked_dist(self, other: Self) -> Option<Self> }
trait_delegate! { fn checked_lerp(self, start: Self, end: Self) -> Option<Self> }
trait_delegate! { fn checked_inv_lerp(self, start: Self, end: Self) -> Option<Self> }
trait_delegate! { fn saturating_neg(self) -> Self }
trait_delegate! { fn saturating_add(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_sub(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_mul(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_div(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_recip(self) -> Self }
trait_delegate! { fn saturating_mul_add(self, mul: Self, add: Self) -> Self }
trait_delegate! { fn saturating_mul_acc(&mut self, a: Self, b: Self) }
trait_delegate! { fn saturating_div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_mul_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn saturating_div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn saturating_rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn saturating_dist(self, other: Self) -> Self }
trait_delegate! { fn saturating_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn saturating_inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn wrapping_neg(self) -> Self }
trait_delegate! { fn wrapping_add(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_sub(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_mul(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_div(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_recip(self) -> Self }
trait_delegate! { fn wrapping_mul_add(self, mul: Self, add: Self) -> Self }
trait_delegate! { fn wrapping_mul_acc(&mut self, a: Self, b: Self) }
trait_delegate! { fn wrapping_div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_mul_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_div_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_shl(self, rhs: u32) -> Self }
trait_delegate! { fn wrapping_shr(self, rhs: u32) -> Self }
trait_delegate! { fn wrapping_dist(self, other: Self) -> Self }
trait_delegate! { fn wrapping_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn wrapping_inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn unwrapped_neg(self) -> Self }
trait_delegate! { fn unwrapped_add(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_sub(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_mul(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_div(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_rem(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_recip(self) -> Self }
trait_delegate! { fn unwrapped_mul_add(self, mul: Self, add: Self) -> Self }
trait_delegate! { fn unwrapped_mul_acc(&mut self, a: Self, b: Self) }
trait_delegate! { fn unwrapped_div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_rem_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_mul_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn unwrapped_div_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn unwrapped_rem_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn unwrapped_div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn unwrapped_rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn unwrapped_shl(self, rhs: u32) -> Self }
trait_delegate! { fn unwrapped_shr(self, rhs: u32) -> Self }
trait_delegate! { fn unwrapped_dist(self, other: Self) -> Self }
trait_delegate! { fn unwrapped_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn unwrapped_inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn overflowing_neg(self) -> (Self, bool) }
trait_delegate! { fn overflowing_add(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_sub(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_div(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_recip(self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul_add(self, mul: Self, add: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul_acc(&mut self, a: Self, b: Self) -> bool }
trait_delegate! { fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_div_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_div_euclid_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_rem_euclid_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_shl(self, rhs: u32) -> (Self, bool) }
trait_delegate! { fn overflowing_shr(self, rhs: u32) -> (Self, bool) }
trait_delegate! { fn overflowing_dist(self, other: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_lerp(self, start: Self, end: Self) -> (Self, bool) }
trait_delegate! {
fn overflowing_inv_lerp(self, start: Self, end: Self) -> (Self, bool)
}
}
impl<Frac: $LeEqU> FromFixed for $Fixed<Frac> {
#[inline]
fn from_fixed<F: Fixed>(src: F) -> Self {
let (wrapped, overflow) = FromFixed::overflowing_from_fixed(src);
debug_assert!(!overflow, "{} overflows", src);
let _ = overflow;
wrapped
}
#[inline]
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self> {
match FromFixed::overflowing_from_fixed(src) {
(_, true) => None,
(wrapped, false) => Some(wrapped),
}
}
#[inline]
fn saturating_from_fixed<F: Fixed>(src: F) -> Self {
let conv = src.private_to_fixed_helper(Self::FRAC_NBITS, Self::INT_NBITS);
if conv.overflow {
return if src < 0 { Self::MIN } else { Self::MAX };
}
let bits = if_signed_unsigned!(
$Signedness,
match conv.bits {
Widest::Unsigned(bits) => {
if (bits as $Bits) < 0 {
return Self::MAX;
}
bits as $Bits
}
Widest::Negative(bits) => bits as $Bits,
},
match conv.bits {
Widest::Unsigned(bits) => bits as $Bits,
Widest::Negative(_) => {
return Self::MIN;
}
},
);
Self::from_bits(bits)
}
#[inline]
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self {
let (wrapped, _) = FromFixed::overflowing_from_fixed(src);
wrapped
}
#[inline]
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool) {
let conv = src.private_to_fixed_helper(Self::FRAC_NBITS, Self::INT_NBITS);
let mut new_overflow = false;
let bits = if_signed_unsigned!(
$Signedness,
match conv.bits {
Widest::Unsigned(bits) => {
if (bits as $Bits) < 0 {
new_overflow = true;
}
bits as $Bits
}
Widest::Negative(bits) => bits as $Bits,
},
match conv.bits {
Widest::Unsigned(bits) => bits as $Bits,
Widest::Negative(bits) => {
new_overflow = true;
bits as $Bits
}
},
);
(Self::from_bits(bits), conv.overflow || new_overflow)
}
#[inline]
fn unwrapped_from_fixed<F: Fixed>(src: F) -> Self {
match FromFixed::overflowing_from_fixed(src) {
(val, false) => val,
(_, true) => panic!("overflow"),
}
}
}
impl<Frac: $LeEqU> ToFixed for $Fixed<Frac> {
#[inline]
fn to_fixed<F: Fixed>(self) -> F {
FromFixed::from_fixed(self)
}
#[inline]
fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
FromFixed::checked_from_fixed(self)
}
#[inline]
fn saturating_to_fixed<F: Fixed>(self) -> F {
FromFixed::saturating_from_fixed(self)
}
#[inline]
fn wrapping_to_fixed<F: Fixed>(self) -> F {
FromFixed::wrapping_from_fixed(self)
}
#[inline]
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
FromFixed::overflowing_from_fixed(self)
}
#[inline]
fn unwrapped_to_fixed<F: Fixed>(self) -> F {
FromFixed::unwrapped_from_fixed(self)
}
}
if_signed! {
$Signedness;
impl<Frac: $LeEqU> FixedSigned for $Fixed<Frac> {
trait_delegate! { fn signed_bits(self) -> u32 }
trait_delegate! { fn abs(self) -> Self }
trait_delegate! { fn unsigned_abs(self) -> Self::Unsigned }
trait_delegate! { fn unsigned_dist(self, other: Self) -> Self::Unsigned }
trait_delegate! { fn signum(self) -> Self }
trait_delegate! { fn checked_abs(self) -> Option<Self> }
trait_delegate! { fn checked_signum(self) -> Option<Self> }
trait_delegate! { fn saturating_abs(self) -> Self }
trait_delegate! { fn saturating_signum(self) -> Self }
trait_delegate! { fn wrapping_abs(self) -> Self }
trait_delegate! { fn wrapping_signum(self) -> Self }
trait_delegate! { fn unwrapped_abs(self) -> Self }
trait_delegate! { fn unwrapped_signum(self) -> Self }
trait_delegate! { fn overflowing_abs(self) -> (Self, bool) }
trait_delegate! { fn overflowing_signum(self) -> (Self, bool) }
trait_delegate! { fn is_positive(self) -> bool }
trait_delegate! { fn is_negative(self) -> bool }
}
}
if_unsigned! {
$Signedness;
impl<Frac: $LeEqU> FixedUnsigned for $Fixed<Frac> {
trait_delegate! { fn significant_bits(self) -> u32 }
trait_delegate! { fn is_power_of_two(self) -> bool }
trait_delegate! { fn highest_one(self) -> Self }
trait_delegate! { fn next_power_of_two(self) -> Self }
trait_delegate! { fn checked_next_power_of_two(self) -> Option<Self> }
trait_delegate! { fn wrapping_next_power_of_two(self) -> Self }
trait_delegate! { fn unwrapped_next_power_of_two(self) -> Self }
}
}
};
}
impl_fixed! { FixedI8, FixedI8, FixedU8, LeEqU8, i8, NonZeroI8, Signed }
impl_fixed! { FixedI16, FixedI16, FixedU16, LeEqU16, i16, NonZeroI16, Signed }
impl_fixed! { FixedI32, FixedI32, FixedU32, LeEqU32, i32, NonZeroI32, Signed }
impl_fixed! { FixedI64, FixedI64, FixedU64, LeEqU64, i64, NonZeroI64, Signed }
impl_fixed! { FixedI128, FixedI128, FixedU128, LeEqU128, i128, NonZeroI128, Signed }
impl_fixed! { FixedU8, FixedI8, FixedU8, LeEqU8, u8, NonZeroU8, Unsigned }
impl_fixed! { FixedU16, FixedI16, FixedU16, LeEqU16, u16, NonZeroU16, Unsigned }
impl_fixed! { FixedU32, FixedI32, FixedU32, LeEqU32, u32, NonZeroU32, Unsigned }
impl_fixed! { FixedU64, FixedI64, FixedU64, LeEqU64, u64, NonZeroU64, Unsigned }
impl_fixed! { FixedU128, FixedI128, FixedU128, LeEqU128, u128, NonZeroU128, Unsigned }