Skip to content

Commit 2d6c541

Browse files
GabrielDertonimbrubeck
authored andcommitted
Add support for bytemuck
1 parent 9d3819a commit 2d6c541

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ rand = { version = "0.8.3", optional = true, default-features = false }
2222
arbitrary = { version = "1.0.0", optional = true }
2323
proptest = { version = "1.0.0", optional = true }
2424
speedy = { version = "0.8.3", optional = true, default-features = false }
25+
bytemuck = { version = "1.12.2", optional = true, default-features = false }
2526

2627
[dev-dependencies]
2728
serde_test = "1.0"

src/lib.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,3 +2173,43 @@ mod impl_arbitrary {
21732173
}
21742174
impl_arbitrary! { f32, f64 }
21752175
}
2176+
2177+
#[cfg(feature = "bytemuck")]
2178+
mod impl_bytemuck {
2179+
use super::{NotNan, OrderedFloat, Float};
2180+
use bytemuck::{CheckedBitPattern, AnyBitPattern, NoUninit, Pod, Zeroable};
2181+
2182+
unsafe impl<T: Zeroable> Zeroable for OrderedFloat<T> {}
2183+
2184+
// The zero bit pattern is indeed not a NaN bit pattern.
2185+
unsafe impl<T: Zeroable> Zeroable for NotNan<T> {}
2186+
2187+
unsafe impl<T: Pod> Pod for OrderedFloat<T> {}
2188+
2189+
// `NotNan<T>` can only implement `NoUninit` and not `Pod`, since not every bit pattern is
2190+
// valid (NaN bit patterns are invalid). `NoUninit` guarantees that we can read any bit pattern
2191+
// from the value, which is fine in this case.
2192+
unsafe impl<T: NoUninit> NoUninit for NotNan<T> {}
2193+
2194+
unsafe impl<T: Float + AnyBitPattern> CheckedBitPattern for NotNan<T> {
2195+
type Bits = T;
2196+
2197+
fn is_valid_bit_pattern(bits: &Self::Bits) -> bool {
2198+
!bits.is_nan()
2199+
}
2200+
}
2201+
2202+
#[test]
2203+
fn test_not_nan_bit_pattern() {
2204+
use bytemuck::checked::{try_cast, CheckedCastError};
2205+
2206+
let nan = f64::NAN;
2207+
assert_eq!(
2208+
try_cast::<f64, NotNan<f64>>(nan),
2209+
Err(CheckedCastError::InvalidBitPattern),
2210+
);
2211+
2212+
let pi = core::f64::consts::PI;
2213+
assert!(try_cast::<f64, NotNan<f64>>(pi).is_ok());
2214+
}
2215+
}

0 commit comments

Comments
 (0)