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 &str {}
54unsafe impl IsFloat for &[u8] {}
55unsafe impl IsFloat for bool {}
56unsafe impl<T: IsFloat> IsFloat for Option<T> {}
57
58mod private {
59    pub trait Sealed {}
60    impl Sealed for i8 {}
61    impl Sealed for i16 {}
62    impl Sealed for i32 {}
63    impl Sealed for i64 {}
64    impl Sealed for i128 {}
65    impl Sealed for u8 {}
66    impl Sealed for u16 {}
67    impl Sealed for u32 {}
68    impl Sealed for u64 {}
69    impl Sealed for f32 {}
70    impl Sealed for f64 {}
71    impl Sealed for &str {}
72    impl Sealed for &[u8] {}
73    impl Sealed for bool {}
74    impl<T: Sealed> Sealed for Option<T> {}
75}
76
77macro_rules! impl_is_float {
78    ($tp:ty, $is_f32:literal, $is_f64:literal) => {
79        unsafe impl IsFloat for $tp {
80            #[inline]
81            fn is_float() -> bool {
82                true
83            }
84
85            fn is_f32() -> bool {
86                $is_f32
87            }
88
89            fn is_f64() -> bool {
90                $is_f64
91            }
92
93            fn nan_value() -> Self {
94                Self::NAN
95            }
96
97            fn pos_inf_value() -> Self {
98                Self::INFINITY
99            }
100
101            fn neg_inf_value() -> Self {
102                Self::NEG_INFINITY
103            }
104
105            #[inline]
106            fn is_nan(&self) -> bool {
107                <$tp>::is_nan(*self)
108            }
109
110            #[inline]
111            fn is_finite(&self) -> bool {
112                <$tp>::is_finite(*self)
113            }
114        }
115    };
116}
117
118impl_is_float!(f32, true, false);
119impl_is_float!(f64, false, true);