diff --git a/tiledb/api/src/convert.rs b/tiledb/api/src/convert.rs index 01d4965d..397d76aa 100644 --- a/tiledb/api/src/convert.rs +++ b/tiledb/api/src/convert.rs @@ -29,3 +29,52 @@ impl CAPIConverter for T { *value } } + +/// Trait for comparisons based on value bits. +/// This exists to work around float NaN which is not equal to itself, +/// but we want it to be for generic operations with TileDB structures. +pub trait BitsEq: PartialEq { + fn bits_eq(&self, other: &Self) -> bool; +} + +macro_rules! derive_reflexive_eq { + ($typename:ty) => { + impl BitsEq for $typename { + fn bits_eq(&self, other: &Self) -> bool { + ::eq(self, other) + } + } + }; +} + +derive_reflexive_eq!(bool); +derive_reflexive_eq!(u8); +derive_reflexive_eq!(u16); +derive_reflexive_eq!(u32); +derive_reflexive_eq!(u64); +derive_reflexive_eq!(i8); +derive_reflexive_eq!(i16); +derive_reflexive_eq!(i32); +derive_reflexive_eq!(i64); + +impl BitsEq for f32 { + fn bits_eq(&self, other: &Self) -> bool { + self.to_bits() == other.to_bits() + } +} + +impl BitsEq for f64 { + fn bits_eq(&self, other: &Self) -> bool { + self.to_bits() == other.to_bits() + } +} + +impl BitsEq for (T1, T2) +where + T1: BitsEq, + T2: BitsEq, +{ + fn bits_eq(&self, other: &Self) -> bool { + self.0.bits_eq(&other.0) && self.1.bits_eq(&other.1) + } +}