From af9cda1078ddf07ce2da875a7e256f7f27e04686 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Mon, 4 Feb 2019 12:46:42 +0100 Subject: [PATCH] reimplement From for fixed-point numbers --- README.md | 10 ++++++++-- RELEASES.md | 6 ++++++ src/convert.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 071cc68..edf03ac 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ numeric primitives are implemented. That is, you can use [`From`] or ## What’s new +### Version 0.3.1 news (unreleased) + + * Reimplement [`From`][`From`] for all fixed-point types which + can represent the integer 1. This was inadvertently removed in + 0.3.0. + ### Version 0.3.0 news (2019-02-03) #### Highlights @@ -48,12 +54,12 @@ numeric primitives are implemented. That is, you can use [`From`] or conversions. * Every fixed-point type now supports comparisons with all primitive number types. - + #### Incompatible changes * The method [`to_int`] was changed; now its return type is generic. * The [`Int`] trait implementation for [`bool`] was removed. - + #### Other changes * The new method [`to_fixed`] was added. diff --git a/RELEASES.md b/RELEASES.md index 9dd6aa2..720da13 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -5,6 +5,12 @@ modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. --> +Version 0.3.1 (unreleased) +========================== + + * Reimplement `From` for all fixed-point types which can + represent the integer 1. This was inadvertently removed in 0.3.0. + Version 0.3.0 (2019-02-03) ========================== diff --git a/src/convert.rs b/src/convert.rs index 0e766ac..6440b29 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -14,7 +14,7 @@ // . use core::ops::{Add, Sub}; -use frac::{IsGreaterOrEqual, IsLessOrEqual, True, Unsigned, U0, U1, U128, U16, U32, U64, U8}; +use frac::{IsGreaterOrEqual, IsLessOrEqual, True, Unsigned, U0, U1, U128, U16, U2, U32, U64, U8}; #[cfg(feature = "f16")] use half::f16; use { @@ -191,6 +191,46 @@ int_to_fixed! { (u64, i64, U64) -> (FixedU128, FixedI128, U128) } int_to_fixed! { (u128, i128) -> (FixedU128, FixedI128) } +macro_rules! bool_to_fixed { + ($DstU:ident, $DstI:ident, $DstBits:ident) => { + // Condition: FracDst <= $DstBits - 1 + impl From for $DstU + where + FracDst: Unsigned + + IsLessOrEqual<$DstBits, Output = True> + + IsLessOrEqual<<$DstBits as Sub>::Output, Output = True>, + { + #[inline] + fn from(src: bool) -> $DstU { + let unshifted = $DstU::::from_bits(src.into()).to_bits(); + let shift = FracDst::U32; + $DstU::::from_bits(unshifted << shift) + } + } + + // Condition: FracDst <= $DstBits - 2 + impl From for $DstI + where + FracDst: Unsigned + + IsLessOrEqual<$DstBits, Output = True> + + IsLessOrEqual<<$DstBits as Sub>::Output, Output = True>, + { + #[inline] + fn from(src: bool) -> $DstI { + let unshifted = $DstI::::from_bits(src.into()).to_bits(); + let shift = FracDst::U32; + $DstI::::from_bits(unshifted << shift) + } + } + }; +} + +bool_to_fixed! { FixedU8, FixedI8, U8 } +bool_to_fixed! { FixedU16, FixedI16, U16 } +bool_to_fixed! { FixedU32, FixedI32, U32 } +bool_to_fixed! { FixedU64, FixedI64, U64 } +bool_to_fixed! { FixedU128, FixedI128, U128 } + macro_rules! fixed_to_int { (($SrcU:ident, $SrcI:ident) -> ($DstU:ident, $DstI:ident)) => { impl From<$SrcU> for $DstU { @@ -390,6 +430,14 @@ mod tests { } } + #[test] + fn from_bool() { + assert_eq!(FixedI8::::from(true), 1); + assert_eq!(FixedI8::::from(false), 0); + assert_eq!(FixedI128::::from(true), 1); + assert_eq!(FixedU128::::from(true), 1); + } + #[test] fn signed_from_float() { type Fix = FixedI8;