diff --git a/README.md b/README.md index 27bd808..590ba9d 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ The conversions supported cover the following cases. [`Fixed`][tf-1-9] trait, and to the [`Wrapping`][w-1-9] and [`Unwrapped`][u-1-9] wrappers: * [`is_zero`][f-iz-1-9] + * The following associated types were added to the [`Fixed`][tf-1-9] trait: + * [`Signed`][tf-s-1-9], [`Unsigned`][tf-u-1-9] * The following traits from the [*bytemuck* crate] were implemented for all fixed-point numbers, added as supertraits to the [`Fixed`][tf-1-9] trait, and implemented for the [`Wrapping`][w-1-9] and [`Unwrapped`][u-1-9] @@ -126,6 +128,8 @@ The conversions supported cover the following cases. [leu64-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/types/extra/trait.LeEqU64.html [leu8-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/types/extra/trait.LeEqU8.html [tf-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html +[tf-s-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html#associatedtype.Signed +[tf-u-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html#associatedtype.Unsigned [u-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.Unwrapped.html [uns-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/types/extra/trait.Unsigned.html [w-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.Wrapping.html diff --git a/RELEASES.md b/RELEASES.md index 3112ee4..2123fef 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -12,6 +12,8 @@ Version 1.9.0 (unreleased) [`Fixed`][tf-1-9] trait, and to the [`Wrapping`][w-1-9] and [`Unwrapped`][u-1-9] wrappers: * [`is_zero`][f-iz-1-9] + * The following associated types were added to the [`Fixed`][tf-1-9] trait: + * [`Signed`][tf-s-1-9], [`Unsigned`][tf-u-1-9] * The following traits from the [*bytemuck* crate] were implemented for all fixed-point numbers, added as supertraits to the [`Fixed`][tf-1-9] trait, and implemented for the [`Wrapping`][w-1-9] and [`Unwrapped`][u-1-9] @@ -43,6 +45,8 @@ Compatibility notes [leu64-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/types/extra/trait.LeEqU64.html [leu8-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/types/extra/trait.LeEqU8.html [tf-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html +[tf-s-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html#associatedtype.Signed +[tf-u-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/traits/trait.Fixed.html#associatedtype.Unsigned [u-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.Unwrapped.html [uns-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/types/extra/trait.Unsigned.html [w-1-9]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.Wrapping.html diff --git a/src/traits.rs b/src/traits.rs index fcee112..2621956 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -296,20 +296,108 @@ where Self: Sealed, { /// The primitive integer underlying type. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{traits::Fixed, types::I16F16}; + /// // 32-bit DELTA is 0x0000_0001_i32 + /// const DELTA_BITS: ::Bits = I16F16::DELTA.to_bits(); + /// assert_eq!(DELTA_BITS, 1i32); + /// ``` type Bits; /// A byte array with the same size as the type. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{traits::Fixed, types::I16F16}; + /// // 32-bit DELTA is 0x0000_0001_i32 + /// const DELTA_LE_BYTES: ::Bytes = I16F16::DELTA.to_le_bytes(); + /// assert_eq!(DELTA_LE_BYTES, 1i32.to_le_bytes()); + /// ``` type Bytes; - /// The number of fractional bits. + /// The number of fractional bits as a compile-time [`Unsigned`] as provided + /// by the [*typenum* crate]. /// /// \::Frac::[U32] is equivalent to /// \::[FRAC\_NBITS]. /// + /// `Frac` can be used as the generic parameter of fixed-point number types. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{traits::Fixed, types::extra::U16, FixedI32, FixedI64}; + /// type Fix1 = FixedI32::; + /// assert_eq!(Fix1::FRAC_NBITS, 16); + /// assert_eq!(Fix1::INT_NBITS, 32 - 16); + /// type Fix2 = FixedI64::<::Frac>; + /// assert_eq!(Fix2::FRAC_NBITS, 16); + /// assert_eq!(Fix2::INT_NBITS, 64 - 16); + /// ``` + /// + /// [*typenum* crate]: https://crates.io/crates/typenum /// [U32]: crate::types::extra::Unsigned::U32 /// [FRAC\_NBITS]: Fixed::FRAC_NBITS type Frac: Unsigned; + /// An unsigned fixed-point number type with the same number of integer and + /// fractional bits as `Self`. + /// + /// If `Self` is signed, then `Self::Signed` is the same as `Self`. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{ + /// traits::Fixed, + /// types::{I16F16, U16F16}, + /// }; + /// // I16F16::Signed is I16F16 + /// assert_eq!(::Signed::FRAC_NBITS, I16F16::FRAC_NBITS); + /// assert_eq!(::Signed::INT_NBITS, I16F16::INT_NBITS); + /// assert_eq!(::Signed::IS_SIGNED, I16F16::IS_SIGNED); + /// // U16F16::Signed is I16F16 + /// assert_eq!(::Signed::FRAC_NBITS, I16F16::FRAC_NBITS); + /// assert_eq!(::Signed::INT_NBITS, I16F16::INT_NBITS); + /// assert_eq!(::Signed::IS_SIGNED, I16F16::IS_SIGNED); + /// ``` + /// + /// [I16F16]: crate::types::I16F16 + /// [U16F16]: crate::types::U16F16 + /// [types]: crate::types + type Signed: FixedSigned; + + /// An unsigned fixed-point number type with the same number of integer and + /// fractional bits as `Self`. + /// + /// If `Self` is unsigned, then `Self::Unsigned` is the same as `Self`. + /// + /// # Examples + /// + /// ```rust + /// use fixed::{ + /// traits::Fixed, + /// types::{I16F16, U16F16}, + /// }; + /// // I16F16::Unsigned is U16F16 + /// assert_eq!(::Unsigned::FRAC_NBITS, U16F16::FRAC_NBITS); + /// assert_eq!(::Unsigned::INT_NBITS, U16F16::INT_NBITS); + /// assert_eq!(::Unsigned::IS_SIGNED, U16F16::IS_SIGNED); + /// // U16F16::Unsigned is U16F16 + /// assert_eq!(::Unsigned::FRAC_NBITS, U16F16::FRAC_NBITS); + /// assert_eq!(::Unsigned::INT_NBITS, U16F16::INT_NBITS); + /// assert_eq!(::Unsigned::IS_SIGNED, U16F16::IS_SIGNED); + /// ``` + /// + /// [I16F16]: crate::types::I16F16 + /// [U16F16]: crate::types::U16F16 + /// [types]: crate::types + type Unsigned: FixedUnsigned; + /// Zero. /// /// See also FixedI32::[ZERO][FixedI32::ZERO] and @@ -2096,11 +2184,10 @@ where /// This trait is sealed and cannot be implemented for more types; it /// is implemented for [`FixedI8`], [`FixedI16`], [`FixedI32`], /// [`FixedI64`], and [`FixedI128`]. -pub trait FixedSigned: Fixed + Neg { - /// An unsigned fixed-point number type with the same number of - /// integer and fractional bits as `Self`. - type Unsigned: FixedUnsigned; - +pub trait FixedSigned: Fixed +where + Self: Neg, +{ /// Returns the number of bits required to represent the value. /// /// See also FixedI32::[signed\_bits][FixedI32::signed_bits]. @@ -3088,13 +3175,15 @@ macro_rules! trait_delegate { } macro_rules! impl_fixed { - ($Fixed:ident, $UFixed:ident, $LeEqU:ident, $Bits:ident, $Signedness:tt) => { + ($Fixed:ident, $IFixed:ident, $UFixed:ident, $LeEqU:ident, $Bits:ident, $Signedness:tt) => { impl FixedOptionalFeatures for $Fixed {} impl Fixed for $Fixed { type Bits = $Bits; type Bytes = [u8; mem::size_of::<$Bits>()]; type Frac = Frac; + type Signed = $IFixed; + type Unsigned = $UFixed; const ZERO: Self = Self::ZERO; const DELTA: Self = Self::DELTA; const MIN: Self = Self::MIN; @@ -3490,7 +3579,6 @@ macro_rules! impl_fixed { if_signed! { $Signedness; impl FixedSigned for $Fixed { - type Unsigned = $UFixed; trait_delegate! { fn signed_bits(self) -> u32 } trait_delegate! { fn abs(self) -> Self } trait_delegate! { fn unsigned_abs(self) -> Self::Unsigned } @@ -3525,13 +3613,13 @@ macro_rules! impl_fixed { }; } -impl_fixed! { FixedI8, FixedU8, LeEqU8, i8, Signed } -impl_fixed! { FixedI16, FixedU16, LeEqU16, i16, Signed } -impl_fixed! { FixedI32, FixedU32, LeEqU32, i32, Signed } -impl_fixed! { FixedI64, FixedU64, LeEqU64, i64, Signed } -impl_fixed! { FixedI128, FixedU128, LeEqU128, i128, Signed } -impl_fixed! { FixedU8, FixedU8, LeEqU8, u8, Unsigned } -impl_fixed! { FixedU16, FixedU16, LeEqU16, u16, Unsigned } -impl_fixed! { FixedU32, FixedU32, LeEqU32, u32, Unsigned } -impl_fixed! { FixedU64, FixedU64, LeEqU64, u64, Unsigned } -impl_fixed! { FixedU128, FixedU128, LeEqU128, u128, Unsigned } +impl_fixed! { FixedI8, FixedI8, FixedU8, LeEqU8, i8, Signed } +impl_fixed! { FixedI16, FixedI16, FixedU16, LeEqU16, i16, Signed } +impl_fixed! { FixedI32, FixedI32, FixedU32, LeEqU32, i32, Signed } +impl_fixed! { FixedI64, FixedI64, FixedU64, LeEqU64, i64, Signed } +impl_fixed! { FixedI128, FixedI128, FixedU128, LeEqU128, i128, Signed } +impl_fixed! { FixedU8, FixedI8, FixedU8, LeEqU8, u8, Unsigned } +impl_fixed! { FixedU16, FixedI16, FixedU16, LeEqU16, u16, Unsigned } +impl_fixed! { FixedU32, FixedI32, FixedU32, LeEqU32, u32, Unsigned } +impl_fixed! { FixedU64, FixedI64, FixedU64, LeEqU64, u64, Unsigned } +impl_fixed! { FixedU128, FixedI128, FixedU128, LeEqU128, u128, Unsigned }