From 019c1eeb23cdfe4f31c25f373ebd68891fc833a3 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Thu, 10 Oct 2019 16:47:10 +0200 Subject: [PATCH] add az support --- Cargo.toml | 1 + src/cast.rs | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 250 insertions(+) create mode 100644 src/cast.rs diff --git a/Cargo.toml b/Cargo.toml index ed431b4..c7daadc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ fail-on-warnings = [] [dependencies] typenum = "1.10" +az = "0.3" half = { version = "1.2", optional = true } serde = { version = "1.0.60", default-features = false, optional = true } diff --git a/src/cast.rs b/src/cast.rs new file mode 100644 index 0000000..7f25c15 --- /dev/null +++ b/src/cast.rs @@ -0,0 +1,248 @@ +// Copyright © 2018–2019 Trevor Spiteri + +// This library is free software: you can redistribute it and/or +// modify it under the terms of either +// +// * the Apache License, Version 2.0 or +// * the MIT License +// +// at your option. +// +// You should have recieved copies of the Apache License and the MIT +// License along with the library. If not, see +// and +// . + +use crate::{ + types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8}, + FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64, + FixedU8, +}; +use az::{Cast, CheckedCast, OverflowingCast, SaturatingCast, StaticCast, WrappingCast}; +use core::mem; +#[cfg(feature = "f16")] +use half::f16; + +macro_rules! run_time { + ($Fixed:ident($LeEqU:ident); $Num:ident) => { + impl Cast<$Fixed> for $Num { + #[inline] + fn cast(self) -> $Fixed { + <$Fixed>::from_num(self) + } + } + + impl Cast<$Num> for $Fixed { + #[inline] + fn cast(self) -> $Num { + self.to_num() + } + } + + impl CheckedCast<$Fixed> for $Num { + #[inline] + fn checked_cast(self) -> Option<$Fixed> { + <$Fixed>::checked_from_num(self) + } + } + + impl CheckedCast<$Num> for $Fixed { + #[inline] + fn checked_cast(self) -> Option<$Num> { + self.checked_to_num() + } + } + + impl SaturatingCast<$Fixed> for $Num { + #[inline] + fn saturating_cast(self) -> $Fixed { + <$Fixed>::saturating_from_num(self) + } + } + + impl SaturatingCast<$Num> for $Fixed { + #[inline] + fn saturating_cast(self) -> $Num { + self.saturating_to_num() + } + } + + impl WrappingCast<$Fixed> for $Num { + #[inline] + fn wrapping_cast(self) -> $Fixed { + <$Fixed>::wrapping_from_num(self) + } + } + + impl WrappingCast<$Num> for $Fixed { + #[inline] + fn wrapping_cast(self) -> $Num { + self.wrapping_to_num() + } + } + + impl OverflowingCast<$Fixed> for $Num { + #[inline] + fn overflowing_cast(self) -> ($Fixed, bool) { + <$Fixed>::overflowing_from_num(self) + } + } + + impl OverflowingCast<$Num> for $Fixed { + #[inline] + fn overflowing_cast(self) -> ($Num, bool) { + self.overflowing_to_num() + } + } + }; +} + +macro_rules! compile_time { + (impl<$Frac:ident: $LeEqU:ident> StaticCast<$Dst:ty> for $Src:ty { $cond:expr }) => { + impl<$Frac: $LeEqU> StaticCast<$Dst> for $Src { + #[inline] + fn static_cast(self) -> Option<$Dst> { + if $cond { + Some(az::cast(self)) + } else { + None + } + } + } + }; + + ($FixedI:ident, $FixedU:ident($LeEqU:ident); int $IntI:ident, $IntU:ident) => { + compile_time! { + impl StaticCast<$FixedI> for $IntI { + $FixedI::::INT_NBITS >= 8 * mem::size_of::<$IntI>() as u32 + } + } + + compile_time! { + impl StaticCast<$IntI> for $FixedI { + 8 * mem::size_of::<$IntI>() as u32 >= $FixedI::::INT_NBITS + } + } + + compile_time! { + impl StaticCast<$FixedU> for $IntI { + false + } + } + + compile_time! { + impl StaticCast<$IntI> for $FixedU { + 8 * mem::size_of::<$IntI>() as u32 >= $FixedU::::INT_NBITS + 1 + } + } + + compile_time! { + impl StaticCast<$FixedI> for $IntU { + $FixedI::::INT_NBITS >= 8 * mem::size_of::<$IntU>() as u32 + 1 + } + } + + compile_time! { + impl StaticCast<$IntU> for $FixedI { + false + } + } + + compile_time! { + impl StaticCast<$FixedU> for $IntU { + $FixedU::::INT_NBITS >= 8 * mem::size_of::<$IntU>() as u32 + } + } + + compile_time! { + impl StaticCast<$IntU> for $FixedU { + 8 * mem::size_of::<$IntU>() as u32 >= $FixedU::::INT_NBITS + } + } + }; + + ($Fixed:ident($LeEqU:ident); float $Float:ident) => { + compile_time! { + impl StaticCast<$Fixed> for $Float { + false + } + } + + compile_time! { + impl StaticCast<$Float> for $Fixed { + true + } + } + }; +} + +macro_rules! cross_num { + ($Fixed:ident($LeEqU:ident); $($Num:ident,)*) => { $( + run_time! { $Fixed($LeEqU); $Num } + )* }; + ($($Fixed:ident($LeEqU:ident),)*) => { $( + cross_num! { + $Fixed($LeEqU); + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize, + f32, f64, + } + #[cfg(feature = "f16")] + cross_num! { + $Fixed($LeEqU); + f16, + } + )* }; +} + +cross_num! { + FixedI8(LeEqU8), FixedI16(LeEqU16), FixedI32(LeEqU32), FixedI64(LeEqU64), FixedI128(LeEqU128), + FixedU8(LeEqU8), FixedU16(LeEqU16), FixedU32(LeEqU32), FixedU64(LeEqU64), FixedU128(LeEqU128), +} + +macro_rules! cross_int { + ($FixedI:ident, $FixedU:ident($LeEqU:ident); $(($IntI:ident, $IntU:ident),)*) => { $( + compile_time! { $FixedI, $FixedU($LeEqU); int $IntI, $IntU } + )* }; + ($($FixedI:ident, $FixedU:ident($LeEqU:ident),)*) => { $( + cross_int! { + $FixedI, $FixedU($LeEqU); + (i8, u8), + (i16, u16), + (i32, u32), + (i64, u64), + (i128, u128), + (isize, usize), + } + )* }; +} + +cross_int! { + FixedI8, FixedU8(LeEqU8), + FixedI16, FixedU16(LeEqU16), + FixedI32, FixedU32(LeEqU32), + FixedI64, FixedU64(LeEqU64), + FixedI128, FixedU128(LeEqU128), +} + +macro_rules! cross_float { + ($Fixed:ident($LeEqU:ident); $($Float:ident,)*) => { $( + compile_time! { $Fixed($LeEqU); float $Float } + )* }; + ($($Fixed:ident($LeEqU:ident),)*) => { $( + cross_float! { + $Fixed($LeEqU); + f32, f64, + } + #[cfg(feature = "f16")] + cross_float! { + $Fixed($LeEqU); + f16, + } + )* }; +} + +cross_float! { + FixedI8(LeEqU8), FixedI16(LeEqU16), FixedI32(LeEqU32), FixedI64(LeEqU64), FixedI128(LeEqU128), + FixedU8(LeEqU8), FixedU16(LeEqU16), FixedU32(LeEqU32), FixedU64(LeEqU64), FixedU128(LeEqU128), +} diff --git a/src/lib.rs b/src/lib.rs index c7bbbaf..03a0ea5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -235,6 +235,7 @@ extern crate std; mod macros; mod arith; +mod cast; mod cmp; pub mod consts; mod convert;