Skip to content

Commit

Permalink
Add support for bytemuck
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielDertoni authored and mbrubeck committed Nov 6, 2022
1 parent 9d3819a commit 2d6c541
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rand = { version = "0.8.3", optional = true, default-features = false }
arbitrary = { version = "1.0.0", optional = true }
proptest = { version = "1.0.0", optional = true }
speedy = { version = "0.8.3", optional = true, default-features = false }
bytemuck = { version = "1.12.2", optional = true, default-features = false }

[dev-dependencies]
serde_test = "1.0"
Expand Down
40 changes: 40 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2173,3 +2173,43 @@ mod impl_arbitrary {
}
impl_arbitrary! { f32, f64 }
}

#[cfg(feature = "bytemuck")]
mod impl_bytemuck {
use super::{NotNan, OrderedFloat, Float};
use bytemuck::{CheckedBitPattern, AnyBitPattern, NoUninit, Pod, Zeroable};

unsafe impl<T: Zeroable> Zeroable for OrderedFloat<T> {}

// The zero bit pattern is indeed not a NaN bit pattern.
unsafe impl<T: Zeroable> Zeroable for NotNan<T> {}

unsafe impl<T: Pod> Pod for OrderedFloat<T> {}

// `NotNan<T>` can only implement `NoUninit` and not `Pod`, since not every bit pattern is
// valid (NaN bit patterns are invalid). `NoUninit` guarantees that we can read any bit pattern
// from the value, which is fine in this case.
unsafe impl<T: NoUninit> NoUninit for NotNan<T> {}

unsafe impl<T: Float + AnyBitPattern> CheckedBitPattern for NotNan<T> {
type Bits = T;

fn is_valid_bit_pattern(bits: &Self::Bits) -> bool {
!bits.is_nan()
}
}

#[test]
fn test_not_nan_bit_pattern() {
use bytemuck::checked::{try_cast, CheckedCastError};

let nan = f64::NAN;
assert_eq!(
try_cast::<f64, NotNan<f64>>(nan),
Err(CheckedCastError::InvalidBitPattern),
);

let pi = core::f64::consts::PI;
assert!(try_cast::<f64, NotNan<f64>>(pi).is_ok());
}
}

0 comments on commit 2d6c541

Please sign in to comment.