pub use crate::traits_bits::{
FixedBits, FixedBitsCast, FixedBitsOptionalArbitrary, FixedBitsOptionalBorsh,
FixedBitsOptionalNum, FixedBitsOptionalSerde,
};
use crate::{
helpers::Sealed,
types::extra::{If, True},
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
FixedU8, ParseFixedError, F128,
};
#[cfg(feature = "arbitrary")]
use arbitrary::Arbitrary;
use az::OverflowingCastFrom;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use bytemuck::{self, Contiguous, Pod, TransparentWrapper};
use core::{
fmt::{Binary, Debug, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex},
hash::Hash,
iter::{Product, Sum},
mem::size_of,
num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
NonZeroU32, NonZeroU64, NonZeroU8, TryFromIntError,
},
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};
#[cfg(not(feature = "arbitrary"))]
pub trait FixedOptionalArbitrary: Sealed {}
#[cfg(feature = "arbitrary")]
pub trait FixedOptionalArbitrary: Sealed
where
Self: for<'a> Arbitrary<'a>,
{
}
#[cfg(not(feature = "borsh"))]
pub trait FixedOptionalBorsh: Sealed {}
#[cfg(feature = "borsh")]
pub trait FixedOptionalBorsh: Sealed
where
Self: BorshSerialize + BorshDeserialize,
{
}
#[cfg(not(feature = "num-traits"))]
pub trait FixedOptionalNum: Sealed {}
#[cfg(feature = "num-traits")]
pub trait FixedOptionalNum: Sealed
where
Self: Zero + Bounded,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: ToPrimitive + FromPrimitive + FloatConst,
{
}
#[cfg(any(not(feature = "serde"), feature = "serde-str"))]
pub trait FixedOptionalSerde: Sealed {}
#[cfg(all(feature = "serde", not(feature = "serde-str")))]
pub trait FixedOptionalSerde: Sealed
where
Self: Serialize + for<'de> Deserialize<'de>,
{
}
#[cfg(not(feature = "num-traits"))]
pub trait FixedStrictOptionalNum: Sealed {}
#[cfg(feature = "num-traits")]
pub trait FixedStrictOptionalNum: Sealed
where
Self: Inv + CheckedDiv,
{
}
#[cfg(not(feature = "serde-str"))]
pub trait FixedStrictOptionalSerdeStr: Sealed {}
#[cfg(feature = "serde-str")]
pub trait FixedStrictOptionalSerdeStr: Sealed
where
Self: Serialize + for<'de> Deserialize<'de>,
{
}
pub trait Fixed: Sealed
where
Self: Debug + Default + Hash + Ord,
Self: Contiguous + Pod + TransparentWrapper<<Self as Fixed>::Bits>,
Self: FromFixed + ToFixed,
Self: Add<Output = Self> + AddAssign,
Self: Sub<Output = Self> + SubAssign,
Self: Mul<Output = Self> + MulAssign,
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: 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<F128>,
Self: FixedOptionalArbitrary,
Self: FixedOptionalBorsh,
Self: FixedOptionalNum,
Self: FixedOptionalSerde,
{
type Bits: FixedBits + From<Self::NonZeroBits>;
type NonZeroBits: TryFrom<Self::Bits, Error = TryFromIntError>;
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 TRY_ONE: Option<Self>;
const DELTA: Self;
const MIN: Self;
const MAX: Self;
const IS_SIGNED: bool;
const INT_BITS: i32;
const FRAC_BITS: i32;
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;
#[must_use]
fn to_be(self) -> Self;
#[must_use]
fn to_le(self) -> Self;
#[must_use]
fn swap_bytes(self) -> Self;
fn from_be_bytes(bytes: [u8; size_of::<Self>()]) -> Self;
fn from_le_bytes(bytes: [u8; size_of::<Self>()]) -> Self;
fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self;
fn to_be_bytes(self) -> [u8; size_of::<Self>()];
fn to_le_bytes(self) -> [u8; size_of::<Self>()];
fn to_ne_bytes(self) -> [u8; size_of::<Self>()];
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);
#[must_use]
fn int(self) -> Self;
#[must_use]
fn frac(self) -> Self;
#[must_use]
fn round_to_zero(self) -> Self;
#[must_use]
fn ceil(self) -> Self;
#[must_use]
fn floor(self) -> Self;
#[must_use]
fn round(self) -> Self;
#[must_use]
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>;
#[must_use]
fn saturating_ceil(self) -> Self;
#[must_use]
fn saturating_floor(self) -> Self;
#[must_use]
fn saturating_round(self) -> Self;
#[must_use]
fn saturating_round_ties_to_even(self) -> Self;
#[must_use]
fn wrapping_ceil(self) -> Self;
#[must_use]
fn wrapping_floor(self) -> Self;
#[must_use]
fn wrapping_round(self) -> Self;
#[must_use]
fn wrapping_round_ties_to_even(self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_ceil(self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_floor(self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_round(self) -> Self;
#[track_caller]
#[must_use]
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);
#[doc(alias("popcount", "popcnt"))]
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;
#[doc(alias("ilog2"))]
#[track_caller]
fn int_log2(self) -> i32;
#[doc(alias("checked_ilog2"))]
fn checked_int_log2(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 abs_diff(self, other: Self) -> Self::Unsigned;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn mean(self, other: Self) -> Self;
#[track_caller]
#[must_use]
fn next_multiple_of(self, other: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self;
#[must_use]
fn add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self;
fn mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
);
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn rem_euclid(self, rhs: 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_rem(self, rhs: Self) -> Option<Self>;
#[must_use]
fn checked_next_multiple_of(self, other: Self) -> Option<Self>;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Option<Self>;
#[must_use = "this `Option` may be a `None` variant indicating overflow, which should be handled"]
fn checked_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Option<Self>;
#[must_use = "this `Option` may be a `None` variant indicating overflow, which should be handled"]
fn checked_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Option<()>;
#[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_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>;
#[must_use]
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;
#[track_caller]
#[must_use]
fn saturating_next_multiple_of(self, other: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self;
#[must_use]
fn saturating_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self;
fn saturating_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_mul_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div_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;
#[must_use]
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;
#[track_caller]
#[must_use]
fn wrapping_next_multiple_of(self, other: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self;
#[must_use]
fn wrapping_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self;
fn wrapping_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_mul_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[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_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;
#[track_caller]
#[must_use]
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_rem(self, rhs: Self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_next_multiple_of(self, other: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self;
#[track_caller]
fn unwrapped_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
);
#[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_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;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn unwrapped_dist(self, other: 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);
#[track_caller]
fn overflowing_next_multiple_of(self, other: Self) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> (Self, bool);
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> (Self, bool);
#[must_use = "this returns whether overflow occurs; use `wrapping_mul_acc` if the flag is not needed"]
fn overflowing_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> bool;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool);
#[track_caller]
#[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_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);
}
pub trait FixedStrict: Fixed
where
Self: Display + LowerExp + UpperExp,
Self: Binary + Octal + LowerHex + UpperHex,
Self: FromStr<Err = ParseFixedError>,
Self: Div<Output = Self> + DivAssign,
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: FixedStrictOptionalNum,
Self: FixedStrictOptionalSerdeStr,
{
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>;
#[track_caller]
fn unwrapped_from_str(src: &str) -> Self;
#[track_caller]
fn unwrapped_from_str_binary(src: &str) -> Self;
#[track_caller]
fn unwrapped_from_str_octal(src: &str) -> Self;
#[track_caller]
fn unwrapped_from_str_hex(src: &str) -> Self;
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>;
#[doc(alias("ilog10"))]
#[track_caller]
fn int_log10(self) -> i32;
#[doc(alias("ilog"))]
#[track_caller]
fn int_log(self, base: u32) -> i32;
#[doc(alias("checked_ilog10"))]
fn checked_int_log10(self) -> Option<i32>;
#[doc(alias("checked_ilog"))]
fn checked_int_log(self, base: u32) -> Option<i32>;
#[track_caller]
#[must_use]
fn recip(self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn div_euclid(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn div_euclid_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn rem_euclid_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[must_use]
fn lerp(self, start: Self, end: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div(self, rhs: Self) -> (Self, bool);
#[track_caller]
fn overflowing_recip(self) -> (Self, bool);
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
#[must_use]
fn inv_lerp(self, start: Self, end: Self) -> Self;
#[must_use = "this returns the result of the operation, without modifying the original"]
fn checked_div(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_div_euclid(self, rhs: Self) -> 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>;
fn checked_lerp(self, start: Self, end: Self) -> Option<Self>;
fn checked_inv_lerp(self, start: Self, end: Self) -> Option<Self>;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div(self, rhs: Self) -> Self;
#[track_caller]
#[must_use]
fn saturating_recip(self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div_euclid(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn saturating_div_euclid_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[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]
fn saturating_lerp(self, start: Self, end: Self) -> Self;
#[must_use]
fn saturating_inv_lerp(self, start: Self, end: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div(self, rhs: Self) -> Self;
#[track_caller]
#[must_use]
fn wrapping_recip(self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div_euclid(self, rhs: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn wrapping_div_euclid_int(self, rhs: Self::Bits) -> Self;
#[track_caller]
#[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]
fn wrapping_lerp(self, start: Self, end: Self) -> Self;
#[must_use]
fn wrapping_inv_lerp(self, start: Self, end: 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]
fn unwrapped_recip(self) -> 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_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]
fn unwrapped_lerp(self, start: Self, end: Self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_inv_lerp(self, start: Self, end: Self) -> Self;
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_div_euclid_int(self, rhs: Self::Bits) -> (Self, bool);
#[track_caller]
#[must_use = "this returns the result of the operation, without modifying the original"]
fn overflowing_rem_euclid_int(self, rhs: Self::Bits) -> (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>,
{
const TRY_NEG_ONE: Option<Self>;
fn signed_bits(self) -> u32;
fn is_positive(self) -> bool;
fn is_negative(self) -> bool;
#[must_use]
fn abs(self) -> Self;
fn unsigned_abs(self) -> Self::Unsigned;
fn unsigned_dist(self, other: Self) -> Self::Unsigned;
#[track_caller]
#[must_use]
fn signum(self) -> Self;
#[must_use]
fn add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn checked_abs(self) -> Option<Self>;
fn checked_signum(self) -> Option<Self>;
#[must_use]
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
#[must_use]
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
#[must_use]
fn saturating_abs(self) -> Self;
#[must_use]
fn saturating_signum(self) -> Self;
#[must_use]
fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn wrapping_abs(self) -> Self;
#[must_use]
fn wrapping_signum(self) -> Self;
#[must_use]
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_abs(self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_signum(self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn overflowing_abs(self) -> (Self, bool);
fn overflowing_signum(self) -> (Self, bool);
#[must_use]
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
#[must_use]
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (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;
#[must_use]
fn highest_one(self) -> Self;
#[must_use]
fn next_power_of_two(self) -> Self;
#[must_use]
fn add_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn sub_signed(self, rhs: Self::Signed) -> Self;
fn checked_next_power_of_two(self) -> Option<Self>;
#[must_use]
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
#[must_use]
fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
#[must_use]
fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn wrapping_next_power_of_two(self) -> Self;
#[must_use]
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_next_power_of_two(self) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_add_signed(self, rhs: Self::Signed) -> Self;
#[track_caller]
#[must_use]
fn unwrapped_sub_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
#[must_use]
fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
}
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 {
#[track_caller]
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<$(const $GEN:ident: $GenT:ident),*$(,)?>
(self $(, $param:ident: $Param:ty)*$(,)?) -> $Ret:ty
) => {
#[inline]
fn $method<$(const $GEN: $GenT),*>(self $(, $param: $Param)*) -> $Ret {
self.$method($($param),*)
}
};
(
fn $method:ident<$(const $GEN:ident: $GenT:ident),*$(,)?>
(&mut self $(, $param:ident: $Param:ty)*$(,)?) $(-> $Ret:ty)*
) => {
#[inline]
fn $method<$(const $GEN: $GenT),*>(&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, $nbits:expr, $Bits:ident, $NonZeroBits:ident,
$Signedness:tt
) => {
impl<const FRAC: i32> FixedOptionalArbitrary for $Fixed<FRAC> {}
impl<const FRAC: i32> FixedOptionalBorsh for $Fixed<FRAC> {}
impl<const FRAC: i32> FixedOptionalNum for $Fixed<FRAC> {}
impl<const FRAC: i32> FixedOptionalSerde for $Fixed<FRAC> {}
impl<const FRAC: i32> FixedStrictOptionalNum for $Fixed<FRAC> where
If<{ (0 <= FRAC) & (FRAC <= $nbits) }>: True
{
}
impl<const FRAC: i32> FixedStrictOptionalSerdeStr for $Fixed<FRAC> where
If<{ (0 <= FRAC) & (FRAC <= $nbits) }>: True
{
}
impl<const FRAC: i32> Fixed for $Fixed<FRAC> {
type Bits = $Bits;
type NonZeroBits = $NonZeroBits;
type Signed = $IFixed<FRAC>;
type Unsigned = $UFixed<FRAC>;
const ZERO: Self = Self::ZERO;
const TRY_ONE: Option<Self> = Self::TRY_ONE;
const DELTA: Self = Self::DELTA;
const MIN: Self = Self::MIN;
const MAX: Self = Self::MAX;
const IS_SIGNED: bool = Self::IS_SIGNED;
const INT_BITS: i32 = Self::INT_BITS;
const FRAC_BITS: i32 = Self::FRAC_BITS;
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: [u8; size_of::<Self>()]) -> Self }
trait_delegate! { fn from_le_bytes(bits: [u8; size_of::<Self>()]) -> Self }
trait_delegate! { fn from_ne_bytes(bits: [u8; size_of::<Self>()]) -> Self }
trait_delegate! { fn to_be_bytes(self) -> [u8; size_of::<Self>()] }
trait_delegate! { fn to_le_bytes(self) -> [u8; size_of::<Self>()] }
trait_delegate! { fn to_ne_bytes(self) -> [u8; size_of::<Self>()] }
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 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 checked_int_log2(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 abs_diff(self, other: Self) -> Self::Unsigned }
trait_delegate! { fn mean(self, other: Self) -> Self }
trait_delegate! { fn next_multiple_of(self, other: Self) -> Self }
trait_delegate! { fn mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self }
trait_delegate! { fn add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self }
trait_delegate! { fn mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) }
trait_delegate! { fn rem_euclid(self, rhs: 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_rem(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_next_multiple_of(self, other: Self) -> Option<Self> }
trait_delegate! { fn checked_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Option<Self> }
trait_delegate! { fn checked_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Option<Self> }
trait_delegate! { fn checked_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Option<()> }
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_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 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_next_multiple_of(self, other: Self) -> Self }
trait_delegate! { fn saturating_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self }
trait_delegate! { fn saturating_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self }
trait_delegate! { fn saturating_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) }
trait_delegate! { fn saturating_mul_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn saturating_div_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn saturating_dist(self, other: 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_next_multiple_of(self, other: Self) -> Self }
trait_delegate! { fn wrapping_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self }
trait_delegate! { fn wrapping_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self }
trait_delegate! { fn wrapping_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) }
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_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 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_rem(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_next_multiple_of(self, other: Self) -> Self }
trait_delegate! { fn unwrapped_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> Self }
trait_delegate! { fn unwrapped_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> Self }
trait_delegate! { fn unwrapped_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) }
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_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 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_next_multiple_of(self, other: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul_add<const MUL_FRAC: i32>(
self,
mul: <Self::Bits as FixedBits>::Fixed<MUL_FRAC>,
add: Self,
) -> (Self, bool) }
trait_delegate! { fn overflowing_add_prod<const A_FRAC: i32, const B_FRAC: i32>(
self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> (Self, bool) }
trait_delegate! { fn overflowing_mul_acc<const A_FRAC: i32, const B_FRAC: i32>(
&mut self,
a: <Self::Bits as FixedBits>::Fixed<A_FRAC>,
b: <Self::Bits as FixedBits>::Fixed<B_FRAC>,
) -> 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_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) }
}
impl<const FRAC: i32> FixedStrict for $Fixed<FRAC>
where
If<{ (0 <= FRAC) & (FRAC <= $nbits) }>: True,
{
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 unwrapped_from_str(src: &str) -> Self }
trait_delegate! { fn unwrapped_from_str_binary(src: &str) -> Self }
trait_delegate! { fn unwrapped_from_str_octal(src: &str) -> Self }
trait_delegate! { fn unwrapped_from_str_hex(src: &str) -> Self }
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_log10(self) -> i32 }
trait_delegate! { fn int_log(self, base: u32) -> i32 }
trait_delegate! { fn checked_int_log10(self) -> Option<i32> }
trait_delegate! { fn checked_int_log(self, base: u32) -> Option<i32> }
trait_delegate! { fn recip(self) -> Self }
trait_delegate! { fn div_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_div(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_recip(self) -> Option<Self> }
trait_delegate! { fn checked_div_euclid(self, rhs: Self) -> 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_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_div(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_recip(self) -> Self }
trait_delegate! { fn saturating_div_euclid(self, rhs: Self) -> 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_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn saturating_inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn wrapping_div(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_recip(self) -> Self }
trait_delegate! { fn wrapping_div_euclid(self, rhs: Self) -> 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_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn wrapping_inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn unwrapped_div(self, rhs: Self) -> Self }
trait_delegate! { fn unwrapped_recip(self) -> Self }
trait_delegate! { fn unwrapped_div_euclid(self, rhs: Self) -> 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_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn unwrapped_inv_lerp(self, start: Self, end: Self) -> Self }
trait_delegate! { fn overflowing_div(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_recip(self) -> (Self, bool) }
trait_delegate! { fn overflowing_div_euclid(self, rhs: Self) -> (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_lerp(self, start: Self, end: Self) -> (Self, bool) }
trait_delegate! {
fn overflowing_inv_lerp(self, start: Self, end: Self) -> (Self, bool)
}
}
if_signed! {
$Signedness;
impl<const FRAC: i32> FixedSigned for $Fixed<FRAC> {
const TRY_NEG_ONE: Option<Self> = Self::TRY_NEG_ONE;
trait_delegate! { fn signed_bits(self) -> u32 }
trait_delegate! { fn is_positive(self) -> bool }
trait_delegate! { fn is_negative(self) -> bool }
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 add_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn sub_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn checked_abs(self) -> Option<Self> }
trait_delegate! { fn checked_signum(self) -> Option<Self> }
trait_delegate! {
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self>
}
trait_delegate! {
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self>
}
trait_delegate! { fn saturating_abs(self) -> Self }
trait_delegate! { fn saturating_signum(self) -> Self }
trait_delegate! { fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn wrapping_abs(self) -> Self }
trait_delegate! { fn wrapping_signum(self) -> Self }
trait_delegate! { fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn unwrapped_abs(self) -> Self }
trait_delegate! { fn unwrapped_signum(self) -> Self }
trait_delegate! { fn unwrapped_add_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn unwrapped_sub_unsigned(self, rhs: Self::Unsigned) -> Self }
trait_delegate! { fn overflowing_abs(self) -> (Self, bool) }
trait_delegate! { fn overflowing_signum(self) -> (Self, bool) }
trait_delegate! {
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool)
}
trait_delegate! {
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (Self, bool)
}
}
}
if_unsigned! {
$Signedness;
impl<const FRAC: i32> 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 add_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn sub_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn checked_next_power_of_two(self) -> Option<Self> }
trait_delegate! { fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self> }
trait_delegate! { fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self> }
trait_delegate! { fn saturating_add_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn saturating_sub_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn wrapping_next_power_of_two(self) -> Self }
trait_delegate! { fn wrapping_add_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn unwrapped_next_power_of_two(self) -> Self }
trait_delegate! { fn unwrapped_add_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! { fn unwrapped_sub_signed(self, rhs: Self::Signed) -> Self }
trait_delegate! {
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool)
}
trait_delegate! {
fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool)
}
}
}
impl<const FRAC: i32> FromFixed for $Fixed<FRAC> {
/// Converts a fixed-point number.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value
/// does not fit. 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_from_fixed`] instead.
///
/// [`wrapping_from_fixed`]: FromFixed::wrapping_from_fixed
#[inline]
#[track_caller]
fn from_fixed<F: Fixed>(src: F) -> Self {
let (wrapped, overflow) = $Fixed::fixed_from_bits(src.to_bits(), F::FRAC_BITS);
debug_assert!(!overflow, "overflow");
let _ = overflow;
wrapped
}
/// Converts a fixed-point number if it fits, otherwise returns [`None`].
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self> {
match $Fixed::fixed_from_bits(src.to_bits(), F::FRAC_BITS) {
(_, true) => None,
(wrapped, false) => Some(wrapped),
}
}
/// Converts a fixed-point number, saturating if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn saturating_from_fixed<F: Fixed>(src: F) -> Self {
match $Fixed::fixed_from_bits(src.to_bits(), F::FRAC_BITS) {
(wrapped, false) => wrapped,
(_, true) => {
let src_bits_zero = F::Bits::overflowing_cast_from(0u8).0;
if src.to_bits() < src_bits_zero {
$Fixed::MIN
} else {
$Fixed::MAX
}
}
}
}
/// Converts a fixed-point number, wrapping if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self {
let (wrapped, _) = $Fixed::fixed_from_bits(src.to_bits(), F::FRAC_BITS);
wrapped
}
/// Converts a fixed-point number.
///
/// Returns a [tuple] of the value and a [`bool`]
/// indicating whether an overflow has occurred. On
/// overflow, the wrapped value is returned.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool) {
$Fixed::fixed_from_bits(src.to_bits(), F::FRAC_BITS)
}
/// Converts a fixed-point number, panicking if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// Panics if the value does not fit, even when debug
/// assertions are not enabled.
#[inline]
#[track_caller]
fn unwrapped_from_fixed<F: Fixed>(src: F) -> Self {
match $Fixed::fixed_from_bits(src.to_bits(), F::FRAC_BITS) {
(val, false) => val,
(_, true) => panic!("overflow"),
}
}
}
impl<const FRAC: i32> ToFixed for $Fixed<FRAC> {
/// Converts a fixed-point number.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value
/// does not fit. 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_to_fixed`] instead.
///
/// [`wrapping_to_fixed`]: ToFixed::wrapping_to_fixed
#[inline]
#[track_caller]
fn to_fixed<F: Fixed>(self) -> F {
FromFixed::from_fixed(self)
}
/// Converts a fixed-point number if it fits, otherwise returns [`None`].
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
FromFixed::checked_from_fixed(self)
}
/// Converts a fixed-point number, saturating if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn saturating_to_fixed<F: Fixed>(self) -> F {
FromFixed::saturating_from_fixed(self)
}
/// Converts a fixed-point number, wrapping if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn wrapping_to_fixed<F: Fixed>(self) -> F {
FromFixed::wrapping_from_fixed(self)
}
/// Converts a fixed-point number.
///
/// Returns a [tuple] of the value and a [`bool`]
/// indicating whether an overflow has occurred. On
/// overflow, the wrapped value is returned.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
FromFixed::overflowing_from_fixed(self)
}
/// Converts a fixed-point number, panicking if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// Panics if the value does not fit, even when debug
/// assertions are not enabled.
#[inline]
#[track_caller]
fn unwrapped_to_fixed<F: Fixed>(self) -> F {
FromFixed::unwrapped_from_fixed(self)
}
}
};
}
impl_fixed! { FixedI8, FixedI8, FixedU8, 8, i8, NonZeroI8, Signed }
impl_fixed! { FixedI16, FixedI16, FixedU16, 16, i16, NonZeroI16, Signed }
impl_fixed! { FixedI32, FixedI32, FixedU32, 32, i32, NonZeroI32, Signed }
impl_fixed! { FixedI64, FixedI64, FixedU64, 64, i64, NonZeroI64, Signed }
impl_fixed! { FixedI128, FixedI128, FixedU128, 128, i128, NonZeroI128, Signed }
impl_fixed! { FixedU8, FixedI8, FixedU8, 8, u8, NonZeroU8, Unsigned }
impl_fixed! { FixedU16, FixedI16, FixedU16, 16, u16, NonZeroU16, Unsigned }
impl_fixed! { FixedU32, FixedI32, FixedU32, 32, u32, NonZeroU32, Unsigned }
impl_fixed! { FixedU64, FixedI64, FixedU64, 64, u64, NonZeroU64, Unsigned }
impl_fixed! { FixedU128, FixedI128, FixedU128, 128, u128, NonZeroU128, Unsigned }