polars_utils/
float.rs

1/// # Safety
2/// unsafe code downstream relies on the correct is_float call
3pub unsafe trait IsFloat: private::Sealed + Sized {
4    fn is_float() -> bool {
5        false
6    }
7
8    fn is_f32() -> bool {
9        false
10    }
11
12    fn is_f64() -> bool {
13        false
14    }
15
16    fn nan_value() -> Self {
17        unimplemented!()
18    }
19
20    fn pos_inf_value() -> Self {
21        unimplemented!()
22    }
23
24    fn neg_inf_value() -> Self {
25        unimplemented!()
26    }
27
28    #[allow(clippy::wrong_self_convention)]
29    fn is_nan(&self) -> bool
30    where
31        Self: Sized,
32    {
33        false
34    }
35    #[allow(clippy::wrong_self_convention)]
36    fn is_finite(&self) -> bool
37    where
38        Self: Sized,
39    {
40        true
41    }
42}
43
44unsafe impl IsFloat for i8 {}
45unsafe impl IsFloat for i16 {}
46unsafe impl IsFloat for i32 {}
47unsafe impl IsFloat for i64 {}
48unsafe impl IsFloat for i128 {}
49unsafe impl IsFloat for u8 {}
50unsafe impl IsFloat for u16 {}
51unsafe impl IsFloat for u32 {}
52unsafe impl IsFloat for u64 {}
53unsafe impl IsFloat for u128 {}
54unsafe impl IsFloat for usize {}
55unsafe impl IsFloat for &str {}
56unsafe impl IsFloat for &[u8] {}
57unsafe impl IsFloat for bool {}
58unsafe impl<T: IsFloat> IsFloat for Option<T> {}
59
60mod private {
61    pub trait Sealed {}
62    impl Sealed for i8 {}
63    impl Sealed for i16 {}
64    impl Sealed for i32 {}
65    impl Sealed for i64 {}
66    impl Sealed for i128 {}
67    impl Sealed for u8 {}
68    impl Sealed for u16 {}
69    impl Sealed for u32 {}
70    impl Sealed for u64 {}
71    impl Sealed for u128 {}
72    impl Sealed for usize {}
73    impl Sealed for f32 {}
74    impl Sealed for f64 {}
75    impl Sealed for &str {}
76    impl Sealed for &[u8] {}
77    impl Sealed for bool {}
78    impl<T: Sealed> Sealed for Option<T> {}
79}
80
81macro_rules! impl_is_float {
82    ($tp:ty, $is_f32:literal, $is_f64:literal) => {
83        unsafe impl IsFloat for $tp {
84            #[inline]
85            fn is_float() -> bool {
86                true
87            }
88
89            fn is_f32() -> bool {
90                $is_f32
91            }
92
93            fn is_f64() -> bool {
94                $is_f64
95            }
96
97            fn nan_value() -> Self {
98                Self::NAN
99            }
100
101            fn pos_inf_value() -> Self {
102                Self::INFINITY
103            }
104
105            fn neg_inf_value() -> Self {
106                Self::NEG_INFINITY
107            }
108
109            #[inline]
110            fn is_nan(&self) -> bool {
111                <$tp>::is_nan(*self)
112            }
113
114            #[inline]
115            fn is_finite(&self) -> bool {
116                <$tp>::is_finite(*self)
117            }
118        }
119    };
120}
121
122impl_is_float!(f32, true, false);
123impl_is_float!(f64, false, true);