vortex_array/arrays/primitive/
native_value.rs

1use vortex_dtype::{NativePType, half};
2
3/// NativeValue serves as a wrapper type to allow us to implement Hash and Eq on all primitive types.
4///
5/// Rust does not define Hash/Eq for any of the float types due to the presence of
6/// NaN and +/- 0. We don't care about storing multiple NaNs or zeros in our dictionaries,
7/// so we define simple bit-wise Hash/Eq for the Value-wrapped versions of these types.
8#[repr(transparent)]
9#[derive(Copy, Clone, Debug)]
10pub struct NativeValue<T>(pub T);
11
12impl<T: NativePType> PartialEq<NativeValue<T>> for NativeValue<T> {
13    fn eq(&self, other: &NativeValue<T>) -> bool {
14        self.0.is_eq(other.0)
15    }
16}
17
18impl<T: NativePType> Eq for NativeValue<T> {}
19
20macro_rules! prim_value {
21    ($typ:ty) => {
22        impl core::hash::Hash for NativeValue<$typ> {
23            fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
24                self.0.hash(state);
25            }
26        }
27    };
28}
29
30macro_rules! float_value {
31    ($typ:ty) => {
32        impl core::hash::Hash for NativeValue<$typ> {
33            fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
34                self.0.to_bits().hash(state);
35            }
36        }
37    };
38}
39
40prim_value!(u8);
41prim_value!(u16);
42prim_value!(u32);
43prim_value!(u64);
44prim_value!(i8);
45prim_value!(i16);
46prim_value!(i32);
47prim_value!(i64);
48float_value!(half::f16);
49float_value!(f32);
50float_value!(f64);