Skip to content

Commit

Permalink
Implement AsPrimitive for OrderedFloat (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
andylokandy authored Sep 10, 2022
1 parent 8962ffc commit e4cf02d
Showing 1 changed file with 47 additions and 1 deletion.
48 changes: 47 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]
#![allow(clippy::derive_partial_eq_without_eq)]

//! Wrappers for total order on Floats. See the [`OrderedFloat`] and [`NotNan`] docs for details.

Expand All @@ -27,7 +28,9 @@ use core::str::FromStr;
use num_traits::float::FloatCore as Float;
#[cfg(feature = "std")]
pub use num_traits::Float;
use num_traits::{Bounded, FromPrimitive, Num, NumCast, One, Signed, ToPrimitive, Zero};
use num_traits::{
AsPrimitive, Bounded, FromPrimitive, Num, NumCast, One, Signed, ToPrimitive, Zero,
};

// masks for the parts of the IEEE 754 float
const SIGN_MASK: u64 = 0x8000000000000000u64;
Expand Down Expand Up @@ -452,6 +455,49 @@ impl<T: NumCast> NumCast for OrderedFloat<T> {
}
}

macro_rules! impl_as_primitive {
(@ (OrderedFloat<$T: ty>) => $(#[$cfg:meta])* impl (OrderedFloat<$U: ty>) ) => {
$(#[$cfg])*
impl AsPrimitive<OrderedFloat<$U>> for OrderedFloat<$T> {
#[inline] fn as_(self) -> OrderedFloat<$U> { OrderedFloat(self.0 as $U) }
}
};
(@ ($T: ty) => $(#[$cfg:meta])* impl (OrderedFloat<$U: ty>) ) => {
$(#[$cfg])*
impl AsPrimitive<OrderedFloat<$U>> for $T {
#[inline] fn as_(self) -> OrderedFloat<$U> { OrderedFloat(self as $U) }
}
};
(@ (OrderedFloat<$T: ty>) => $(#[$cfg:meta])* impl ($U: ty) ) => {
$(#[$cfg])*
impl AsPrimitive<$U> for OrderedFloat<$T> {
#[inline] fn as_(self) -> $U { self.0 as $U }
}
};
($T: tt => { $( $U: tt ),* } ) => {$(
impl_as_primitive!(@ $T => impl $U);
)*};
}

impl_as_primitive!((OrderedFloat<f32>) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((OrderedFloat<f64>) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });

impl_as_primitive!((u8) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((i8) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((u16) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((i16) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((u32) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((i32) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((u64) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((i64) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((usize) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((isize) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((f32) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });
impl_as_primitive!((f64) => { (OrderedFloat<f32>), (OrderedFloat<f64>) });

impl_as_primitive!((OrderedFloat<f32>) => { (u8), (u16), (u32), (u64), (usize), (i8), (i16), (i32), (i64), (isize), (f32), (f64) });
impl_as_primitive!((OrderedFloat<f64>) => { (u8), (u16), (u32), (u64), (usize), (i8), (i16), (i32), (i64), (isize), (f32), (f64) });

impl<T: FromPrimitive> FromPrimitive for OrderedFloat<T> {
fn from_i64(n: i64) -> Option<Self> {
T::from_i64(n).map(OrderedFloat)
Expand Down

0 comments on commit e4cf02d

Please sign in to comment.